You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In programming, a paradigm is an abstract way to understand and solve a problem.
A paradigm is like a perspective, a high point from which you can survey the terrain and try to decide the path your journey will take.
Toay, there are three major programming paradigms:
Imperative Programming.
Object Oriented Programming (OOP).
Functional Programming (FP).
In principle any language can be used to program in any paradigm, but in practice certain languages tend to favor certain paradigms.
For instance C is generally used in the imperative style, while Java and C++ favor Object Oriented Programming, and
Haskell and Lisp encourage functional programming.
In this tour we will focus on Python and how it can be used in all three paradigms.
We will discover that Python is excellent at imperative programming, decent at object oriented programming,
and poor at functional programming. We will explore the characteristics of each paradigm and understand their advantages and drawbacks.
The Object Oriented Programmer sees the world as groups of data (objects), and actions on that data (methods).
Where the imperative programmer was a cook or a chemist, following recipes and formulas to acheive a desired result,
the object oriented programmer is a greek philosopher or 19th century naturalist concerned with the proper taxonomy and cescription of the creatures and places of the programming world.
Object Oriented Programming is characterised by describing a program as groups of data (objects) and actions on that data (methods).
Object Oriented Programs typtically also have, classes, a differentiation between class and object data,
virtual functions, and strict access controls. However, not every object oriented programming language has all of these features. You may be surprised to learn that Javascript is an OOP language that doesn't even have classes!
What is an Object?
An object is a collection of data and functions which act on that data. Different data which belong to an object are called attributes. Functions which act on an object called methods.
In Python we can inspect the methods and attributes with the dir function:
You can create your own types of objects with the class keyword:
classGPA(object):
pass# do nothing for now...
Defining methods on this class is easy:
classGPA(object):
defshow(self):
print(self.value) # What is self.value? Undefined for now, we'll get to that in a minute.
A method always takes at least one argument. The first argument, conventionally called self, will be the object which the method is called on. When we do self.value we're accessing the value attribute of the self object.
One of the most useful and important methods is called the constructor.
A constructor is a special method which is called automatically whenever a new object is created.
In Python the constructor is called __init__.
It doesn't have to return anything, but it can take however many arguments one likes.
It can be used to initialize the method so it can be used later.
Let's initialize the value attribute so it can be used in the show method later:
classGPA(object):
def__init__(self, value):
self.value=value# Set the attribute value on the self object to be equal to the value argument.defshow(self):
print(self.value)
chemistry_gpa=GPA(3.0)
chemistry_gpa.show() # prints 3.0
The object in parentheses means that the GPA class inherits from the object class.
It is imporatant to note that we are not calling GPA here.
We're just telling Python what the parent of the GPA class is.
Objects are arranged in a hierarchy: each class inherits from one or more parent classes.
Child classes have all of their parents methods and attributes, and act just like their parents.
Think like a family tree, where a parents have many children which have their eye color, brains, brawn, or other traits.
Now this analogy is kind of flawed, because all humans have the same attributes, and can do the same things with their methods. Maybe it would be better to describe humans as class which can be instantiated into individual people objects?
We could get rather carried away describing all of human physiology as a class.
What about Dogs and Cats? We could describe them that way too.
They can eat, sleep, but they can't read and write.
We could just copy pase that code, remove read and write, change some of the physiology and be done with that.
However, copy pasting code sucks and is an easy way to make mistakes.
If you have to change a bug in one place, now you have to track down every other place it was pasted.
Since sleep, drink, and eat
are pretty much the same for all animals, it would be handy if we could share code between them.
Animals are arranged in a kind of scientific hierarchy (think taxonomy and Latin names) already based on their attributes and what they do. I wonder if we could apply that to our code?
In fact this is an excellent model of inheritence.
Since all animals eat, and sleep, and drink we can define those methods for all animals as part of an Animal class.
Then every animal can inherit from the Animal class or one of its children just like that taxonomic tree.
This is what I meant when I said that object oriented programmers are like naturalists.
They look at the world and describe it was what attributes a thing has, and what it can do.
They look at how objects interact, how objects can create other objects, the objects which fit in each attribute.
They look at people and see that they have eyes, which are made up of cells, which can be Eukaryotic or Prokaryotic (two classes!), which are made up of organelles, and molecules (organic and inorganic classes!) and are made up of Atoms and so on.
Everything in a problem, everything in the world can be viewed as an object which has attributes and can do things.
Code can be shared between objects effortlessly. A change in one place can change the whole system.
Methods can work differently for different classes -- who cares whether an animal has one stomach like a human or eight like a cow? As long as it has an animal has a digest method you can pass food to it and get what you want out the other end (errr or don't want. Analogies man, too easy to get lost.).
Analogy: Classes as Form Letters
A class is like a form letter.
Dear ___,
____,
Sincerely,
Dept. of Programming & Charity
A class can inherit from another class, in which case it has all of the attributes of its parents:
Dear ___,
We were hoping you could donate some money.
Sincerely,
Dept. of Programming & Charity
Finally, a completed letter with no more blank spaces can be filled out. This is the final object:
Dear Billy,
We were hoping you could donate some money.
Sincerely,
Dept. of Programming & Charity
Now this analogy is also flawed because it doesn't mention methods, or constructors, at all.
But it does show how inheritance works and how attributes are filled in.
Python Class Hierarchy
Okay, classes are arranged in a hierarchy. What is Python's class heirachy? We can use the type and isinstance functions to find out.
Wait. type isn't a function. It's a class. So type is its constructor, which returns the type/class of whatever is given to it.
More Python Methods
In Python, and pretty much only in Python, Attributes or methods which begin and end with two underscores, like __init__ and __del__, have special meaning to the Python interpreter.
For instance, when you write 'a' + 'b', the Python interpreter will look up the __add__ method on the str objects respectively and transform them into something like this: 'a'.__add__('b').
If you want to be able to "add" your objects together you just need to implement the __add__ method for your class.
classGPA(object):
def__init__(self, value):
self.value=valuedef__add__(self, other):
returnGPA((self.value+other.value) /2)
python_gpa=GPA(4.0)
film_making_gpa=GPA(3.9)
total_gpa=python_gpa+film_making_gpaanother_total_gpa=python_gpa.__add__(film_making_gpa) # Exactly the same as above.
There are many of the double under score methods for Python objects which have a wide variety of meanings. You can implement or override any operator you can think of (-, /, in, ||, >>, the brackets in my_list[3], etc.) or even dig into the guts of the object. You can learn more about each of these and what they do here:
https://docs.python.org/3/reference/datamodel.html.
Classes introduce two more kinds of variables: attributes, which we've already discussed, and class variables.
A class variable, also known as a static class variables in other languages like C++ and Java, is shared by all instances of a ccallss
(AKA all objects of that class). It's kind of like a global variable which belongs to a class.
In Python you can create them like this:
classExample(object):
my_class_variable='something'def__init__(self, word):
self.my_attribute=self.my_class_variable+' '+worde=Example('else')
f=Example('other')
print(e.my_attribute) # something elseprint(f.my_attribute) # something otherprint(e.my_class_variable) # somethingprint(f.my_class_variable) # something# You can also access class variables like this:print(Example.my_class_variable) # something
In a rather annoying move, Python allows you to shadow class
variables or create attributes with the same name as the class variable.
This is generally considered a bad idea because it's confusing.
Most object oriented programming languages have some way of protecting certain attributes and methods
so they can't be accessed or called outside of the class and its children.
This keeps other programmers from shooting themselves in the foot messing with things they shouldn't and promotes
separation of concerns.
Python doesn't offer any such protections, but they're still important to know about when learning other languages,
and may help you understand certain Python conventions.
The assumption is that programmers know what they're doing. Ha.
OOP languages typically have three levels of protection:
Public. Attributes and methods (AKA members when discussed as a group) are accessible to every object, every function, everywhere in the program.
Private. Memberss are only accessible to the class and its children.
Friend. Members are only accessible to the class and other classes which are explicitly marked as friends to the class.
If this is somewhat confusing you can remember it with this naughty phrase:
"C++ lets friends touch others' private members".
By convention if you don't want other programmers to use a method or an attribute you can prefix it with an underscore:
Note that these protection levels are not a security feature -- a compromised program can potentially access private values.
They are only there to help make the code more maintainable.
A Bit of OOP History
FIXME: Move to section 0
The first object oriented language was called Smalltalk and was invented at Xerox Palo Alto Research Center in 1972.
The researchers Xerox PARC not only invented one of the most important programming paradigms, they also created
the first graphical user interface, the desktop paradigm and similar analogies for modern computing, and
made advances in semiconductors. Xerox pretty much squandered everything they did at PARC, but Steve Jobs and Apple ripped off
their inventions after a public demo and created the original Macintosh personal computer.
What happens is that the child class overrides the parent class's method and only the child method is called.
However, sometimes you only want to extend the parent class's method, and do a little work at the end.
Fortunately there is a function for that called super.
super takes an object and its class and returns the object with its type as a parent class (AKA super class).
classSon(Parent):
deffoo(self):
self_as_parent_type=super(self, Parent)
self_as_parent_type.foo() # calls the parent's foo methodprint('son')
d=Daughter()
d.foo() # daughters=Son()
s.foo() # parent# son
One common pattern you'll see in constructors is super(self, SOME_PARENT_TYPE).__init__() which calls the parent's
constructor.
Multiple Inheritance
In reality people have multiple parents, but in Python so far all of the classes have only had one parent.
Python allows you to inherit from multiple classes:
classA(object):
defdo_some_thing(self):
print('some thing')
defdo_a_thing(self):
print('a thing')
classB(object):
defdo_some_thing(self):
print('some thing else')
defdo_b_thing(self):
print('b thing')
classC(A, B):
defdo_c_thing(self):
print('c thing')
c=C()
c.do_a_thing() # a thingc.do_b_thing() # b thingc.do_c_thing() # c thingc.do_something() # some thing else
If two parent classes have a method or attribute with the same name, the last class, or the leftmost class always wins.
Maybe it would make sense to think of it the last class as being genetically dominant. Its genes will always win out.
Or maybe "King of the Hill" is a better analogy.
Not all programming languages allow multiple inheritance -- Java in particular forbids it because
multiple inheritance tends to make things complicated. If you see a method called on an object, it can be hard
to figure out where it was defined. Was it defined on the parent? The grandparent? The other great grandparent?
This gets to be a royal pain.
One common pattern multiple inheritance allows is called "mix-ins".
A mix-in is a simple class which provides just a little bit of functionality,
maybe a couple methods which can be combined with multiple different classes of disparate genealogies.
To be honest, I don't have any simple examples of this. I've never actually needed this pattern myself,
but you will find it in widely used libraries like werkzeug which is used for HTTP requests in the Flask
web application framework.
Abstract Classes
We've seen how you can use classes in order to promote code reuse, and admittedly our animal example was pretty contrived.
However, when you stop to think about it, there's one detail which doesn't make sense --
it makes sense to have a base Animal class, from which all other animal species descend,
but there's no such thing as a generic animal.
All of the animals are a specific species, so doing this doesn't make a lot of sense:
classAnimal(object):
# ...generic_animal=Animal()
We want to make Animal an abstract class, which can't actually be instantiated.
This is useful for classes where you just want to share some code, but don't want to provide the full functionality.
In order to prevent Animal from being instantiated we need a virtual method.
It's kind of like a slot which says "fill this in here in the child classes".
Any class with a virtual method is called an abstract class. It can't be instantiated, or made concrete.
Making abstract classes in Python requires some pretty advanced features of the language.
They aren't baked in to the basic syntax the same way as C++.
In order to define an abstract class in Python you need something called a metaclass, which is a class of a class,
and another thing called a decorator which is a way of wrapping a function in a function.
Both of these are fascinating topics for another day.
fromabcimportABCMeta, abstractmethod# Make this a Abstract Base ClassclassAbstract(metaclass=ABCMeta):
# The funny thing with an @ sign is called a decorator.@abstractmethoddefvirtual_method(self):
# ...classConcrete(Abstact):
defvirtual_method(self):
print('concrete')
classAsphalt(Abstract):
# Don't define virtual_methoda=Abstract()
# Throws TypeError: Can't instantiate abstract class Abstract with abstract methods virtual_methodc=Concrete()
c.virtual_method() # concreteb=Asphalt()
# Throws TypeError: Can't instantiate abstract class Abstract with abstract methods virtual_method
Open and Closed Classes
Some programming languages like Ruby allow you to add methods to a class after it's been defined.
This is called having "open" classes, like somone can just open up the hood of the car and jam something
in there which they think is useful. Sometimes it's also called "monkey patching" a class.
In Python you can change the attributes for an object, or even a class, but you can't change the methods.
Personally, I think open classes are a terrible idea.
A coworker of mine has a story about removing a third party Ruby library which wasn't used any more, and then all of a sudden
everything break.
What happened was the library opened up one of the core Ruby classes and added a method to the string class called
to_lower.
Code all throughout the website used to_lower everywhere.
The worst part was that the string class already had a method called lowercase which did the exact same thing!
The most frightening part about this is that this story is in no way unique, and this behavior is common in the Ruby community.
Classes aren't the only way to do object oriented programming.
Some languages like Smalltalk and JavaScript don't have classes at all,
but still have inheritance using a technique called prototypes.
Essentially, it's very easy to define your own objects.
You can then take an object and create a new object which inherits directly from it.
Instead of inheriting from classes, objects inherit from other objects.
We won't provide a lot of examples of prototypal inheritance but it's important to know that classes aren't the only way of having inheritance.
Inheritance with classes is sometimes called "classical", which may be the only good programming pun I know.
Object Oriented Programming Without Inheritance at All
Not to put too fine a point on it, but deeply nested inheritance hierachies are a pain in the ass.
It can be hard to find where something is defined,
and sometimes it's not clear whether a child method calls its parent method or not.
Many modern languages like Go and Rust eschew inheritance altogether,
but that doesn't mean that they aren't object oriented.
In order to leverage some of the same types of code reuse they use concepts called interfaces and traits, but those are a story for another day.
In my definition of object oriented programming was that there must be groups of data and methods on that data.
Going by that definition it's not hard to object oriented programming in C, the king of all imperative languages.
In between the soaring rhetoric, broken analogies, and useless code samples we covered a lot of ground.
We learned about attributes and methods, constructors and destructors, classes and inheritance, and abstract classes and virtual methods.
If you understand what all of those things are and how they're useful, then I've done my job.
The foundations of OOP are simple: the world of problems can be broken down into groups of data (objects), and actions on that data (methods).
Based on this foundation are layers which make OOP one of the most powerful and widely used paradigms of programming.
With all of this power comes a lot of flexibility, and also a lot of complication.
It's always a trade off -- do I need this layer abstraction, this level of complication?
Does it allow my code to be simpler (Keep It Simple Stupid), and promote code reuse?
Or is it a lot of boilerplate which does nothing and obscures what's actually happening?
Not every programming language does OOP the same way, but
it's important to learn the basic principles so you can transfer them to other languages even if they have different features
and slightly different terminology.
Always consider whether there's a better way to solve the problem.
Yes, you are absolutely right. In programming, the term "paradigm" is used to refer to a general methodology or approach to software development. I know that developers often combine different paradigms in their projects depending on the requirements of the task. When I need help with programming assignment I try not to hesitate, but to find a solution to the problem by talking to experts. I found a reliable, professional resource where I have the opportunity to connect with several professional programmers who have the skills and experience to complete various programming homework assignments. I try to discuss the details of my order, so I always get the best result.
Programming paradigms are approaches to programming based on distinct concepts and methodologies. Key paradigms include procedural, object-oriented, functional, and declarative programming. Procedural programming focuses on step-by-step instructions, while object-oriented programming organizes code into objects. Functional programming emphasizes immutable data and pure functions, and declarative programming expresses logic without explicitly outlining control flow. Understanding these paradigms is crucial for effective coding and problem-solving. For students struggling with these concepts, an assignment provider Australia can offer expert guidance and support, ensuring a clear grasp of programming paradigms and their applications in various projects.
Finding assignments challenging? Help with assignment tasks is available from professional services that specialize in academic support. Whether you need help with writing, editing, or research, expert assistance can improve the quality of your work and boost your academic performance. These services offer personalized solutions to fit your needs, helping you meet deadlines and achieve better grades. Explore options for professional help to make your academic journey smoother.
Yes, you are absolutely right. In programming, the term "paradigm" is used to refer to a general methodology or approach to software development. I know that developers often combine different paradigms in their projects depending on the requirements of the task. When I need help with programming assignment I try not to hesitate, but to find a solution to the problem by talking to experts. I found a reliable, professional resource where I have the opportunity to connect with several professional programmers who have the skills and experience to complete various programming homework assignments. I try to discuss the details of my order, so I always get the best result.