Python Guide 1: Python Basics

Table of Contents


Getting Started

Running Python

# Interactive mode (REPL)
python3

# Run Python file
python3 script.py

# Run as module
python3 -m module_name

# Check Python version
python3 --version

Your First Program

# hello.py
print("Hello, World!")

# Run it
# python3 hello.py

Comments

# Single-line comment

"""
Multi-line comment
or docstring
Can span multiple lines
"""

'''
Also a multi-line
comment
'''

Basic Syntax

Variables and Assignment

# Variable assignment (no type declaration needed)
x = 5
name = "Alice"
is_valid = True

# Multiple assignment
a, b, c = 1, 2, 3

# Same value to multiple variables
x = y = z = 0

# Swapping variables
a, b = b, a

# Type hints (optional, for documentation)
age: int = 25
name: str = "Bob"
scores: list[int] = [90, 85, 95]

Variable Naming Rules

# Valid names
user_name = "Alice"
user_age = 30
_private_var = 10
MAX_SIZE = 100

# Invalid names
# 2users = 10        # Can't start with number
# user-name = "Bob"  # Can't use hyphens
# class = "Python"   # Can't use reserved keywords
# Basic print
print("Hello")

# Multiple values
print("Hello", "World")  # Hello World

# Custom separator
print("Hello", "World", sep="-")  # Hello-World

# Custom ending
print("Hello", end=" ")
print("World")  # Hello World (on same line)

# Formatted output
name = "Alice"
age = 30
print(f"My name is {name} and I'm {age}")

Data Types

Numbers

Integers (int)

# Integer
x = 10
y = -5
big_num = 1_000_000  # Underscores for readability

# Binary, octal, hex
binary = 0b1010      # 10
octal = 0o12         # 10
hexadecimal = 0xA    # 10

# Type conversion
int_from_float = int(3.7)    # 3
int_from_string = int("100") # 100

Floating Point (float)

# Float
pi = 3.14159
negative = -2.5

# Scientific notation
scientific = 1.5e-4  # 0.00015
large = 2.5e10       # 25000000000.0

# Type conversion
float_from_int = float(10)       # 10.0
float_from_string = float("3.14") # 3.14

# Precision issues
result = 0.1 + 0.2  # 0.30000000000000004

Complex Numbers (complex)

# Complex numbers
z = 3 + 4j
z2 = complex(3, 4)  # Same as above

# Access parts
real_part = z.real  # 3.0
imag_part = z.imag  # 4.0

# Operations
conjugate = z.conjugate()  # 3-4j

Arithmetic Operations

# Basic operations
addition = 10 + 5        # 15
subtraction = 10 - 5     # 5
multiplication = 10 * 5  # 50
division = 10 / 3        # 3.333... (always float)
floor_division = 10 // 3 # 3 (integer division)
modulo = 10 % 3          # 1 (remainder)
exponentiation = 2 ** 3  # 8 (power)

# Compound assignment
x = 10
x += 5   # x = x + 5  → 15
x -= 3   # x = x - 3  → 12
x *= 2   # x = x * 2  → 24
x /= 4   # x = x / 4  → 6.0
x //= 2  # x = x // 2 → 3.0
x %= 2   # x = x % 2  → 1.0
x **= 3  # x = x ** 3 → 1.0

Strings (str)

# String creation
single = 'Hello'
double = "World"
triple = '''Multi-line
string'''

# String concatenation
full_name = "John" + " " + "Doe"

# String repetition
repeated = "Ha" * 3  # "HaHaHa"

# String length
length = len("Hello")  # 5

# String indexing (0-based)
text = "Python"
first = text[0]   # 'P'
last = text[-1]   # 'n'
second_last = text[-2]  # 'o'

# String slicing
s = "Python Programming"
first_6 = s[0:6]    # "Python"
first_6_alt = s[:6] # "Python" (same)
from_7 = s[7:]      # "Programming"
last_4 = s[-4:]     # "ming"
every_2nd = s[::2]  # "Pto rgamn"
reversed_s = s[::-1] # "gnimmargorP nohtyP"

String Methods

text = "  Hello World  "

# Case conversion
upper = text.upper()       # "  HELLO WORLD  "
lower = text.lower()       # "  hello world  "
title = text.title()       # "  Hello World  "
capitalize = text.capitalize()  # "  hello world  "
swapcase = text.swapcase()     # "  hELLO wORLD  "

