A Python program is nothing more than a plain text file with a .py extension. When you hand that file to the python command, the interpreter reads it top to bottom, executing every statement in order. There is no separate compile step you have to run by hand, no build file, no main() that the runtime calls magically — execution begins at the first line and stops at the last, or at the first uncaught exception. Understanding this simple execution model is the foundation for everything that follows in the course.
Python programs can be run in three different ways, and knowing when to pick which one matters. First, you can run a saved script with python path/to/file.py; this is how almost all real programs are launched. Second, you can start the interactive interpreter (the REPL) by running python with no arguments and type statements one at a time; this is perfect for exploring a library or testing a single expression. Third, you can run short one-liners with python -c "print('hi')", which is handy inside shell scripts and CI pipelines.
Every script also has the option of being imported by another script. Python exposes a module-level variable called __name__ which equals the string "__main__" when the file is the top-level program and equals the module name when it has been imported. The classic if __name__ == "__main__": guard uses this to separate code that runs on import (defining functions and constants) from code that runs only when you execute the file directly (such as reading arguments and printing a result). Getting used to this pattern early is worth the tiny amount of extra structure it requires.
Running a program is also where you first meet tracebacks. A traceback is Python's error report: the deepest frame in the call stack is printed last, and each frame shows the file, line number and source line that was active. Learning to read a traceback bottom-up is the fastest bug-fixing skill to build. The last line is always the exception type and message; everything above it is the call chain that led there.
Finally, your first program is the moment to establish a few habits: save files with UTF-8 encoding, end them with a single trailing newline, use four spaces for indentation (never tabs), and name files in lowercase with underscores. These habits cost nothing to adopt on day one and prevent a long list of small frustrations later.
Saving, running, and the script entry-point
Create a file called hello.py in any folder, type print("Hello, PythonDeck") and save. From a terminal in the same folder, run python hello.py on Windows or python3 hello.py on macOS/Linux. The output appears on the next line and control returns to the shell. If Python prints SyntaxError, open the file in an editor and check for a missing quote or parenthesis on the line it reports.
As soon as a script grows past a handful of lines, wrap its top-level logic in a function (by convention called main) and guard the call with if __name__ == "__main__":. This keeps the file importable: other code can reuse its functions without running the main script by accident.
The REPL and debugging from the command line
Launch the REPL by running python with no arguments. The >>> prompt is Python waiting for one statement; the ... prompt means your statement is incomplete (usually inside a block). Type exit() or press Ctrl+Z then Enter (Windows) / Ctrl+D (macOS/Linux) to leave.
When a script raises an uncaught exception, the interpreter exits with a non-zero status code and prints a traceback. To drop into a debugger at the point of the failure, run python -m pdb hello.py. The pdb commands n (next), s (step), c (continue) and p expr (print) are enough to investigate most crashes without leaving the terminal.
These are the core tools used for Writing and Running Your First Python Program. The script itself only needs print(), but you will meet the rest within your first week.
| Tool | Purpose |
|---|---|
print()built-in | Writes text to standard output, followed by a newline. |
__name__module attribute | Equals "__main__" for the script launched by python. |
python -cshell flag | Executes a string of Python code and exits. |
python -mshell flag | Runs a module as a script (python -m pdb, -m venv, ...). |
pdbstandard-library module | Interactive debugger for stepping through Python code. |
sys.argvattribute | List of command-line arguments passed to the script. |
sys.exit()function | Ends the program with an optional status code. |
tracebackconcept | Error report printed bottom-up when an exception is uncaught. |
Writing and Running Your First Python Program code example
The script below is a properly structured first program: it defines one function, reads an argument safely, and uses the __main__ guard so it can be imported by future lessons.
# Lesson: Writing and Running Your First Python Program
# Save as hello.py and run: python hello.py -> uses the default name
# python hello.py PythonDeck -> uses an argument
import sys
def greet(name: str) -> str:
'''Return a friendly greeting for `name`. No side effects.'''
if not name:
raise ValueError("name must not be empty")
return f"Hello, {name}!"
def main(argv: list[str]) -> int:
'''Entry-point. Returns an exit status so pytest/CI can read it.'''
name = argv[1] if len(argv) > 1 else "world"
print(greet(name))
print(f"(ran on Python {sys.version_info.major}.{sys.version_info.minor})")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))
Read the script top-down before running it:
1) `greet()` has a single responsibility and can be imported and tested.
2) `main()` handles argument parsing; it never runs unless __name__ is "__main__".
3) `sys.exit(main(...))` returns an explicit status code to the shell.
4) Two prints give one line of result plus one line of diagnostic info.
Try both snippets to practice the run cycle without changing the main file.
# Example A: run a one-liner from the shell (no file needed)
# python -c "print(sum(range(1, 11)))"
# Expected output: 55
# Example B: import hello.py from another script and reuse greet()
# other.py (in the same folder):
# from hello import greet
# print(greet("importer"))
# Running "python other.py" prints "Hello, importer!" without re-running main()
Call greet() directly to confirm the pure function behaves as expected.
assert greet("Ada") == "Hello, Ada!"
assert greet("PythonDeck").endswith("!")
try:
greet("")
except ValueError:
pass
else:
raise AssertionError("empty name should raise ValueError")
Running python hello.py PythonDeck on Python 3.12 prints:
Hello, PythonDeck!
(ran on Python 3.12)