Skip to content

Commit

Permalink
Code refactoring & added more testcases (#23)
Browse files Browse the repository at this point in the history
* Added new testcases

* Update field name to fit with the original response.

* Added type hinting.

* `StudentFactory` now returning Unicode Vietnamese to match original data.
  • Loading branch information
hwangswan authored Dec 13, 2024
1 parent 355e7f9 commit 8f6b38e
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 48 deletions.
5 changes: 3 additions & 2 deletions check.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import csv
from argparse import ArgumentParser
from pathlib import Path
from typing import Dict
import yaml
from src.dstn import DSTNSingleRequest, DSTNListRequest


def handle_single_request(config, args):
def handle_single_request(config: Dict[str, str], args: Dict[str, str]) -> None:
"""Handling single request
Args:
Expand Down Expand Up @@ -49,7 +50,7 @@ def handle_single_request(config, args):
print(record)


def handle_multiple_request(config, args):
def handle_multiple_request(config: Dict[str, str], args: Dict[str, str]) -> None:
"""Handling multiple check request
Args:
Expand Down
63 changes: 48 additions & 15 deletions src/dstn.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

from abc import abstractmethod
from typing import Dict, List, Tuple
import requests as rq
import termtables as tt
from .exception import NotFoundException, HTTPException
Expand All @@ -25,7 +26,10 @@ class DSTNItem:
- Me A. Doge <[email protected]>
"""

def __init__(self, **kwargs):
# Informations stored
info: Dict[str, str]

def __init__(self, **kwargs) -> None:
"""Initialization
Author(s):
Expand All @@ -43,7 +47,7 @@ def __init__(self, **kwargs):
for key, value in json_data.items():
self.info[key] = value

def get_info(self):
def get_info(self) -> str:
"""Get info saved inside this item (for testing).
Returns:
Expand All @@ -55,7 +59,7 @@ def get_info(self):

return self.info

def get_language(self):
def get_language(self) -> str:
"""Get the language used when parsing the result.
Returns:
Expand All @@ -67,11 +71,11 @@ def get_language(self):

return self.info["language"]

def get_string(self):
def get_string(self) -> str:
"""Parsing class property to formatted (tabular) UI
Returns:
_str_: _the tabular string_
str: _the tabular string_
Author(s):
- Quan H. Tran <[email protected]>
Expand Down Expand Up @@ -111,7 +115,17 @@ def get_string(self):

return tt.to_string(dstn_string, style=tt.styles.ascii_thin_double)

def __str__(self):
def __str__(self) -> str:
"""Get the string representation (tabular) of the Item.
This is just basically calling `get_string` method.
Returns:
str: tabular string.
Author(s):
- Xuong L. Tran <[email protected]>
"""

return self.get_string()


Expand All @@ -123,7 +137,19 @@ class DSTNRequest:
- Me A. Doge <[email protected]>
"""

def __init__(self, **kwargs):
# Base API URL
api_url: str

# Result parameters
results: Dict[str, str]

# Headers for the request.
headers: Dict[str, str]

# Query parameter
params: Dict[str, str]

def __init__(self, **kwargs) -> None:
"""Initialize
Author(s):
Expand Down Expand Up @@ -165,6 +191,7 @@ def get(self):
headers=self.headers,
timeout=60,
)

except rq.exceptions.Timeout as timeout_exception_handler:
raise HTTPException(
"Connection timeout") from timeout_exception_handler
Expand Down Expand Up @@ -199,7 +226,10 @@ class DSTNSingleRequest(DSTNRequest):
- Me A. Doge <[email protected]>
"""

def __init__(self, **kwargs):
# Language used in the report.
language: str

def __init__(self, **kwargs) -> None:
"""Initialization
Author(s):
Expand All @@ -210,13 +240,13 @@ def __init__(self, **kwargs):

super().__init__(**kwargs)

self.__language = kwargs.get("language", None)
self.language = kwargs.get("language", None)

# Update masv and sobang to parameters
self.params["masv"] = kwargs.get("student_name", None)
self.params["sobang"] = kwargs.get("degree_id", None)

def process(self):
def process(self) -> List[DSTNItem]:
"""Processing to get the result.
Author(s):
Expand Down Expand Up @@ -245,7 +275,7 @@ def process(self):
else:
for record in response_json["rows"]:
record_list.append(
DSTNItem(json=record, language=self.__language))
DSTNItem(json=record, language=self.language))

