Skip to main content

Python

Welcome to Python

Python is a versatile, high-level programming language known for its readability and broad community support. Developed in the early 1990s, it emphasizes clear, concise syntax, making it an excellent choice for beginners and professionals alike. Python's extensive standard library and thriving ecosystem of third-party packages allow it to be used in many fields—from web development and data analysis to artificial intelligence and scientific computing. Its ease of learning, coupled with powerful capabilities, makes Python a valuable skill for anyone looking to dive into programming or advance their tech career.

Introduction to Python

How to install Python and write your first "Hello, World!" program.

Python is one of the most popular programming languages due to its simplicity and versatility. Whether you're a beginner or an experienced coder, installing Python and running your first script is a straightforward process.

Step 1: Download and Install Python

  1. Visit the Official Website
    Go to Python.org and download the latest stable version of Python for your operating system (Windows, macOS, or Linux).

  2. Run the Installer

    • For Windows: Double-click the downloaded .exe file and check "Add Python to PATH" before clicking "Install Now".

    • For Mac: Download the macOS installer and follow the setup instructions.

    • For Linux: Use the package manager (e.g., for Ubuntu).

      sudo apt install python3
  3. Verify the Installation
    Open a terminal or command prompt and type:

  4. python --version
    

    or

    python3 --version
    

    This should display the installed Python version.

Step 2: Choose an IDE or Code Editor

Python comes with IDLE, a built-in Integrated Development Environment (IDE), which is great for beginners. However, more advanced users often prefer editors like:

  • VS Code – Lightweight and powerful, with Python extensions.

  • PyCharm – Feature-rich IDE for professional developers.

  • Jupyter Notebook – Best for data science and interactive coding.

For beginners, launching IDLE (installed with Python) is the simplest way to start coding.

Step 3: Write and Run Your First Python Script

  1. Using IDLE:

    • Open IDLE.

    • Click File → New File.

    • Type the following code:

      print("Hello, World!")
      
    • Save the file with a .py extension (e.g., hello.py).

    • Run it by selecting Run → Run Module or pressing F5.

  2. Using Command Line:

    • Open a terminal or command prompt.

    • Navigate to the folder where you saved hello.py.

    • Run the script by typing:

    • python hello.py
      
    • You should see the output:

    • Hello, World!
      

Congratulations! You have successfully installed Python and run your first script. 🎉

For more details, visit the official Python documentation at docs.python.org. Happy coding! 🚀

Syntax of python

1. Python Indentation (No Braces for Blocks)

Python uses indentation (whitespace) to define blocks of code instead of curly braces {} like in other languages. This makes Python code more readable but also means incorrect indentation will cause errors.

Correct Example:

if 5 > 3:
    print("Five is greater than three")  # Proper indentation

Incorrect Example (Raises IndentationError):

if 5 > 3:
print("This will cause an error!")  # No indentation

Python enforces indentation for better code structure and readability. The recommended indentation is 4 spaces per level.

2. Zero-Based Indexing

Python follows zero-based indexing, meaning the first element of a sequence (like a list, string, or tuple) starts at index 0, not 1.

Example:

fruits = ["apple", "banana", "cherry"]
print(fruits[0])  # Outputs: apple
print(fruits[2])  # Outputs: cherry

Incorrect Example (IndexError):

print(fruits[3])  # IndexError: list index out of range

Since Python starts counting from 0, attempting to access an index that is equal to or greater than the length of the sequence results in an error.

3. Comments in Python

Comments help developers understand code by adding explanations. Python supports both single-line and multi-line comments.

Single-Line Comment:

# This is a single-line comment
print("Hello, World!")  # Inline comment

Multi-Line Comment:

"""
This is a multi-line comment.
It is often used for documentation.
"""
print("Hello, World!")

Although triple quotes can be used for multi-line comments, they are mainly meant for docstrings, which are special comments placed inside functions for documentation.

4. Case Sensitivity

Python is case-sensitive, meaning it treats uppercase and lowercase letters differently. Variable names, function names, and keywords must be used consistently.

Example:

myVar = 5
MyVar = 10

print(myVar)  # Outputs: 5
print(MyVar)  # Outputs: 10 (different variable)

Here, myVar and MyVar are considered two different variables because of their capitalization.

Incorrect Example:

Print("Hello")  # NameError: name 'Print' is not defined

Python’s built-in functions like print() must be written in lowercase.

5. Variables and Dynamic Typing

Python is dynamically typed, meaning you don’t need to declare the type of a variable explicitly. The type is determined automatically based on the assigned value.

Example:

x = 10       # Integer
y = 3.14     # Float
z = "Hello"  # String

print(type(x))  # Outputs: <class 'int'>
print(type(y))  # Outputs: <class 'float'>
print(type(z))  # Outputs: <class 'str'>

Reassigning Different Data Types:

a = 5        # Initially an integer
a = "Python" # Now reassigned as a string
print(a)     # Outputs: Python

