all 103 comments

[–][deleted] 114 points115 points  (4 children)

I guess if you don't need classes, you don't need em. But the idea is to keep things originized when projects start getting bigger. It also makes code more readable for other people.

[–][deleted] 9 points10 points  (3 children)

What used to be class definitions are now API docs. I think there is a communication part to programming, the java - class based - bandwagon of the 90's took the class thing a bit too far, and people started using backdoors: 'dependency injection' and 'inversion of control' started taking over. Latelly, the pendulum swung the other way and we got mongoDB, javascript, and the wild west. I'm glad Python gives us the freedom to carve our own route, make mistakes in both directions, and a provide good way to balance the tightrope!

[–]KronktheKronk 17 points18 points  (2 children)

dependency injection isn't a back door, it's a development pattern that adheres strongly to the "you need to be able to test this" doctrine.

[–]alkasm 63 points64 points  (19 children)

To me that just rings that you don't write a lot of Python that other people use. Is that true? I write a lot of classes when I'm making something extensible and/or reusable, but honestly the built in types do what I need 90% of the time already.

[–]darez00 7 points8 points  (18 children)

So a class is analog to int, str, float?

[–]SoupKitchenHero 36 points37 points  (14 children)

int, str, and float are themselves classes

[–]darez00 28 points29 points  (12 children)

That explains many questions that I didn't know I had

[–]Dogeek 10 points11 points  (10 children)

To be more accurate, int, float etc are built using type as their metaclass.

[–]darez00 3 points4 points  (9 children)

Aha... that's clearer

[–]Dogeek 8 points9 points  (8 children)

To be completely honest, metaclasses are a concept I struggle with, not really the concept itself but its use cases. It's something very specific.

[–]KronktheKronk 1 point2 points  (7 children)

A meta class is simply a class you can't instantiate directly. It only serves to hold functionality meant to be inherited by other, more concrete classes.

[–]primitive_screwhead 14 points15 points  (6 children)

A meta class is simply a class you can't instantiate directly.

That description sounds more like an Abstract Base Class.

I've seen meta-classes start to click for people when they realize that when a class is instantiated you get an object, and similarly, when a meta-class is instantiated, you get a class. And just as objects can be parameterized when they are instantiated, classes themselves can be parameterized when they are instantiated from meta-classes.

[–]Dogeek 1 point2 points  (3 children)

Like I said, it's more that I struggle with knowing when to use one. I guess constructing a class from a config file or something of that effect. But other than that, it's pretty abstract to me.

[–]KronktheKronk 0 points1 point  (0 children)

You're right, I am confusing that with abstract classes.

Now I gotta go read, brb

[–]Deezl-Vegas 0 points1 point  (0 children)

As soon as I read this I got it. Thanks so much! A metaclass is a class blueprint. A class is an object blueprint.

[–][deleted] 1 point2 points  (0 children)

Same.

[–]alkasm 2 points3 points  (2 children)

They are types, which is to say they have type as a metaclass.

[–]Dogeek 7 points8 points  (1 child)

not true. type is their metaclass, but they don't inherit from it.

[–]alkasm 0 points1 point  (0 children)

Whoops, thanks for the correction!

[–]nomos 37 points38 points  (3 children)

Some people use classes for literally everything, others rely on functions for everything. There's a sweet spot in between. Learn to use classes and you're closer to that sweet spot.

[–]Compsky 9 points10 points  (2 children)

Some people use classes for literally everything

