Python Basics for Beginners

Welcome! In this tutorial, we will explore the foundational concepts of Python programming. This guide is designed for beginners and will help you get started quickly with hands-on examples.


1. Variables and Data Types

In Python, variables act as containers for storing data values. Python is dynamically typed, meaning you don’t need to declare a variable’s type explicitly. Instead, Python infers the data type automatically based on the value assigned to the variable.

Declaring Variables

To declare a variable, simply assign a value to a name using the assignment operator (=):

</>
Copy
# Example: Variable Declaration
name = "Alice"       # String
age = 25             # Integer
height = 5.6         # Float
is_student = True    # Boolean

print(name, age, height, is_student)

Explanation:

  • name: A variable storing a string ("Alice").
  • age: A variable storing an integer (25).
  • height: A variable storing a floating-point number (5.6).
  • is_student: A variable storing a Boolean value (True).

Key Data Types in Python

Python has several built-in data types to represent various kinds of values. Here are some of the most common:

  • int: Represents whole numbers (e.g., 10, -42).
  • float: Represents decimal numbers (e.g., 10.5, -3.14).
  • str: Represents strings, which are sequences of characters (e.g., "Hello", "Python").
  • bool: Represents Boolean values (True or False).
  • list: Represents ordered collections of items (e.g., [1, 2, 3], ["apple", "banana"]).

Checking the Type of a Variable

You can use the built-in type() function to determine the type of a variable:

</>
Copy
# Example: Checking Variable Types
name = "Alice"
age = 25
height = 5.6
is_student = True

print(type(name))     # Output: <class 'str'>
print(type(age))      # Output: <class 'int'>
print(type(height))   # Output: <class 'float'>
print(type(is_student))  # Output: <class 'bool'>

Dynamic Typing

In Python, variables can change types dynamically. You can assign a value of one type to a variable, and later assign a value of a different type to the same variable:

</>
Copy
# Example: Dynamic Typing
x = 10          # x is an integer
print(type(x))  # Output: <class 'int'>

x = "Hello"     # x is now a string
print(type(x))  # Output: <class 'str'>

Multiple Assignments

Python allows multiple variables to be assigned values in a single line:

</>
Copy
# Example: Multiple Assignments
a, b, c = 5, 10, 15
print(a, b, c)  # Output: 5 10 15

# Assign the same value to multiple variables
x = y = z = 0
print(x, y, z)  # Output: 0 0 0

Type Casting

You can convert variables from one type to another using type casting:

</>
Copy
# Example: Type Casting
num_str = "42"            # String containing a number
num_int = int(num_str)    # Convert to integer
print(num_int + 8)        # Output: 50

num_float = float(num_int)  # Convert to float
print(num_float)           # Output: 42.0

bool_value = bool(0)       # Convert to boolean
print(bool_value)          # Output: False

2. Conditional Statements

Conditional statements allow your program to execute specific blocks of code depending on whether a condition is True or False. In Python, conditional statements use keywords like if, elif, and else to create decision-making structures.

The basic structure of a conditional statement is:

</>
Copy
if condition:
    # Code block executed if condition is True
elif another_condition:
    # Code block executed if the above condition is False, but this one is True
else:
    # Code block executed if all conditions are False

Here’s an example where we determine if someone is an adult or a minor based on their age:

</>
Copy
# Example: If-Else
age = 20
if age >= 18:
    print("You are an adult.")
else:
    print("You are a minor.")

Explanation of the code:

  • if age >= 18: – This checks if the age variable is greater than or equal to 18. If this condition is True, the program executes the code indented below it, printing "You are an adult."
  • else: – If the condition in the if statement is False, the code under the else block executes, printing "You are a minor."

We can expand this example further using the elif keyword to check multiple conditions:

</>
Copy
# Example: If-Elif-Else
age = 15
if age >= 18:
    print("You are an adult.")
elif age >= 13:
    print("You are a teenager.")
else:
    print("You are a child.")

Explanation of the extended example:

  • if age >= 18: – Checks if the person is 18 or older. If True, it prints "You are an adult."
  • elif age >= 13: – If the first condition is False, this checks if the age is 13 or older. If True, it prints "You are a teenager."
  • else: – If none of the above conditions are True, it defaults to the else block, printing "You are a child."

Conditional statements can also be nested, where an if block contains another if or else statement:

