2 Python Basics

2.1 Variables and Data Types

In Python, variables are used to store data values. They act as containers that hold different types of information, such as numbers, strings, or boolean values. Understanding variables and data types is fundamental to programming in Python.

Variables

A variable is created when a value is assigned to it using the assignment operator (=). For example:

x = 5

In this case, the variable x is assigned the value 5. Variables can be named using letters, numbers, and underscores, but they cannot start with a number. It is important to choose meaningful and descriptive names for variables to make the code more readable and understandable.

Python is a dynamically typed language, which means that variables can hold values of different types. The type of a variable is determined by the value assigned to it. For example:

x = 5
y = "Hello"

In this case, x is an integer variable and y is a string variable. Python automatically assigns the appropriate data type based on the value assigned to the variable.

Data Types

Python has several built-in data types that can be assigned to variables. Some of the commonly used data types include:

  • Numeric Types: Python supports integers, floating-point numbers, and complex numbers. Integers are whole numbers without a decimal point, while floating-point numbers have a decimal point. Complex numbers are written in the form a + bj, where a and b are real numbers and j represents the square root of -1.

  • Strings: Strings are sequences of characters enclosed in single quotes ('') or double quotes (""). They are used to represent text in Python. For example:

      name = "John Doe"
    
  • Boolean: Boolean values represent the truth or falsity of a condition. They can only have two possible values: True or False. Boolean values are often used in conditional statements and logical operations.

  • Lists: Lists are ordered collections of items enclosed in square brackets ([]). They can contain elements of different data types and can be modified. Lists are versatile and commonly used in Python for storing and manipulating data.

  • Tuples: Tuples are similar to lists, but they are immutable, meaning their elements cannot be modified once they are assigned. Tuples are created using parentheses (()).

  • Dictionaries: Dictionaries are unordered collections of key-value pairs enclosed in curly braces ({}). Each value is associated with a unique key, which allows for efficient retrieval of values based on their keys.

  • Sets: Sets are unordered collections of unique elements. They are useful for performing mathematical operations such as union, intersection, and difference.

Type Conversion

Python provides built-in functions to convert variables from one data type to another. This process is known as type conversion or type casting. Some of the commonly used type conversion functions include:

  • int(): Converts a value to an integer.

  • float(): Converts a value to a floating-point number.

  • str(): Converts a value to a string.

  • bool(): Converts a value to a boolean.

Type conversion is useful when performing operations that require operands of the same data type or when displaying data in a specific format.

Variable Naming Conventions

When naming variables in Python, it is important to follow certain naming conventions to ensure code readability and maintainability. Here are some commonly accepted conventions:

  • Variable names should be descriptive and meaningful.

  • Use lowercase letters and separate words with underscores (snake_case).

  • Avoid using reserved keywords as variable names.

  • Avoid using single-letter variable names, except for simple loop counters.

By following these conventions, your code will be easier to understand and collaborate on with other developers.

Conclusion

In this section, we explored the concept of variables and data types in Python. Variables are used to store data values, and Python supports various data types such as numeric types, strings, booleans, lists, tuples, dictionaries, and sets. Understanding variables and data types is crucial for writing effective and efficient Python code. In the next section, we will delve into operators, which allow us to perform operations on variables and data.

2.2 Operators

In Python, operators are symbols or special characters that perform specific operations on one or more operands. They are an essential part of any programming language and allow us to manipulate data and perform various calculations. Python provides a wide range of operators that can be used for arithmetic, comparison, logical, assignment, and other operations.

Arithmetic Operators