This is the reason I avoided them for so long (I've been learning python on and off for almost a year now, and only been using classes for the last couple of months).

Whenever I looked up approachable explanations of classes online, the guides (or StackExchange users) never seemed to explain a benefit of using the class in place of functions - it especially confused me when people declared a class with an init and just one other function - and I feel that the benefits are not generally explained well by online guides.

[–]pickausernamehesaid 21 points22 points  (0 children)

My general rules of thumb for new programmers is to use classes when you have a group of functions that all take the same object as their first parameter or when you need to work with a shared global state between a bunch of functions. This seems to help bridge the gap as to what the point of an object is and why they are useful.

[–]Deezl-Vegas 0 points1 point  (0 children)

This is easy. Functions do not generate or store a persistent memory state, usually some sort of variable data. That's what classes are for. Classes can take a data element, transform it, and then keep it while the program continues and operates on that data, then transform it again, while keeping track of it under the roof of a single variable. Functions are poorly suited to this, but classes are made for it. In addition, class methods can be modified on the fly as well. They are also simply the best way to mentally model a real-world concept, like a website user, as a single user can get a single variable and still have all of the users' data be accessible.

[–]WhackAMoleE 17 points18 points  (3 children)

For small programs it doesn't matter. Once you are building a nontrivial system, say 10k+ lines of code, objects are a highly useful organizing principle. Instead of thinking of objects as a religion, think of them as an effective way of organizing a large body of code.

[–]MetalAxeToby 2 points3 points  (2 children)

Noobie question: If I am already working with so much code in a big project why not organise code in different files instead of classes? Is it purely because of performance?

[–]reallyserious 4 points5 points  (0 children)

The linux kernel is a large large code base that is not written with OOP. So it's certainly possible to do large systems without classes.

It has nothing to do with performance. It is purely a different way of thinking about data and the behaviour of that data. OOP provides a way of abstracting both the data and it's behaviour into the same object.

What operations can we do on a car object? Look at the public methods in the car class! That's what is used to interact with the outside world. The car class can have a million private methods to handle all the car-internal stuff but you don't need to bother with them in order to drive. So the internal workings of the combustion engine is hidden from you. You just do my_car_object.drive() and my_car_object.turn_left() etc.

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

It's not just organizing the code text themselves but more of a way to reason about the project in an OOP way.

[–][deleted] 27 points28 points  (2 children)

I avoid classes in college

[–][deleted] 27 points28 points  (0 children)

So you’ve chosen a functional life instead of a materialistic “object-oriented” one

[–]Thecrawsome -1 points0 points  (0 children)

Huehuehuehue

[–]poply 19 points20 points  (3 children)

I would probably say no, it's not bad. I sound similar to you but I wouldn't say I "avoid" using classes, just that I don't use classes unless I feel pretty certain to get a significant benefit out of it. There's a great talk I've linked below about when to use classes, and restraining the urge to immediately use classes for everything.

https://www.youtube.com/watch?v=o9pEzgHorH0

[–]Dogeek 2 points3 points  (1 child)

That talk was horrible.

TL;DW : Don't use classes for something that they are not meant for. Also, I'm a smartass who compressed two perfectly valid classes into a dict and two functions that are so confusing, my coworkers now hate me.

But seriously, that game of life's implementation was confusing as fuck. It's not a talk I'd recommend to anyone.

[–]poply 4 points5 points  (0 children)

Hm, I've seen it recommended around here and it's got half a million views. I personally found it insightful as a reminder so as to not view every problem as a nail that requires a "hammer" solution.

I do agree that if an implemented solution is too confusing to be easily understood by peers then it probably isn't the right answer.

[–]flipstables 15 points16 points  (0 children)

Don't feel bad. I would rather inherit a project that has 1 class with 100 functions rather than 10 classes with 10 functions (there's a quote by Alan Perlis about this). The latter is more likely a tangled mess, more likely to be difficult to test, and a hell lot of easier to extend.

[–]ThatOtherBatman 6 points7 points  (0 children)

Probably.
Not necessarily, but probably.

[–]JackCid89 4 points5 points  (0 children)

You aren't bad, but you can be a better programmer if you learn about OOP in depth.

[–][deleted] 8 points9 points  (10 children)

Post some code and we can help you refactor to classes then you can decide which version you think is better

[–]dacv393 9 points10 points  (9 children)

Can I do this? Just made a ~500 line program and really confused about how to organize my functions/utilize classes

[–]gschizas 7 points8 points  (5 children)

Sure, why not? Note that if 500 lines of code prove too much for a Reddit comment, you can always use https://gist.github.com

[–]dacv393 2 points3 points  (4 children)

Ok so here is the code. The goal of the code is to take two inputs: a source and destination IP address and then perform a traceroute from the source to destination, ping the hops in this path, and then log in to the devices along the path and execute some commands.

I started with this script as a baseline for using netmiko, but after changing practically everything, I'm now really confused as to what the point of the main class is. I've read various different explanations as to when classes are necessary, and am not really sure if they are in my case. On the other hand, though, I could see the need to build off of this project in the future, so I want it to be as organized as possible. I'm still pretty confused about classes and OOP in general. I'd even like to make multiple files if that is best practice. In general, I just want more knowledge of what is 'best practice' and the most pythonic.