return record_list

Expand All @@ -257,17 +287,20 @@ class DSTNListRequest(DSTNRequest):
- Xuong L. Tran <[email protected]>
"""

def __init__(self, **kwargs):
# Student list read from .csv file.
student_list: List[Tuple[str, str]]

def __init__(self, **kwargs) -> None:
"""Initialization
Author(s):
- Xuong L. Tran <[email protected]>
"""

super().__init__(**kwargs)
self.__student_list = kwargs.get("student_list", None)
self.student_list = kwargs.get("student_list", None)

def process(self):
def process(self) -> List[Tuple[str, str, str]]:
"""Processing to get the result.
Author(s):
Expand All @@ -276,7 +309,7 @@ def process(self):

status_list = []

for name, degree_id in self.__student_list:
for name, degree_id in self.student_list:
self.params["masv"] = name
self.params["sobang"] = degree_id

Expand Down
19 changes: 15 additions & 4 deletions src/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- Xuong L. Tran <[email protected]>
"""

from typing import Optional, Any


class HTTPException(Exception):
"""HttpException for DSTN
Expand All @@ -14,7 +16,13 @@ class HTTPException(Exception):
- Xuong L. Tran <[email protected]>
"""

def __init__(self, message=None, **kwargs):
# Extra message to return in exception
message: str

# Response from the request
response: Any

def __init__(self, message: Optional[str] = None, **kwargs) -> str:
"""Initialization
Args:
Expand All @@ -29,7 +37,7 @@ def __init__(self, message=None, **kwargs):
self.message = message
self.response = kwargs.get("response", None)

def __str__(self):
def __str__(self) -> str:
"""__str__ method
Returns:
Expand All @@ -53,7 +61,10 @@ class NotFoundException(Exception):
- Xuong L. Tran <[email protected]>
"""

def __init__(self, *args):
# Extra message to return in exception
message: str

def __init__(self, *args) -> None:
"""Initialize
Author(s):
Expand All @@ -64,7 +75,7 @@ def __init__(self, *args):

self.message = args[0] if args else None

def __str__(self):
def __str__(self) -> str:
"""__str__ method
Returns:
Expand Down
51 changes: 32 additions & 19 deletions tests/factory/student_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datetime
import string
import random
from typing import Dict, Optional
from faker import Faker
from .type.student_type import ProgramType, GraduationType, MajorType

Expand All @@ -18,6 +19,18 @@ class StudentFactory:
- Xuong L. Tran <[email protected]>
"""

# Faker instance to generate fake data
fake: Faker

# Available programs
program_type: Dict[str, ProgramType]

# Available majors
major: Dict[str, MajorType]

# Available graduation type
graduation_type: Dict[str, GraduationType]

def __init__(self):
"""Intialize the class.
Expand All @@ -30,30 +43,30 @@ def __init__(self):

# Available program types of a student.
self.program_type = {
"CQ": ProgramType(name_vn="Chinh quy", name_en="Full-time", code=0),
"CLC": ProgramType(name_vn="Chat luong cao", name_en="High-quality", code=7),
"TT": ProgramType(name_vn="Tien tien", name_en="Advanced Program", code=5),
"VP": ProgramType(name_vn="Viet Phap", name_en="Vietnamese-France", code=6)
"CQ": ProgramType(name_vn="Chính quy", name_en="Full-time", code=0),
"CLC": ProgramType(name_vn="Chất lượng cao", name_en="High-quality", code=7),
"TT": ProgramType(name_vn="Tiên tiến", name_en="Advanced Program", code=5),
"VP": ProgramType(name_vn="Việt Pháp", name_en="Vietnamese-France", code=6)
}

