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."
Try It Yourself
13 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.
Write 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))
Extend 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}!")
Mini-Challenge · 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.
Homework
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.