</>
Copy
# Example: Nested If-Else
age = 25
if age >= 18:
    if age >= 21:
        print("You can drink alcohol in the U.S.")
    else:
        print("You are an adult but cannot drink alcohol in the U.S.")
else:
    print("You are a minor.")

3. Loops

Loops are used to repeat a block of code multiple times. They are particularly useful when you need to perform repetitive tasks, iterate through data, or process elements in a sequence.

Python provides two main types of loops: for loops and while loops.

For Loops

The for loop is used to iterate over a sequence (like a list, tuple, dictionary, set, or string) or a range of numbers. The loop executes the block of code once for each element in the sequence.

</>
Copy
# Example: For Loop with Range
for i in range(5):  # Loops from 0 to 4
    print("Iteration:", i)

Explanation:

  • range(5) generates numbers from 0 to 4 (5 is exclusive).
  • For each number in this range, the print statement executes, displaying the current iteration number.

You can also use for loops to iterate through a list, string, or any iterable object:

</>
Copy
# Example: For Loop with a List
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print("I like", fruit)

# Example: For Loop with a String
word = "Python"
for letter in word:
    print(letter)

While Loops

The while loop executes a block of code as long as the specified condition is True. It’s typically used when the number of iterations is not known in advance.

</>
Copy
# Example: While Loop
count = 0
while count < 5:  # Loop until count is less than 5
    print("Count:", count)
    count += 1  # Increment count to avoid infinite loop

Explanation:

  • The condition count < 5 is checked before each iteration.
  • If the condition is True, the block of code inside the loop is executed.
  • count += 1 increments the value of count by 1 in each iteration, eventually causing the loop to terminate when count reaches 5.

Break and Continue

You can control the flow of a loop using break and continue statements:

</>
Copy
# Example: Break
for i in range(10):
    if i == 5:  # Exit the loop when i is 5
        break
    print("i:", i)

# Example: Continue
for i in range(5):
    if i == 2:  # Skip the rest of the code for i == 2
        continue
    print("i:", i)

Explanation:

  • break: Immediately terminates the loop, skipping the remaining iterations.
  • continue: Skips the current iteration and moves to the next iteration of the loop.

Nested Loops

You can nest one loop inside another to handle more complex tasks, such as iterating through a matrix or generating combinations.

</>
Copy
# Example: Nested Loops
for i in range(3):  # Outer loop
    for j in range(2):  # Inner loop
        print(f"Outer: {i}, Inner: {j}")

Explanation:

  • The outer loop iterates 3 times (for i values 0, 1, 2).
  • For each iteration of the outer loop, the inner loop iterates 2 times (for j values 0, 1).

4. Functions

Functions are reusable blocks of code designed to perform a specific task. They help you write modular, organized, and reusable code, reducing repetition and making your program easier to read and maintain. In Python, functions are defined using the def keyword followed by the function name and parentheses.

The basic structure of a function looks like this:

</>
Copy
# Function Structure
def function_name(parameters):
    # Code block to execute
    return value  # Optional, returns a result

Let’s break this down:

  • def: This keyword starts the function definition.
  • function_name: The name of the function, which should be descriptive of its purpose.
  • parameters: Optional values that can be passed into the function to customize its behavior.
  • return: Optional, allows the function to send back a result or value.

Here’s an example of a simple function:

</>
Copy
# Example: Function Definition
def greet(name):
    return f"Hello, {name}!"

message = greet("Alice")  # Call the function with "Alice" as an argument
print(message)

Explanation:

  • def greet(name): defines a function named greet that takes one parameter, name.
  • return f"Hello, {name}!" creates and returns a greeting message.
  • greet("Alice") calls the function with "Alice" as an argument, and the returned value is stored in the variable message.
  • print(message) displays the output: Hello, Alice!.

Functions with Multiple Parameters

Functions can take multiple parameters to perform more complex tasks:

</>
Copy
# Example: Function with Multiple Parameters
def add_numbers(a, b):
    return a + b

result = add_numbers(5, 3)
print("Sum:", result)

Explanation:

  • add_numbers is a function that takes two parameters, a and b.
  • It returns the sum of a and b, which is stored in the variable result.
  • The print statement displays the output: Sum: 8.

Default Parameters

Functions can have default parameter values, which are used if no argument is provided:

</>
Copy
# Example: Function with Default Parameters
def greet(name="Guest"):
    return f"Hello, {name}!"

