Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
28: Constants and Naming Conventions for Them
Wait, does Python actually have a way to stop a variable from being changed?
The short answer is: no. Coming from languages like Java or C++, this is usually where learners get frustrated. In those languages, you have a const or final keyword that tells the compiler, "If anyone tries to change this value, throw an error." Python doesn't do that. Everything in Python is technically mutable if you really want it to be.
In Python, a "constant" is more of a gentleman's agreement. We use constants to represent values that shouldn't change while the program is running—like the gravity constant in a physics engine or a specific API timeout value. We just trust each other not to overwrite them. I've seen a few juniors try to "hack" this by creating complex classes with read-only properties, but honestly? Don't do that. It's overkill and not how the community works. Just follow the naming convention, and other Python devs will know exactly what you mean.
Why the all-caps naming style?
You'll see constants written in SCREAMING_SNAKE_CASE. This means all uppercase letters with underscores separating words. It's a visual signal. When I'm scanning a file with 500 lines of code and I see a variable in all caps, my brain immediately registers: "This is a configuration value; do not assign a new value to this."
Take a look at this example for a digital storefront:
# These are constants
TAX_RATE = 0.07
MAX_ITEMS_PER_ORDER = 50
SUPPORT_EMAIL = "help@mystore.com"
def calculate_total(price):
# I can use the constant here...
return price + (price * TAX_RATE)
# If I do this, Python won't stop me, but I'm breaking the "contract"
TAX_RATE = 0.08
If you see TAX_RATE being reassigned in the middle of a function, that's a huge red flag during a code review. It tells me the developer is confused about whether they're dealing with a configuration setting or a local variable.
Where should I actually put these in my files?
I've seen people scatter constants throughout their functions, and it's a nightmare to maintain. If you decide to change your MAX_RETRIES from 3 to 5, you don't want to have to hunt through ten different functions to find every instance of that number.
The rule of thumb is: put them at the very top of your module, right after the imports but before any function or class definitions. If your project grows and you end up with dozens of constants, I recommend moving them into a completely separate file—usually named config.py or settings.py. Then you can just import them where you need them:
# In config.py
DATABASE_TIMEOUT = 30
API_KEY = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
# In main.py
from config import DATABASE_TIMEOUT
def connect_to_db():
print(f"Connecting with a timeout of {DATABASE_TIMEOUT} seconds...")
This keeps your logic clean and your configuration centralized. It's much easier to manage when you're deploying your code to different environments (like switching from a test database to a production database).
📋 Practical Task
Refactoring the Storefront Configuration
You've inherited a piece of code for a shipping calculator, but it's full of "magic numbers"—values hardcoded directly into the logic that make the code hard to read and maintain. Your task is to refactor this into a professional structure using constants.
The Goal:
- Identify the three fixed values in the code below (the flat shipping fee, the free shipping threshold, and the heavy package surcharge).
- Move these values to the top of the script as constants using
SCREAMING_SNAKE_CASE. - Replace the hardcoded numbers inside the
calculate_shippingfunction with your new constants.
def calculate_shipping(weight, order_total):
# This logic is messy. Refactor the numbers below!
if order_total > 100:
return 0.0
shipping_cost = 10.0
if weight > 20:
shipping_cost += 15.0
return shipping_cost
# Test cases
print(calculate_shipping(10, 50)) # Should use constants
print(calculate_shipping(25, 50)) # Should use constants
print(calculate_shipping(10, 150)) # Should use constants
There are no comments for now.