Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • Python Tutorial
  • Interview Questions
  • Python Quiz
  • Python Glossary
  • Python Projects
  • Practice Python
  • Data Science With Python
  • Python Web Dev
  • DSA with Python
  • Python OOPs
Open In App
Next Article:
Understanding Python Dataclasses
Next article icon

Understanding Code Reuse and Modularity in Python 3

Last Updated : 21 Mar, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

What is Object Oriented Programming(OOP)?

OOP is a programming paradigm based on the concept of “objects”, which may contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. Learn more here, or just Google “OOP”.
Objects have characteristics and features, known as attributes, and can do various things, through their methods. The biggest feature of OOP is how well objects can be interacted with, and even molded in the future, which makes them very friendly to developers, scale, change over time, testing, and much more.
 

What is Modularity?

Modularity refers to the concept of making multiple modules first and then linking and combining them to form a complete system (i.e, the extent to which a software/Web application may be divided into smaller modules is called modularity). Modularity enables re-usability and will minimize duplication.
 

Flow of the Article

Aim: To learn object oriented programming – Modularity. How can we turn some portions of our code into a library so that it can be used by anyone for future reference. Making the code modular will enable re-usability and minimizes duplication.

Dependencies: pygame

Summary: We are going to make a small game(not really a game) but just an environment and some objects in it. We will try to make the environment static and the objects( blobs in our case) modular. We will make use of PyGame, since it gives us a simple way to actually visualize what we’re doing and building, so we can see our objects in action. What we’re going to do is build Blob World, which is a world that consists of actors, known as blobs. Different blobs have different properties, and the blobs need to otherwise function within their Blob World environment. With this example, we’ll be able to illustrate modularity. 

We are dividing our learning process into two phases.  

  1. Creating the Environment and the Blobs
  2. Understanding Modularity

BLOB WORLD ( Python Code )

Python




import pygame
import random
  
STARTING_BLUE_BLOBS = 10
STARTING_RED_BLOBS = 3
  
WIDTH = 800
HEIGHT = 600
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
  
game_display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Blob World")
clock = pygame.time.Clock()
  
class Blob:
  
    def __init__(self, color):
        self.x = random.randrange(0, WIDTH)
        self.y = random.randrange(0, HEIGHT)
        self.size = random.randrange(4,8)
        self.color = color
  
    def move(self):
        self.move_x = random.randrange(-1,2)
        self.move_y = random.randrange(-1,2)
        self.x += self.move_x
        self.y += self.move_y
  
        if self.x < 0: self.x = 0
        elif self.x > WIDTH: self.x = WIDTH
          
        if self.y < 0: self.y = 0
        elif self.y > HEIGHT: self.y = HEIGHT
  
  
def draw_environment(blob_list):
    game_display.fill(WHITE)
  
    for blob_dict in blob_list:
        for blob_id in blob_dict:
            blob = blob_dict[blob_id]
            pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size)
            blob.move()
  
    pygame.display.update()
      
  
def main():
    blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)]))
    red_blobs = dict(enumerate([Blob(RED) for i in range(STARTING_RED_BLOBS)]))
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        draw_environment([blue_blobs,red_blobs])
        clock.tick(60)
  
if __name__ == '__main__':
    main()
 
 

Output: 

https://media.geeksforgeeks.org/wp-content/uploads/bobWorld.mp4

PART(1/2): Blob World In this part, we are creating a simple game environment and some objects in it because visualizing what we have created is an exceptional way of learning programming. All we need to understand is how to make our code modular.

PART(2/2): Modularity In this second part, we are going to understand an essential feature of Object Oriented Programming, i.e Modularity. So far, we’ve not introduced anything that will make this (BLOB WORLD code) too hard to maintain or scale over time, at least within the scope of what we can do with PyGame. What about making it modular? There’s a really easy test for this, let’s try to import it! 

To do this, let’s have two files. Let’s copy the Blob class and random, and make a new file: blob.py  

import random    class Blob:        def __init__(self, color):          self.x = random.randrange(0, WIDTH)          self.y = random.randrange(0, HEIGHT)          self.size = random.randrange(4,8)          self.color = color        def move(self):          self.move_x = random.randrange(-1,2)          self.move_y = random.randrange(-1,2)          self.x += self.move_x          self.y += self.move_y            if self.x  WIDTH: self.x = WIDTH                    if self.y  HEIGHT: self.y = HEIGHT

Back to our original file, let’s remove the Blob class, and then import Blob from blob.py.  

import pygame  import random  from blob import Blob    STARTING_BLUE_BLOBS = 10  ...

Immediately, we’re given an error in the blob.py file, regarding our Blob class, where we have some undefined variables. This is definitely a problem with writing classes, we should try to avoid using constants or variables outside of the class. Let’s add these values to the __init__ method, then modify all of the parts where we used the constants. 
So, here is our new Blob class file :blob.py 

Next, within our original file, when we call the Blob class, it’s expecting some values for those arguments, so you’d add those in the main function:  

def main():      blue_blobs = dict(enumerate([Blob(BLUE,WIDTH,HEIGHT) for i in range(STARTING_BLUE_BLOBS)]))      red_blobs = dict(enumerate([Blob(RED,WIDTH,HEIGHT) for i in range(STARTING_RED_BLOBS)]))      while True:          ...

Great, so now our Blob class can at least be imported, so it’s modular by nature already! Another good idea is to attempt to give the developer that is using your code as much power as possible, and to make your class as generalize-able as possible. At least one example where we could definitely give more to the programmer using this class is in the definition of the blob’s size:  

  self.size = random.randrange(4,8) 