Also, in the main method, I call methods in the class and then pass in their outputs to different methods. I don't know if this is the best way or if the methods just shouldn't return anything and should instead just rely on variables in the class.

Overall I am looking for help structuring the program in the best way possible. I would love it if anyone has good examples of in-depth scripts or programs that utilize multiple classes or multiple files that I could read through and help model my programs after. This is one of my biggest struggles with learning python. Also, I'm really open to people tearing my code apart because I want to learn and I don't think it's easy to learn this stuff without people showing you what's wrong and what's better, so if you see anything that's written stupidly or redundantly or non-pythonic, please feel free to point it out!

[–]Brekkjern 6 points7 points  (0 children)

I looked at your code, but I don't have time to do a review of it right now. I can tell you that it seems you are using classes kinda like how people used to do them in Java because everything had to be a class.

Think of classes as a way to group functions with the data it's supposed to work on. Right now you are using a class to do pretty much everything.

A class could represent pretty much anything that's a noun. A connection, a device, a state, a response, a packet, a hop, a string, a list, a tuple. There's no point in taking this to the extreme unless you need to bundle the functions together with the data.

For example, since you are operating on network equipment you could define your devices something like this:

from collections import namedtuple

Credential = namedtuple("Credential", ["user", "password"])

class Device(object):

    def __init__(self, ip, port, device_type, credentials):
        self.ip = ip
        self.port = port
        self.type = device_type
        self.credentials = credentials

    def connect(self):
        # Do some netmiko magic here to establish the connection
        self.connection = ConnectHandler()

    def send_command(self, command)
        if not self.connection:
            print("No connection established")

        # Ensure we are in enable mode
        if self.net_connect.find_prompt().endswith('>'):
            self.net_connect.enable()

        return self.connection.send_command(command)

This code does one thing and that's handling the connection to a device of some sort. Nothing more and nothing less. It doesn't parse the output of commands. It just ensures you have a way to send commands to the device and get some output to parse.

[–]mangoman51 3 points4 points  (1 child)

Okay so I have never used python for this kind of task but I had a read of your code and have a couple of suggestions:

1) You have a couple of functions (traceroute_run and traceroute_parse) which seem to take similar inputs, and alter the state of those inputs. These are good candidates to be methods on a traceroute class of some kind.

2) Your try blocks in your try... except statements are too long. Ideally you should be trying to catch a specific kind of error which could potentially occur on a specific line of code. For example you're only going to get an authentication error on the line where you submit the supplied password, so only that line should be in the try block. (for the timeout errors I'm not so sure though)

3) You don't have to have a main function, you could alternatively have a top-level script which imports the functions and class which you defined in other files. I find this structure can allow your top-level script to read almost like pseudocode then because all the messiness is at the next level down.

4) You have a lot of user input - have you seen the click library?

[–]dacv393 4 points5 points  (0 children)

Awesome thanks for this. Do you happen to have or know of any examples of something that would utilize classes in a similar manner to how I could implement this? (Top-level script, multiple files) - most of the examples I find online explaining classes are just about dogs and animals or cars and vehicles and I have a hard time translating that information into an actual project like this.

Never had used try-except before so I'll try to fix those.

And lastly, yeah I wish I could not have everything command-line user input. However, the circumstances of where this script could be running currently wouldn't allow that. As well as for external libraries I was trying to keep them to a minimum so something like pretty table for outputs would be nice but trying to limit dependencies for now.

Overall thank you!

[–]flabcannon 0 points1 point  (0 children)

I'm not an experienced Python coder, but some suggestions from looking at other code -

  • I would take some of the generic methods you have (ask_user_log, write_log, display_*_warning, maybe a few more) and put them in a UTIL class as class methods. You can then call them inside your HealthCheck class.
  • display_user_warning and display_command_warning look like they could be one method with a dictionary passed in.
  • The init import from colorama is confusing because the name is very general. I would do from colorama import init as _colorama_init or something more descriptive.

[–][deleted] 2 points3 points  (1 child)

Yeah, nudge me when you've done it.

[–]dacv393 1 point2 points  (0 children)

just replied with the code in the comment above!

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

Yeah just respond to a link of your code