# Available majors of a student.
self.major = {
"CNTT": MajorType(name_vn="Cong nghe thong tin", name_en="Information Technology"),
"HTTT": MajorType(name_vn="He thong thong tin", name_en="Information Systems"),
"KHMT": MajorType(name_vn="Khoa hoc may tinh", name_en="Computer Science"),
"CNPM": MajorType(name_vn="Cong nghe phan mem", name_en="Software Engineering"),
"CNTT": MajorType(name_vn="Công nghệ thông tin", name_en="Information Technology"),
"HTTT": MajorType(name_vn="Hệ thống thông tin", name_en="Information Systems"),
"KHMT": MajorType(name_vn="Khoa học máy tính", name_en="Computer Science"),
"CNPM": MajorType(name_vn="Công nghệ phần mềm", name_en="Software Engineering"),
}

# Available graduation type of a student.
self.graduation_type = {
"XS": GraduationType(name_vn="Xuat sac", name_en="Excellent"),
"G": GraduationType(name_vn="Gioi", name_en="Very good"),
"KH": GraduationType(name_vn="Kha", name_en="Good"),
"TBK": GraduationType(name_vn="Trung binh kha", name_en="Average good"),
"TB": GraduationType(name_vn="Trung binh", name_en="Average")
"XS": GraduationType(name_vn="Xuất sắc", name_en="Excellent"),
"G": GraduationType(name_vn="Giỏi", name_en="Very good"),
"KH": GraduationType(name_vn="Khá", name_en="Good"),
"TBK": GraduationType(name_vn="Trung bình khá", name_en="Average good"),
"TB": GraduationType(name_vn="Trung bình", name_en="Average")
}

def get_mssv(self, class_of: int, program="CQ") -> str:
def get_mssv(self, class_of: int, program: Optional[str] = "CQ") -> str:
"""Create Student ID from a class (of year) and program.
The format should be
Expand All @@ -70,7 +83,7 @@ def get_mssv(self, class_of: int, program="CQ") -> str:
- Xuong L. Tran <[email protected]>
"""

prefix = class_of.year % 100
prefix = class_of % 100
program_code = self.program_type[program].get_code()
generated = random.randint(0, 999)

Expand Down Expand Up @@ -110,7 +123,7 @@ def generate_sobang() -> str:

return f"SOBANG/{random_id}"

def create_student(self) -> dict:
def create_student(self) -> Dict[str, str]:
"""Generate a fake student.
Note that the return is a dict - which is automatically parse from response.json.
Expand All @@ -132,12 +145,12 @@ def create_student(self) -> dict:

# Wrapping informations into a dict.
student = {
"masv": self.get_mssv(khoa, mahe),
"masv": self.get_mssv(khoa.year, mahe),
"ngaysinh": ngaysinh.strftime("%d/%m/%Y"),
"hoten": hoten,
"hotenAnh": hoten,
"bac": "DH",
"tenbac": "Dai hoc",
"Bac": "DH",
"tenbac": "Đại học",
"tenbacAnh": "Bachelor of Science",
"mahe": mahe,
"tenhe": self.program_type[mahe].get_name_vn(),
Expand Down
15 changes: 12 additions & 3 deletions tests/factory/type/student_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ class GeneralType:
- Xuong L. Tran <[email protected]>
"""

def __init__(self, **kwargs):
# Name of the type in Vietnamese
name_vn: str

# Name of the type in English
name_en: str

def __init__(self, **kwargs) -> None:
"""Initialization
Author(s):
Expand Down Expand Up @@ -48,7 +54,10 @@ class ProgramType(GeneralType):
- Xuong L. Tran <[email protected]>
"""

def __init__(self, **kwargs):
# Code of the program.
code: str

def __init__(self, **kwargs) -> None:
"""Initialize
Author(s):
Expand All @@ -58,7 +67,7 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)
self.code = kwargs.get("code", None)

def get_code(self):
def get_code(self) -> str:
"""Get the Program Code
Returns:
Expand Down
Loading

0 comments on commit 8f6b38e

Please sign in to comment.