diff --git a/module/picker/schema.py b/module/picker/schema.py new file mode 100644 index 0000000..087befc --- /dev/null +++ b/module/picker/schema.py @@ -0,0 +1,129 @@ +from typing import Optional + +from openpyxl.reader.excel import load_workbook +from openpyxl.workbook.workbook import Workbook +from openpyxl.worksheet.worksheet import Worksheet + + +class PickerStudent: + total_time: int = 0 + + def __init__(self, name: str, position: int, scores: list[int]): + self._name = name + self._position = position + self._scores = scores + self._modify = False + self._scores = [] + self._scores.extend(scores) + self._scores_pointer = -1 + + self.init_score() + + def init_score(self): + self._scores += [0] * (self.total_time - len(self._scores)) + + for idx, val in enumerate(self._scores): + if val is None: + self._scores[idx] = 0 + if self._scores[idx] == 0: + self._scores_pointer = idx + break + + def append_score(self, score: int) -> int: + if self._scores_pointer > self.total_time or self._scores_pointer < 0: + raise IndexError + self._scores[self._scores_pointer] = score + self._scores_pointer += 1 + self.modified() + return self._scores_pointer - 1 + + def change_score(self, new_score: int, index: int): + if index < 0 or index > self.total_time: + raise IndexError + self._scores[index] = new_score + self.modified() + + @classmethod + def set_total_time(cls, total_time: int): + cls.total_time = total_time + + @property + def position(self) -> int: + return self._position + + @property + def scores(self) -> list[int]: + return self._scores + + @property + def modify(self) -> bool: + return self._modify + + def saved(self): + self._modify = False + + def modified(self): + self._modify = True + + def __str__(self): + return f"PickerStudent {self._name} at {self.position}, with scores: {','.join(str(x) for x in self._scores if x)}" + + def __repr__(self): + return self.__str__() + + +class PickerExcel: + wb: Optional[Workbook] + ws: Optional[Worksheet] + path: str = '' + max_time_position = 'L1' + + def __init__(self, path: str): + self.open(path) + + @classmethod + def open(cls, path: str): + cls.path = path + cls.wb = load_workbook(path) + cls.ws = cls.wb.active + PickerStudent.set_total_time(cls.ws[cls.max_time_position].value) + + @classmethod + def read_student(cls, path: Optional[str] = None) -> list[PickerStudent]: + if path: + cls.open(path) + + if cls.wb and cls.ws: + ret = [] + for row in cls.ws.iter_rows(min_row=4, max_col=4 + cls.ws[cls.max_time_position].value, values_only=True): + if (name := row[2]) is None: + break + ret.append(PickerStudent(name, int(row[0]) + 3, row[4:])) + return ret + else: + raise Exception('No Workbook or Worksheet') + + @classmethod + def write_back(cls, student: PickerStudent): + start_col = 5 # E列 + row = student.position + + for i, val in enumerate(student.scores): + cls.ws.cell(row=row, column=start_col + i, value=val if val != 0 else '') + + student.saved() + + @classmethod + def write_all(cls, students: list[PickerStudent]): + for student in students: + if student.modify: + cls.write_back(student) + + @classmethod + def save(cls): + if cls.ws: + cls.wb.save(cls.path) + + +if __name__ == '__main__': + ...