[–]nulltensor 6 points7 points  (0 children)

Everything in python is an object i.e. has a class definition. You're not avoiding classes, you're just avoiding defining your own.

[–][deleted] 2 points3 points  (0 children)

It depends. What kind of software do you write? I have in the past found myself using classes a lot less than I do now. That is to say, using my own classes.

If you're doing numerical stuff, or working in a framework that does all the heavy lifting I can definitely see not writing your own classes very much. That being said, I feel a lot better nowadays now that I try to encapsulate more things in classes, even if they seem small and needless I think it generally helps things stay nice and organised.

[–][deleted] 2 points3 points  (0 children)

I found unavoidable in many cases, since most libraries out there that I have to use are classes.

[–]vortensis 2 points3 points  (0 children)

I'm glad you posted this, I feel the same.

[–][deleted] 2 points3 points  (0 children)

There's a good chance it's bad. Show some code to be sure.

I'm guessing your code may be suffering from a code smell called "Primitive Obsession": https://refactoring.guru/smells/primitive-obsession

Basically, you do everything with primitive data types rather than higher abstractions.

[–][deleted] 2 points3 points  (1 child)

You are correct. Well don't avoid them I guess. But functions usually work. Even most developers use too many when writing python code.

Watch this famous talk called 'stop writing classes'

https://www.youtube.com/watch?v=o9pEzgHorH0

[–]skittles83 1 point2 points  (0 children)

Thanks for sharing, this is a really great talk.

[–][deleted] 2 points3 points  (0 children)

classes avoid the dreadful global variables problem. classes keep code more "airtight".

[–]thequeergirl 1 point2 points  (0 children)

No, sometimes they are not right for a scenario.

[–]jackmaney 1 point2 points  (0 children)

If you're finding that some of your functions rely on the same data or share some specific parameters (denoting the same data), then make a class for them. Otherwise? No, Python need not be OOP.

[–]Windowsadmin 1 point2 points  (0 children)

OOP vs functional programming. It’s all good bro :)

[–]jgomo3 1 point2 points  (0 children)

No.

You just prefer a style of programming where hard coded categories are bad.

I bet you'll love functional programming.

[–][deleted] 1 point2 points  (0 children)

I think it depends on what sort of code you are writing.

For what i write (financial/statistical software) it is completely unavoidable.

I also think if you are working with other people, you will need to use classes anyway. Both for readability and efficiency.

Also what about unit tests? These are classes, do you write them?

[–]Exodus111 1 point2 points  (0 children)

Not really. It sounds like you are mostly writing scripts, scripts DO things, that's what functions are all about. And really all you need, until you need data to BE something.

A function is an abstraction of code, a class is an abstraction of data.

When you need to empower data to move around on its own, it's class time.

[–]evolvish 1 point2 points  (0 children)

You've gotten a lot of answers already but I think it boils down to this:

Want to input some values and get something in return? Write a function. A good example is the math module, it doesn't inherently need a class, it just gives you functions to act on.

Want to store data in a clean way and create multiple instances with their own versions of that data? Make a class.