# Whitespace removal
stripped = text.strip()    # "Hello World"
lstrip = text.lstrip()     # "Hello World  "
rstrip = text.rstrip()     # "  Hello World"

# Search and replace
replaced = text.replace("World", "Python")
count = text.count("l")    # 3
index = text.find("World") # 8 (or -1 if not found)
index2 = text.index("World") # 8 (raises error if not found)

# Split and join
words = "Hello,World,Python".split(",")  # ['Hello', 'World', 'Python']
joined = "-".join(words)  # "Hello-World-Python"

# Check content
is_alpha = "Hello".isalpha()   # True
is_digit = "123".isdigit()     # True
is_alnum = "Hello123".isalnum()  # True
starts = "Hello".startswith("He")  # True
ends = "Hello".endswith("lo")      # True

String Formatting

name = "Alice"
age = 30
pi = 3.14159

# f-strings (Python 3.6+, recommended)
message = f"My name is {name} and I'm {age}"
formatted = f"Pi: {pi:.2f}"  # "Pi: 3.14"
expression = f"Next year: {age + 1}"  # "Next year: 31"

# .format() method
message = "My name is {} and I'm {}".format(name, age)
message = "My name is {n} and I'm {a}".format(n=name, a=age)
formatted = "Pi: {:.2f}".format(pi)

# % formatting (old style, avoid)
message = "My name is %s and I'm %d" % (name, age)

Boolean (bool)

# Boolean values
is_true = True
is_false = False

# Boolean from comparison
result = 5 > 3     # True
result = 10 == 10  # True
result = 5 != 3    # True

# Boolean operations
and_result = True and False  # False
or_result = True or False    # True
not_result = not True        # False

# Truthy and Falsy values
# Falsy: False, 0, 0.0, "", [], {}, (), None
# Everything else is Truthy

bool(0)      # False
bool(1)      # True
bool("")     # False
bool("text") # True
bool([])     # False
bool([1])    # True

None Type

# None represents absence of value
x = None

# Checking for None
if x is None:
    print("x is None")

# Common use: default parameter
def greet(name=None):
    if name is None:
        name = "Guest"
    return f"Hello, {name}"

# Difference between None and empty
x = None    # No value
x = ""      # Empty string (still a value)
x = []      # Empty list (still a value)

Lists

# List creation
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4], [5, 6]]
empty = []

# List operations
numbers.append(6)           # Add to end: [1, 2, 3, 4, 5, 6]
numbers.insert(0, 0)        # Insert at position: [0, 1, 2, 3, 4, 5, 6]
numbers.remove(3)           # Remove first occurrence: [0, 1, 2, 4, 5, 6]
popped = numbers.pop()      # Remove and return last: 6
numbers.extend([7, 8])      # Add multiple: [0, 1, 2, 4, 5, 7, 8]
numbers.clear()             # Remove all elements

# List methods
numbers = [3, 1, 4, 1, 5]
numbers.sort()              # Sort in place: [1, 1, 3, 4, 5]
numbers.reverse()           # Reverse in place: [5, 4, 3, 1, 1]
count = numbers.count(1)    # Count occurrences: 2
index = numbers.index(4)    # Find index: 1
length = len(numbers)       # Length: 5

# List indexing and slicing
numbers = [0, 1, 2, 3, 4, 5]
first = numbers[0]          # 0
last = numbers[-1]          # 5
first_three = numbers[:3]   # [0, 1, 2]
last_three = numbers[-3:]   # [3, 4, 5]
middle = numbers[2:5]       # [2, 3, 4]
every_other = numbers[::2]  # [0, 2, 4]
reversed_list = numbers[::-1]  # [5, 4, 3, 2, 1, 0]

# List comprehension
squares = [x**2 for x in range(5)]  # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0]  # [0, 2, 4, 6, 8]

Tuples

# Tuple creation (immutable)
point = (3, 4)
rgb = (255, 0, 128)
single = (5,)  # Comma required for single element
empty = ()

# Tuple unpacking
x, y = point
r, g, b = rgb

# Tuple operations (limited due to immutability)
length = len(point)      # 2
count = rgb.count(0)     # 1
index = rgb.index(128)   # 2

# Accessing elements
first = point[0]   # 3
last = point[-1]   # 4

# Why use tuples?
# - Faster than lists
# - Can be dictionary keys
# - Protect data from modification
coordinates = {(0, 0): "origin", (1, 0): "right"}

Sets

# Set creation (unordered, unique elements)
numbers = {1, 2, 3, 4, 5}
duplicates = {1, 1, 2, 2, 3}  # {1, 2, 3}
empty = set()  # NOT {} (that's a dict)

# Set operations
numbers.add(6)              # Add element
numbers.remove(3)           # Remove (error if not present)
numbers.discard(3)          # Remove (no error if not present)
numbers.clear()             # Remove all

# Set operations (mathematical)
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

union = a | b                # {1, 2, 3, 4, 5, 6}
intersection = a & b         # {3, 4}
difference = a - b           # {1, 2}
symmetric_diff = a ^ b       # {1, 2, 5, 6}
is_subset = {1, 2}.issubset(a)     # True
is_superset = a.issuperset({1, 2}) # True

# Remove duplicates from list
unique_list = list(set([1, 1, 2, 2, 3, 3]))  # [1, 2, 3]

Dictionaries

# Dictionary creation (key-value pairs)
person = {
    "name": "Alice",
    "age": 30,
    "city": "New York"
}
empty = {}

# Accessing values
name = person["name"]              # "Alice" (raises error if not found)
age = person.get("age")            # 30
height = person.get("height", 0)   # 0 (default if not found)

# Adding/updating
person["email"] = "alice@email.com"  # Add new key
person["age"] = 31                   # Update existing
person.update({"phone": "123-456"})  # Update multiple

# Removing
del person["city"]                 # Delete key
email = person.pop("email")        # Remove and return
person.clear()                     # Remove all

# Dictionary methods
person = {"name": "Alice", "age": 30}
keys = person.keys()               # dict_keys(['name', 'age'])
values = person.values()           # dict_values(['Alice', 30])
items = person.items()             # dict_items([('name', 'Alice'), ('age', 30)])

# Check membership
has_name = "name" in person        # True
has_email = "email" in person      # False

# Looping
for key in person:
    print(f"{key}: {person[key]}")

for key, value in person.items():
    print(f"{key}: {value}")

# Dictionary comprehension
squares = {x: x**2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# Nested dictionaries
students = {
    "alice": {"age": 20, "grade": "A"},
    "bob": {"age": 22, "grade": "B"}
}
alice_age = students["alice"]["age"]  # 20

Operators

Comparison Operators

x = 5
y = 10

# Comparison
equal = x == y          # False
not_equal = x != y      # True
greater = x > y         # False
less = x < y            # True
greater_equal = x >= y  # False
less_equal = x <= y     # True

# Chaining comparisons
age = 25
is_adult = 18 <= age < 65  # True

Logical Operators

a = True
b = False

# Logical operations
and_result = a and b  # False
or_result = a or b    # True
not_result = not a    # False

# Short-circuit evaluation
result = False and expensive_function()  # expensive_function not called
result = True or expensive_function()    # expensive_function not called

# Practical examples
age = 25
if age >= 18 and age < 65:
    print("Working age")

has_ticket = False
is_child = True
if has_ticket or is_child:
    print("Can enter")

Membership Operators

# in, not in
numbers = [1, 2, 3, 4, 5]
result = 3 in numbers      # True
result = 6 not in numbers  # True

text = "Hello World"
result = "World" in text   # True
result = "Python" not in text  # True

person = {"name": "Alice", "age": 30}
result = "name" in person  # True

Identity Operators

# is, is not (check if same object)
x = [1, 2, 3]
y = x
z = [1, 2, 3]

x is y      # True (same object)
x is z      # False (different objects)
x == z      # True (same content)
x is not z  # True

# Common use with None
value = None
if value is None:
    print("Value is None")

Control Flow

if, elif, else

# Simple if
x = 10
if x > 0:
    print("Positive")

# if-else
if x > 0:
    print("Positive")
else:
    print("Non-positive")

# if-elif-else
if x > 0:
    print("Positive")
elif x < 0:
    print("Negative")
else:
    print("Zero")

# Nested if
if x > 0:
    if x % 2 == 0:
        print("Positive even")
    else:
        print("Positive odd")

# Ternary operator (one-line if-else)
result = "Even" if x % 2 == 0 else "Odd"
max_val = a if a > b else b

for Loop

# Iterate over range
for i in range(5):
    print(i)  # 0, 1, 2, 3, 4

# Iterate over list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# Iterate with index (enumerate)
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

# Iterate over string
for char in "Hello":
    print(char)

# Iterate over dictionary
person = {"name": "Alice", "age": 30}
for key in person:
    print(f"{key}: {person[key]}")

for key, value in person.items():
    print(f"{key}: {value}")

# range() function
range(5)         # 0, 1, 2, 3, 4
range(2, 5)      # 2, 3, 4
range(0, 10, 2)  # 0, 2, 4, 6, 8
range(10, 0, -1) # 10, 9, 8, ..., 1

# Nested loops
for i in range(3):
    for j in range(3):
        print(f"({i}, {j})")

while Loop

# Basic while
count = 0
while count < 5:
    print(count)
    count += 1

# While with break
while True:
    user_input = input("Enter 'q' to quit: ")
    if user_input == 'q':
        break

# While with continue
i = 0
while i < 10:
    i += 1
    if i % 2 == 0:
        continue  # Skip even numbers
    print(i)

# While-else (else executes if loop completes normally)
i = 0
while i < 5:
    print(i)
    i += 1
else:
    print("Loop completed normally")

break, continue, pass

# break - exit loop
for i in range(10):
    if i == 5:
        break
    print(i)  # 0, 1, 2, 3, 4

# continue - skip to next iteration
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)  # 1, 3, 5, 7, 9

# pass - do nothing (placeholder)
for i in range(5):
    pass  # TODO: implement later

def not_implemented():
    pass  # Placeholder for future code

class EmptyClass:
    pass  # Empty class definition

Functions

Defining Functions

# Basic function
def greet():
    print("Hello!")

greet()  # Call function

# Function with parameters
def greet_name(name):
    print(f"Hello, {name}!")

greet_name("Alice")

# Function with return value
def add(a, b):
    return a + b

result = add(3, 5)  # 8

# Function with default parameters
def greet_default(name="Guest"):
    print(f"Hello, {name}!")

greet_default()        # Hello, Guest!
greet_default("Alice") # Hello, Alice!

# Multiple return values
def get_min_max(numbers):
    return min(numbers), max(numbers)

min_val, max_val = get_min_max([1, 2, 3, 4, 5])

Function Parameters

# Positional arguments
def describe_pet(animal, name):
    print(f"I have a {animal} named {name}")

describe_pet("dog", "Buddy")

# Keyword arguments
describe_pet(name="Buddy", animal="dog")

# *args - variable positional arguments
def sum_all(*args):
    return sum(args)

sum_all(1, 2, 3)        # 6
sum_all(1, 2, 3, 4, 5)  # 15

# **kwargs - variable keyword arguments
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="NYC")

# Combining parameter types
def complex_func(pos1, pos2, *args, kwarg1="default", **kwargs):
    print(f"Positional: {pos1}, {pos2}")
    print(f"Args: {args}")
    print(f"Keyword: {kwarg1}")
    print(f"Kwargs: {kwargs}")

complex_func(1, 2, 3, 4, kwarg1="custom", extra="value")

Lambda Functions

# Lambda - anonymous function
square = lambda x: x ** 2
add = lambda a, b: a + b

print(square(5))  # 25
print(add(3, 4))  # 7

# Lambda with map
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))  # [1, 4, 9, 16, 25]

# Lambda with filter
evens = list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

# Lambda with sorted
points = [(1, 2), (3, 1), (5, 0)]
sorted_points = sorted(points, key=lambda p: p[1])  # [(5, 0), (3, 1), (1, 2)]

Docstrings

def calculate_area(length, width):
    """
    Calculate the area of a rectangle.

    Args:
        length (float): The length of the rectangle
        width (float): The width of the rectangle

    Returns:
        float: The area of the rectangle

    Example:
        >>> calculate_area(5, 3)
        15
    """
    return length * width

# Access docstring
print(calculate_area.__doc__)
help(calculate_area)

Input/Output

Input

# Get user input (always returns string)
name = input("Enter your name: ")
print(f"Hello, {name}!")

# Convert input to int
age_str = input("Enter your age: ")
age = int(age_str)

# One-liner
age = int(input("Enter your age: "))

# Handle invalid input
try:
    age = int(input("Enter your age: "))
except ValueError:
    print("Invalid number")

Output

# Basic print
print("Hello")

# Multiple values
print("Name:", "Alice", "Age:", 30)

# Custom separator
print("apple", "banana", "cherry", sep=", ")

# Custom ending
print("Loading", end="...")
print("Done!")

# Formatted output
name = "Alice"
age = 30

# f-strings
print(f"Name: {name}, Age: {age}")

# Format specifiers
pi = 3.14159
print(f"Pi: {pi:.2f}")        # 2 decimal places
print(f"Pi: {pi:10.2f}")      # 10 width, 2 decimals
print(f"Number: {42:05d}")    # Zero-padded: 00042

Common Patterns

Swapping Variables

# Without temporary variable
a, b = b, a

# Example
x = 5
y = 10
x, y = y, x  # x=10, y=5

Conditional Expressions

# Ternary operator
status = "adult" if age >= 18 else "minor"
max_value = a if a > b else b

# Multiple conditions
category = "child" if age < 13 else "teen" if age < 20 else "adult"

Checking Empty Sequences

# Pythonic way (uses truthiness)
if items:  # Better than: if len(items) > 0
    print("Has items")

if not items:  # Better than: if len(items) == 0
    print("Empty")

Dictionary get with Default

# Safe dictionary access
person = {"name": "Alice"}
age = person.get("age", 0)  # Returns 0 if 'age' not found

# vs unsafe access
# age = person["age"]  # Raises KeyError if not found

List/String Operations

# Joining strings
words = ["Hello", "World", "Python"]
sentence = " ".join(words)  # "Hello World Python"
csv = ",".join(words)       # "Hello,World,Python"

# Splitting strings
sentence = "Hello World Python"
words = sentence.split()    # ['Hello', 'World', 'Python']
parts = "a,b,c".split(",")  # ['a', 'b', 'c']

# Reversing
reversed_list = numbers[::-1]
reversed_string = text[::-1]

Type Checking

# Check type
x = 5
print(type(x))            # <class 'int'>
print(isinstance(x, int)) # True
print(isinstance(x, (int, float)))  # True (check multiple types)

Quick Reference

Data Types Summary

int         # 10, -5, 0
float       # 3.14, -2.5
str         # "hello", 'world'
bool        # True, False
list        # [1, 2, 3]
tuple       # (1, 2, 3)
set         # {1, 2, 3}
dict        # {"key": "value"}
None        # None

Common Operations

len(sequence)           # Length
min(sequence)           # Minimum
max(sequence)           # Maximum
sum(numbers)            # Sum
sorted(sequence)        # Sorted copy
reversed(sequence)      # Reversed iterator
enumerate(sequence)     # Index and value
zip(seq1, seq2)         # Combine sequences

String Formatting

f"{variable}"           # Basic
f"{num:.2f}"           # 2 decimal places
f"{num:10d}"           # Width 10
f"{num:05d}"           # Zero-padded
f"{text:<10}"          # Left align
f"{text:>10}"          # Right align
f"{text:^10}"          # Center align

Practice Exercises

Exercise 1: Temperature Converter

def celsius_to_fahrenheit(celsius):
    """Convert Celsius to Fahrenheit."""
    return celsius * 9/5 + 32

# Test
print(celsius_to_fahrenheit(0))   # 32.0
print(celsius_to_fahrenheit(100)) # 212.0

Exercise 2: Find Maximum

def find_max(numbers):
    """Find maximum number in list."""
    if not numbers:
        return None

    max_num = numbers[0]
    for num in numbers:
        if num > max_num:
            max_num = num
    return max_num

# Test
print(find_max([3, 1, 4, 1, 5, 9]))  # 9

Exercise 3: Count Vowels

def count_vowels(text):
    """Count vowels in string."""
    vowels = "aeiouAEIOU"
    count = 0
    for char in text:
        if char in vowels:
            count += 1
    return count

# Test
print(count_vowels("Hello World"))  # 3

Additional Resources

Happy coding! 🐍