Learning Goals
3 minBy the end of this lesson you can:
- Read command-line arguments with
sys.argv. - Explain why
sys.argv[0]is the script name, not the first real argument. - Convert string arguments to the types you need (and handle when they're missing).
- Write a script someone can run as
python greet.py Aisha 3.
Warm-Up · You Already Use This
5 minEvery command you've typed in this course is a program plus arguments:
pip install requests → program "pip", args ["install", "requests"] git commit -m "fix bug" → program "git", args ["commit", "-m", "fix bug"] python tool.py data.csv → program "python", args ["tool.py", "data.csv"]
The shell splits your line into words and hands the list to the program. In Python, that list arrives as sys.argv. Reading it is the difference between a script that only works one way and a tool that works on any input the user names.
New Concept · sys.argv
14 minIt's just a list of strings
import sys print(sys.argv)
Run it as python show.py hello 42 file.txt and you get:
['show.py', 'hello', '42', 'file.txt']
sys.argv[0]is always the script name (hereshow.py).sys.argv[1]onward are the real arguments the user typed.- Everything is a string — even
42arrives as'42'.
Counting and slicing
import sys args = sys.argv[1:] # drop the script name print("you passed", len(args), "arguments") for i, value in enumerate(args, start=1): print(f" arg {i}: {value!r}")
Using sys.argv[1:] is the standard move: it gives you just the user's words, ignoring the script name.
Converting types
Because arguments are strings, you convert what you need:
import sys name = sys.argv[1] # already a string — fine times = int(sys.argv[2]) # convert "3" → 3 for _ in range(times): print(f"Hello, {name}!")
What if the argument is missing?
Reading sys.argv[1] when nothing was passed raises IndexError. A good tool checks first and prints a clear usage message:
import sys if len(sys.argv) < 3: print("Usage: python greet.py <name> <times>") sys.exit(1) # non-zero = "something went wrong" name = sys.argv[1] times = int(sys.argv[2]) print("\n".join(f"Hello, {name}!" for _ in range(times)))
sys.exit(1) stops the program and tells the shell it failed — important when other scripts run yours. sys.exit(0) means success.
sys.argv is perfect for one or two simple arguments. The moment you want --flags, help text, or optional values, switch to argparse (next lesson). Hand-parsing flags out of sys.argv gets ugly fast.
Worked Example · A Unit Converter
12 minGoal: python convert.py 100 km mi prints kilometres in miles. Let's build it piece by piece.
import sys RATES = { # how many of "to" in one "from" ("km", "mi"): 0.621371, ("mi", "km"): 1.609344, ("kg", "lb"): 2.204623, ("lb", "kg"): 0.453592, } if len(sys.argv) != 4: print("Usage: python convert.py <amount> <from> <to>") sys.exit(1) amount = float(sys.argv[1]) unit_from = sys.argv[2] unit_to = sys.argv[3] rate = RATES.get((unit_from, unit_to)) if rate is None: print(f"Don't know how to convert {unit_from} → {unit_to}") sys.exit(1) result = amount * rate print(f"{amount} {unit_from} = {result:.2f} {unit_to}")
Run it:
$ python convert.py 100 km mi 100.0 km = 62.14 mi $ python convert.py 5 kg lb 5.0 kg = 11.02 lb $ python convert.py 100 km lightyears Don't know how to convert km → lightyears
Read the code
Three defensive checks make this a real tool, not a demo: wrong argument count → usage message; bad number → float() raises a clear error; unknown units → friendly message instead of a crash. Each one exits non-zero so a calling script knows it failed. That care is the whole difference between "works on my machine" and "works."
Basic
5 minWrite echo.py that prints every argument the user passed, one per line, numbered. Running python echo.py a b c prints 1: a, 2: b, 3: c.
Challenge 1
4 minWrite add.py that adds up all the numbers passed as arguments and prints the total. python add.py 3 4 5 → 12. Convert each with float().
Hint
import sys numbers = [float(x) for x in sys.argv[1:]] print(sum(numbers))
Challenge 2
4 minExtend the greeter so times is optional — default to 1 if the user passes only a name. Print a usage message if no name is given at all. Test all three cases.
Hint
import sys if len(sys.argv) < 2: print("Usage: python greet.py <name> [times]") sys.exit(1) name = sys.argv[1] times = int(sys.argv[2]) if len(sys.argv) > 2 else 1 for _ in range(times): print(f"Hello, {name}!")
Challenge 3 · The Tiny Calculator
8 minBuild calc.py so that python calc.py 6 x 7 prints 42. Support +, -, x (multiply), and /. Handle divide-by-zero and unknown operators with clear messages, exiting non-zero on error.
Show a sample solution
import sys if len(sys.argv) != 4: print("Usage: python calc.py <a> <op> <b>") sys.exit(1) a, op, b = float(sys.argv[1]), sys.argv[2], float(sys.argv[3]) if op == "+": print(a + b) elif op == "-": print(a - b) elif op == "x": print(a * b) elif op == "/": if b == 0: print("Cannot divide by zero") sys.exit(1) print(a / b) else: print(f"Unknown operator: {op}") sys.exit(1)
Note we use x, not * — the shell would expand * into a file list before Python ever sees it.
Recap
3 minsys.argv is the list of words the shell hands your script: index 0 is the script name, 1 onward are the user's arguments, and everything is a string. Slice with sys.argv[1:], convert types with int()/float(), check the count before you index, and exit non-zero on errors so other tools know you failed. It's the foundation under every command-line tool — and the moment you need flags or help text, you'll reach for argparse next lesson.
Vocabulary Card
- argument
- A word typed after the program name that tells it what to do.
- sys.argv
- A list of strings: the script name plus all arguments.
- exit code
- A number a program returns: 0 means success, non-zero means an error.
- usage message
- A one-line hint showing how to call the tool correctly.
Extra Mission
4 minWrite wordcount.py that takes a filename as its only argument, opens the file, and prints how many lines, words, and characters it contains — like the Unix wc tool. Print a usage message if no filename is given, and a friendly error if the file doesn't exist.
Sample · wordcount.py
import sys if len(sys.argv) != 2: print("Usage: python wordcount.py <file>") sys.exit(1) path = sys.argv[1] try: text = open(path, encoding="utf-8").read() except FileNotFoundError: print(f"No such file: {path}") sys.exit(1) lines = text.splitlines() words = text.split() print(f"lines: {len(lines)}") print(f"words: {len(words)}") print(f"chars: {len(text)}")
Non-negotiables: argument-count check, a FileNotFoundError guard, and three correct counts.