def tour_result(self): """Выводит результат в файл tournament_result.txt""" winner = {"name": '', "score": 0} with open(file=self.file_in, mode='r', encoding='utf8') as file_in: with open(file=self.file_out, mode='w', encoding='utf8') as file_out: for line in file_in: line_rep = line.replace('\t', ' ') line_pars = line_rep.split(' ') if line_pars[0] == '###': # Если начало тура file_out.write(f'{line}') winner['name'] = '' winner[ 'score'] = 0 # Обнуляет победителя тура, при начале нового elif line_pars[0] == 'winner': # Если конец тура self.tour_stat[winner['name']]['winners'] += 1 file_out.write(f"winner is {winner['name']}") elif line == '\n': # Если пустая строка continue else: # Если результа участника for x in line_pars[::-1]: if x == '': line_pars.remove(x) name = line_pars[0] result = line_pars[1] b = Bowling(result.replace('\n', '')) score = b.get_score() if score > winner['score']: winner['name'] = name winner['score'] = score line = line_rep.replace('\n', '') file_out.write(f'{line.ljust(32, " ")}{score}\n') if name in self.tour_stat: self.tour_stat[name]['games'] += 1 else: self.tour_stat[name] = {'games': 1, 'winners': 0} self.print_term()
def test_spare(self): digit = str(random.randint(1, 9)) bowl_engine = Bowling(digit + '/') score = bowl_engine.get_score() self.assertEqual(score, 15)
def test_strike(self): bowl_engine = Bowling('X') score = bowl_engine.get_score() self.assertEqual(score, 20)
def test_returns_score(self): bowl_engine = Bowling('X4/34-4') score = bowl_engine.get_score() self.assertEqual(score, 46)
def parse_line(self, line): name, game_result = line.split() self.game_count[name] += 1 bowl_engine = Bowling(game_result) score = bowl_engine.get_score() return name, score
def test_max_score(self): with self.assertRaises(ValueError): bowl_engine = Bowling('77') bowl_engine.get_score()
def test_wrong_char(self): with self.assertRaises(ValueError): bowl_engine = Bowling('X23W4') bowl_engine.get_score()
def test_two_miss(self): bowl_engine = Bowling('--') score = bowl_engine.get_score() self.assertEqual(score, 0)
def test_wrong_symbol_strike_only_first(self): with self.assertRaises(Exception) as exc: bowling = Bowling('12-D') bowling.get_score() expected_msg = 'Некорректный символ' self.assertEqual(exc.exception.args[0], expected_msg)
def test_strike_only_first(self): with self.assertRaises(Exception) as exc: bowling = Bowling('12-X') bowling.get_score() expected_msg = 'Страйк может быть только первым броском' self.assertEqual(exc.exception.args[0], expected_msg)
def test_spare_only_second(self): with self.assertRaises(Exception) as exc: bowling = Bowling('25/-') bowling.get_score() expected_msg = 'Спэир может быть только вторым броском' self.assertEqual(exc.exception.args[0], expected_msg)
def test_more_ten_in_frame_or_not_spare(self): with self.assertRaises(Exception) as exc: bowling = Bowling('1165') bowling.get_score() expected_msg = 'Больше 10 в одном фрейме или не указан Spare' self.assertEqual(exc.exception.args[0], expected_msg)
def test_less_ten_frames(self): with self.assertRaises(Exception) as exc: bowling = Bowling('12-536') bowling.get_score() expected_msg = 'Сыграно меньше 10 фреймов' self.assertEqual(exc.exception.args[0], expected_msg)
def test_wrong_throws(self): with self.assertRaises(Exception) as exc: bowling = Bowling('1') bowling.get_score() expected_msg = 'Некорректное число бросков' self.assertEqual(exc.exception.args[0], expected_msg)
def test_two_hits(self): bowl_engine = Bowling('34') score = bowl_engine.get_score() self.assertEqual(score, 7)
def test_only_strike(self): b = Bowling('XXXXXXXXXX') result = b.get_score() self.assertEqual(result, 200)
def test_one_miss(self): bowl_engine = Bowling('-4') score = bowl_engine.get_score() self.assertEqual(score, 4)
def test_only_digits(self): b = Bowling('34126316123413145254') result = b.get_score() self.assertEqual(result, 61)
def test_length(self): with self.assertRaises(ValueError): bowl_engine = Bowling('X234') bowl_engine.get_score()
def test_only_zero(self): b = Bowling('-11--55----1-2-3-4-5') result = b.get_score() self.assertEqual(result, 27)
def test_misplaced_slash(self): with self.assertRaises(ValueError): bowl_engine = Bowling('X23/4') bowl_engine.get_score()
def test_all(self): b = Bowling('X-2344/4/--12X231-') result = b.get_score() self.assertEqual(result, 88)
class BowlingTest(unittest.TestCase): def setUp(self): self.b = Bowling() def tearDown(self): del self.b def test_one_throw_11_pins(self): self.assertRaises(ValueError, self.b.throw, 11) def test_two_throw_13_pins_in_total(self): self.b.throw(3) self.assertRaises(ValueError, self.b.throw, 10) def test_one_throw(self): self.b.throw(3) self.assertEqual(self.b.num_pins_remained, 7) self.assertFalse(self.b.new_frame) self.assertEqual(self.b.current_frame, 0) self.assertEqual(self.b.get_score(), 3) def test_two_throws(self): self.b.throw(3) self.b.throw(4) self.assertEqual(self.b.num_pins_remained, 10) self.assertTrue(self.b.new_frame) self.assertEqual(self.b.current_frame, 1) self.assertEqual(self.b.get_score(), 7) self.assertEqual(self.b.score[0], 7) def test_three_throw(self): self.b.throw(3) self.b.throw(4) self.b.throw(7) self.assertEqual(self.b.num_pins_remained, 3) self.assertFalse(self.b.new_frame) self.assertEqual(self.b.current_frame, 1) self.assertEqual(self.b.get_score(), 14) self.assertEqual(self.b.score[0], 7) self.assertEqual(self.b.score[1], 7) def test_spare_counts_next_frame_score(self): self.b.throw(3) self.b.throw(7) self.b.throw(7) self.b.throw(2) self.assertEqual(self.b.num_pins_remained, 10) self.assertTrue(self.b.new_frame) self.assertEqual(self.b.current_frame, 2) self.assertEqual(self.b.get_score(), 28) self.assertEqual(self.b.score[0], 19) self.assertEqual(self.b.score[1], 9) def test_spare_counts_next_frame_score_advance_to_next_frame(self): self.b.throw(3) self.b.throw(7) self.b.throw(7) self.b.throw(2) self.assertEqual(self.b.num_pins_remained, 10) self.assertTrue(self.b.new_frame) self.assertEqual(self.b.current_frame, 2) self.assertEqual(self.b.score[0], 19) self.assertEqual(self.b.score[1], 9) self.assertEqual(self.b.get_score(), 28) def test_strike_moves_to_next_frame(self): self.b.throw(10) self.assertEqual(self.b.num_pins_remained, 10) self.assertTrue(self.b.new_frame) self.assertEqual(self.b.current_frame, 1) self.assertEqual(self.b.get_score(), 10) self.assertEqual(self.b.score[0], 10) def test_strike_counts_next_frame_scores(self): self.b.throw(10) self.assertTrue(self.b.strike[1]) self.assertFalse(self.b.strike[0]) self.b.throw(7) self.b.throw(3) self.assertFalse(self.b.strike[1]) self.assertTrue(self.b.strike[0]) self.b.throw(7) self.b.throw(3) self.assertFalse(self.b.strike[1]) self.assertFalse(self.b.strike[0]) self.assertEqual(self.b.num_pins_remained, 10) self.assertTrue(self.b.new_frame) self.assertEqual(self.b.current_frame, 3) self.assertEqual(self.b.score[0], 30) self.assertEqual(self.b.score[1], 20) self.assertEqual(self.b.score[2], 10) self.assertEqual(self.b.get_score(), 60) def test_spare_on_last_frame(self): self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(0) self.b.throw(10) self.assertRaises(ValueError, self.b.throw, 3) self.assertEqual(self.b.get_score(), 270) def test_strike_on_last_frames_and_throw_11th_frame(self): self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.b.throw(10) self.assertRaises(ValueError, self.b.throw, 3) self.assertEqual(self.b.get_score(), 270)
# «Х4/34» # Предлагается упрощенный способ подсчета количества очков: # «Х» – 20 очков, «4/» - 15 очков, «34» – сумма 3+4=7 # То есть для игры «Х4/34» сумма очков равна 20+15+7=42 # # Надо написать python-модуль (назвать bowling), предоставляющий API расчета количества очков: # функцию get_score, принимающую параметр game_result. Функция должна выбрасывать исключения, # когда game_result содержит некорректные данные. Использовать стандартные исключения по максимуму, # если не хватает - создать свои. # # Обязательно написать тесты на этот модуль. Расположить в папке tests. # Из текущего файла сделать консольную утилиту для определения количества очков, с помощью пакета argparse # Скрипт должен принимать параметр --result и печатать на консоль: # Количество очков для результатов ХХХ - УУУ. import argparse from bowling import Bowling if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("result", type=str) args = parser.parse_args() bowling = Bowling(game_result=args.result) result = bowling.get_score() print(result) # При написании кода помнить, что заказчик может захотеть доработок и новых возможностей... # И, возможно, вам пригодится паттерн проектирования "Состояние", # см https://clck.ru/Fudd8 и https://refactoring.guru/ru/design-patterns/state # зачет!