Fundamental of Python
- Introduction to Python
- Basic Data Types and Variables
- Operators and Expressions
- Control Flow Statements
- Functions
- Lists
- Tuples
- Dictionaries
- Sets
- Modules and Packages
- File I/O
- Exception Handling
- Object-Oriented Programming (OOP)
- Additional Topics (Optional)
What is Python?
Python is a high-level, general-purpose programming language known for its simplicity, readability, and versatility. It’s widely used in various fields, including web development, data science, machine learning, automation, and scientific computing.
History and Evolution of Python
- Creation: Python was created by Guido van Rossum in the late 1980s.
- Release: The first version of Python was released in 1991.
- Growth: Python’s popularity has grown significantly over the years, thanks to its user-friendly syntax and extensive libraries.
- Community: A large and active community of developers contributes to Python’s development and supports its users.
Key Features of Python
- Readability: Python’s code is often described as “pseudocode-like,” making it easy to read and understand.
- Simplicity: Python’s syntax is clean and concise, reducing the amount of code needed to accomplish tasks.
- Versatility: Python can be used for a wide range of applications, from simple scripts to complex data analysis projects.
- Cross-platform compatibility: Python runs on various operating systems, including Windows, macOS, and Linux.
- Extensive libraries: Python comes with a rich standard library and a vast ecosystem of third-party libraries for tasks like web development, data science, machine learning, and more.
Applications of Python
- Web development: Python frameworks like Django and Flask are popular for building web applications.
- Data science: Python’s libraries like NumPy, Pandas, and Matplotlib are essential for data analysis, manipulation, and visualization.
- Machine learning: Python’s libraries like TensorFlow and PyTorch are widely used for building machine learning models.
- Automation: Python can be used to automate repetitive tasks and streamline workflows.
- Scientific computing: Python’s libraries like SciPy and SymPy are used for scientific calculations and simulations.
Setting Up Python Environment
Installing Python
- Visit the official Python website (https://www.python.org/downloads/).
- Download the appropriate installer for your operating system. 1. github.comgithub.com
- Follow the installation instructions.
Numbers
Python supports three numerical data types:
- Integers: Whole numbers without decimal points (e.g.,
10
,-5
,0
). - Floating-point numbers: Numbers with decimal points (e.g.,
3.14
,-2.5
). - Complex numbers: Numbers with a real and an imaginary part (e.g.,
2+3j
).
# Examples of different number types
integer_number = 10
floating_point_number = 3.14
complex_number = 2+3j
print(integer_number)
print(floating_point_number)
print(complex_number)
Strings
Strings are sequences of characters enclosed in single or double quotes.
string1 = "Hello, world!"
string2 = 'This is a string.'
print(string1)
print(string2)
Boolean Values
Boolean values represent True
or False
. They are often used in conditional statements.
is_true = True
is_false = False
print(is_true)
print(is_false)
Variables and Assignment
Variables are used to store data. You can assign values to variables using the =
operator.
x = 10
name = "Alice"
is_student = True
print(x)
print(name)
print(is_student)
Type Conversion
You can convert values from one data type to another using built-in functions:
int()
: Converts to an integer.float()
: Converts to a floating-point number.str()
: Converts to a string.bool()
: Converts to a boolean value.1. github.comgithub.com
number = 10.5
string_number = str(number)
integer_number = int(number)
print(string_number)
print(integer_number)
Remember: When converting between data types, be mindful of potential data loss or rounding errors.
In Python, operators are symbols used to perform operations on values (operands). Expressions combine variables, values, and operators to compute a result. This chapter explores various operators and how they work.
Arithmetic Operators
- Addition (
+
): Adds two operands. - Subtraction (
-
): Subtracts the second operand from the first. - Multiplication (
*
): Multiplies two operands. - Division (
/
): Divides the first operand by the second (results in a float).1. pwskills.compwskills.com - Floor division (
//
): Divides the first operand by the second and returns the whole number result (integer). - Modulo (
%
): Returns the remainder after division. - Exponentiation (
**
): Raises the first operand to the power of the second.
x = 5
y = 3
# Examples of arithmetic operators
result_add = x + y
result_sub = x - y
result_mul = x * y
result_div = x / y
result_floor_div = x // y
result_mod = x % y
result_exp = x ** y
print(result_add) # Output: 8
print(result_sub) # Output: 2
print(result_mul) # Output: 15
print(result_div) # Output: 1.6666666666666667 (float)
print(result_floor_div) # Output: 1 (integer quotient)
print(result_mod) # Output: 2 (remainder)
print(result_exp) # Output: 125 (5 raised to the power of 3)
Comparison Operators
- Equal (
==
): Checks if two operands are equal. - Not equal (
!=
): Checks if two operands are not equal. - Greater than (
>
): Checks if the left operand is greater than the right operand.1. github.comgithub.com - Less than (
<
): Checks if the left operand is less than the right operand. - Greater than or equal to (
>=
): Checks if the left operand is greater than or equal to the right operand. - Less than or equal to (
<=
): Checks if the left operand is less than or equal to the right operand.1. easyexamnotes.comeasyexamnotes.com
x = 10
y = 5
# Examples of comparison operators
result_equal = x == y
result_not_equal = x != y
result_greater = x > y
result_less = x < y
result_greater_equal = x >= y
result_less_equal = x <= y
print(result_equal) # Output: False
print(result_not_equal) # Output: True
print(result_greater) # Output: True
print(result_less) # Output: False
print(result_greater_equal) # Output: True
print(result_less_equal) # Output: False
Logical Operators
- And (
and
): ReturnsTrue
only if both operands areTrue
. - Or (
or
): ReturnsTrue
if at least one operand isTrue
. - Not (
not
): Inverts the logical value of the operand.
x = True
y = False
# Examples of logical operators
result_and = x and y
result_or = x or y
result_not = not x
print(result_and) # Output: False (both operands need to be True)
print(result_or) # Output: True (at least one operand is True)
print(result_not) # Output: False (inverts True to False)
Note: Logical operators follow short-circuit evaluation. In and
, if the first operand is False
, the second operand is not evaluated. Similarly, for or
, if the first operand is True
, the second operand is skipped.
Bitwise Operators
Bitwise operators work on the binary representation of numbers. Here are some common examples:
- Bitwise AND (
&
): Performs a bitwise AND operation on each bit of the operands. - Bitwise OR (
|
): Performs a bitwise OR operation on each bit of the operands. - Bitwise XOR (
^
): Performs a bitwise XOR operation on each bit of the operands. - Left shift (
<<
): Shifts the bits of the left operand to the left by the number of bits specified by the right operand. - Right shift (
>>
): Shifts the bits
Control flow statements are used to alter the normal sequential execution of a program. They allow you to make decisions and repeat code blocks based on certain conditions.
Conditional Statements
if
Statement:
- Executes a block of code if a condition is
True
.
x = 10
if x > 0:
print("x is positive")
if-else
Statement:
- Executes one block of code if a condition is
True
, and another block if it’sFalse
.
x = -5
if x > 0:
print("x is positive")
else:
print("x is negative")
if-elif-else
Statement:
- Provides multiple conditions to check.
x = 0
if x > 0:
print("x is positive")
elif x < 0:
print("x is negative")
else:
print("x is zero")
Looping Statements
for
Loop:
- Iterates over a sequence (like a list, tuple, or string).
numbers = [1, 2, 3, 4, 5]
for number in numbers:
print(number)
while
Loop:
- Repeats a block of code as long as a condition is
True
.
count = 0
while count < 5:
print(count)
count += 1
break
and continue
Statements
break
: Exits the loop immediately.continue
: Skips the current iteration and continues with the next one.
numbers = [1, 2, 3, 4, 5]
for number in numbers:
if number == 3:
break
print(number)
for number in numbers:
if number % 2 == 0:
continue
print(number)
Nested Loops
- Loops within loops.
for row in range(3):
for col in range(4):
print(row, col)
Example:
for i in range(1, 11):
for j in range(1, 11):
product = i * j
print(f"{i} x {j} = {product}")
This will print the multiplication table from 1 to 10.
Defining Functions
Functions are reusable blocks of code that perform specific tasks. They help to organize your code, make it more modular, and improve readability.
def greet(name):
print("Hello, " + name + "!")
greet("Alice")
In this example, greet
is the function name, and name
is a parameter. When you call the function, you provide an argument ("Alice"
) that is passed to the parameter.
Function Parameters and Arguments
- Parameters: Variables defined within parentheses when a function is defined.
- Arguments: Values passed to the function when it is called.
def add(x, y):
return x + y
result = add(3, 5)
print(result) # Output: 8
Function Return Values
Functions can return values using the return
statement. This allows you to use the result of the function in other parts of your code.
def calculate_area(length, width):
area = length * width
return area
area_of_rectangle = calculate_area(5, 3)
print(area_of_rectangle) # Output: 15
Scope of Variables
The scope of a variable determines where it can be accessed.
- Global variables: Defined outside of functions and can be accessed anywhere in the program.
- Local variables: Defined inside functions and can only be accessed within that function.
global_variable = 10
def my_function():
local_variable = 20
print(global_variable) # Accessing global variable
print(local_variable) # Accessing local variable
my_function()
Recursive Functions
A recursive function is a function that calls itself. They are often used to solve problems that can be broken down into smaller, similar subproblems.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n – 1)
result = factorial(5)
print(result) # Output: 120
In this example, the factorial
function calculates the factorial of a number using recursion. If the number is 0, it returns 1. Otherwise, it calculates the factorial of n-1
and multiplies it by n
.
Lists are ordered collections of items. They can contain elements of different data types.
Creating Lists
my_list = [1, 2, 3, “hello”, True]
empty_list = []
Accessing Elements
You can access elements in a list using their index, starting from 0.
my_list = [10, 20, 30]
first_element = my_list[0] # Output: 10
second_element = my_list[1] # Output: 20
Slicing Lists
You can extract a portion of a list using slicing.
my_list = [1, 2, 3, 4, 5]
sublist = my_list[1:4] # Output: [2, 3, 4]
Modifying Lists
You can add, remove, or modify elements in a list.
my_list = [10, 20, 30]
my_list.append(40) # Add an element
my_list.insert(1, 50) # Insert an element at a specific index
my_list.remove(20) # Remove an element by value
del my_list[0] # Remove an element by index
my_list[1] = 60 # Modify an element
List Methods
Lists have many built-in methods that can be used to perform various operations.
my_list = [1, 2, 3, 2, 4]
length = len(my_list) # Get the length of the list
count = my_list.count(2) # Count the occurrences of an element
index = my_list.index(3) # Find the index of an element
my_list.sort() # Sort the list in ascending order
my_list.reverse() # Reverse the order of elements
List Comprehension
List comprehensions provide a concise way to create new lists based on existing lists.
numbers = [1, 2, 3, 4, 5]
squared_numbers = [x**2 for x in numbers] # Output: [1, 4, 9, 16, 25]
This is equivalent to:
squared_numbers = []
for x in numbers:
squared_numbers.append(x**2)
Tuples are similar to lists, but they are immutable, meaning their elements cannot be changed once created.
Creating Tuples
my_tuple = (1, 2, 3, “hello”)
empty_tuple = ()
Accessing Elements
You can access elements in a tuple using their index, just like with lists.
my_tuple = (10, 20, 30)
first_element = my_tuple[0] # Output: 10
second_element = my_tuple[1] # Output: 20
Slicing Tuples
You can extract a portion of a tuple using slicing.
my_tuple = (1, 2, 3, 4, 5)
subtuple = my_tuple[1:4] # Output: (2, 3, 4)
Tuples are Immutable
Unlike lists, tuples cannot be modified after creation. Attempting to change an element will raise an error.
my_tuple = (1, 2, 3)
my_tuple[0] = 10 # This will raise an error
Tuple Packing and Unpacking
- Packing: Multiple values can be packed into a tuple using parentheses.
- Unpacking: Elements of a tuple can be unpacked into individual variables.
# Packing
my_tuple = (1, 2, 3)
# Unpacking
a, b, c = my_tuple
print(a) # Output: 1
print(b) # Output: 2
print(c) # Output: 3
Note: Tuples are often used for immutable data structures, such as coordinates, configuration settings, or return values from functions.
Dictionaries are unordered collections of key-value pairs. Each key is unique, and it maps to a corresponding value.
Creating Dictionaries
my_dict = {“name”: “Alice”, “age”: 30, “city”: “New York”}
empty_dict = {}
Accessing Values
You can access the value associated with a key using square brackets.
my_dict = {“name”: “Alice”, “age”: 30}
name = my_dict[“name”] # Output: “Alice”
age = my_dict[“age”] # Output: 30
Modifying Dictionaries
You can add, remove, or modify key-value pairs in a dictionary.
my_dict = {“name”: “Alice”, “age”: 30}
my_dict[“city”] = “New York” # Add a new key-value pair
my_dict[“age”] = 31 # Modify an existing value
del my_dict[“name”] # Remove a key-value pair
Dictionary Methods
Dictionaries have many built-in methods that can be used to perform various operations.
my_dict = {“name”: “Alice”, “age”: 30, “city”: “New York”}
keys = my_dict.keys() # Get a list of keys
values = my_dict.values() # Get a list of values
items = my_dict.items() # Get a list of key-value pairs
has_key = “name” in my_dict # Check if a key exists
Dictionary Comprehension
Dictionary comprehensions provide a concise way to create new dictionaries based on existing dictionaries or other iterables.
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers} # Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
This is equivalent to:
squares = {}
for x in numbers:
squares[x] = x**2
Sets are unordered collections of unique elements. They are useful for performing set operations like union, intersection, difference, and symmetric difference.
Creating Sets
my_set = {1, 2, 3, 4, 5}
empty_set = set()
Set Operations
- Union (
|
): Combines elements from both sets, removing duplicates. - Intersection (
&
): Returns elements that are common to both sets. - Difference (
-
): Returns elements that are in the first set but not in the second. - Symmetric difference (
^
): Returns elements that are in either set but not both.
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1 | set2 # Output: {1, 2, 3, 4, 5}
intersection_set = set1 & set2 # Output: {3}
difference_set = set1 – set2 # Output: {1, 2}
symmetric_difference_set = set1 ^ set2 # Output: {1, 2, 4, 5}
Set Methods
Sets have many built-in methods that can be used to perform various operations.
my_set = {1, 2, 3, 4, 5}
my_set.add(6) # Add an element
my_set.remove(3) # Remove an element (raises an error if not found)
my_set.discard(7) # Remove an element if it exists (no error if not found)
my_set.pop() # Remove a random element and return it
my_set.clear() # Remove all elements
Set Comprehension
Set comprehensions provide a concise way to create new sets based on existing sets or other iterables.
numbers = [1, 2, 3, 2, 4]
unique_numbers = {x for x in numbers} # Output: {1, 2, 3, 4}
This is equivalent to:
unique_numbers = set()
for x in numbers:
unique_numbers.add(x)
Importing Modules
Modules are Python files containing functions, classes, and variables. You can import modules into your code using the import
statement.
import math
result = math.sqrt(4)
print(result) # Output: 2.0
You can also import specific functions or classes from a module:
from math import pi
print(pi) # Output: 3.141592653589793
Creating Your Own Modules
To create your own module, save your Python code in a file with a .py
extension. Then, import the module in another Python file.
# my_module.py
def greet(name):
print(“Hello, ” + name + “!”)
# main.py
import my_module
my_module.greet(“Alice”)
Using Packages
Packages are directories containing multiple modules. To use a package, you need to import it using the dot notation.
import my_package.my_module
my_package.my_module.greet(“Bob”)
The Standard Library
Python comes with a rich standard library that provides a wide range of modules for various tasks. Some common modules include:
math
: Mathematical functions (e.g.,sqrt
,sin
,cos
).random
: Functions for generating random numbers.os
: Functions for interacting with the operating system.time
: Functions for working with time and dates.datetime
: Functions for manipulating date and time objects.json
: Functions for working with JSON data.urllib
: Functions for working with URLs and web requests.
You can find a complete list of modules in the official Python documentation.
Opening and Closing Files
To work with files, you need to open them first and then close them when you’re finished.
file = open(“myfile.txt”, “r”) # Open the file in read mode
content = file.read()
file.close() # Close the file
Reading and Writing Data
- Reading: Use the
read()
method to read the entire contents of the file as a string. - Writing: Use the
write()
method to write data to the file.
# Reading
file = open(“myfile.txt”, “r”)
content = file.read()
print(content)
file.close()
# Writing
file = open(“newfile.txt”, “w”)
file.write(“This is a new file.”)
file.close()
File Modes
r
: Read mode (default).w
: Write mode (creates a new file or overwrites an existing one).a
: Append mode (appends data to the end of an existing file).r+
: Read and write mode.
Context Managers (with statement)
The with
statement is a convenient way to work with files, as it automatically closes the file when you’re done.
with open(“myfile.txt”, “r”) as file:
content = file.read()
print(content)
Example:
# Reading a file line by line
with open(“data.txt”, “r”) as file:
for line in file:
print(line.strip())
# Writing data to a file
with open(“output.txt”, “w”) as file:
file.write(“Hello, world!\n”)
file.write(“This is another line.”)
Note: When working with large files, it’s more efficient to read them line by line using the readline()
method or iterating over the file object.
Exceptions are errors that occur during program execution. Python provides mechanisms to handle exceptions gracefully, preventing your program from crashing.
Try-Except Blocks
A try-except
block is used to catch and handle exceptions.
try:
# Code that might raise an exception
result = 10 / 0
except ZeroDivisionError:
print(“Error: Division by zero”)
except Exception as e:
print(“An unexpected error occurred:”, e)
Raising Exceptions
You can raise exceptions using the raise
keyword.
def divide(x, y):
if y == 0:
raise ZeroDivisionError(“Cannot divide by zero”)
return x / y
try:
result = divide(10, 0)
except ZeroDivisionError as e:
print(e)
Custom Exceptions
You can create your own custom exceptions by defining new classes that inherit from the Exception
class.
class MyCustomError(Exception):
pass
def check_age(age):
if age < 0:
raise MyCustomError(“Age cannot be negative”)
try:
check_age(-10)
except MyCustomError as e:
print(e)
Example:
try:
file = open(“nonexistent_file.txt”, “r”)
content = file.read()
except FileNotFoundError:
print(“File not found.”)
except Exception as e:
print(“An unexpected error occurred:”, e)
else:
print(“File content:”, content)
finally:
if file:
file.close()
print(“File closed.”)
This example demonstrates the use of a try-except-else-finally
block. The else
block is executed if no exceptions occur, and the finally
block is always executed, regardless of whether an exception is raised.
Classes and Objects
In object-oriented programming, a class is a blueprint for creating objects. An object is an instance of a class.
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(“Woof!”)
# Create objects
dog1 = Dog(“Buddy”, “Golden Retriever”)
dog2 = Dog(“Max”, “Labrador”)
Attributes and Methods
Attributes are variables that belong to objects. Methods are functions that belong to objects.
class Dog:
# Attributes
name = “”
breed = “”
# Methods
def bark(self):
print(“Woof!”)
def eat(self):
print(“Eating food”)
Inheritance
Inheritance allows you to create new classes based on existing classes. The new class inherits the attributes and methods of the parent class.
class Animal:
def eat(self):
print(“Eating food”)
class Dog(Animal):
def bark(self):
print(“Woof!”)
# Create an object of the derived class
dog = Dog()
dog.eat() # Inherited from Animal
dog.bark()
Polymorphism
Polymorphism allows objects of different classes to be treated as if they were of the same type.
class Animal:
def make_sound(self):
pass
class Dog(Animal):
def make_sound(self):
print(“Woof!”)
class Cat(Animal):
def make_sound(self):
print(“Meow!”)
def animal_sound(animal):
animal.make_sound()
dog = Dog()
cat = Cat()
animal_sound(dog) # Output: Woof!
animal_sound(cat) # Output: Meow!
Encapsulation
Encapsulation is the practice of bundling data (attributes) and methods that operate on that data within a single unit (class). This helps to protect data from external access and modification.
class BankAccount:
def __init__(self, balance):
self.__balance = balance
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
else:
print(“Insufficient funds”)
def get_balance(self):
return self.__balance
In this example, the __balance
attribute is private, meaning it cannot be accessed directly from outside the class. You can only access it through the public methods deposit
, withdraw
, and get_balance
. This ensures data integrity and prevents unauthorized modifications.
Regular Expressions
Regular expressions are powerful tools for pattern matching in text. They provide a concise way to specify search patterns.
import re
text = “The quick brown fox jumps over the lazy dog.”
pattern = r”\bfox\b” # Matches the word “fox”
match = re.search(pattern, text)
if match:
print(“Found a match:”, match.group())
Functional Programming
Functional programming is a paradigm that emphasizes functions as the primary building blocks of programs. It promotes immutability, pure functions, and higher-order functions.
def square(x):
return x * x
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(square, numbers))
print(squared_numbers) # Output: [1, 4, 9, 16, 25]
Decorators
Decorators are functions that modify the behavior of other functions. They are defined using the @
syntax.
def my_decorator(func):
def wrapper():
print(“Before function call”)
func()
print(“After function call”)
return wrapper
@my_decorator
def greet():
print(“Hello!”)
greet()
Generators
Generators are functions that return an iterator, allowing you to generate values on-the-fly. They use the yield
keyword to return values.
def count_up(n):
for i in range(n):
yield i
for number in count_up(5):
print(number)
Libraries and Frameworks
Python has a vast ecosystem of libraries and frameworks that can be used to accomplish various tasks. Some popular ones include:
- NumPy: For numerical computing and scientific computing.
- Pandas: For data manipulation and analysis.
- Matplotlib: For data visualization.
- Scikit-learn: For machine learning.
- TensorFlow: For deep learning.
- Django: For web development.
- Flask: For lightweight web development.
By exploring these additional topics, you can deepen your understanding of Python and its capabilities.
By the end of this course, you will be able to understand and apply Python programming concepts to solve real-world problems. You will gain hands-on experience in writing Python scripts and developing projects using the language’s fundamental building blocks.