print(greet())        # Uses default value
print(greet("Alice")) # Overrides default value

Explanation:

  • If no argument is passed to greet, the default value "Guest" is used.
  • When an argument is provided, such as "Alice", it overrides the default value.

Keyword Arguments

You can pass arguments to a function using keywords, which makes the function call more readable:

</>
Copy
# Example: Keyword Arguments
def describe_person(name, age):
    return f"{name} is {age} years old."

print(describe_person(age=30, name="Bob"))  # Order doesn't matter

Explanation:

  • Arguments are passed using name=value pairs, allowing flexibility in the order of arguments.

Returning Multiple Values

Functions can return multiple values as a tuple:

</>
Copy
# Example: Returning Multiple Values
def calculate(a, b):
    sum_result = a + b
    product_result = a * b
    return sum_result, product_result

sum_value, product_value = calculate(4, 5)
print("Sum:", sum_value)
print("Product:", product_value)

Explanation:

  • calculate returns two values: the sum and the product of a and b.
  • The returned tuple is unpacked into sum_value and product_value.

Anonymous Functions (Lambda)

Python supports anonymous functions, which are created using the lambda keyword. These are useful for short, single-use functions.

</>
Copy
# Example: Lambda Function
square = lambda x: x ** 2
print("Square:", square(4))

Explanation:

  • lambda x: x ** 2 creates a function that takes one argument x and returns its square.
  • square(4) calls the lambda function, returning 16.

5. Lists and Loops

Lists are a fundamental data structure in Python, used to store ordered collections of items. They are highly versatile and can contain elements of different data types, such as numbers, strings, or even other lists. One of the most common operations with lists is iterating through them using loops, allowing you to process each element individually.

Here is an example of a basic for loop used to iterate over a list:

</>
Copy
# Example: Iterating Through a List
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

Explanation:

  • fruits = ["apple", "banana", "cherry"]: This creates a list named fruits containing three string elements.
  • for fruit in fruits:: The loop iterates through each item in the list. For each iteration, the current item is assigned to the variable fruit.
  • print(fruit): This outputs the value of fruit in the current iteration.

Using Indexes in Lists

You can access elements in a list by their index. The index of the first element is 0, the second is 1, and so on. Use the enumerate() function to get both the index and the value in a loop.

</>
Copy
# Example: Using Indexes
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
    print(f"Index: {index}, Fruit: {fruit}")

Explanation:

  • enumerate(fruits): Returns a tuple containing the index and the item for each iteration.
  • The for loop unpacks the tuple into the variables index and fruit.
  • The print statement displays both the index and the item.

Modifying Lists in a Loop

You can also modify the elements of a list while iterating through it. Use range() to loop through the indexes.

</>
Copy
# Example: Modifying List Elements
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
    numbers[i] *= 2  # Double each element
print(numbers)

Explanation:

  • range(len(numbers)): Iterates over the indexes of the list.
  • numbers[i] *= 2: Multiplies each element by 2 and updates the list.
  • The final list contains doubled values: [2, 4, 6, 8, 10].

Nested Loops

Nested loops allow you to iterate through multiple lists or multi-dimensional structures. For example, you can process each element in a list of lists.

</>
Copy
# Example: Nested Loops with a List of Lists
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for row in matrix:
    for item in row:
        print(item, end=" ")
    print()  # Newline after each row

Explanation:

  • matrix: A list of lists, representing a 3×3 grid.
  • for row in matrix: Iterates through each sub-list (row).
  • for item in row: Iterates through each element in the current row.
  • print(item, end=" "): Prints each element on the same line, separated by spaces.
  • print(): Adds a newline after printing each row.

List Comprehensions

List comprehensions provide a concise way to create lists using loops in a single line of code.

</>
Copy
# Example: List Comprehension
numbers = [1, 2, 3, 4, 5]
squared_numbers = [num ** 2 for num in numbers]
print(squared_numbers)

Explanation:

  • [num ** 2 for num in numbers]: Creates a new list by squaring each element in the original list.
  • squared_numbers contains the result: [1, 4, 9, 16, 25].

6. Basic Input/Output

Python provides simple and intuitive functions for interacting with users: input() for collecting input from the user and print() for displaying output. These functions form the foundation of interactive programming in Python.

Getting Input with input()

The input() function allows the user to enter data through the console. It always returns the input as a string, so you may need to convert it to another data type if required.