Since Python allows dynamic typing, a variable’s type can change during execution.

Conclusion

Understanding Python’s basic syntax is essential for writing clean and efficient code. Key takeaways include:

  • Python enforces indentation instead of curly braces for code blocks.

  • Zero-based indexing means the first element in a sequence is at index 0.

  • Comments improve code readability and can be single-line (#) or multi-line (""" """).

  • Python is case-sensitive, so Var and var are treated as different variables.

  • Python supports dynamic typing, allowing variables to change types.

Mastering these basics will provide a strong foundation for learning more advanced Python concepts. Happy coding! 🚀

print

The print() function in Python is used to display output on the screen. It is one of the most commonly used functions, especially for debugging and user interaction. In this short guide, we’ll explore different ways to use print() effectively, including how to print multiple values, format output, and control separators and end characters.


1. Basic print() Usage

The simplest way to use print() is to pass a string or a number inside the parentheses:

print("Hello, World!")  # Outputs: Hello, World!
print(42)               # Outputs: 42

You can print multiple values by separating them with a comma ,:

print("Hello", "Python")  # Outputs: Hello Python

By default, Python inserts a space between the values.

2. Using the sep Parameter

The sep parameter controls the separator between multiple values in print(). By default, it is a space, but you can change it to anything else:

print("apple", "banana", "cherry", sep=", ")  
# Outputs: apple, banana, cherry
print("Python", "is", "fun", sep="-")  
# Outputs: Python-is-fun

3. Using the end Parameter

By default, print() adds a newline (\n) at the end of the output. You can change this behavior using the end parameter:

print("Hello", end=" ")
print("World!")  
# Outputs: Hello World! (on the same line)

Here, end=" " replaces the default newline with a space.

4. Printing Variables

You can print variables just like string literals:

name = "Alice"
age = 25
print("Name:", name, "Age:", age)  
# Outputs: Name: Alice Age: 25

Alternatively, you can use f-strings for a cleaner output:

print(f"Name: {name}, Age: {age}")  
# Outputs: Name: Alice, Age: 25

5. Printing Special Characters

Use escape sequences to format the output:

print("Hello\nWorld!")  # \n adds a new line
print("This is a tab:\tPython")  # \t adds a tab space

Conclusion

The print() function is a powerful tool in Python that allows you to display output in various ways. Key takeaways:

  • Use print(value1, value2, …) to print multiple values.

  • Change the separator using sep="custom_separator".

  • Control line endings with end="custom_end".

  • Use f-strings for better formatting.

Mastering print() will make debugging and output handling in Python much easier.

Binary Operations in Python

1. Arithmetic Operators

Arithmetic operators perform mathematical calculations between two operands. Python supports addition, subtraction, multiplication, division, modulo, floor division, and exponentiation.

Examples:

a = 15
b = 4

print(a + b)   # 19 (addition)
print(a - b)   # 11 (subtraction)
print(a * b)   # 60 (multiplication)
print(a / b)   # 3.75 (true division)
print(a // b)  # 3 (floor division)
print(a % b)   # 3 (modulus)
print(a ** b)  # 50625 (exponentiation)

Arithmetic operators always return a new value without changing the original variables.

2. Comparison Operators

Comparison operators compare two values and return a boolean result (True or False). These include equality, inequality, greater/less than, and their combinations.

Examples:

x = 7
y = 10

print(x == y)   # False (equal to)
print(x != y)   # True (not equal to)
print(x > y)    # False
print(x < y)    # True
print(x >= 7)   # True
print(y <= 7)   # False

Comparison results are often used inside if statements or loops to control program flow.

3. Logical Operators

Logical operators combine boolean values and return True or False. The three operators are and, or, and not (unary).

Examples:

is_sunny = True
is_warm = False

print(is_sunny and is_warm)   # False (both must be True)
print(is_sunny or is_warm)    # True  (at least one is True)
print(not is_warm)            # True  (negates the value)

Logical operators are frequently used in conditions, e.g. checking multiple requirements at once.

4. Bitwise Operators

Bitwise operators act on the binary representations of integers. They include & (AND), | (OR), ^ (XOR), << (left shift), and >> (right shift).

Examples:

a = 6   # binary: 110
b = 3   # binary: 011

print(a & b)   # 2 (binary 010)
print(a | b)   # 7 (binary 111)
print(a ^ b)   # 5 (binary 101)
print(a << 1)  # 12 (binary 1100, shifted left by 1)
print(b >> 1)  # 1 (binary 001, shifted right by 1)

Bitwise operations are often used in low-level programming, cryptography, or performance optimization.

5. Assignment Operators

Assignment operators assign values to variables. They can also combine assignment with arithmetic or bitwise operations.

Examples:

x = 10   # simple assignment
x += 5   # equivalent to x = x + 5 → 15
x -= 3   # equivalent to x = x - 3 → 12
x *= 2   # equivalent to x = x * 2 → 24
x //= 4  # equivalent to x = x // 4 → 6
x %= 4   # equivalent to x = x % 4 → 2
x **= 3  # equivalent to x = x ** 3 → 8

Assignment operators are shorthand to update a variable in place, making code more concise.

Integers

Integers are whole numbers, either positive, negative, or zero. They are one of Python's basic numeric types and are used for mathematical operations.


1. Creating Integers

Integers can be created by assigning integer values to variables:

a = 10
b = -5
c = 0
print(a, b, c)

2. Integer Operations

Integers support various arithmetic operations:

print(5 + 3)   # Addition
print(5 - 3)   # Subtraction
print(5 * 3)   # Multiplication
print(5 / 3)   # Division (returns float)
print(5 // 3)  # Floor division
print(5 % 3)   # Modulus

3. Type Conversion

Converting other types to integers:

num = int("123")
print(num)  # Outputs: 123

num = int(3.1415)
print(num)  # Outputs: 3

Floats

Floats represent real numbers that can have fractional parts. They are another basic numeric type in Python and are essential for decimal calculations.


1. Creating Floats

Floats can be created by assigning decimal values to variables:

a = 3.1415
b = -0.5
c = 100.0
print(a, b, c)

2. Float Operations

Floats support various arithmetic operations:

print(2.5 + 1.5)  # Addition
print(5.0 / 2)    # Division
print(3.1415 ** 2) # Exponentiation
print(7.3 % 3)    # Modulus

3. Type Conversion

Converting other types to floats:

num = float("123.45")
print(num)  # Outputs: 123.45

num = float(3)
print(num)  # Outputs: 3.0

num = float(5.5)
print(num)  # Outputs: 5.5

Strings

Strings are sequences of characters used to represent text. They are immutable and can be defined using single quotes, double quotes, or triple quotes for multi-line strings.


1. Creating Strings

Strings can be created using different types of quotes:

a = 'Hello, World!'
b = "Python is great"
c = """This is a
multi-line string"""
print(a, b, c, sep='\n')

2. String Operations

Strings support various operations like concatenation and repetition:

print("Hello" + " World")  # Concatenation
print("Hello" * 3)        # Repetition
print("Hello"[0])        # Accessing characters
print("Hello"[1:3])      # Slicing

3. String Methods

Strings have various built-in methods for manipulation:

text = "hello world"
print(text.upper())      # Outputs: HELLO WORLD
print(text.lower())      # Outputs: hello world
print(text.replace("world", "earth"))  # Outputs: hello earth

String Functions

Strings have many useful methods for trimming, splitting, and replacing text.

Trimming with .strip()

text = "   hello world   "
print(text.strip())   # "hello world"
print(text.lstrip())  # "hello world   "
print(text.rstrip())  # "   hello world"

Splitting Strings

line = "apple,banana,cherry"
print(line.split(","))   # ['apple', 'banana', 'cherry']

words = "one two three".split()
print(words)             # ['one', 'two', 'three']

Replacing Text

sentence = "I like cats"
print(sentence.replace("cats", "dogs"))
# "I like dogs"

Joining Strings

parts = ["2025", "09", "26"]
date = "-".join(parts)
print(date)   # "2025-09-26"

Common Pitfalls

  • .strip() removes whitespace by default, but you can pass characters: "hello!!".strip("!").
  • .split() without arguments splits on any whitespace, not just spaces.
  • .replace() replaces all occurrences, unless you pass a third argument (max count).
  • .join() requires all elements to be strings (not numbers).

String Formatting & Case Methods

Python offers several methods to format strings and adjust their case. This helps create dynamic output and control the appearance of text.

Formatting with .format()

# Insert values into placeholders {}
template = "The sum of {0} and {1} is {2}"
msg = template.format(2, 4, 2+4)
print(msg)   # The sum of 2 and 4 is 6

# Named placeholders
info = "Name: {name}, Age: {age}".format(name="Alice", age=30)
print(info)

Case Conversion

text = "Hello World"
print(text.upper())   # "HELLO WORLD"
print(text.lower())   # "hello world"

Partitioning Strings

line = "user:password"
print(line.partition(":"))
# ('user', ':', 'password')

.partition() splits into a 3-part tuple: text before, the separator itself, and text after.

Common Pitfalls

  • Using .format() with missing or wrong keys raises KeyError or IndexError.
  • .upper() / .lower() create a new string, they don’t modify the original.
  • .partition() only splits on the first occurrence of the separator.

Lists

Lists are versatile, mutable sequences used to store collections of items. They are defined with square brackets [] and support a variety of operations for modification and access.


1. Creating a List

Define a list with various elements:

my_list = [1, 2, 3, "Python", True]
print(my_list)

2. Accessing and Modifying Lists

Lists support indexing, slicing, and methods for modifying their content:

# Accessing an element
print(my_list[3])  # Outputs: Python

# Changing an element
my_list[1] = "changed"
print(my_list)

# Appending a new element
my_list.append("new item")
print(my_list)

3. List Comprehensions

List comprehensions provide a concise way to create lists by iterating over sequences and optionally applying conditions:

# Creating a list of squares for numbers 0 to 9
squares = [x**2 for x in range(10)]
print(squares)

Indexing Lists

In Python, lists are ordered collections, and you can access elements using their index. Indexing starts at 0 for the first element. Negative indices count from the end of the list, with -1 being the last element.

Basic Indexing

fruits = ["apple", "banana", "cherry"]
print(fruits[0])   # Outputs: apple
print(fruits[-1])  # Outputs: cherry

Modifying Elements via Index

numbers = [10, 20, 30]
numbers[1] = 25
print(numbers)  # Outputs: [10, 25, 30]

Common Pitfalls

  • IndexError: Accessing an index outside the range of the list.
  • Mutable vs Immutable: Only mutable lists can be modified via indexing; tuples do not support assignment.

Slicing Lists

Slicing allows you to extract a portion of a list using the syntax list[start:stop:step]. The start index is inclusive, stop is exclusive, and step defines the interval.

Basic Slicing

numbers = [0, 1, 2, 3, 4, 5]
print(numbers[1:4])    # Outputs: [1, 2, 3]
print(numbers[:3])     # Outputs: [0, 1, 2]
print(numbers[3:])     # Outputs: [3, 4, 5]
print(numbers[::2])    # Outputs: [0, 2, 4] - every 2nd element

Reversing a List

print(numbers[::-1])  # Outputs: [5, 4, 3, 2, 1, 0]

Common Pitfalls

  • Stop index is exclusive; list[start:stop] does not include the element at stop.
  • Negative indices can be tricky; ensure they are used correctly with the list length.
  • Slicing returns a new list; it does not modify the original unless assigned back.

List-Specific Functions & Methods

Python provides many built-in functions and methods specifically for lists to manipulate, query, and transform data efficiently.

Common Methods

fruits = ["apple", "banana", "cherry"]
fruits.append("date")      # Add element at the end
fruits.insert(1, "blueberry")  # Insert at index 1
fruits.remove("banana")    # Remove element by value
popped = fruits.pop()      # Remove and return last element
print(fruits, popped)

Other Useful Methods

numbers = [3, 1, 4, 2]
numbers.sort()     # Sorts in ascending order
numbers.reverse()  # Reverses the list
print(numbers)

Built-in Functions for Lists

nums = [1, 2, 3, 4]
print(len(nums))   # Number of elements
print(sum(nums))   # Sum of elements
print(max(nums))   # Maximum value
print(min(nums))   # Minimum value

Working with Multiple Lists

# enumerate() gives index + value when looping
animals = ["cat", "dog", "mouse"]
for index, animal in enumerate(animals):
    print(index, animal)

# zip() pairs elements from multiple lists
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
    print(name, "scored", score)

enumerate() is helpful when you need both the position and the value of a list element. zip() is useful when combining two or more lists element by element.

Common Pitfalls

  • Methods like sort() and reverse() modify the list in place and return None.
  • Removing elements that do not exist raises ValueError.
  • Be careful with pop() on empty lists; it raises IndexError.
  • zip() stops at the shortest list length.

Tuples

Tuples are immutable sequences used to store a collection of items. They are defined with parentheses () and are useful when you want to ensure data integrity.


1. Creating a Tuple

A simple tuple containing different types of data:

my_tuple = (10, "hello", 3.14)
print(my_tuple)

2. Accessing Tuple Elements

Access elements by their index, similar to lists:

# Accessing the first element
print(my_tuple[0])  # Outputs: 10

# Slicing the tuple
print(my_tuple[1:])  # Outputs: ('hello', 3.14)

Since tuples are immutable, their values cannot be changed after creation.

Dictionaries

Dictionaries store data in key-value pairs, making data lookup efficient. They are created using curly braces {} and can be accessed by their keys.


1. Creating a Dictionary

A basic dictionary mapping fruits to their colors:

fruit_colors = {
    "apple": "red",
    "banana": "yellow",
    "cherry": "red"
}

2. Accessing and Modifying Data

Access a value using its key, add a new key-value pair, or update an existing one:

# Accessing a value
print(fruit_colors["apple"])  # Outputs: red

# Adding a new entry
fruit_colors["orange"] = "orange"

# Updating an entry
fruit_colors["banana"] = "green"

Iterate through keys and values using the items() method:

for fruit, color in fruit_colors.items():
    print(f"{fruit} is {color}")

Dictionary Functions

Dictionaries (dict) store data as key–value pairs. Python provides methods like .keys() and .values() to access the keys and values separately.

Accessing Keys

person = {"name": "Alice", "age": 25, "city": "Zurich"}

print(person.keys())   # dict_keys(['name', 'age', 'city'])

# Loop through keys
for key in person.keys():
    print("Key:", key)

Accessing Values

print(person.values())  # dict_values(['Alice', 25, 'Zurich'])

# Loop through values
for value in person.values():
    print("Value:", value)

Using Keys and Values Together

# Often combined with a for-loop
for key in person.keys():
    print(key, "->", person[key])

Common Pitfalls

  • .keys() and .values() return special views, not normal lists. If you need a list, wrap them with list().
  • Dictionaries are unordered before Python 3.7. In modern Python, they keep insertion order.

Variables

Variables are used to store data in Python. They act as named containers for values of different types (numbers, strings, etc.). Python variables must follow certain naming rules:

  • The name of a variable must start with a letter or an underscore (_).
  • A variable name cannot start with a number.
  • A variable cannot use reserved Python keywords (see keyword module).

1. Creating Variables

In Python, variables are created automatically when you assign them a value using the assignment operator =. There is no explicit declaration needed.

a = 10
b = "Hello"
c = 3.14
print(a, b, c)   # Outputs: 10 Hello 3.14

2. Using Input to Create Variables

Variables can also be created from user input using the input() function. By default, input() returns a string, but you can convert it to other types if needed.

name = input("Enter your name: ")
age = int(input("Enter your age: "))  # type conversion to integer
print("Hello", name, "you are", age, "years old.")

3. Type Conversion

Sometimes you may need to convert between data types (e.g., from string to integer). Common functions include int(), float(), and str().

num_str = "123"
num = int(num_str)   # convert string to integer
print(num, type(num))  # Outputs: 123 <class 'int'>

pi = 3.1415
print(str(pi))        # convert float to string → "3.1415"

4. Operators and Variables

Variables can be used together with arithmetic, comparison, and other assignment operators. See the dedicated sections on operators for details and examples.

Conditionals: if, elif and else

Conditional statements in Python allow you to execute code blocks based on whether a condition is True or False. The basic structure uses if, followed optionally by elif (else if), and else for fallback.


1. Basic if Statement

Use the if statement to execute code only when a condition is met:

x = 10
if x > 5:
    print("x is greater than 5")  
    # Outputs: x is greater than 5

2. if-else Statement

Include an else block to execute code when the condition is not met:

x = 3
if x > 5:
    print("x is greater than 5")
else:
    print("x is not greater than 5")  
    # Outputs: x is not greater than 5

3. if-elif-else Chain

For multiple conditions, use elif to check additional conditions:

x = 5
if x > 5:
    print("x is greater than 5")
elif x == 5:
    print("x is exactly 5")
else:
    print("x is less than 5")
    # Outputs: x is exactly 5

These constructs allow you to create robust decision-making structures in your Python programs.

for-loop (Basics)

A for loop in Python repeats code for each element in a sequence (like a list, string, or range of numbers). Unlike while, the number of repetitions is usually known in advance.

Counting with range()

for i in range(5):
    print("Number:", i)
# Prints 0, 1, 2, 3, 4

range(5) generates numbers from 0 up to (but not including) 5.

Looping Through a List

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print("I like", fruit)

The loop visits each element in the list one by one.

Looping Through a String

word = "hi!"
for char in word:
    print(char)
# Prints h, i, !

Using break and continue

for num in range(1, 6):
    if num == 3:
        continue   # skip number 3
    if num == 5:
        break      # stop the loop completely
    print(num)
# Prints 1, 2, 4

Common Pitfalls

  • Off-by-one errors: Remember that range(n) stops before n.
  • Forgetting that in checks items: for x in list gives elements, not indexes.
  • Mixing break and continue: break ends the loop, continue only skips the current step.

while-loop (Basics)

A while loop repeats a block of code as long as its condition is True. Unlike for loops, the number of repetitions is not fixed in advance. The condition is checked before each repetition.

Important: Be careful with the condition. If it never becomes False, the loop will run forever (an infinite loop).

Simple Counting Example

x = 0
while x < 5:
    print("Counted to:", x)
    x += 1   # Important: update the counter!

This loop starts at x = 0 and stops once x is no longer less than 5.

Stopping Early with break

x = 10
while True:       # runs "forever" unless stopped
    if x % 7 == 0:
        print("Found a multiple of 7:", x)
        break     # exit the loop
    x += 1

Here we use while True but escape with break once a condition is met.

Skipping Iterations with continue

x = -3
while x <= 3:
    x += 1
    if x == 0:       # skip division by zero
        continue
    print("1/", x, "=", 1/x)

The continue statement skips the current loop step and moves to the next one.

Basic Pitfalls

  • Forgetting to update the variable: If x += 1 is missing, the condition never changes, and the loop runs forever.
  • Overly broad conditions: while True is safe only if you include a proper break.

Loop Control Statements: break, continue, and pass

Python provides special statements that alter the normal flow of loops. They are useful for fine-grained control of iteration, handling exceptional cases, and making code more expressive.

break — Exiting a Loop

break immediately terminates the nearest enclosing loop, regardless of the loop condition. It is commonly used when a target condition has been met and no further iteration is needed.

nums = [1, 4, 7, 10]
for n in nums:
    if n > 5:
        print(f"Found {n}, stopping loop.")
        break
# Only iterates until 7, then exits

continue — Skipping an Iteration

continue skips the rest of the current iteration and jumps directly to the next one. It is often used for filtering unwanted cases.

for n in range(5):
    if n % 2 == 0:
        continue
    print(f"Odd: {n}")
# Prints Odd: 1, 3

pass — Placeholder Statement

pass does nothing and acts as a syntactic placeholder. It is useful when a block of code is required syntactically but no action should be taken yet (e.g., during development or in abstract class methods).

for n in range(3):
    if n == 1:
        pass  # Placeholder for future logic
    else:
        print(n)
# Prints 0 and 2, does nothing on 1

Common Pitfalls

  • Confusing break with return: break exits only the loop, not the function. Use return to exit a function entirely.
  • Infinite Loops with continue: In while loops, placing continue before updating loop variables can cause the condition to never change.
  • Misusing pass: Since pass does nothing, leaving it in production code unintentionally may hide missing logic or bugs.

Quick Comparison

  • break: Exit the loop entirely.
  • continue: Skip to the next iteration.
  • pass: Do nothing, placeholder only.

Nested Loops

Nested loops are loops inside loops. The outer loop runs once for each iteration of the inner loop, multiplying the total iterations. They are essential for working with multi-dimensional data, combinatorics, and algorithmic problems.

Cartesian Product

colors = ["red", "blue"]
sizes = ["S", "M", "L"]
for color in colors:
    for size in sizes:
        print(color, size)

Nested while

i = 1
while i <= 3:
    j = 1
    while j <= 2:
        print(i, j)
        j += 1
    i += 1

Pitfalls

Complexity Explosion: Two nested loops over n elements each result in O(n²) complexity. Adding more levels increases runtime dramatically.

Variable Shadowing: Accidentally reusing variable names in inner and outer loops can override values unexpectedly.

Functions and Lambda Expressions

Functions in Python are defined using the def keyword and allow you to encapsulate code for reuse. Additionally, lambda expressions provide a shorthand for creating small anonymous functions.


1. Defining Functions

Use def to define a function, optionally with parameters:

def greet(name):
    return f"Hello, {name}!"

print(greet("Alice"))  
# Outputs: Hello, Alice!

2. Lambda Functions

Lambda expressions create small anonymous functions. They are useful for short, simple functions:

# A lambda that adds two numbers
add = lambda a, b: a + b
print(add(3, 4))  # Outputs: 7

Both regular functions and lambda expressions are essential tools for organizing and simplifying your code.

Importing Modules in Python

Python allows you to extend functionality by importing modules (files that contain Python code, functions, and classes). Modules can be built-in, custom-made, or installed from external sources (like PyPI).


1. Basic Import Syntax

Use the import statement to bring a module into your program.

import math
print(math.sqrt(16))   # Outputs: 4.0

2. Importing Specific Functions or Aliases

You can import specific functions or rename modules for convenience.

from math import pi, sin
print(pi)        # Outputs: 3.141592653589793
print(sin(90))   # Uses radians by default

import numpy as np
arr = np.array([1, 2, 3])
print(arr)

3. Commonly Used Built-in Modules

Some of the most useful built-in modules include:

  • math → Mathematical functions (sqrt, pi, sin, cos...)
  • random → Random numbers, shuffling, choices
  • datetime → Dates and times
  • os → Operating system interactions (files, directories)
  • sys → System-specific parameters and functions
  • json → Working with JSON data

4. Installing External Modules

Many popular modules are not built-in and need to be installed via pip (Python’s package manager).

pip install numpy
pip install requests
import requests
response = requests.get("https://api.github.com")
print(response.status_code)

5. Resolving Import Errors

Common issues when importing modules:

  • ModuleNotFoundError: The module is not installed. ➝ Fix: Run pip install modulename.
  • ImportError: A specific function/class cannot be imported. ➝ Fix: Check the module’s documentation for correct function names.
  • Version Conflicts: A module version may not support your Python version. ➝ Fix: Upgrade with pip install --upgrade modulename.
  • Virtual Environment Issues: The module is installed in a different environment. ➝ Fix: Activate the correct environment before running the script.

6. Checking Installed Modules

pip list        # Shows installed modules
pip show numpy  # Details about a specific module

Knowing how to import and manage modules allows you to extend Python’s functionality far beyond its core features.

Basic File Methods

The built-in open() function returns a file object which you can use to read from or write to files on disk. The mode determines allowed actions: 'r' (read, default), 'w' (write, overwrite), 'a' (append). Opening a file does not read or write data by itself — you must call the file methods shown below. Always close files when finished (or, preferably, use a context manager).

Modes — quick examples

# implicit read mode (same as 'r')
f = open("example.txt")
f.close()

# explicit read
f = open("example.txt", "r")
f.close()

# open for writing (will overwrite)
f = open("output.txt", "w")
f.write("line 1\n")
f.close()

# open for appending (adds to end)
f = open("output.txt", "a")
f.write("another line\n")
f.close()

.read() — read entire contents

read() returns the remainder of the file as a single string. If called again when already at the end, it returns an empty string.

f = open("notes.txt", "r", encoding="utf-8")
all_text = f.read()
print(len(all_text))   # number of characters read
more = f.read()        # already at EOF → returns ''
print(repr(more))      # shows ''
f.close()

.readline() — read the next line

readline() returns the next line (including the trailing newline if present). Calling it repeatedly advances through the file. A size argument (e.g., readline(50)) limits the number of characters returned — it does not select the “nth line”.

f = open("notes.txt", "r", encoding="utf-8")
first = f.readline()
second = f.readline()
print("First:", first)
print("Second:", second)
# to get the 3rd line specifically, iterate 3 times or use itertools.islice
f.close()

.readlines() — get all lines as a list

readlines() returns a list where each element is one line from the file (including newline characters). Use with care on very large files.

f = open("notes.txt", "r", encoding="utf-8")
lines = f.readlines()
print("Number of lines:", len(lines))
print("Line 0:", lines[0])
f.close()

.write() — write strings to a file

write() requires a string. Convert other types with str(). Behavior (overwrite vs append) depends on the mode used when opening the file.

# overwrite file
f = open("results.txt", "w", encoding="utf-8")
f.write("score: " + str(42) + "\n")
f.close()

# append
f = open("results.txt", "a", encoding="utf-8")
f.write("score: " + str(100) + "\n")
f.close()

.close() and best practice

close() releases the file handle and ensures buffered data is flushed to disk. Forgetting to close can block other programs or lose data. The recommended pattern is the context manager which closes automatically.

# manual close (works but easy to forget on errors)
f = open("data.txt", "r", encoding="utf-8")
try:
    content = f.read()
finally:
    f.close()

# preferred: context manager (automatic close)
with open("data.txt", "r", encoding="utf-8") as f:
    for line in f:
        process(line.rstrip("\n"))
# file is closed here automatically

Small practical examples

# Example: copy a file line-by-line (memory-friendly)
with open("source.txt", "r", encoding="utf-8") as src, \
     open("copy.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line)

# Example: read the 3rd line safely
from itertools import islice
with open("notes.txt", "r", encoding="utf-8") as f:
    third_line = next(islice(f, 2, 3), "")  # returns "" if missing

Common errors & quick fixes

  • FileNotFoundError: check the path or use an absolute path.
  • PermissionError: ensure you have write/read permissions for the target folder.
  • UnicodeDecodeError: specify the correct encoding (e.g., "utf-8", "latin-1") or open in binary mode "rb" for raw bytes.

NumPy — Install & Import

NumPy is the core package for numerical computing in Python (arrays, fast math, linear algebra). Install it with pip or your package manager, then import it (conventionally as np).

Install

# with pip
pip install numpy

# or with conda
conda install numpy

Import

import numpy as np
# now use np.array, np.linspace, np.zeros, ...

Common Pitfalls

  • Make sure you install into the same Python environment you run (virtualenv / conda env issues).
  • Importing as anything other than np is allowed but uncommon — other people expect np.

NumPy Arrays — Create, Index, Slice

NumPy arrays are like lists but with fixed numeric types and fast vectorized operations. You can convert lists, create nested (2D) arrays, and index/slice them.

Create from lists

import numpy as np

a = np.array([1, 2, 3, 4])            # 1D array
b = np.array([[1, 2, 3], [4, 5, 6]])  # 2D array
print(a.shape)   # (4,)
print(b.shape)   # (2, 3)

Indexing (1D & 2D)

print(a[0])      # first element -> 1
print(b[1, 2])   # second row, third column -> 6
print(b[0][1])   # alternative syntax -> 2

Slicing

c = np.arange(10)       # array([0,1,2,...,9])
print(c[1:5])             # [1 2 3 4]
print(b[0:2, 1:3])        # rows 0..1 and cols 1..2 (2x2 subarray)

Common Pitfalls

  • NumPy arrays require uniform dtype — mixed Python objects lead to dtype=object.
  • Slices are **views**, not copies — modifying a slice can change the original array.

Array Shape & the .shape Property

.shape returns a tuple with the size of each dimension. It is a property (no parentheses).

Examples

import numpy as np
a = np.array([1, 2, 3, 4])
b = np.array([[1,2,3],[4,5,6]])

print(a.shape)   # (4,)
print(b.shape)   # (2, 3)

# reshape if needed
c = a.reshape((2,2))
print(c.shape)   # (2, 2)

Common Pitfalls

  • Calling .shape() with parentheses is wrong — it's a property, not a function.
  • reshape requires sizes that multiply to the same number of elements (or use -1 for automatic inference).

NumPy — Basic Functions (linspace, zeros, random, ...)

NumPy offers convenient constructors and helpers for commonly used arrays and sequences.

Common constructors

import numpy as np

# even spacing: start, stop, num-values
x = np.linspace(0, 1, num=5)    # [0.  0.25 0.5  0.75 1. ]

# zeros with shape / dtype
Z = np.zeros((2,3), dtype=float)  # 2x3 array of zeros

# arange like Python range -> integers
r = np.arange(0, 10, 2)           # [0 2 4 6 8]

Random numbers

# modern usage (numpy >= 1.17) prefers Generator, but simple forms below:
rand = np.random.rand(3)       # 3 uniform floats in [0,1)
rnorm = np.random.randn(3)     # 3 standard normal samples
rint = np.random.randint(0, 10, size=4)  # 4 ints in [0,10)

Data type behavior

a = np.array([1, 2, 3], dtype=int)
a[0] += 0.2
print(a)  # still integer array; fractional part lost (a[0] remains 1)
  • If an array has integer dtype, in-place operations will be cast to that dtype (possible truncation).
  • To allow floats, create the array with dtype=float or cast with .astype().

Matplotlib — Install & Import

Matplotlib is the standard plotting library for Python. Install it with your package manager and import the pyplot module (commonly as plt).

Install

# with pip
pip install matplotlib

# or with conda
conda install matplotlib

Import

import matplotlib.pyplot as plt
# optionally import numpy for data
import numpy as np

Common Pitfalls

  • Install into the active environment (virtualenv/conda) used by your script or notebook.
  • In some environments (e.g. headless servers) you may need a non-interactive backend to save figures.

Matplotlib — Basic Usage (plt.plot, plt.show, save)

Simple plotting workflow: create data, call plotting functions, then display or save the figure.

Simple line plot

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

plt.plot(x, y)       # plot the line
plt.show()           # display the plot window (or inline in notebooks)

Multiple series and saving

plt.plot(x, np.sin(x), label='sin')
plt.plot(x, np.cos(x), label='cos')
plt.legend()
plt.savefig('sincos.png')  # save to file
plt.show()

Common Pitfalls

  • Call plt.show() after configuring the plot — otherwise some backends may not render full styling.
  • When plotting multiple figures, use plt.figure() or fig, ax = plt.subplots() to keep them separate.

Matplotlib — Modifiers & Styling (title, legend, axes, aspect)

Use labels, limits, legends and axis methods to adjust the appearance and layout of plots.

Labels, title, legend

plt.plot(x, np.sin(x), label='sin')
plt.plot(x, np.cos(x), label='cos')
plt.xlabel('x (rad)')
plt.ylabel('value')
plt.title('Sine & Cosine')
plt.legend()  # show labels in top-right by default
plt.show()

Axis limits & aspect

plt.plot([0,1,2], [0,1,4])
plt.xlim(0, 2)        # set x limits
plt.ylim(0, 5)        # set y limits

ax = plt.gca()        # get current Axes
ax.set_aspect('equal')   # equal scaling for x and y units
plt.show()

Hide axes or ticks

ax = plt.gca()
ax.xaxis.set_visible(False)   # hide x-axis
ax.yaxis.set_visible(False)   # hide y-axis

Common Pitfalls

  • Changing axis properties requires an Axes object (from plt.gca() or the return of plt.subplots()).
  • Many styling options are persistent to the current figure/axes — call them in the right order or create a new figure for separate plots.

Advanced Python Concepts

Beyond the basics, Python offers many advanced features to write concise, efficient, and robust code. Topics like list comprehensions, generators, and exception handling can help you take your programming skills to the next level.


1. List Comprehensions

List comprehensions provide a concise way to create lists. They can replace loops in many cases:

# Traditional loop
squares = []
for i in range(10):
    squares.append(i ** 2)

# Using list comprehension
squares = [i ** 2 for i in range(10)]
print(squares)

2. Exception Handling

Use try-except blocks to gracefully handle errors and exceptions:

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")
else:
    # is executed if try did not work
    # and the exception is not the same as in except
    print("Not execute but no ZeroDivisionError.")
finally:
    # is always executed
    print("Execution complete.")
    # Outputs an error message 
    # and a final execution statement

3. Generators

Generators allow you to iterate over large data sets efficiently without storing the entire sequence in memory:

def count_up_to(n):
    count = 1
    while count <= n:
        yield count
        count += 1

for number in count_up_to(5):
    print(number)
    # Outputs: 1 2 3 4 5

Exploring these advanced topics can significantly enhance your Python programming capabilities.

Comments