Python/Lab_6/example.py

183 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
import curses
import copy
class Participant:
def __init__(self, surname, gender, drugs, weight_category, result):
self.surname = surname
self.gender = gender
self.drugs = drugs
self.weight_category = weight_category
self.result = result
class CompetitionContainer:
def __init__(self):
self.participants = []
def clamp_result(self, result):
if 0 <= result <= 100:
return result
elif result > 100:
return 100
else:
return 0
@property
def max_len(self):
return max( [len(j.surname) for j in self.participants] )
def generate_random_participant(self, max_surname_len = 10):
surname = chr(random.randint(1040, 1066)) + "".join([chr(random.randint(1072, 1098)) for i in range(random.randint(4, max_surname_len))])
gender = random.choice(["чоловік", "жінка"])
drugs = (random.random() <= 0.04)
weight_category = random.choice(["мінімальна", "найлегша", "легка", "напівсередня", "середня", "напівважка", "важка"])
result = round(random.random() * 100, 2)
return Participant(surname, gender, drugs, weight_category, self.clamp_result(result + int(drugs)*random.randint(0, round(100 - result))))
def add_new_participants(self, amount = 40):
self.participants += [self.generate_random_participant() for i in range(amount)]
self.participants.sort(key = lambda x: x.result, reverse = True)
def get_table(self, params):
p = copy.deepcopy(self.participants)
for i in params:
p = [j for j in p if getattr(j, i[0], False) == i[1]]
return "Таблиця найкращих результатів за фільтрами: {}\n".format(", ".join([ "{} - {}".format(k[0], k[1]) for k in params ])) + "\n".join( [ "{}: {} балів".format(i.surname.rjust(self.max_len), i.result) for i in p if (not i.drugs) ] )
def get_disqualified(self):
return ["Дискваліфіковані:"] + ["{}: {} балів".format(k.surname.rjust(self.max_len), k.result) for k in self.participants if k.drugs]
class ScreenManager:
def __init__(self):
self.buffered_result = ["Вітаємо у інтерактивній консолі!", "Наявні команди:", "лідери [жінки/чоловіки] [мінімальна/найлегша/легка/напівсередня/середня/напівважка/важка]", "учасники [жінки/чоловіки] [мінімальна/найлегша/легка/напівсередня/середня/напівважка/важка]", "дискваліфіковані"]
self.input_buffer = []
self.suggests_buffer = ["учасник", "найращі", "додати_учасників", "очистити_учасників", "дискваліфіковані", "вихід"]
self.screen = curses.initscr()
self.LINES, self.COLS = self.screen.getmaxyx()
curses.noecho()
self.running = True
self.possible_parameters = {"gender": {"жінка", "чоловік"}, "weight_category": {"мінімальна", "найлегша", "легка", "напівсередня", "середня", "напівважка", "важка"}}
self.suggest_base_commands = ["учасник", "найкращі", "додати_учасників", "очистити_учасників", "дискваліфіковані", "вихід"]
self.suggest_types = ["жінка", "чоловік", "мінімальна", "найлегша", "легка", "напівсередня", "середня", "напівважка", "важка"]
self.render_buffer()
while self.running:
self.process_input()
curses.endwin()
def process_input(self):
c = self.screen.get_wch()
if c == '\x0a':
self.buffer_results()
del self.input_buffer[:]
elif c == '\x7f':
if len(self.input_buffer):
self.input_buffer.pop()
elif c == '\x09':
if len(self.suggests_buffer) > 0:
self.input_buffer = list("".join("".join(self.input_buffer).rsplit(" ", 1)[:-1]) + " " + self.suggests_buffer[0])
else:
self.input_buffer.append(c)
self.auto_suggest()
self.render_buffer()
def render_buffer(self):
self.screen.clear()
# rendering results of previous command
for i in range(min(len(self.buffered_result), self.LINES-13)):
self.screen.addstr(i, 0, self.buffered_result[i])
# auto-completion (missing at the moment)
for i in range(min(len(self.suggests_buffer), 10)):
overflow = max(len(self.suggests_buffer[i]) - (self.COLS - len(self.input_buffer)) + 5, 0)
self.screen.addstr(self.LINES-2-i, len(self.input_buffer) + 2, self.suggests_buffer[i][overflow:])
# rendering user input string
if len(self.input_buffer) < self.COLS - 6:
self.screen.addstr(self.LINES-1, 0, "> " + "".join(list(map(lambda x: str(x), self.input_buffer))))
else:
overflow_amount = len(self.input_buffer) - (self.COLS - 6)
self.screen.addstr(self.LINES-1, 0, "> ..." + "".join(list(map(lambda x: str(x), self.input_buffer[overflow_amount:]))))
# flush the screen buffers
self.screen.refresh()
def auto_suggest(self):
if len(self.input_buffer) > 0:
cs = [i for i in "".join(self.input_buffer).split(" ") if i != ""]
if len(cs) == 1:
self.suggests_buffer = [j for j in self.suggest_base_commands if j.startswith(cs[0])]
elif len(cs) == 2:
if cs[0] == "учасник":
self.suggests_buffer = [k.surname for k in cc.participants if k.surname.startswith(cs[1])]
elif len(cs) > 1:
if cs[0] == "найкращі":
self.suggests_buffer = [i for i in self.suggest_types if i.startswith(cs[-1])]
def buffer_results(self):
command = "".join(self.input_buffer)
if len(command) > 0:
cs = command.split(" ")
while "" in cs:
cs.remove("")
if len(cs) == 0:
self.buffered_result = ["Команда не введена!"]
return 0
params = {}
if cs[0] == "найкращі":
if len(cs) == 1:
self.buffered_result = cc.get_table([]).split("\n")
else:
for i in cs[1:]:
for j in self.possible_parameters:
if i in self.possible_parameters[j]:
params[j] = i
self.buffered_result = cc.get_table(list(params.items())).split("\n")
elif cs[0] == "учасник":
if len(cs) == 2:
if cs[1] in [i.surname for i in cc.participants]:
self.buffered_result = [ "{}: {} балів".format(i.surname.rjust(len(i.surname)), i.result) for i in cc.participants if i.surname == cs[1]]
else:
self.buffered_result = ["Помилка!", "Невідомий учасник"]
elif cs[0] == "дискваліфіковані":
self.buffered_result = cc.get_disqualified()
elif cs[0] == "вихід":
self.running = False
elif cs[0] == "очистити_учасників":
cc.participants.clear()
self.buffered_result = ["Успіх!", "Список учасників було очищено"]
elif cs[0] == "додати_учасників":
if (len(cs) == 2) and (cs[1].isdigit()):
cc.add_new_participants(int(cs[1]))
elif (len(cs) == 1):
cc.add_new_participants()
else:
self.buffered_result = ["Помилка!", "Ви ввели неправильну кількість аргументів для команди додати_учасників"]
else:
self.buffered_result = ["Такої команди не існує!"]
else:
self.buffered_result = ["Команда не введена!"]
if __name__ == "__main__":
cc = CompetitionContainer()
cc.add_new_participants()
sm = ScreenManager()