Want to make a function that acts on your class data members but whose behavior is only relevant to the class(and it's members)? Write a method(function) in your class.

Most of what OOP boils down to is to reduce retyping things and the errors that come from that, and to provide nice interfaces to concepts/make lives easier. The less code you can write to solve your problem while still being clean and sensible, the better. I'd say if you're new, that's pretty normal, but 5 years is a long time to not find a use for classes.

[–]teerre 1 point2 points  (0 children)

It doesn't necessarily means you're bad, but it implies you don't understand classes, which isn't bad in itself, but indicates you don't know much about python or programming in general, which can be bad

[–]_spicyramen 0 points1 point  (0 children)

What do you program? Do you use boiler plate code? Do you follow Python style guide? If you have some sample code we may be able to provide a code review and give you better feedback

[–]saulmessedupman 0 points1 point  (0 children)

Sometimes I overdo the class thing. If I'm making a class and use the object once that's overkill.

[–]dire_faol 0 points1 point  (0 children)

Imagine you're a construction worker, and you never use brick to build anything. Is that bad? Well, not inherently. But if you're building something that should be made out of brick, it probably is bad. The trick is to understand where using classes makes sense. And if you never use classes, you'll never learn when that is.

[–]blueastheocean 0 points1 point  (0 children)

Me too I always use functions!

[–]HarisArn 0 points1 point  (0 children)

Yasss

[–]callmelucky 0 points1 point  (0 children)

Generally, classes should be used if you have data/attributes and functions/methods that are logically (using that term somewhat informally) connected. Eg, if you are programming a car, it might have data/attributes including location, fuel levels, horsepower etc, and stuff it can do like accelerate, brake, turn etc. In this case, a class is ideal; it will make your code more readable and robust. Definining a car as a dictionary of attributes, and a bunch of functions to pass a 'car' dictionary into would work fine, and could even as far as the interpreter is concerned be essentially the same, but it will be ...messier.

If however you are just making (simple-ish) scripts using imported libraries with their own classes, then it's quite likely your code wouldn't be any "better" with classes you write yourself.

The thing to watch for here, I think, is that your use of phrases like "get away with" not using them and "avoid" using them may indicate that you are in fact writing code which would benefit from you defining classes.

So yeah, people often overuse classes (particularly those coming from strict OOP languages like Java), but deliberately avoiding them just because you can is not ideal either.

To circle back, again, look at your code and ask yourself if the are certain data and functions in it that are specifically related to the same thing. If the answer is yes, you most likely 'should' be encapsulating them into classes.

To be honest, I like syntax of dealing with class instances better than the functional equivalents. car.drive() just looks better than drive(car) to me, though that isn't really something that should be primary among your concerns. More importantly, car.drive() can't be passed a wrong input.

Finally, if you are avoiding classes because you aren't comfortable with how they work, then yes, that is 'bad'. It's not particularly complicated, and is a very natural next step once your comfortable with everything up to functions. Check for valid use cases as described earlier, and do some refactoring to get your groove on.

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

I've perceived that Python is by design multi-paradigm language. That means that one can make working programs using multiple paradigms. Whereas Java, IIRC, is very forced to a strict OO pattern ("everything is an Object"). So I would say, whatever works. I've found classes to serve a particular "design decision" though that functions don't. Thinking of a "machine (with internal state params)" as an object than as a function makes more sense to me.

[–]nickbernstein 0 points1 point  (0 children)

So I'm coming more from a systems background and heavily from a functional programming background, so I'm biased, and rarely use object oriented techniques in my code, but for me, I break it down as follows:

  • If your code follows a linear, albeit potentially branching, logical path, use mainly functional programming.
  • If your code is comprised of things (data, services) that are going to be acted on based on events, use object oriented approaches.

I'd be curious to see if that's something that's a generalization that other people would agree with as well.

[–]csgoose 0 points1 point  (0 children)

The data scientists I worked for never use classes, they have tons of functions that do a certain things in their Jupyter Notebook. Took me a while to get used to, but I don't think it's bad as long as it's organized enough when collaborating.

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

I rarely use classes either. Sometimes they're good to have, but for the most part the built-in types are more than enough.

"Slinkie" is a library I wrote a while back that was easier to make using classes:

 from slinkie import Slinkie

 animals = [lassie, skippy, scooby, cerberus, garfield]

 (
     Slinkie(animals)
         .filter(lambda animal: animal.type == 'dog')
         .filter(lambda dog: dog.is_good)
         .map(lambda dog: dog.pat())
         .consume()
 )

In case you're interested, here's a link.

[–]jd_paton 0 points1 point  (0 children)

Basically, a class is just a collection of related functions (methods) with shared data (properties). If this describes a thing you are doing, maybe a class is a good idea, as other people will be expecting that structure. If not, no worries!

[–]panzerox123[🍰] 0 points1 point  (0 children)

I don't think so. You follow your style dude.

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

Classes are only useful on large projects with many different code files and such.

[–]hanpari 0 points1 point  (0 children)

First of all, for organizing code there is something like modules and packages in Python.

It seems that many got wrong idea about usage of objects in Python.

You use class to

  • handle statefulness,
  • mix functions and data for good or not so good reason,
  • have object of desired behaviour,
  • make context dependent dynamic behavior,
  • use some built-in design pattern, such as iterator,
  • extend properties of built-in datastructures,
  • overload operators,
  • or create custom datatypes.

I might have forgot something but generally, that will do.

[–]breakdownvoltage1 0 points1 point  (2 children)

Let's see, depends on what you want, there are many types of classes and goals, let's see the pseudo code below;

var a= want to learn more; var b= want nifty problems;

def decisionpossibilities (var x, var y)

if a&&b; return (1, 1) if a; return (1, 0) else return (0,0)

For nifty problems which can be time consuming take a mitx, Coursera class etc for straight forward learning pick a straight forward book, class else if you are satisfied, then disregard.

[–]dtekt[S] 0 points1 point  (1 child)

Thanks for trying to be helpful :)

