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
93: Working with File Paths Portably
I can't tell you how many times I've received a bug report that simply said, "The script crashes on startup," only to realize the user was on Windows and I'd written the code on a Mac. The culprit is almost always the slash. Windows likes backslashes (\); Unix-based systems (Linux, macOS) use forward slashes (/). If you hardcode these into your strings, your code is essentially a ticking time bomb for anyone using a different OS.
The hardcoded trap
Let's say we're building a small utility that reads a configuration file from a config folder and writes a session log to a logs folder. My first instinct—and I'll admit I still do this when I'm rushing—is to just write the path as a string. Check this out:
# My initial (flawed) approach
log_path = "logs/session.log"
with open(log_path, "w") as f:
f.write("Session started")
This works perfectly on my MacBook. But the moment I send this to a colleague on Windows, they might hit an FileNotFoundError or a permissions issue because the OS is expecting a different path separator. Even if Python's open() function is smart enough to handle forward slashes on Windows most of the time, relying on that is a bad habit. It falls apart the second you start interacting with system shells or external APIs.
Switching to the Pathlib way
Years ago, we used os.path.join(). It worked, but it was clunky and felt like writing a math equation just to find a file. Now, we have pathlib. It treats paths as objects rather than strings, which is a total game-changer.
Here is how I'd actually rewrite that log manager to be truly portable:
from pathlib import Path
# Create a Path object for the current directory
base_dir = Path(".")
# We use the / operator!
# Pathlib overloads this to join paths regardless of the OS.
log_folder = base_dir / "logs"
log_file = log_folder / "session.log"
# Make sure the directory actually exists first
log_folder.mkdir(exist_ok=True)
log_file.write_text("Session started")
print(f"Log written to: {log_file}")
The / operator here isn't doing division; pathlib has hijacked it to mean "append this to the path." If you're on Windows, it knows to use \ under the hood. If you're on Linux, it uses /. You don't have to think about it, which is exactly where you want to be.
Avoiding the "Current Working Directory" headache
There's one more trap. In the example above, I used Path("."). That refers to the current working directory—which is wherever the user happened to be in their terminal when they ran the script. If they are in their home folder but the script is in /projects/my_app/, Path(".") will look in the home folder and fail to find your config files.
To fix this, I always anchor my paths to the location of the script itself using __file__. This ensures the script always knows where its own folders are, no matter where it's called from:
from pathlib import Path
# This gets the absolute path to the directory where this script lives
SCRIPT_DIR = Path(__file__).resolve().parent
# Now we define paths relative to the script location
CONFIG_FILE = SCRIPT_DIR / "config" / "settings.ini"
LOG_DIR = SCRIPT_DIR / "logs"
print(f"Looking for config at: {CONFIG_FILE}")
By using .resolve().parent, we've made the script completely independent of the user's terminal state. It's a small detail, but it's the difference between a script that "mostly works" and professional-grade software.
📋 Practical Task
Build a Portable Project Directory Initializer
Your task is to create a script that sets up a project folder structure automatically. The script must be portable and should not rely on the user's current working directory.
Write a script that does the following:
- Determines the directory where the script is located using
__file__. - Creates three folders relative to that location:
data,exports, andtemp. - Inside the
datafolder, creates an empty file nameddatabase.csv. - Inside the
exportsfolder, creates an empty file namedreport.pdf. - Prints the absolute path of the
report.pdffile to the console to verify it was created in the right place.
Constraint: You must use pathlib.Path for all path manipulations. Do not use string concatenation or os.path.
There are no comments for now.