This article set covers two concluding steps in a beginner-friendly Python series: using modules and building real programs with file handling and error management (Part 7), then organizing code with object-oriented programming (Part 8). In Part 7, the series explains that a module is a reusable file of Python code and shows how to import standard library modules (such as math and datetime) using both full-module imports and selective imports. It also introduces JSON as a common data-exchange format, demonstrating conversion between Python dictionaries and JSON strings and reading/writing JSON using open() and json.dump/json.load. File input/output is presented with with statements for safe resource handling, including reading whole files, line-by-line iteration, and writing or appending output. The series then covers exception handling with try/except, multiple specific exceptions, and the try/except/else/finally structure, plus raising custom exceptions. It also covers installing third-party libraries with pip (e.g., requests, numpy, pandas). Part 8 turns these concepts into scalable code organization using classes and objects, including __init__ and self, instance versus class variables, inheritance with super(), polymorphism, encapsulation conventions, common dunder methods, and properties via @property.
Python beginner series explains modules, file I/O, errors, and object-oriented programming
This article set covers two concluding steps in a beginner-friendly Python series: using modules and building real programs with file handling and error management (Part 7), then organizing code with...
- Part 7 explains importing modules, including the math and datetime modules, and how to import specific items or alias names.
- Part 7 demonstrates reading and writing files using with open(...), including reading line-by-line and writing or appending output.
- Part 7 covers exception handling with try/except, multiple exception types, and try/except/else/finally, plus raising exceptions.
- Part 7 describes using pip to install external libraries and using them like modules (example: requests.get).
- Part 8 teaches OOP basics: defining classes, using __init__ and self, instance vs class variables, inheritance with super(), polymorphism, encapsulation conventions, and Python dunder methods/properties.
Part 8 of an 8-part beginner-friendly series on learning Python from scratch. Congratulations — you've made it to the final part! Everything you've learned — variables, control flow, collections, functions, file I/O, error handling — can be organized into classes and objects. This is object-oriented programming (OOP), and it's how professional Python code is written. OOP isn't required to write working programs, but it's essential for writing code that scales, is maintainable, and professional. This final article brings everything together. Classes and Objects A class is a blueprint for creating objects. An object is an instance of that class. Think of a class like a cookie cutter and objects like the cookies it produces. Defining a class class Person: pass # Create an object (instance) person = Person() print(person) # <__main__.Person object at 0x...> class Person: defines a class. person = Person() creates an object from that class. The __init__ Method and self The __init__ method runs automatically when you create an object. It's where you initialize the object's data. class Person: def __init__(self, name, age): self.name = name self.age = age person = Person("Ramesh", 25) print(person.name) # Ramesh print(person.age) # 25 self represents the object itself. When you write self.name = name, you're saying "this object's name attribute equals the name I was given." Think of it this way: name (parameter) is the input self.name (attribute) is the object's stored data Creating multiple objects class Person: def __init__(self, name, age): self.name = name self.age = age person1 = Person("Ramesh", 25) person2 = Person("Priya", 23) print(person1.name, person1.age) # Ramesh 25 print(person2.name, person2.age) # Priya 23 Each object is independent. person1.name is separate from person2.name. Methods A method is a function inside a class. Methods operate on the object's data: class Person: def __init__(self, name, age): self.name = name self.age = age def greet(self): return f"Hello, I'm {self.name}" def have_birthday(self): self.age += 1 person = Person("Ramesh", 25) print(person.greet()) # Hello, I'm Ramesh person.have_birthday() print(person.age) # 26 Call methods with dot notation: person.greet(). The self parameter is passed automatically — you don't type it. Instance vs Class Variables Instance variables are unique to each object. Class variables are shared by all objects of that class: class Dog: species = "Canis familiaris" # Class variable def __init__(self, name): self.name = name # Instance variable dog1 = Dog("Buddy") dog2 = Dog("Max") print(dog1.name) # Buddy (unique to dog1) print(dog2.name) # Max (unique to dog2) print(Dog.species) # Canis familiaris (shared) print(dog1.species) # Canis familiaris (accessible via instance too) Use class variables for data shared by all instances. Use instance variables for data unique to each instance. Inheritance Inheritance lets you create a new class based on an existing class. The new class inherits methods and attributes from the parent: class Animal: def __init__(self, name): self.name = name def speak(self): return f"{self.name} makes a sound" class Dog(Animal): def speak(self): return f"{self.name} barks" class Cat(Animal): def speak(self): return f"{self.name} meows" dog = Dog("Buddy") cat = Cat("Whiskers") print(dog.speak()) # Buddy barks print(cat.speak()) # Whiskers meows Dog and Cat inherit from Animal and override the speak() method. This is called method overriding. Using super() Call the parent class's method with super(): class Animal: def __init__(self, name): self.name = name def describe(self): return f"{self.name} is an animal" class Dog(Animal): def __init__(self, name, breed): super().__init__(name) # Call parent's __init__ self.breed = breed def describe(self): parent_desc = super().describe() # Call parent's describe return f"{parent_desc} and is a {self.breed}" dog = Dog("Buddy", "Golden Retriever") print(dog.describe()) # Buddy is an animal and is a Golden Retriever super() lets you access the parent class without repeating code. Polymorphism Polymorphism means "many shapes" — the same function name works differently depending on the object type: class Dog: def speak(self): return "Woof!" class Cat: def speak(self): return "Meow!" class Cow: def speak(self): return "Moo!" animals = [Dog(), Cat(), Cow()] for animal in animals: print(animal.speak()) # Output: # Woof! # Meow! # Moo! Each animal speaks differently, but you call the same method. This is polymorphism in action. Encapsulation Encapsulation is the idea of bundling data and methods together, and controlling access to them. Python uses naming conventions: public_attribute — accessible from outside (convention) _private_attribute — intended private (convention, not enforced) __really_private — name-mangled, harder to access (enforced) class BankAccount: def __init__(self, balance): self.__balance = balance # "Private" def deposit(self, amount): if amount > 0: self.__balance += amount def withdraw(self, amount): if 0 < amount <= self.__balance: self.__balance -= amount def get_balance(self): return self.__balance account = BankAccount(1000) account.deposit(500) print(account.get_balance()) # 1500 # Can't access directly: # print(account.__balance) # AttributeError (name-mangled) The double underscore (__) makes the attribute private. Access it through methods instead. This prevents accidental misuse. Dunder Methods Dunder methods (double underscore) are special methods Python calls automatically. Here are the most important: __str__ and __repr__ class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f"{self.name} ({self.age})" def __repr__(self): return f"Person('{self.name}', {self.age})" person = Person("Ramesh", 25) print(str(person)) # Ramesh (25) — human-readable print(repr(person)) # Person('Ramesh', 25) — for debugging __str__ is for end users. __repr__ is for developers. __len__ class ShoppingCart: def __init__(self): self.items = [] def add(self, item): self.items.append(item) def __len__(self): return len(self.items) cart = ShoppingCart() cart.add("apple") cart.add("banana") print(len(cart)) # 2 Now len(cart) returns the number of items. __eq__ class Person: def __init__(self, name): self.name = name def __eq__(self, other): return self.name == other.name person1 = Person("Ramesh") person2 = Person("Ramesh") print(person1 == person2) # True (compares names) Define how == works for your objects. Properties and Getters/Setters Properties let you access attributes like data, but with method-like control: class Person: def __init__(self, name): self._name = name @property def name(self): return self._name @name.setter def name(self, value): if len(value) > 0: self._name = value person = Person("Ramesh") print(person.name) # Ramesh (getter) person.name = "Priya" # Setter print(person.name) # Priya The @property decorator makes name act like an attribute but run validation code. Practical Examples Example 1: User class class User: def __init__(self, username, email): self.username = username self.email = email self.created_at = datetime.now() def __str__(self): return f"User({self.username})" def change_email(self, new_email): if "@" in new_email: self.email = new_email else: raise ValueError("Invalid email") user = User("ramesh", "ramesh@example.com") print(user) # User(ramesh) user.change_email("ramesh.new@example.com") Example 2: Inheritance with Bank Accounts class Account: def __init__(self, owner, balance): self.owner = owner self.balance = balance def deposit(self, amount): self.balance += amount class SavingsAccount(Account): def __init__(self, owner, balance, interest_rate): super().__init__(owner, balance) self.interest_rate = interest_rate def apply_interest(self): self.balance *= (1 + self.interest_rate) savings = SavingsAccount("Ramesh", 1000, 0.05) savings.deposit(500) savings.apply_interest() print(savings.balance) # 1575.0 Example 3: Polymorphism with shapes class Shape: def area(self): raise NotImplementedError class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius ** 2 class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height shapes = [Circle(5), Rectangle(4, 6)] for shape in shapes: print(f"Area: {shape.area()}") # Output: # Area: 78.5 # Area: 24 Why This Matters OOP is how professional code is organized. Without it, programs become tangled messes of functions and variables. With OOP, you group related data and behavior together into classes, making code: Reusable — inheritance lets you extend existing code Maintainable — encapsulation hides complexity Scalable — polymorphism lets you add new types easily Clear — objects represent real-world concepts The most common beginner mistakes: Forgetting self in methods Confusing __init__ (constructor) with class definition Not using inheritance when it makes sense Overcomplicating with too many classes (start simple) Breaking encapsulation with direct attribute access Your Journey is Complete You've now learned: Syntax and basics (Parts 1–2) Working with text and logic (Parts 3–4) Organizing data (Part 5) Organizing code (Part 6) Working in the real world (Part 7) Professional code structure (Part 8: OOP) You have all the fundamental skills of a Python programmer. Where you go from here is up to you — web development, data science, automation, games, machine learning — Python is everywhere. What's Next You've completed the 8-part beginner series. From here: Web development: Flask or Django frameworks Data science: Pandas, NumPy, Matplotlib Automation: Scripts to automate tasks Games: Pygame library Machine learning: Scikit-learn, TensorFlow Advanced Python: Decorators, metaclasses, async/await The fundamentals you've learned here apply to everything. Pick a project that excites you and build it.
9 hours agoPart 7 of a beginner-friendly series on learning Python from scratch. In Part 6, we learned to write reusable functions. Now it's time to make those functions work in the real world: reading data from files, handling things when they go wrong, and using code other people have written. This is where Python transitions from "learning exercises" to "actual programs." Real programs read files, talk to the internet, handle unexpected input, and use libraries to solve complex problems. Modules and Imports A module is a file containing Python code that you can reuse. Python comes with a huge standard library of modules, and you can also install external ones. Using the math module import math print(math.sqrt(16)) # 4.0 print(math.pow(2, 3)) # 8.0 print(math.pi) # 3.14159... print(math.ceil(4.3)) # 5 (round up) print(math.floor(4.7)) # 4 (round down) import math loads the math module. You access its functions and constants with dot notation: math.sqrt(), math.pi, etc. Importing specific items If you only need a few things, import them directly: from math import sqrt, pi print(sqrt(16)) # 4.0 (no need for math.) print(pi) # 3.14159... Now you use sqrt() directly, not math.sqrt(). Aliasing imports Use as to give a module a shorter name: import math as m print(m.sqrt(16)) # 4.0 Or alias specific items: from math import sqrt as square_root print(square_root(16)) # 4.0 Working with datetime The datetime module is essential for handling dates and times: from datetime import datetime, timedelta # Get current date and time now = datetime.now() print(now) # 2024-06-23 14:30:45.123456 # Create a specific date birthday = datetime(1999, 5, 15) print(birthday) # 1999-05-15 00:00:00 # Format as string print(now.strftime("%Y-%m-%d")) # 2024-06-23 print(now.strftime("%A, %B %d")) # Sunday, June 23 # Time differences future = now + timedelta(days=30) print(future) # Date 30 days from now Working with JSON JSON (JavaScript Object Notation) is a standard format for exchanging data. Python dictionaries map perfectly to JSON: import json # Convert Python dict to JSON string person = { "name": "Ramesh", "age": 25, "city": "Chennai", "hobbies": ["reading", "coding", "gaming"] } json_string = json.dumps(person) print(json_string) # {"name": "Ramesh", "age": 25, "city": "Chennai", "hobbies": ["reading", "coding", "gaming"]} # Convert JSON string back to Python dict parsed = json.loads(json_string) print(parsed["name"]) # Ramesh Reading and writing JSON files: import json # Write to file data = {"name": "Ramesh", "age": 25} with open("data.json", "w") as file: json.dump(data, file) # Read from file with open("data.json", "r") as file: data = json.load(file) print(data) Regular Expressions (Regex) Regex is a language for pattern matching in text. It's powerful but takes time to master. Here are common patterns: import re text = "My phone is 555-1234 and email is user@example.com" # Find a pattern phone = re.search(r"\d{3}-\d{4}", text) if phone: print(phone.group()) # 555-1234 # Find all matches emails = re.findall(r"[\w.-]+@[\w.-]+\.\w+", text) print(emails) # ['user@example.com'] # Replace cleaned = re.sub(r"\d", "X", text) print(cleaned) # Phone is XXX-XXXX... # Check if pattern matches if re.match(r"^\d+$", "12345"): print("It's all digits") Regex patterns (a few common ones): \d — any digit (0-9) \w — any word character (letter, digit, underscore) \s — any whitespace . — any character * — zero or more + — one or more ? — zero or one {n} — exactly n times ^ — start of string $ — end of string [abc] — a, b, or c Regex is complex; this is just an introduction. Most beginners use regex sparingly and look up patterns when needed. File Input and Output Reading files # Simple read with open("myfile.txt", "r") as file: content = file.read() print(content) # Read line by line with open("myfile.txt", "r") as file: for line in file: print(line.strip()) # strip() removes newline # Read all lines as a list with open("myfile.txt", "r") as file: lines = file.readlines() print(lines[0]) # First line The with statement is crucial — it automatically closes the file when you're done, even if an error occurs. Writing files # Write (overwrites if file exists) with open("output.txt", "w") as file: file.write("Hello, World!\n") file.write("Second line\n") # Append (add to end of file) with open("output.txt", "a") as file: file.write("Third line\n") Working with file paths import os # Check if file exists if os.path.exists("myfile.txt"): print("File found") # Get file size size = os.path.getsize("myfile.txt") print(f"File size: {size} bytes") # List files in directory files = os.listdir(".") print(files) # Create directory os.makedirs("my_folder", exist_ok=True) # Delete file os.remove("myfile.txt") Exception Handling Real programs fail sometimes — bad file paths, network errors, invalid input. Handle these gracefully with try/except: try: # Code that might fail number = int("not a number") except ValueError: print("That's not a valid number") If int() fails, Python catches the ValueError and runs the except block instead of crashing. Multiple exceptions try: file = open("missing.txt", "r") number = int(file.read()) except FileNotFoundError: print("File doesn't exist") except ValueError: print("File contains non-numeric data") except Exception as e: print(f"Something went wrong: {e}") Handle specific errors first, then generic ones. Exception catches everything. Try, except, else, finally try: file = open("data.txt", "r") data = file.read() except FileNotFoundError: print("File not found") else: # Runs if no exception occurred print(f"Successfully read {len(data)} characters") finally: # Always runs, useful for cleanup print("Done") try — code that might fail except — what to do if it fails else — what to do if it succeeds finally — always runs (cleanup) Raising exceptions You can raise exceptions yourself: def validate_age(age): if age < 0: raise ValueError("Age cannot be negative") if age > 150: raise ValueError("Age seems unrealistic") return True try: validate_age(-5) except ValueError as e: print(f"Invalid input: {e}") Installing External Libraries with pip The pip package manager lets you install libraries others have written: pip install requests # Install the requests library pip install numpy pandas # Install multiple packages pip install requests==2.28.0 # Install specific version pip list # Show installed packages pip uninstall requests # Remove a package Once installed, use them like built-in modules: import requests response = requests.get("https://api.github.com") print(response.status_code) # 200 Popular libraries for beginners: requests — make web requests numpy — numerical computing pandas — data analysis matplotlib — plotting and visualization flask — build web applications Practical Examples Example 1: Read and count words def count_words(filename): try: with open(filename, "r") as file: content = file.read() words = content.split() return len(words) except FileNotFoundError: print(f"Error: {filename} not found") return 0 count = count_words("myfile.txt") print(f"Total words: {count}") Example 2: Save and load JSON data import json def save_contacts(contacts, filename): with open(filename, "w") as file: json.dump(contacts, file, indent=2) def load_contacts(filename): try: with open(filename, "r") as file: return json.load(file) except FileNotFoundError: return [] # Save contacts = [ {"name": "Ramesh", "phone": "555-1234"}, {"name": "Priya", "phone": "555-5678"} ] save_contacts(contacts, "contacts.json") # Load loaded = load_contacts("contacts.json") print(loaded) Example 3: Extract data with regex import re def extract_emails(text): pattern = r"[\w.-]+@[\w.-]+\.\w+" return re.findall(pattern, text) text = "Contact me at john@example.com or jane.doe@company.co.uk" emails = extract_emails(text) print(emails) # ['john@example.com', 'jane.doe@company.co.uk'] Why This Matters File I/O and exception handling are what separate learning exercises from real programs. Every professional program reads data from files or the internet, handles errors gracefully, and uses external libraries. Modules let you leverage thousands of hours of other people's work instead of writing everything yourself. The most common beginner mistakes: Forgetting to close files (use with — it's mandatory style) Not handling file not found errors Assuming regex patterns are simpler than they are Catching generic Exception instead of specific errors Not installing libraries with pip correctly What's Next In Part 8, the final part, we'll explore object-oriented programming — classes, inheritance, and polymorphism. OOP is how professional Python code is structured, and everything you've learned so far will come together. This is Part 7 of an 8-part beginner Python series. Catch up on Part 1: Getting Started & Syntax, Part 2: Variables, Data Types & Numbers, Part 3: Strings & Booleans, Part 4: Operators & Control Flow, Part 5: Collections, and Part 6: Functions.
9 hours ago
Iowa news anchor Dustin Nolan clarifies departure after on-air goodbye at KWQC TV6
Iowa news anchor Dustin Nolan makes a clarification after his viral on-air farewell from KWQC TV6 in the Quad Cities. Mu...
Madhya Pradesh sees heatwave, thunderstorms and monsoon delay through late June
Madhya Pradesh continues to experience hot and humid conditions along with rain and thunderstorms as the southwest monso...
SpaceX to launch first Starfall reentry capsule on June 23
SpaceX is preparing to launch its first Starfall spacecraft on June 23, its debut reentry-capable vehicle designed to de...