After having read the complete chapter, I looked back through the sub topics of the chapter and made the following mental thoughts and notes:
- Item 1: Know Which Version of Python You're Using
- This section covers python versions and making sure that you're on version 3.
- Nothing to practice here. This section can be skipped.
- Item 2: Follow the PEP 8 Style Guide
- There's a lot of little things in this section. I won't be able to cover everything here.
- Though the whitespace and naming will undoubtedly be covered no matter what problem I come up with.
- It might be good to try to cover inline negation or empty container checks.
- Item 3: Know the Differences Between bytes and str
- While the information here is useful to know about under the right circumstances, it is not something that I expect my group of developers to be running into often, and as such I am fine with skipping this point in the practice problem.
- Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format
- It would be very worthwhile to cover f-strings, potentially something that allows for a complex f-string
- With f-string being recommended as the best practice, there is no need to cover any of the older string formatting variants.
- Item 5: Write Helper Functions Instead of Complex Expressions
- Covering this point is a maybe, if I can get it to fit into the problem.
- That being said, this is a principle that should be universal to programming in general, and not unique to python, so I don't believe that it is something that the developers will be unfamiliar with.
- Item 6: Prefer Multiple Assignment Unpacking Over Indexing
- This could potentially be good to cover. While this feature isn't unique to Python, the number of languages that have this feature are limited, and as such it could be good to practice.
- Item 7: Prefer enumerate Over range
- This is a maybe. It might fit well with f-strings.
- It could also tie in nicely Item 6 from above.
- Item 8: Use zip to Process Iterators in Parallel
- This is another maybe, but I could likely pass on it. Of the developers that I'm presenting to, a large number of them are very familiar with rxJava, and have used its zip function, which works in a very similar way.
- Item 9: Avoid else Blocks After for and while Loops
- This covers a Python specific feature that I've not seen in other languages that the author explicitly recommends avoiding. Easy enough to do. We can skip it for the practice problem.
- Item 10: Prevent Repetition with Assignment Expressions
- This covers the walrus operator, which would be worthwhile to cover.
- It might be difficult to come up with a good case, though.
So with these points in mind, I started thinking through what might make for a good exercise. My thought process went somewhat as follows:
In order to use the f-string I'll probably want to take some data and format it to print prettily on the screen, and most likely I'll want this data to be a list of some sort to allow for different variations of the string to be formatted. So I imagine that I'll want something similar to the grocery list example from the book. Allowing for an empty list case and having a requirement to handle it differently would also pull in another one of the points that I'm trying to cover.
With these thoughts in mind, I looked into how to perhaps pull in some of my other points, and by looking over enumerate I figured that it would be simple enough to pull it in by simply making the list an ordered list of rankings. I would also get the added bonus of pulling in multiple assignment in that way. So with that emerged the idea to have a score board display.
With that, I started considering how I might be able to pull an assignment expression into the problem, and I had to think on that one for a while. Ultimately I figured that what would lead to its likely use would be to have a complex object for each item in my list, where certain fields may or may not be there.
This then led to the idea of displaying a competition score board where you would be given a list of users where a user would have a user name and a score, and may or may not have a team name.
After coming up with the problem, I went through and coded up a basic solution to the problem, and as I coded up the solution, it made me aware of holes in my problem definition that needed to be specified, such as a max length for the user name and the team name.
In the end, I had a simple problem definition put together, which can be found here, and an example solution put together that I could reference as needed as I took my group of developers through the practice problem, which I've shared below. Note that the code that I came up with here and the code that came out of the mob programming exercise with the group (found here) is slightly different. Also note that the code from the mob programming in addition to completing the exercise also to the exercise a step further. This is the result of the experimentation phase that I recommend following the mob programming practice problem, which can be read about in the Presenter section in this post.
With that, here's the example solution that I had come up with while putting the problem together:
def format_score_board(users: List[dict]) -> str: if not users: return "Awaiting Final Ranking" result = "" for i, user in enumerate(users): if team_name := user.get('team_name', ''): team_name = f" ({team_name})" line = f"{i+1} {(user['user_name'] + team_name):<43} {user['score']:8.2f}" result += "\n" + line return result