Avatar of davearonson

davearonson's solution

to High Scores in the Python Track

Published at Mar 27 2019 · 0 comments
Instructions
Test suite
Solution

Note:

This exercise has changed since this solution was written.

Manage a game player's High Score list.

Your task is to build a high-score component of the classic Frogger game, one of the highest selling and addictive games of all time, and a classic of the arcade era. Your task is to write methods that return the highest score from the list, the last added score and the three highest scores.

Submitting Exercises

Note that, when trying to submit an exercise, make sure the solution is in the exercism/python/<exerciseName> directory.

For example, if you're submitting bob.py for the Bob exercise, the submit command would be something like exercism submit <path_to_exercism_dir>/python/bob/bob.py.

For more detailed information about running tests, code style and linting, please see the help page.

Source

Tribute to the eighties' arcade game Frogger

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

high_scores_test.py

import unittest

from high_scores import HighScores


# Tests adapted from `problem-specifications//canonical-data.json` @ v4.0.0


class HighScoreTest(unittest.TestCase):
    def test_list_of_scores(self):
        scores = [30, 50, 20, 70]
        expected = [30, 50, 20, 70]
        self.assertEqual(HighScores(scores).scores, expected)

    def test_latest_score(self):
        scores = [100, 0, 90, 30]
        expected = 30
        self.assertEqual(HighScores(scores).latest(), expected)

    def test_personal_best(self):
        scores = [40, 100, 70]
        expected = 100
        self.assertEqual(HighScores(scores).personal_best(), expected)

    def test_personal_top_three_from_a_long_list(self):
        scores = [10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70]
        expected = [100, 90, 70]
        self.assertEqual(HighScores(scores).personal_top_three(), expected)

    def test_personal_top_three_highest_to_lowest(self):
        scores = [20, 10, 30]
        expected = [30, 20, 10]
        self.assertEqual(HighScores(scores).personal_top_three(), expected)

    def test_personal_top_three_when_there_is_a_tie(self):
        scores = [40, 20, 40, 30]
        expected = [40, 40, 30]
        self.assertEqual(HighScores(scores).personal_top_three(), expected)

    def test_personal_top_three_when_there_are_less_than_3(self):
        scores = [30, 70]
        expected = [70, 30]
        self.assertEqual(HighScores(scores).personal_top_three(), expected)

    def test_personal_top_three_when_there_is_only_one(self):
        scores = [40]
        expected = [40]
        self.assertEqual(HighScores(scores).personal_top_three(), expected)


if __name__ == "__main__":
    unittest.main()

daves_high_scores_test.py

# additional test suite written as exercise in what/how to test;
# code should pass both this and Exercism's supplied test suite.

import pytest

from high_scores import HighScores

# pylint: disable=R0201  # need these to be methods for pytest

class TestScoresAccess:

    def test_basic(self):
        array = [17, 42, 23, 0]
        assert HighScores(array).scores == array

    def test_alternate(self):
        array = [17, 42, 23, 0, 69]
        assert HighScores(array).scores == array

    def test_with_none(self):
        array = []
        assert HighScores(array).scores == array

    def test_dont_modify_list(self):
        array = [17, 42, 86, 23, 0, 69]
        highs = HighScores(array)
        _ = highs.scores  # don't need to use it
        assert highs.scores == array


class TestLatestMethod:

    def test_basic(self):
        array = [17, 42, 23, 0]
        assert HighScores(array).latest() == 0

    def test_alternate(self):
        array = [17, 42, 23, 0, 69]
        assert HighScores(array).latest() == 69

    def test_with_none(self):
        assert HighScores([]).latest() is None

    def test_dont_modify_list(self):
        array = [17, 42, 86, 23, 0, 69]
        highs = HighScores(array)
        _ = highs.latest()  # don't need to use it
        assert highs.scores == array

class TestPersonalBestMethod:

    def test_basic(self):
        array = [17, 42, 23, 0]
        assert HighScores(array).personal_best() == 42

    def test_alternate(self):
        array = [17, 69, 42, 23, 0]
        assert HighScores(array).personal_best() == 69

    def test_with_none(self):
        assert HighScores([]).personal_best() is None

    def test_dont_modify_list(self):
        array = [17, 42, 86, 23, 0, 69]
        highs = HighScores(array)
        _ = highs.personal_best()  # don't need to use it
        assert highs.scores == array

class TestPersonalTopThreeMethod:

    def test_basic(self):
        array = [17, 42, 23, 0, 86, 69]
        assert HighScores(array).personal_top_three() == [86, 69, 42]

    def test_alternate(self):
        array = [17, 42, 23, 72, 86, 69]
        assert HighScores(array).personal_top_three() == [86, 72, 69]

    def test_with_first_place_3_way_tie(self):
        array = [17, 69, 42, 69, 26, 69, 42]
        assert HighScores(array).personal_top_three() == [69, 69, 69]

    def test_with_first_place_2_way_tie(self):
        array = [17, 69, 42, 39, 26, 69, 42]
        assert HighScores(array).personal_top_three() == [69, 69, 42]

    def test_with_second_place_3_way_tie(self):
        array = [17, 69, 42, 69, 86, 69, 42]
        assert HighScores(array).personal_top_three() == [86, 69, 69]

    def test_with_only_three(self):
        array = [42, 86, 69]
        expected = sorted(array, reverse=True)
        assert HighScores(array).personal_top_three() == expected

    def test_with_only_two(self):
        array = [42, 69]
        expected = sorted(array, reverse=True)
        assert HighScores(array).personal_top_three() == expected

    def test_with_only_one(self):
        array = [42]
        assert HighScores(array).personal_top_three() == array

    def test_with_none(self):
        array = []
        assert HighScores(array).personal_top_three() == array

    def test_dont_modify_list(self):
        array = [17, 42, 86, 23, 0, 69]
        highs = HighScores(array)
        highs.personal_top_three()  # don't need to use it
        assert highs.scores == array

high_scores.py

class HighScores:

    def __init__(self, scores):
        # could possibly insert some bulletproofing here to make sure that
        # scores is an array of non-negative integers -- not bothering now.
        self.scores = scores

    def latest(self):
        return self.scores[-1] if self.scores else None

    def personal_best(self):
        return max(self.scores) if self.scores else None

    def personal_top_three(self):
        return sorted(self.scores, reverse=True)[:3]

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?