完善提问模块
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import random
|
||||
from typing import Optional
|
||||
|
||||
from openpyxl.reader.excel import load_workbook
|
||||
@@ -8,8 +9,9 @@ from openpyxl.worksheet.worksheet import Worksheet
|
||||
class PickerStudent:
|
||||
total_time: int = 0
|
||||
|
||||
def __init__(self, name: str, position: int, scores: list[int]):
|
||||
def __init__(self, name: str, so: str, position: int, scores: list[int]):
|
||||
self._name = name
|
||||
self._so = so
|
||||
self._position = position
|
||||
self._scores = scores
|
||||
self._modify = False
|
||||
@@ -43,6 +45,24 @@ class PickerStudent:
|
||||
self._scores[index] = new_score
|
||||
self.modified()
|
||||
|
||||
@staticmethod
|
||||
def pick(student: list['PickerStudent']) -> Optional['PickerStudent']:
|
||||
filtered = [item for item in student if item.weight != 100 and item.weight > 0]
|
||||
if not filtered:
|
||||
return None
|
||||
|
||||
# 计算倒数权重
|
||||
weights = [1 / item.weight for item in filtered]
|
||||
total = sum(weights)
|
||||
r = random.uniform(0, total)
|
||||
|
||||
cumulative = 0
|
||||
for item, w in zip(filtered, weights):
|
||||
cumulative += w
|
||||
if r <= cumulative:
|
||||
return item
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def set_total_time(cls, total_time: int):
|
||||
cls.total_time = total_time
|
||||
@@ -63,6 +83,14 @@ class PickerStudent:
|
||||
def weight(self) -> int:
|
||||
return int(sum(1 for x in self._scores if x != 0) / self.total_time * 100)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def so(self) -> str:
|
||||
return self._so
|
||||
|
||||
def saved(self):
|
||||
self._modify = False
|
||||
|
||||
@@ -80,7 +108,8 @@ class PickerExcel:
|
||||
wb: Optional[Workbook]
|
||||
ws: Optional[Worksheet]
|
||||
path: str = ''
|
||||
max_time_position = 'L1'
|
||||
max_time_position = 'M1'
|
||||
start_row = 5
|
||||
|
||||
def __init__(self, path: str):
|
||||
self.open(path)
|
||||
@@ -88,7 +117,7 @@ class PickerExcel:
|
||||
@classmethod
|
||||
def open(cls, path: str):
|
||||
cls.path = path
|
||||
cls.wb = load_workbook(path)
|
||||
cls.wb = load_workbook(path, keep_vba=True)
|
||||
cls.ws = cls.wb.active
|
||||
PickerStudent.set_total_time(cls.ws[cls.max_time_position].value)
|
||||
|
||||
@@ -99,13 +128,40 @@ class PickerExcel:
|
||||
|
||||
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):
|
||||
for index, row in enumerate(cls.ws.iter_rows(
|
||||
min_row=cls.start_row,
|
||||
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:]))
|
||||
ret.append(PickerStudent(name, row[1], cls.start_row + index, row[4:]))
|
||||
return ret
|
||||
else:
|
||||
raise Exception('No Workbook or Worksheet')
|
||||
raise Exception('No Workbook or Worksheet')
|
||||
|
||||
@classmethod
|
||||
def read_total_time(cls, path: Optional[str] = None) -> int:
|
||||
if path:
|
||||
cls.open(path)
|
||||
|
||||
if cls.wb and cls.ws:
|
||||
val = cls.ws[cls.max_time_position].value
|
||||
if isinstance(val, int):
|
||||
return val
|
||||
raise Exception(f'总次数读取错误,期待类型 {type(1)} 但实际为 {type(val)}\n'
|
||||
f'可能的解决方法:\n'
|
||||
f'1、确保总次数位于 \'{cls.max_time_position}\' 单元格;\n'
|
||||
f'2、确保选择了正确的 Excel 文件。')
|
||||
raise Exception('No Workbook or Worksheet')
|
||||
|
||||
@classmethod
|
||||
def save_total_time(cls, path: Optional[str] = None, value: Optional[int] = None) -> None:
|
||||
if path:
|
||||
cls.open(path)
|
||||
|
||||
if cls.wb and cls.ws and value:
|
||||
cls.ws[cls.max_time_position].value = value
|
||||
cls.save()
|
||||
|
||||
@classmethod
|
||||
def write_back(cls, student: PickerStudent):
|
||||
@@ -116,6 +172,7 @@ class PickerExcel:
|
||||
cls.ws.cell(row=row, column=start_col + i, value=val if val != 0 else '')
|
||||
|
||||
student.saved()
|
||||
cls.save()
|
||||
|
||||
@classmethod
|
||||
def write_all(cls, students: list[PickerStudent]):
|
||||
|
||||
Reference in New Issue
Block a user