""" ================================================================================ 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' """)