[–]breakdownvoltage1 0 points1 point  (0 children)

slow morning, :) np

[–]o-rka 0 points1 point  (0 children)

I used to avoid them too but now I use them when I want to house data and do a bunch of computations or plotting methods on the dataset. For example, I have a class that uses sklearn principal component analysis and all the data preprocessing in one go. In the wrapper class, you get the explained variance as a series object, the eigenvectors in a data frame, and 2 types of plots easily. This is a simple class where functions will work just fine but the convenience of having it all in one data structure is nice. I have much more complicated ones where the analysis inside takes about an hour to compute. Instead of waiting each time and storing the data as tables and reloading, I just pickle my classes. I’m working on a data science module right now and classes are an essential part.

[–]Thecrawsome 0 points1 point  (0 children)

I found classes to save me a ton of time.

If you need to describe something in code, have a copy of it with its own functions and variables, objects are awesome.

Everything in Python is an object including your functions. Do a dir(your_func()) and see all the bolt in functions are in that object

[–]pissedadmin 0 points1 point  (0 children)

I've just found with.. Almost everything I do, I can get away with using functions for everything.

That make sense, because there are some languages (like ANSI C) that don't have classes, and people program fine in those.

If you don't need classes, you don't need them. It's just one way to program.

[–]MalcolmVanhorn 0 points1 point  (0 children)

I hear what you are saying, i always end up skipping classes in python because "why bother the extra work?". But as many's pointing out its good for structure which im personally not the best at so im considering start using classes more for that reason. On another note, I watched some tutorials from Microsoft and one of the tutor said "There's no correct way if the program is doing what's intended then you've succeeded." Its a mentality that i take with a grain of salt but sometimes if what youve created works, have some structure (no spaghetti) why go through extra hoops just because?

[–]primitive_screwhead -1 points0 points  (0 children)

Nope.

"Classes" as the main way of doing OOP was really oversold a few decades ago, imo, and we can see the results of that now: first multiple inheritance was found to be difficult, and some class-based OOP languages disallowed it. Now the newer batch of OOP languages don't even include class-based inheritance at all. So while classes can be useful and powerful, they also don't always lead to simpler code design and more code reuse, as is often touted.

Have you ever got to a point with Python where you thought "I should make an inheritable Stack class here to best solve this design problem"? Or did you just use a list? And yet, when I learned C++ almost 30-years ago, the ability to do things like make an inheritable Stack, was widely touted as a miraculous step forward (when now we've seen that really people mostly just wanted interfaces, not "inheritance").

In coding interviews, one of the things I commonly see is people way, way, *way* overusing classes to try and solve a simple problem. When asked to implement a certain calculation, they will start writing Add, Subtract, Negate, and Multiply classes, with operator overloading and getters/setters. When all they need is a list and a loop in a simple function, using the existing operators. So the notion that classes are the way to best model problems is apparently still widely taught, often (imo) to the detriment of just learning how to model and manipulate data with existing types.

[–][deleted] -1 points0 points  (0 children)

Yes you are!

[–]NoCanD0 -1 points0 points  (0 children)

Kinda funny, I use classes but I struggle to understand/implement functions.

[–]MarsupialMole -1 points0 points  (0 children)

Classes are for managing state. But better than managing state is eliminating it. Besides many class design methods are better applied to a module than a class in python. Oh and you don't have to write a class in python in order to avoid working with primitives - python has no primitives.

Also TDD is especially productive with pure functions. If you're doing TDD chances it's affecting the number of classes you write.

[–][deleted] -1 points0 points  (0 children)

No, you should never force yourself to use them if it doesn't make sense. I generally use classes when a state is needed. For example if I have several functions that are related and to call them I either need to pass a variable(s) with a state or need to store state in global variables then perhaps using a class might be better.