Arithmetic operators are used to perform mathematical calculations on numerical values. Python supports the following 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.

  • Modulus (%): Returns the remainder of the division.

  • Exponentiation (**): Raises the first operand to the power of the second.

  • Floor Division (//): Returns the quotient of the division, discarding the remainder.

These operators can be used with both integers and floating-point numbers. Let's see some examples:

x = 10
y = 3

print(x + y)  # Output: 13
print(x - y)  # Output: 7
print(x * y)  # Output: 30
print(x / y)  # Output: 3.3333333333333335
print(x % y)  # Output: 1
print(x ** y) # Output: 1000
print(x // y) # Output: 3

Comparison Operators

Comparison operators are used to compare two values and return a Boolean result (True or False). Python supports the following comparison operators:

  • Equal to (==): Returns True if the operands are equal.

  • Not equal to (!=): Returns True if the operands are not equal.

  • Greater than (>): Returns True if the first operand is greater than the second.

  • Less than (<): Returns True if the first operand is less than the second.

  • Greater than or equal to (>=): Returns True if the first operand is greater than or equal to the second.

  • Less than or equal to (<=): Returns True if the first operand is less than or equal to the second.

These operators can be used with any data type, including numbers, strings, and even objects. Here are some examples:

x = 5
y = 10

print(x == y)  # Output: False
print(x != y)  # Output: True
print(x > y)   # Output: False
print(x < y)   # Output: True
print(x >= y)  # Output: False
print(x <= y)  # Output: True

Logical Operators

Logical operators are used to combine multiple conditions and evaluate the result. Python supports the following logical operators:

  • Logical AND (and): Returns True if both operands are True.

  • Logical OR (or): Returns True if at least one of the operands is True.

  • Logical NOT (not): Returns the opposite of the operand's value.

These operators are commonly used in conditional statements and loops to control the flow of the program. Let's see some examples:

x = 5
y = 10
z = 3

print(x < y and y > z)  # Output: True
print(x < y or y < z)   # Output: True
print(not x < y)        # Output: False

Assignment Operators

Assignment operators are used to assign values to variables. They combine the assignment (=) operator with other arithmetic or logical operators. Python supports the following assignment operators:

  • Assignment (=): Assigns the value on the right to the variable on the left.

  • Addition assignment (+=): Adds the value on the right to the variable on the left and assigns the result to the variable.

  • Subtraction assignment (-=): Subtracts the value on the right from the variable on the left and assigns the result to the variable.

  • Multiplication assignment (*=): Multiplies the variable on the left by the value on the right and assigns the result to the variable.

  • Division assignment (/=): Divides the variable on the left by the value on the right and assigns the result to the variable.

  • Modulus assignment (%=): Performs modulus operation on the variable on the left with the value on the right and assigns the result to the variable.

  • Exponentiation assignment (**=): Raises the variable on the left to the power of the value on the right and assigns the result to the variable.

  • Floor division assignment (//=): Performs floor division on the variable on the left with the value on the right and assigns the result to the variable.

These operators provide a concise way to update the value of a variable based on its current value. Here are some examples:

x = 5

x += 3  # Equivalent to x = x + 3
print(x)  # Output: 8

x -= 2  # Equivalent to x = x - 2
print(x)  # Output: 6

x *= 4  # Equivalent to x = x * 4
print(x)  # Output: 24

x /= 6  # Equivalent to x = x / 6
print(x)  # Output: 4.0

x %= 3  # Equivalent to x = x % 3
print(x)  # Output: 1.0

x **= 2  # Equivalent to x = x ** 2
print(x)  # Output: 1.0

x //= 0.5  # Equivalent to x = x // 0.5
print(x)  # Output: 2.0

These are just a few examples of the operators available in Python. Operators are fundamental building blocks of any programming language, and understanding how to use them effectively is crucial for writing efficient and concise code. In the next section, we will explore control flow statements, which allow us to control the execution of our code based on certain conditions.

2.3 Control Flow

Control flow refers to the order in which statements are executed in a program. It allows us to control the flow of execution based on certain conditions or criteria. In Python, control flow is achieved through the use of conditional statements and loops.

Conditional Statements

Conditional statements allow us to execute different blocks of code based on certain conditions. The most commonly used conditional statements in Python are the if, elif, and else statements.

The if statement is used to execute a block of code if a certain condition is true. Here's the basic syntax of an if statement:

if condition:
    # code to be executed if condition is true

The elif statement is used to check additional conditions if the previous conditions are not met. It stands for "else if". Here's the syntax of an elif statement:

if condition1:
    # code to be executed if condition1 is true
elif condition2:
    # code to be executed if condition2 is true

The else statement is used to execute a block of code if none of the previous conditions are true. It is optional and can only appear after an if or elif statement. Here's the syntax of an else statement:

if condition1:
    # code to be executed if condition1 is true
elif condition2:
    # code to be executed if condition2 is true
else:
    # code to be executed if none of the conditions are true

Let's look at an example to understand how conditional statements work in Python:

age = 25

if age < 18:
    print("You are a minor.")
elif age >= 18 and age < 65:
    print("You are an adult.")
else:
    print("You are a senior citizen.")

In this example, the program checks the value of the age variable and prints a corresponding message based on the condition that is true.

Loops

Loops allow us to repeatedly execute a block of code until a certain condition is met. Python provides two types of loops: for loops and while loops.

For Loops

A for loop is used to iterate over a sequence (such as a list, tuple, or string) or other iterable objects. It executes a block of code for each item in the sequence. Here's the syntax of a for loop:

for item in sequence:
    # code to be executed for each item

Let's look at an example to understand how for loops work in Python:

fruits = ["apple", "banana", "orange"]

for fruit in fruits:
    print(fruit)

In this example, the for loop iterates over each item in the fruits list and prints it.

While Loops

A while loop is used to repeatedly execute a block of code as long as a certain condition is true. It continues to execute the code until the condition becomes false. Here's the syntax of a while loop:

while condition:
    # code to be executed as long as condition is true

Let's look at an example to understand how while loops work in Python:

count = 0

while count < 5:
    print(count)
    count += 1

In this example, the while loop continues to execute as long as the value of count is less than 5. It prints the value of count and increments it by 1 in each iteration.

Control Flow Keywords

Python provides several keywords that can be used to control the flow of execution within conditional statements and loops.

The break keyword is used to exit a loop prematurely. It is often used with an if statement to check for a certain condition and break out of the loop if the condition is met.

The continue keyword is used to skip the rest of the code in the current iteration of a loop and move on to the next iteration.

The pass keyword is used as a placeholder when a statement is required syntactically but you don't want to execute any code. It is often used as a placeholder for future code implementation.

Conclusion

Control flow is an essential concept in programming, and Python provides powerful tools for controlling the flow of execution in a program. Conditional statements allow us to execute different blocks of code based on certain conditions, while loops allow us to repeatedly execute a block of code until a certain condition is met. By understanding and utilizing control flow in Python, you can write more efficient and flexible programs.

2.4 Functions

In Python, a function is a block of reusable code that performs a specific task. It allows you to break down your program into smaller, more manageable pieces, making your code more organized and easier to understand. Functions also promote code reusability, as you can call a function multiple times throughout your program without having to rewrite the same code over and over again.

Defining a Function

To define a function in Python, you use the def keyword followed by the function name and a pair of parentheses. Inside the parentheses, you can specify any parameters that the function requires. Parameters are variables that hold the values passed to the function when it is called.

Here's an example of a simple function that takes two parameters and returns their sum:

def add_numbers(a, b):
    sum = a + b
    return sum

In this example, add_numbers is the name of the function, and a and b are the parameters. Inside the function, we calculate the sum of a and b and store it in the variable sum. Finally, we use the return keyword to return the value of sum back to the caller.

Calling a Function

Once you have defined a function, you can call it by using its name followed by a pair of parentheses. If the function requires any parameters, you can pass them inside the parentheses.

Continuing with our previous example, here's how you would call the add_numbers function:

result = add_numbers(5, 3)
print(result)  # Output: 8

In this case, we pass the values 5 and 3 as arguments to the add_numbers function. The function calculates their sum and returns the result, which we store in the variable result. Finally, we print the value of result, which is 8.

Default Parameters

In Python, you can also define default values for function parameters. Default parameters are used when the caller does not provide a value for that parameter. This allows for more flexibility when calling a function.

Here's an example of a function with a default parameter:

def greet(name="John"):
    print("Hello, " + name + "!")

In this example, the greet function takes a parameter called name, which has a default value of "John". If the caller does not provide a value for name, the function will use the default value instead.

greet()  # Output: Hello, John!
greet("Alice")  # Output: Hello, Alice!

In the first call to greet, since no argument is provided, the function uses the default value of "John". In the second call, we pass the argument "Alice", so the function uses that value instead.

Variable Number of Arguments

Python also allows you to define functions that can accept a variable number of arguments. This is useful when you don't know in advance how many arguments will be passed to the function.

To define a function with a variable number of arguments, you can use the *args syntax. The * before args tells Python to treat any additional arguments as a tuple.

Here's an example:

def calculate_average(*args):
    total = sum(args)
    average = total / len(args)
    return average

In this example, the calculate_average function can accept any number of arguments. We use the sum function to calculate the total of all the arguments and then divide it by the number of arguments to get the average.

result = calculate_average(5, 10, 15)
print(result)  # Output: 10.0

In this case, we pass three arguments to the calculate_average function. The function treats them as a tuple and calculates their average, which is 10.0.

Recursion

Recursion is a powerful technique in programming where a function calls itself to solve a problem. It is particularly useful for solving problems that can be broken down into smaller, similar subproblems.

Here's an example of a recursive function that calculates the factorial of a number:

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

In this example, the factorial function calls itself with a smaller value of n until n becomes 0. The base case is when n is 0, in which case the function returns 1. Otherwise, it multiplies n with the factorial of n - 1 and returns the result.

result = factorial(5)
print(result)  # Output: 120

In this case, the factorial function is called with 5. It calculates the factorial of 5 by multiplying 5 with the factorial of 4, which in turn multiplies 4 with the factorial of 3, and so on, until it reaches the base case.

Conclusion

Functions are an essential part of Python programming. They allow you to break down your code into smaller, reusable pieces, making your code more organized and easier to understand. By using functions, you can promote code reusability and improve the overall structure of your programs. In this section, we covered the basics of defining and calling functions, using default parameters, accepting a variable number of arguments, and implementing recursion. With this knowledge, you can start unlocking the mysteries of Python and write more efficient and modular code.