/ 10 min read
Python Refresher: Revisiting the Fundamentals
Python is a versatile and beginner-friendly programming language used in various fields, including web development, data analysis, machine learning, and more. Whether you’re a seasoned Python developer or just getting started, it’s essential to review and reinforce your knowledge of Python’s fundamental concepts. In this Python refresher, we’ll revisit some of these key concepts to help you strengthen your Python programming skills.
Variables and Data Types
Python is a dynamically typed language, which means you don’t need to explicitly declare variable types. Here are some of the most common data types in Python, along with code examples:
Boolean Values (bool
)
Boolean values represent true or false. They are often used in conditional statements and logical operations. Examples include True
and False
.
Integers (int
)
Integers represent whole numbers without any decimal point. Examples include -1
, 0
, and 42
.
Floating-point Numbers (float
)
Floating-point numbers represent numbers with decimal points or fractions. Examples include 3.14
, 0.01
, and -0.5
.
Srtrings (str
)
Strings represent text and are enclosed in single or double quotation marks. Examples include "Hello, World!"
, 'Python'
, and "123"
.
Lists (list
)
Lists are ordered collections of items. They can contain elements of different data types and are defined using square brackets []
.
Examples include [1, 2, 3]
, ["apple", "banana", "cherry"]
, and [1, "two", 3.0]
.
Dictionaries (dict
)
Dictionaries are collections of key-value pairs. Each key is associated with a value, and they are defined using curly braces {}
.
Examples include {"name": "Alice", "age": 25}
, {"city": "New York", "population": 8.4 million}
, and {}
(an empty dictionary).
Control Structures
Python offers control structures for decision-making and repetition. These control structures allow you to manage the flow of your program and perform actions based on conditions or repeatedly execute code. Let’s explore some of the key control structures in Python:
If Statements
Conditional statements, often referred to as “if statements,” are used to make decisions in your code. They allow you to execute specific blocks of code based on whether a condition is true or false.
In this example, if the age
is greater than or equal to 18, it prints “You are an adult”; otherwise, it prints “You are a minor.”
While Loops
The while loop is used for repetitive tasks. It repeatedly executes a block of code as long as a condition is true. Be cautious to avoid infinite loops by ensuring that the condition eventually becomes false.
For Loops (for-in)
The for
loop, often used with the in
keyword, is used for iterating over a sequence (such as a list or string). It simplifies iteration and is commonly used in Python.
Break and Continue Statements
Python provides two special statements within loops: break
and continue
.
- The
break
statement is used to exit a loop prematurely. It terminates the loop’s execution based on a condition. - The
continue
statement is used to skip the current iteration of a loop and move to the next one.
These statements are handy for controlling loop behavior and responding to specific conditions.
Functions
Functions in Python allow you to encapsulate and reuse code. You can define functions using the def
keyword.
Classes and Objects
Classes in Python are blueprints for creating objects, while objects are instances of classes. They allow you to model real-world entities in your code.
In this example, we define a class called Person
with attributes name
and age
.
The __init__
method is a special method called when an object is created, and the greet
method returns a personalized greeting for the person.
We then create an instance of the Person
class named alice with the name "Prajwal"
and age 25
.
Finally, we call the greet method for the alice object to print a greeting message.
Modules
A module is a single Python file containing variables, functions, and classes. Modules are used to encapsulate related code and promote code reusability.
You can import modules using the import
keyword.
Packages
In Python, packages are a way to organize and structure your code into directories and modules. They allow you to group related modules together, making it easier to manage and maintain large codebases. Packages are essential for organizing complex projects and preventing naming conflicts between modules.
An example to understand clear distinction b/w packages and modules is as follows:
In this structure:
geometry_project
is the root directory of your project.shapes
andutils
are packages.circles.py
,squares.py
, and math_operations.py are modules.
To import a module from a package, you use dot notation. For example:
Exceptions
Exceptions are events that occur during program execution when something unexpected or erroneous happens. These exceptions can disrupt the normal flow of your code, and handling them appropriately is essential to ensure your program remains robust and responsive.
The Try-Except Block
The try-except
block is used to catch and handle exceptions in Python. Here’s the basic structure:
Let’s break down how the try-except block works:
- The
try
block contains the code that you suspect might raise an exception. - If an exception occurs within the
try
block, Python immediately jumps to the correspondingexcept
block. - In the
except
block, you specify the type of exception you want to catch (e.g.,ExceptionName
). This is optional, and you can use a genericexcept
clause to catch any exception. - Within the
except
block, you can write code to handle the exception, which might include logging an error message, recovering from the error, or taking other appropriate actions.
Let’s consider an example where we attempt to divide a number by zero, which would raise a ZeroDivisionError
exception:
In this example, the try
block attempts to perform a division operation that can result in a ZeroDivisionError
.
When the exception occurs, Python immediately transfers control to the except
block, where we print an error message.
File I/O
In Python, you can read from and write to files using the open() function. This functionality is crucial for handling data persistence and interacting with external files.
Reading a File
To read the contents of a file, you can use the open()
function with the mode "r"
(read mode). Here’s how you can read a file:
Writing to a File
To write data to a file, you can use the open()
function with the mode "w"
(write mode). Here’s how you can write to a file:
Additional File Modes
In addition to "r"
(read) and "w"
(write) modes, there are other modes you can use with the open()
function,
such as "a"
(append) for appending data to a file without truncating it and "b"
for binary mode when dealing with non-text files.
Lambda Functions
Lambda functions, also known as anonymous functions, are a concise way to define small, one-time-use functions in Python. They are defined in a single line using the lambda keyword.
Here’s how you can define and use a lambda function:
In this example:
- We define a lambda function called
add
that takes two argumentsx
andy
and returns their sum. - We then use the lambda function by calling
add(2, 3)
, which returns5
.
Lambda functions are commonly used in functional programming and with functions like map()
, filter()
, and sorted()
.
Generators
Generators in Python are a powerful way to create iterable sequences of items. Unlike lists or other data structures, generators create values on-the-fly as you iterate over them. This can be incredibly efficient, especially for large datasets or infinite sequences.
Defining a Generator
Generators are defined using functions, just like regular functions, but instead of using the return
keyword, they use the yield
keyword. The yield
statement is used to produce a value from the generator function while preserving the function’s state for the next iteration.
Here’s an example of a simple generator function:
In this example, the countdown
generator yields a sequence of numbers from n
down to 1
.
Using a Generator
Once you’ve defined a generator, you can use it to iterate over the generated values. You typically create a generator object by calling the generator function with the desired parameters.
You can retrieve values from the generator using the next()
function, as shown here:
You can also iterate over the generator using a for loop, which will continue until the generator is exhausted:
Generators are memory-efficient and are especially useful when dealing with large datasets or when you want to create sequences dynamically. They allow you to work with data one item at a time, rather than loading everything into memory at once.
Decorators
Decorators in Python are a powerful way to modify the behavior of functions or methods without changing their code. They are often used to add functionality or behavior to functions dynamically.
Defining a Decorator
A decorator is itself a function that takes another function as an argument and returns a new function that usually extends or enhances the behavior of the original function.
Decorators are typically defined using the @
symbol followed by the decorator function’s name.
Here’s an example of defining a simple decorator called uppercase
:
In this example, the uppercase
decorator takes a function func
as an argument, and it defines an inner function wrapper
that modifies the result of func
by converting it to uppercase.
Using a Decorator
Once a decorator is defined, you can use it to modify the behavior of other functions. You apply a decorator to a function using the @ symbol, followed by the decorator’s name, just before the function definition:
In this example, the @uppercase
decorator is applied to the greet
function.
When you call greet()
, it will actually invoke the wrapper
function created by the decorator, which will modify the result to be in uppercase.
Decorators are a powerful tool in Python for extending and customizing the behavior of functions, making your code more modular, reusable, and maintainable. They are widely used in libraries and frameworks to add functionality to classes and methods.