Is there any reason why we wouldn’t want to give the programmer an easy way to change these? I don’t think so. Unlike x_boundary and y_boundary, however, we do not necessarily *need* the programmer to provide us a value for the size, since we can at least use a reasonable starting default. Thus, we can do something like:  

class Blob:        def __init__(self, color, x_boundary, y_boundary, size_range=(4,8)):          self.x_boundary = x_boundary          self.y_boundary = y_boundary          self.x = random.randrange(0, self.x_boundary)          self.y = random.randrange(0, self.y_boundary)          self.size = random.randrange(size_range[0],size_range[1])          self.color = color

Now, if the programmer wants to change the size, they can, otherwise they don’t have to. We might also want to allow the programmer to modify the speed of the blob if they want to: 

import random      class Blob:        def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):          self.size = random.randrange(size_range[0],size_range[1])          self.color = color          self.x_boundary = x_boundary          self.y_boundary = y_boundary          self.x = random.randrange(0, self.x_boundary)          self.y = random.randrange(0, self.y_boundary)          self.movement_range = movement_range        def move(self):          self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])          self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])          self.x += self.move_x          self.y += self.move_y            if self.x  self.x_boundary: self.x = self.x_boundary                    if self.y  self.y_boundary: self.y = self.y_boundary

Now we’ve opened up the class quite a bit. Does anything else jump out at us? Yes, the line where we force the blob to remain in-bounds. Might there be examples where we’d like the blobs to be able to roam freely out of view? Certainly! Is this bounding code useful though? Is it likely that programmers will want to make use of this quite often? Certainly! however, that it makes more sense to either not have the code at all, or to give it its own method, like so: 

import random    class Blob:        def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):          self.size = random.randrange(size_range[0],size_range[1])          self.color = color          self.x_boundary = x_boundary          self.y_boundary = y_boundary          self.x = random.randrange(0, self.x_boundary)          self.y = random.randrange(0, self.y_boundary)          self.movement_range = movement_range        def move(self):          self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])          self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])          self.x += self.move_x          self.y += self.move_y        def check_bounds(self):          if self.x  self.x_boundary: self.x = self.x_boundary                    if self.y  self.y_boundary: self.y = self.y_boundary

Now, the programmer can decide to use it or not. You could also give some sort of argument in the move method, where, if True, then boundaries would be enforced. 
So we got a glimpse of how we can make our python code Modular.

Resources: 

  • Original Video Series (by pythonprogramming.net)
  • pythonprogramming.net
  • Harrison Kinsley (Thank you H.Kinsley)

 



Next Article
Understanding Python Dataclasses

A

Amartya Ranjan Saikia
Improve
Article Tags :
  • Python
  • Technical Scripter
Practice Tags :
  • python

Similar Reads

  • Using C codes in Python | Set 1
    Prerequisite: How to Call a C function in Python Let's discuss the problem of accessing C code from Python. As it is very evident that many of Python’s built-in libraries are written in C. So, to access C is a very important part of making Python talk to existing libraries. There is an extensive C p
    4 min read
  • Using C codes in Python | Set 2
    Prerequisite: Using C codes in Python | Set 1 In the previous article, we have discussed how to access C code in Python. Now, let's see how to access C functions. Code #1 : Accessing C functions with Python import work print ("GCD : ", work.gcd(35, 42)) print ("\ndivide : ", work
    2 min read
  • Deconstructing Interpreter: Understanding Behind the Python Bytecode
    When the CPython interpreter executes your program, it first translates onto a sequence of bytecode instructions. Bytecode is an intermediate language for the Python virtual machine that’s used as a performance optimization. Instead of directly executing the human-readable source code, compact numer
    4 min read
  • Understanding Python PyInstaller Hooks
    In the world of Python development, distributing applications can sometimes be a complex task. PyInstaller simplifies this process by packaging Python applications into standalone executables, enabling them to run on systems without requiring a Python interpreter. However, creating an executable tha
    5 min read
  • Understanding Python Dataclasses
    DataClasses has been added in a recent addition in python 3.7 as a utility tool for storing data. DataClasses provides a decorator and functions for automatically adding generated special methods such as __init__() , __repr__() and __eq__() to user-defined classes. DataClass in Python DataClasses ar
    7 min read
  • Reloading modules in Python
    The reload() is a previously imported module. If you've altered the module source file using an outside editor and want to test the updated version without leaving the Python interpreter, this is helpful. The module object is the return value. Reloading modules in Python2.xreload(module)For above 2.
    1 min read
  • Issues with using C code in Python | Set 1
    Prerequisite: Using C codes in Python | Set 1, Set 2 Issue #1 : If using ctypes then there is a problem that the original C code may use language that don’t map cleanly to Python. Let's take the example of divide() function as it returns a value through one of its arguments. It is a common C techniq
    2 min read
  • Bound, unbound, and static methods in Python
    Methods in Python are like functions except that it is attached to an object.The methods are called on objects and it possibly make changes to that object. These methods can be Bound, Unbound or Static method. The static methods are one of the types of Unbound method. These types are explained in de
    5 min read
  • C Extension Module using Python
    Writing a simple C extension module directly using Python’s extension API and no other tools. It is straightforward to make a handcrafted extension module for a simple C code. But first, we have to make sure that the C code has a proper header file. Code #1 : #include <math.h> extern int gcd(i
    4 min read
  • How to create modules in Python 3 ?
    Modules are simply python code having functions, classes, variables. Any python file with .py extension can be referenced as a module. Although there are some modules available through the python standard library which are installed through python installation, Other modules can be installed using t
    4 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences