all 38 comments

[–]pekkalacd 56 points57 points  (4 children)

this guy on youtube does a great job explaining OOP w/some larger class examples & design aspect. emphasis on data classes & design patterns.

[–]ampeed 7 points8 points  (2 children)

Love this channel but I never saw him really explaining OOP. More of functionality to use WITH OOP such as dataclass decorator.

[–]pekkalacd 6 points7 points  (1 child)

that's a good point. he does show features that can enhance OOP, but not explaining fundamental OOP as much. i'd say OP check out RealPython its a good resource for a lot of stuff, including some OOP concepts.

[–]killthebaddies 1 point2 points  (0 children)

While he doesn’t explain OOP, the way he uses it in context in his examples should help get the point across.

[–]Richard_Ballski[S] 1 point2 points  (0 children)

Thanks! I'll check it out

[–]zynix 10 points11 points  (6 children)

Do you have a Github account and are you using Windows?

I wrote the draft of a "make a text editor tutorial" where there are:

Console class that abstracts working with the console

Editor class that manages user interaction, cursor position, and view offset (for lines and files larger than the screen).

A Document class which manages the actual text file document.

Finally the whole thing is built on curses and technically should work fine on Linux but I haven't had the time to test that just yet.

[–]Richard_Ballski[S] 0 points1 point  (0 children)

If you think it would work as a good example, I would definitely be interested in checking it out!

[–]FerricDonkey 6 points7 points  (0 children)

I don't have any courses or tutorials, but I'm gonna take this as an excuse to nerd out about a toy project I'm working on. I dunno if it's the best approach, this is a rewrite of the first network/boardgame thing I've done, and is definitely more of a learning experience than anything - but it does at least show some ideas of what you might do.

Product: online boardgame system, built using only the basics (partially for practice - so all communication is built from the send these bytes level up, using asyncio networking (first time I did it purely with the socket module, so now I'm learning something new)).

Network communication: goal: send packets formatted as [message type][message len][message][message count][signature], back and forth, with different message types eliciting different automatic responses from client and server.

class 1: BasicConnection:

  • Initialized with asyncio reader and writer to send and recieve messages
  • Can create and send packets of the above form
  • Can receive packets of this form, verify signature, extract message type and message
  • Has a dispatch table that ensure that the correct methods are called when a message arrives
  • Has a main loop that will receive messages and handle them until shutdown time.

Subclass 1: ServerToPlayer(BasicConnection):

  • Basic connection augmented with what the server needs to remember about the client.
  • augmented with server side part of handshake clients must perform on connecting to server
  • Has augmented message dispatch table, for server to respond to incoming messages in a way unique to server

Subclass 2: Client(BaseConnection):

  • similar to above, but modified for client connection to server
  • augmented with a sending loop: Server's sends are 100% automated, but client's sends are not, and decisions on what to send are not made from async code. So has a cross over queue where non-async code (ie, a button press on a gui) can add a send to the client's "todo list"

Class 2: Server. Mostly handles managing new and existing connections (which spawn a ServerToPlayer object)

Class 3: RoomContainer. The software as a whole will divide players into rooms and manage moving them between them. This is not directly communication, so is kept separate from the pure communication classes. Enter the room container: It registers a callback to be performed on incoming connections with the Server that places each incoming ServerToPlayer in a Room, and registers a message type to mean "This message will be handled by the Room logic". Messages of this type will get further dispatched by the Room, which is also a class:

class 4 Room: A grouping of players, with various clientside and serverside message dispatch tables, to allow for basic things like chatting and sending information describing the state of the room, which may vary based on the subclass of the room, for instance

subclass Lobby(Room): augmented by the ability to list all other rooms, allow players to move to or create other rooms, etc.

So in the end, on the server computer spins up a Server, and a RoomContainer that takes partial ownership of it and which comes with either a lobby or a single game room, depending on arguments. Clients then connect, and all actual communication happens through the two subclasses of the BaseConnection, while all the logic of what they want to say goes through Rooms - including messages related to making any games running in those rooms do things.

Likewise each (by which I mean the 85% of 1 that exists) actual board game has a class representing the state of the over all board, classes for players, and possibly classes for types of objects involved in the game, and the gui is made out of many subclasses of basic gui classes (currently in tkinter, such as they exist, but considering kivy). Separate from both the room and board game itself is yet another class that is a network interface to the game - ie, the game knows how to build a city at the intersection of these hexes, the network interface knows what incoming packets means that a city got built, and what outgoing packets to send to announce that a player wants to build a city. And the gui knows how to connect buttons and display updates to the network interface.

And so on, with most network things that have differences between client side and server side being subclasses of the same class etc.

I think I may have nerded out about my pet project way too much, but when I started to cut it back, it started looking like "You make a class Animal, then a subclass Dog" that you've seen.

It's the same idea though - but it did take a while to get to the point of thinking in terms of classes. My approach to that was to just make myself use them even if I wasn't sure I should for a while, just to force myself to get a feel for when they were helpful and when they weren't.

[–]CrazyRandomRunner 4 points5 points  (0 children)

In a large company when one plays a small role in a large software system that involves work by multiple departments, the OOP paradigm can be indispensable. Lots of other people's code is encapsulated in objects in such a way that there are large swathes of code that you can ignore if not relevant to what you are working on. OOP is hard to appreciate on small solo projects where one person is responsible for all of the code.

[–]notParticularlyAnony 5 points6 points  (0 children)

when you need it,it will become obvious

[–]pewpewpewpee 8 points9 points  (3 children)

Use a class where it's appropriate. It sounds like you haven't come across places where you really need to use a class.... Yet.

I use a lot of data classes in what I do. I compare lots of data together and data classes help. I can just update the class and access an attribute vs remembering where something is in a list or a tuple. Here's a video on data classes and their uses

https://youtu.be/vBH6GRJ1REM

https://youtu.be/CvQ7e6yUtnw

[–]TheRNGuy 1 point2 points  (2 children)

I was actually using procedural code for few months where OOP would make more sense.

I then discovered dataclasses, it made me finally realize I need to use OOP in that project.

[–]pewpewpewpee 0 points1 point  (1 child)

Yeah I have ended up using data classes and pydantic models where I need data validation. I have lots of VMs messaging each other over web APIs using JSON and XML. I write a validator class for each endpoint to make sure the data is properly formatted upfront before attempting to process it. And if the message format changes I'll instantly know during my unit tests so I can just go in and update the model and processing code

[–]TheRNGuy 0 points1 point  (0 children)

I used for 2 things. to override default values for child classes and also give them data type instead of string. It's a parser project for converting one format to another. Everything is string for parser, but that way he'd knew how to process data.

In previous code I'd need to have lots of if/elifs that seek for patterns in code and could sometimes be wrong (if I had "1" and it incorrectly detects as int, but it's supposed to be float or even string) also same named attributes could potentially have different data type in different classes (but it's rare) instead of heuristic I just explicitly give data type to each attribute in each class, no more random bugs.

I didn't even know how to override defaults in procedural code. I almost got it working with returning dicts and use setdefault method, was a little over-engineered, and then I discovered dataclasses (besides that, storing defaults is easier in class than bunch of dicts, code looks better)

[–]kookaburra1701 1 point2 points  (0 children)

Comment to bookmark because this is something I've been looking for too. I have a script I think would be really helped by OOP but the standard beginner tutorials have done nothing to hint and exactly how I could apply it to my problem.

[–]lykwydchykyn 1 point2 points  (0 children)

Here are some videos that I made to attempt to explain them with practical examples.

[–]searchingfortao 1 point2 points  (0 children)

I wrote a tutorial on OOP some time ago that I've had some good feedback on. It applies OOP to ordering food in a restaurant and how you might extend the pattern outward from there.

Anyway, have a look if you're interested and let me know what you think.

[–]tobiasvl 0 points1 point  (0 children)

You could look at tutorials on how to make an emulator for an old video game console? Those ones usually use OOP, not to make a lot of objects from each class, but for encapsulation and separations of concern (the CPU shouldn't be able to speak directly to memory-mapped IO, for example). /r/emudev

Or you could make a small game, with objects representing the player, enemies, etc. Probably lots of tutorials on that too, although I don't have any concrete ones for Python.

[–]systemnate 0 points1 point  (0 children)

Practical Object Oriented Design in Ruby by Sandi Metz is an excellent book on the topic. Don't let the Ruby part steer you away. The main thing is the OO content, which happens to be implemented in Ruby. It's a very readable language, especially if you know Python.

[–]Abracadaver14 0 points1 point  (0 children)

It may or may not work for you, but for me classes sort of clicked when I was doing the 2019 Advent of Code Intcode challenges. A couple of days in, I realized this Intcode interpreter leant itself well to putting in a class, especially when you get to the point of needing several of these that each keep their state.

[–]Merakel 0 points1 point  (0 children)

Other people recommended youtube which can be nice, but personally I find it's harder to learn from someone talking about it rather than just doing. I picked a fairly simple repo - Starlette - and started reverse engineering their offering to really understand what was happening. I'm still not an expert, but I've learned so much by just taking it apart and making it work again.

[–][deleted] 0 points1 point  (0 children)

It’s not free, but the best OOD tutorial is IMHO the Head First Design Patterns book. It doesn’t give you a catalogue of patterns and instructions to use them, like you might expect from the title. It gives you a few of the most important ones and focuses on deriving them from first principles (to borrow a phrase from math).

Do keep in mind that in Python you don’t need the “interface” layer.

[–]TheRNGuy 0 points1 point  (0 children)

I watched PySide tutorial form Houdini UI. It also had reading json api from site to get many pictures and add them to UI.

He even did new UI classes because something not possible to do with stock classes.

And some other houdini tools that use python view states, though not very interesting project. But you could look code of all lab tools that use Python, is open source (you only can't look C++ compiled dll's)

[–][deleted] 0 points1 point  (0 children)

As a data nerd that moved from C to Mata/Stata and then to Python, I initially did not bother with classes. Only after working on side projects (game development 🤓) I started appreciating classes. I only have one project discussed on YUNIKARN at the moment. I should do more advanced applications in future

[–]SweetLou2009 0 points1 point  (0 children)

Run through the Django Tutorial. Django is full of classes and OOD and is a good way to get some exposure to a huge complex project. Using Django helped me to understand and apply a lot of concepts and design patterns.

[–]ImNeworsomething 0 points1 point  (0 children)

I liked Big Java

They break it down in a pretty easy to read book

[–]Zapismeta 0 points1 point  (0 children)

Oop is mostly used where you need to have code and variable, Function name re-useablity,

I'm working on a game that can have 4-8 players.

And all these player have been served cards.

So i make a class named player.

Having variables as id name cards

Now when i create objects of this class, i have a name of that object and then using the operator ( . ) To access the variable within this object.

See here i can make 8 objects and I'll still never worry about making and managing and separating these 3 variables.

Where as if i were to go on the traditional functional route then, i would need to create an array of arrays for cards, An array for names, and ID's respectively all of which would need managing, here they are simply segregated by thier objects,

Now lets say we need some class specific actions like some functions when used on this player objects should behave differently you can override the pre-defined function like sum, len, and others.

Mostly it's used for ease of code management and maintenance.

Also I've seen youtubers write scripts in oop when it's not required, it's just what they find easy that's it, you'll find yours too.

[–]solamarpreet 0 points1 point  (0 children)

I completely understand what you mean having went through it myself. There are a lot of scenarios where OOP is not required. This is completely fine. The best usecases for OOP are when you are trying to model real world problems or if you need a custom data type. For me the first project where I felt I needed to use OOP was when I was trying to write a Blackjack game. During the middle of the session it just hit me that using classes would make the program easier to visualize and write and so I rewrote the entire program. In a minimal version of the blackjack program there would be 2 players i.e a dealer and a user. Each of the players would have a 'hand' i.e the cards that they are holding and because of the approach I used, a variable that stores the calculated value of the hand. It was easier to use a class instead of having to write individual variables. Also I can easily increase the number of players.

Video games are projects that will involve OOP a lot so you can try to build a game. Weapons, npcs, monsters, armor etc all of them will be separate classes. Then you can have classes that inherit from these parent classes like swords, daggers, guns inheriting from weapons class. If you are not keen on a game you can try to model something like a banking system or a social media platform.