</>
Copy
# Example: Getting Input from the User
name = input("Enter your name: ")
print("Hello,", name)

Explanation:

  • input("Enter your name: "): Displays the prompt "Enter your name: " in the console and waits for the user to type something and press Enter.
  • The user’s input is stored as a string in the variable name.
  • print("Hello,", name): Displays the greeting along with the user’s input.

You can also include a custom message in the input() prompt for more context:

</>
Copy
# Example: Custom Prompt
age = input("Please enter your age: ")
print("You entered:", age)

Converting Input to Other Data Types

Since input() returns a string, you can use typecasting to convert the input to other types like integers or floats:

</>
Copy
# Example: Converting Input
age = int(input("Enter your age: "))  # Convert the input to an integer
print("Next year, you will be", age + 1, "years old.")

Explanation:

  • int(input("Enter your age: ")): Converts the input string to an integer.
  • The program performs a calculation (age + 1) using the integer value.
  • print(): Displays the result of the calculation along with the message.

Displaying Output with print()

The print() function is used to display text, variables, or other data types on the console. You can pass multiple arguments to print() by separating them with commas, and Python will add spaces between them automatically.

</>
Copy
# Example: Displaying Variables
name = "Alice"
age = 30
print("Name:", name)
print("Age:", age)

Explanation:

  • print("Name:", name): Combines a string and the value of the variable name into one output line.
  • Python automatically adds a space between "Name:" and the value of name.

Formatted Strings for Enhanced Output

Using formatted strings (f-strings) allows you to embed variables and expressions directly into a string, improving the readability of your output:

</>
Copy
# Example: Formatted Strings
name = "Alice"
age = 30
print(f"{name} is {age} years old.")

Explanation:

  • f"{name} is {age} years old.": This is an f-string where the values of name and age are embedded directly into the string.
  • The output will display: Alice is 30 years old.

Taking Multiple Inputs

You can collect multiple inputs in a single line using the split() method. This is particularly useful when you need to gather multiple pieces of data at once:

</>
Copy
# Example: Multiple Inputs
x, y = input("Enter two numbers separated by a space: ").split()
print("First number:", x)
print("Second number:", y)

Explanation:

  • input().split(): Splits the user input into a list of strings based on spaces.
  • The values are assigned to x and y.
  • You can convert these values to integers or other types if needed.

Combining Input and Output

Here’s a more complex example that combines input and output to create a simple interaction:

</>
Copy
# Example: Interactive Program
name = input("What is your name? ")
age = int(input("How old are you? "))
print(f"Hello, {name}! You will be {age + 1} years old next year.")

Explanation:

  • input("What is your name? "): Collects the user’s name.
  • int(input("How old are you? ")): Collects the user’s age and converts it to an integer.
  • The print() statement uses an f-string to display a message and calculate the user’s age for the next year.

7. Error Handling

In Python, errors or exceptions occur when something goes wrong during the execution of a program. To prevent the program from crashing and to handle errors gracefully, Python provides the tryexcept block. This allows you to “catch” exceptions and take appropriate action instead of letting the program terminate unexpectedly.

Using tryexcept Blocks

The tryexcept block is used to handle exceptions. Here’s the basic syntax:

</>
Copy
# Syntax of try-except
try:
    # Code that might raise an exception
except ExceptionType:
    # Code to execute if the exception occurs

Let’s look at a simple example to handle invalid user input:

</>
Copy
# Example: Error Handling with try-except
try:
    num = int(input("Enter a number: "))  # Might raise a ValueError if input is not a number
    print("You entered:", num)
except ValueError:
    print("That's not a valid number!")

Explanation:

  • try: The code inside this block is executed. If an exception occurs, the program jumps to the except block.
  • int(input("Enter a number: ")): Attempts to convert user input into an integer. If the input is not a valid integer, a ValueError is raised.
  • except ValueError: This block is executed if a ValueError occurs, displaying an error message.

Handling Multiple Exceptions

You can handle different types of exceptions by using multiple except blocks:

</>
Copy
# Example: Handling Multiple Exceptions
try:
    num = int(input("Enter a number: "))
    result = 10 / num
    print("Result:", result)
except ValueError:
    print("Invalid input! Please enter a number.")
except ZeroDivisionError:
    print("Division by zero is not allowed.")

Explanation:

  • except ValueError: Catches errors when the input cannot be converted to an integer.
  • except ZeroDivisionError: Catches errors when attempting to divide by zero.

