Skip to content
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

Incorporate fw appendices 2022 #77

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

fwimp
Copy link
Collaborator

@fwimp fwimp commented Oct 2, 2022

Incorporate the appendices from last year that sat in PR hell. These have been re-implemented to get the branch up to date with master (rather than fixing the branch from last year. See https://xkcd.com/1597 for details)

… and add warning about f-string use in logging.
Copy link
Collaborator

@mhasoba mhasoba left a comment

Choose a reason for hiding this comment

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

Logging appendix is great, but need a bit more (intuitive) CS context in the OOP appendices. The biggest hurdle in the way of using Python's OOP capabilities, starting with classes, is practicality: why do you need it?

So I suggest: (1) Explaining functional P vs OOP intuitively; (2) Explicitly showing in an example how using classes made the implementation better (better encapsulation? more robust? faster/slower?); When not to use classes (this is a nice video: https://www.youtube.com/watch?v=o9pEzgHorH0)

@mhasoba
Copy link
Collaborator

mhasoba commented Oct 4, 2022

@davidorme, see my comment above in response to @fwimp 's proposed addtion OOP appendices. Any thoughts welcome!

@davidorme
Copy link
Collaborator

davidorme commented Oct 4, 2022

Yeah - it's a tricky one. I agree with @mhasoba that the OOP guides are a bit abstract at the moment. I think they're good, but the 'why' is quite hard to pick out. You could possibly use data classes as way in? That makes intuitive sense as an encapsulated set of data, and then you can extend it methods acting on that data?

Having something implemented using OOP and functional would be nice for a side-by-side comparison, but is a lot of work.

Some immediate comments on the content (I would do these as review comments, but the files have only been renamed):

  • I don't buy why saw_leg isn't a method of the class - makes a lot more sense that way. I get you're looking for a function that takes a Class instance as an input, but this feels artificial and breaks out of the OOP mindset that we're trying to teach.
  • It would be nice to include class attributes - there's an obvious case for adding type = 'chair' as a class attribute, that can then be overloaded in subclasses (and hence is available for modifying the __str__ output to be subclass specific).
class Stool(Seat):
    type = 'stool'
  • The say_woof example and Exception is a bit confusing - I think it would be better to carry on building the chair framework to show things working together. One option would be to reframe chairstack (which should be ChairStack) to have an add method, that could use class attributes to throw MismatchedSeat exceptions when you try to put a stool on stack of chairs and maybe even add a stackable class attribute that allows you to raise NotStackable when people try to stack Beanbags.

@fwimp
Copy link
Collaborator Author

fwimp commented Oct 4, 2022

Agreed, this set of tutorials has existed for about 2 years in PR hell, so probably could do with a bit of a rework anyway.

Honestly a lot of the issue I've had is that Functional vs OO is not something where one is inherently better than another. I'll work into some more context and explanations in OOP1.

Data classes is a nice idea, I might argue that it's a bit complex as an intro into classes though, would you reckon it's good as an extra example showing why we might use it in biology?

The saw_leg question is really one of abstraction. If we wanna go whole-hog OOP, then the chair class could have a mutate method that arbitrarily allows changing of elements of the class according to certain rules and checks, then saw_leg() should call the class's mutate method with set params. But I think this would be an example of massive overabstraction.

In the end any function that acts on a class can be reimplemented as a method, and even for saw_leg I'd probably make it a static method which can work on other things too but is part of the class def. My thought was that you could also apply saw_leg to an object of class Human and make it have the same effect. Finally I generally think it as most intuitive when one thinks of methods of a class as things that class can do. Seeing as the chair does not saw off its own leg, that doesn't quite fit with my mental model but I do get your point.

Attributes are absolutely a good idea, and something I should have included!

I agree that say_woof is a toy example and a bit delinked from the rest of the tutorial, I think I wrote it first whilst looking after a dog. Remaking in the example of the chairs is a better idea for sure!

I'll try to give it a look this evening or over the next week. No-one will come to this one for a while anyway.

@fwimp
Copy link
Collaborator Author

fwimp commented Oct 27, 2024

@mhasoba is it worthwhile spinning off the logging primer from this and integrating it straight out? It's pretty much completed and is a decent addition to the course. The OOP primers we can revisit anon.

@mhasoba mhasoba assigned fwimp and unassigned mhasoba Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants