python-by-example/01_basics/03_variables.py
2025-12-30 08:50:00 +02:00

408 lines
12 KiB
Python

"""
================================================================================
File: 03_variables.py
Topic: Variables in Python
================================================================================
This file demonstrates how to create and use variables in Python. Variables
are containers for storing data values. Unlike other programming languages,
Python has no command for declaring a variable - it's created the moment
you assign a value to it.
Key Concepts:
- Variable creation and assignment
- Variable naming conventions
- Multiple assignments
- Variable types and type checking
- Constants
- Variable scope basics
================================================================================
"""
# -----------------------------------------------------------------------------
# 1. Creating Variables
# -----------------------------------------------------------------------------
# Variables are created when you assign a value to them
print("--- Creating Variables ---")
# Simple variable assignments
name = "Baraa"
age = 25
height = 1.75
is_student = True
print(f"Name: {name}")
print(f"Age: {age}")
print(f"Height: {height}m")
print(f"Is student: {is_student}")
# Variables can be reassigned to different values
x = 10
print(f"\nx = {x}")
x = 20
print(f"x = {x} (reassigned)")
# Variables can even change types (dynamic typing)
value = 100
print(f"\nvalue = {value} (type: {type(value).__name__})")
value = "one hundred"
print(f"value = {value} (type: {type(value).__name__})")
# -----------------------------------------------------------------------------
# 2. Variable Naming Rules
# -----------------------------------------------------------------------------
# Rules for Python variable names
print("\n--- Variable Naming Rules ---")
# ✅ Valid variable names
my_variable = 1 # Lowercase with underscores (snake_case) - RECOMMENDED
myVariable = 2 # camelCase - valid but not Pythonic
MyVariable = 3 # PascalCase - usually for classes
_private_var = 4 # Starts with underscore - convention for private
__very_private = 5 # Double underscore - name mangling
var123 = 6 # Can contain numbers (but not start with them)
CONSTANT = 7 # ALL CAPS - convention for constants
print(f"my_variable = {my_variable}")
print(f"_private_var = {_private_var}")
print(f"CONSTANT = {CONSTANT}")
# ❌ Invalid variable names (would cause errors):
# 123var = 1 # Cannot start with a number
# my-variable = 1 # Hyphens not allowed
# my variable = 1 # Spaces not allowed
# class = 1 # Cannot use reserved keywords
# Reserved keywords in Python (cannot use as variable names):
import keyword
print(f"\nPython reserved keywords: {keyword.kwlist[:10]}...")
# -----------------------------------------------------------------------------
# 3. Naming Conventions (PEP 8)
# -----------------------------------------------------------------------------
print("\n--- Naming Conventions (PEP 8) ---")
# Variables and functions: snake_case
user_name = "john_doe"
max_value = 100
is_active = True
# Constants: UPPER_SNAKE_CASE
PI = 3.14159
MAX_CONNECTIONS = 100
DEFAULT_TIMEOUT = 30
# Classes: PascalCase (CapWords)
# class MyClass:
# pass
# Private variables: leading underscore
_internal_state = "private"
# "Very private" / Name-mangled: double leading underscore
__name_mangled = "mangled"
print(f"user_name: {user_name}")
print(f"PI (constant): {PI}")
print(f"MAX_CONNECTIONS (constant): {MAX_CONNECTIONS}")
# Descriptive names are better than short names
# ✅ Good
total_price = 99.99
customer_name = "Alice"
is_logged_in = True
# ❌ Bad (avoid!)
# tp = 99.99
# cn = "Alice"
# il = True
# -----------------------------------------------------------------------------
# 4. Multiple Variable Assignment
# -----------------------------------------------------------------------------
print("\n--- Multiple Variable Assignment ---")
# Assign the same value to multiple variables
a = b = c = 100
print(f"a = {a}, b = {b}, c = {c}")
# Assign different values in one line
x, y, z = 1, 2, 3
print(f"x = {x}, y = {y}, z = {z}")
# Swap variables easily
print(f"\nBefore swap: x = {x}, y = {y}")
x, y = y, x
print(f"After swap: x = {x}, y = {y}")
# Unpack a list/tuple into variables
coordinates = (10, 20, 30)
x, y, z = coordinates
print(f"\nUnpacked coordinates: x={x}, y={y}, z={z}")
# Extended unpacking with *
first, *rest = [1, 2, 3, 4, 5]
print(f"first = {first}, rest = {rest}")
*beginning, last = [1, 2, 3, 4, 5]
print(f"beginning = {beginning}, last = {last}")
first, *middle, last = [1, 2, 3, 4, 5]
print(f"first = {first}, middle = {middle}, last = {last}")
# -----------------------------------------------------------------------------
# 5. Variable Types and Type Checking
# -----------------------------------------------------------------------------
print("\n--- Variable Types and Type Checking ---")
# Python is dynamically typed - types are determined at runtime
integer_var = 42
float_var = 3.14
string_var = "Hello"
bool_var = True
list_var = [1, 2, 3]
dict_var = {"key": "value"}
none_var = None
# Check types using type()
print(f"integer_var: {integer_var} -> {type(integer_var)}")
print(f"float_var: {float_var} -> {type(float_var)}")
print(f"string_var: {string_var} -> {type(string_var)}")
print(f"bool_var: {bool_var} -> {type(bool_var)}")
print(f"list_var: {list_var} -> {type(list_var)}")
print(f"dict_var: {dict_var} -> {type(dict_var)}")
print(f"none_var: {none_var} -> {type(none_var)}")
# Check if variable is of a specific type using isinstance()
print(f"\nIs integer_var an int? {isinstance(integer_var, int)}")
print(f"Is string_var a str? {isinstance(string_var, str)}")
print(f"Is list_var a list? {isinstance(list_var, list)}")
# Check multiple types
print(f"Is integer_var int or float? {isinstance(integer_var, (int, float))}")
# -----------------------------------------------------------------------------
# 6. Type Casting (Converting Types)
# -----------------------------------------------------------------------------
print("\n--- Type Casting ---")
# String to integer
str_num = "123"
int_num = int(str_num)
print(f"'{str_num}' (str) -> {int_num} (int)")
# String to float
str_float = "3.14"
float_num = float(str_float)
print(f"'{str_float}' (str) -> {float_num} (float)")
# Number to string
number = 42
str_number = str(number)
print(f"{number} (int) -> '{str_number}' (str)")
# Float to integer (truncates, doesn't round)
pi = 3.99
int_pi = int(pi)
print(f"{pi} (float) -> {int_pi} (int) [truncated]")
# Boolean conversions
print(f"\nbool(1) = {bool(1)}") # True
print(f"bool(0) = {bool(0)}") # False
print(f"bool('hello') = {bool('hello')}") # True
print(f"bool('') = {bool('')}") # False
print(f"bool([1, 2]) = {bool([1, 2])}") # True
print(f"bool([]) = {bool([])}") # False
# Integer to boolean
print(f"\nint(True) = {int(True)}") # 1
print(f"int(False) = {int(False)}") # 0
# -----------------------------------------------------------------------------
# 7. Constants
# -----------------------------------------------------------------------------
print("\n--- Constants ---")
# Python doesn't have true constants, but by convention:
# - Use UPPER_SNAKE_CASE for constants
# - Don't modify them after initial assignment
# Mathematical constants
PI = 3.14159265359
E = 2.71828182845
GOLDEN_RATIO = 1.61803398875
# Application constants
MAX_USERS = 1000
API_TIMEOUT = 30
BASE_URL = "https://api.example.com"
DEBUG_MODE = False
print(f"PI = {PI}")
print(f"MAX_USERS = {MAX_USERS}")
print(f"BASE_URL = {BASE_URL}")
# You CAN modify them (Python won't stop you), but you SHOULDN'T
# PI = 3 # Don't do this!
# For true constants, you can use:
# 1. Separate constants module (constants.py)
# 2. typing.Final (Python 3.8+)
from typing import Final
MAX_SIZE: Final = 100
# MAX_SIZE = 200 # Type checker will warn about this
print(f"MAX_SIZE (Final) = {MAX_SIZE}")
# -----------------------------------------------------------------------------
# 8. Variable Scope (Basic)
# -----------------------------------------------------------------------------
print("\n--- Variable Scope ---")
# Global variable
global_var = "I'm global"
def my_function():
# Local variable
local_var = "I'm local"
print(f"Inside function - global_var: {global_var}")
print(f"Inside function - local_var: {local_var}")
my_function()
print(f"Outside function - global_var: {global_var}")
# print(local_var) # Error! local_var doesn't exist here
# Modifying global variables inside functions
counter = 0
def increment():
global counter # Declare we want to use global counter
counter += 1
print(f"\nBefore increment: counter = {counter}")
increment()
increment()
print(f"After 2 increments: counter = {counter}")
# -----------------------------------------------------------------------------
# 9. Variable Identity and Memory
# -----------------------------------------------------------------------------
print("\n--- Variable Identity and Memory ---")
# id() returns the memory address of a variable
a = 10
b = 10
c = a
print(f"a = {a}, id(a) = {id(a)}")
print(f"b = {b}, id(b) = {id(b)}")
print(f"c = {c}, id(c) = {id(c)}")
# Small integers (-5 to 256) are cached in Python
print(f"\na is b: {a is b}") # True (same memory location)
print(f"a is c: {a is c}") # True
# Larger numbers may have different ids
x = 1000
y = 1000
print(f"\nx = {x}, id(x) = {id(x)}")
print(f"y = {y}, id(y) = {id(y)}")
# 'is' vs '=='
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1
print(f"\nlist1 == list2: {list1 == list2}") # True (same values)
print(f"list1 is list2: {list1 is list2}") # False (different objects)
print(f"list1 is list3: {list1 is list3}") # True (same object)
# -----------------------------------------------------------------------------
# 10. Deleting Variables
# -----------------------------------------------------------------------------
print("\n--- Deleting Variables ---")
temp_var = "I will be deleted"
print(f"temp_var exists: {temp_var}")
del temp_var
# print(temp_var) # Error! NameError: name 'temp_var' is not defined
print("temp_var has been deleted")
# Check if variable exists
if 'temp_var' not in dir():
print("temp_var no longer exists in current scope")
# -----------------------------------------------------------------------------
# 11. Practical Examples
# -----------------------------------------------------------------------------
print("\n--- Practical Examples ---")
# Example 1: User profile
first_name = "Baraa"
last_name = "Shaer"
full_name = f"{first_name} {last_name}"
email = f"{first_name.lower()}.{last_name.lower()}@example.com"
print(f"Full Name: {full_name}")
print(f"Email: {email}")
# Example 2: Shopping cart
item_price = 29.99
quantity = 3
discount_percent = 10
subtotal = item_price * quantity
discount_amount = subtotal * (discount_percent / 100)
total = subtotal - discount_amount
print(f"\nSubtotal: ${subtotal:.2f}")
print(f"Discount ({discount_percent}%): -${discount_amount:.2f}")
print(f"Total: ${total:.2f}")
# Example 3: Temperature conversion
celsius = 25
fahrenheit = (celsius * 9/5) + 32
kelvin = celsius + 273.15
print(f"\n{celsius}°C = {fahrenheit}°F = {kelvin}K")
# -----------------------------------------------------------------------------
# Summary
# -----------------------------------------------------------------------------
print("\n" + "=" * 60)
print("VARIABLES SUMMARY")
print("=" * 60)
print("""
1. Variables are created by assignment (=)
2. Python is dynamically typed
3. Use snake_case for variables (PEP 8)
4. Use UPPER_CASE for constants
5. Multiple assignments: x, y, z = 1, 2, 3
6. Check types with type() or isinstance()
7. Convert types with int(), str(), float(), bool()
8. Variables have scope (local vs global)
9. Use 'is' for identity, '==' for equality
10. Delete variables with 'del'
""")