Using else with tryexcept

You can use an optional else block to execute code only if no exception occurs:

</>
Copy
# Example: Using else
try:
    num = int(input("Enter a number: "))
except ValueError:
    print("Invalid input!")
else:
    print("You entered a valid number:", num)

Explanation:

  • else: Executes only if the code inside the try block runs without raising an exception.
  • If an exception occurs, the else block is skipped.

Using finally

The finally block is used to define code that should always execute, regardless of whether an exception occurs. This is useful for cleanup tasks like closing files or releasing resources.

</>
Copy
# Example: Using finally
try:
    num = int(input("Enter a number: "))
    result = 10 / num
except ZeroDivisionError:
    print("Cannot divide by zero!")
except ValueError:
    print("Invalid input!")
else:
    print("Result:", result)
finally:
    print("Execution completed.")

Explanation:

  • finally: Executes after the try block and any except or else blocks, regardless of what happens.
  • Even if an exception occurs or the program exits early, the finally block is guaranteed to run.

Raising Exceptions

In some cases, you might want to raise an exception intentionally using the raise keyword:

</>
Copy
# Example: Raising an Exception
def check_positive(num):
    if num < 0:
        raise ValueError("Number must be positive!")
    return num

try:
    number = int(input("Enter a positive number: "))
    print("Positive number:", check_positive(number))
except ValueError as e:
    print("Error:", e)

Explanation:

  • raise ValueError("Number must be positive!"): Manually raises a ValueError if the condition is not met.
  • The exception is caught in the tryexcept block, and the error message is displayed.

8. File Handling

File handling in Python allows you to work with files for reading, writing, and modifying data. Python provides built-in functions like open(), which make working with files simple and efficient. File handling operations are typically done using the with statement, which ensures proper handling and closure of files.

Opening Files

The open() function is used to open a file. It takes two main arguments:

  • file: The name of the file to open (e.g., "example.txt").
  • mode: Specifies the operation to perform, such as read ("r"), write ("w"), append ("a"), or both read and write ("r+").

Here’s an example of opening a file in write mode:

</>
Copy
# Example: Writing to a File
with open("example.txt", "w") as file:
    file.write("Hello, World!")

Explanation:

  • open("example.txt", "w"): Opens the file example.txt in write mode. If the file does not exist, it will be created.
  • file.write("Hello, World!"): Writes the string "Hello, World!" to the file. If the file already contains data, it will be overwritten.
  • The with statement ensures that the file is properly closed after the operation, even if an error occurs.

Reading Files

You can read data from a file using the read() method. Here’s an example:

</>
Copy
# Example: Reading from a File
with open("example.txt", "r") as file:
    content = file.read()
    print(content)

Explanation:

  • open("example.txt", "r"): Opens the file in read mode.
  • file.read(): Reads the entire content of the file and stores it in the variable content.
  • print(content): Displays the content of the file.

Appending Data to Files

To add data to an existing file without overwriting its content, use the append mode ("a"):

</>
Copy
# Example: Appending to a File
with open("example.txt", "a") as file:
    file.write("\nThis is an additional line.")

Explanation:

  • open("example.txt", "a"): Opens the file in append mode. The new data will be added at the end of the file without removing the existing content.
  • file.write("\nThis is an additional line."): Adds a new line to the file. The \n ensures the new content appears on a separate line.

Reading Files Line by Line

Sometimes, you may want to read a file line by line instead of reading its entire content at once. This is useful for processing large files:

</>
Copy
# Example: Reading Line by Line
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

Explanation:

  • for line in file: Iterates through each line in the file.
  • line.strip(): Removes any leading or trailing whitespace, including the newline character at the end of each line.

Handling File Exceptions

When working with files, exceptions like FileNotFoundError can occur. You can handle these errors using a tryexcept block:

</>
Copy
# Example: Handling File Exceptions
try:
    with open("nonexistent.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("The file does not exist.")

Explanation:

  • try: Attempts to open and read the file.
  • except FileNotFoundError: Catches the exception if the file does not exist and displays an appropriate message.

Writing and Reading Files Simultaneously

Using the mode "r+", you can read and write to a file simultaneously:

</>
Copy
# Example: Reading and Writing
with open("example.txt", "r+") as file:
    content = file.read()  # Read the content
    file.write("\nAppending new data.")  # Append new data
print(content)