Skip to content

Simplify High-scores exercise. Replace Class with functions #1764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 3, 2019
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ bin/configlet
bin/configlet.exe
.idea/
.cache
.pytest_cache
__pycache__
8 changes: 4 additions & 4 deletions exercises/high-scores/.meta/HINTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
In this exercise you're going to create a **class** and use lists to organize scores. _Don't worry, it's not as complicated as you think!_
In this exercise, you're going to use and manipulate lists. Python lists are very versatile, and you'll find yourself using them again and again in problems both simple and complex.

- [**A First Look at Classes**](https://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes) from the Python 3 documentation.
- [**How to Define a Class in Python**](https://realpython.com/python3-object-oriented-programming/#how-to-define-a-class-in-python) from the Real Python website.
- [**Data Structures in Python**](https://docs.python.org/3/tutorial/datastructures.html) from the Python 3 documentation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to ping @BethanyG for suggestions on new HINTS content. She put some good work into the current HINTS.md (less than a month ago), and I would feel bad about dumping that work without offering the chance to contribute an alternative.

Copy link
Member

@BethanyG BethanyG Apr 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to write up some new hints...but I think the bigger issue here is that if you remove making a class in this exercise (which is a fairly easy one), then when students have to make a class (and deal with side effect questions) in the next exercise..well, we've just kicked the can down the road. The same issues that apply to High Scores apply to Matrix (and Kindergarten Garden, etc.) ...and eventually, a python learner has to to deal with classes. They're part of the language (it's really is objects all the way down), and widely used in frameworks like Django. The sooner students get (even a little) practice in a controlled fashion, the less they struggle later.

So the way I see it is that we either have to craft an exercise or two around classes and mutability specifically, or re-work tests and mentor notes on current exercises to address it. I don't think the answer is to re-write this exercise (and the next) to not need a class. If we don't want a class-based exercise here because we want to focus on lists, we could move this exercises to a later stage (and address its shortcomings through a re-write of tests). We could replace it with something like Say or Run Length Encoding - or any other number of exercises that focus on lists and arrays. But only 6 of 18 core exercises require writing a class currently, and I'm not sure we are doing a great job of giving students practice in that area.

All that being said....if we do indeed want to make this exercise function based, I can try to make some new hints this week. However, we then should move these hints to the Matrix exercise, since it will then be the exercise to introduce classes. We maybe should also provide a hint on mutability there as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies - forgot one last point: We'll need to re-work the mentor notes for this exercise as well. I don't think I will be able to get to either that or the hints until this afternoon, PST.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the way I see it is that we either have to craft an exercise or two around classes and mutability specifically

I'm not opposed to that.

If we don't want a class-based exercise here because we want to focus on lists, we could move this exercises to a later stage (and address its shortcomings through a re-write of tests).

There are very few easy exercises as it is. I'd prefer not to overcomplicate what was meant to be a simple list exercise.

All that being said....if we do indeed want to make this exercise function based, I can try to make some new hints this week. However, we then should move these hints to the Matrix exercise, since it will then be the exercise to introduce classes. We maybe should also provide a hint on mutability there as well.

I can get behind that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - I wasn't able to make suggestions in the pull (I don't have access) - but here's my proposed hint text:


In this exercise, you're going to use and manipulate lists. Python lists are very versatile, and you'll find yourself using them again and agin in problems both simple and complex.


I'll submit a pull for revised mentor notes and for the new hint on Matrix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See exercism/website-copy#956 for the updated mentor notes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @BethanyG :)
I will add the new hints right now :)

And actually will push the old hints to Matrix in this PR. So we did not loose them.

For me Matrix is better Class based exercise. But we can make other also.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind creating a separate PR for the changes to matrix? We try to limit PR changes to one exercise at a time (there are few exceptions).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well doesn't that count as exception? We have not changed the exercise in Matrix, just add the hints because previously they ware available at this exercise?

I can open other PR is not a big deal, but we have to merge them one after the other. I thought it would be better if we push this as one change.

I will make new one tomorrow morning and will edit this one to remove matrix docs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have an issue with both exercises temporarily having the same generic hints about classes, so I went ahead and merged #1766.

- [**Data Structures (Python 3 Documentation Tutorial)**](https://docs.python.org/3/tutorial/datastructures.html)
- [**Lists and Tuples in Python (Real Python)**](https://realpython.com/python-lists-tuples/)
- [**Python Lists (Google for Education)**](https://developers.google.com/edu/python/lists)
8 changes: 4 additions & 4 deletions exercises/high-scores/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ 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.

In this exercise you're going to create a **class** and use lists to organize scores. _Don't worry, it's not as complicated as you think!_
In this exercise, you're going to use and manipulate lists. Python lists are very versatile, and you'll find yourself using them again and again in problems both simple and complex.

- [**A First Look at Classes**](https://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes) from the Python 3 documentation.
- [**How to Define a Class in Python**](https://realpython.com/python3-object-oriented-programming/#how-to-define-a-class-in-python) from the Real Python website.
- [**Data Structures in Python**](https://docs.python.org/3/tutorial/datastructures.html) from the Python 3 documentation.
- [**Data Structures (Python 3 Documentation Tutorial)**](https://docs.python.org/3/tutorial/datastructures.html)
- [**Lists and Tuples in Python (Real Python)**](https://realpython.com/python-lists-tuples/)
- [**Python Lists (Google for Education)**](https://developers.google.com/edu/python/lists)



Expand Down
16 changes: 7 additions & 9 deletions exercises/high-scores/example.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
class HighScores(object):
def __init__(self, scores):
self.scores = scores
def latest(scores):
return scores[-1]

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

def personal_best(self):
return max(self.scores)
def personal_best(scores):
return max(scores)

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

def personal_top_three(scores):
return sorted(scores, reverse=True)[:3]
13 changes: 10 additions & 3 deletions exercises/high-scores/high_scores.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
class HighScores(object):
def __init__(self, scores):
pass
def latest(scores):
pass


def personal_best(scores):
pass


def personal_top_three(scores):
pass
20 changes: 8 additions & 12 deletions exercises/high-scores/high_scores_test.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
import unittest

from high_scores import HighScores
from high_scores import latest, personal_best, personal_top_three


# 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)
self.assertEqual(latest(scores), expected)

def test_personal_best(self):
scores = [40, 100, 70]
expected = 100
self.assertEqual(HighScores(scores).personal_best(), expected)
self.assertEqual(personal_best(scores), 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)
self.assertEqual(personal_top_three(scores), 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)
self.assertEqual(personal_top_three(scores), 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)
self.assertEqual(personal_top_three(scores), 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)
self.assertEqual(personal_top_three(scores), expected)

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


if __name__ == "__main__":
Expand Down