Skip to content

Run and Test Your First Script

First PublishedLast UpdatedByAtif Alam

This page is for beginners who already installed uv on a Mac (Environment setup).

Every Python script you run is a small program that takes input (the keyboard in this walkthrough; files and APIs later), runs your code, and produces output (usually text in the terminal).

flowchart LR
  input["Input"]
  app["Python app main.py"]
  output["Output"]
  input --> app --> output

You will:

  1. Create a project folder.
  2. Write a few lines of Python and run them.
  3. Optionally check that Python is using your project’s isolated environment (a virtual environment, or venv — a private copy of Python and packages for this folder only).
  4. Read name and age from the keyboard with input().
  5. Check that name and age look valid before you use them.
  6. Try a quick assert self-check, then a simple automated test with pytest (a popular test tool).

Run each command in Terminal right after the step that shows it. You should see output similar to what each step describes.

What you will have at the end: a folder called hello_uv/ containing main.py, test_main.py, and a hidden-style .venv/ folder that holds your project’s Python.

You do not need to write any def functions in the app script. Later steps use input() and simple if checks; pytest test files use def only because that is how pytest finds tests.


Goal: Make a new folder and tell uv to set up Python for it.

Run these commands one at a time (or copy the block — && means “run the next command only if the previous one succeeded”):

Terminal window
mkdir hello_uv
cd hello_uv
uv init --python 3.12
uv venv

What each command does:

CommandWhat it does
mkdir hello_uvCreates a new folder named hello_uv.
cd hello_uvMoves you inside that folder.
uv init --python 3.12Creates main.py and pyproject.toml (a small config file for the project).
uv venvCreates .venv/ — your project’s private Python environment.

You should now see something like:

hello_uv/
pyproject.toml
.venv/
main.py

Goal: Put three lines of Python in main.py and run the file.

Open main.py in any text editor. Replace everything in the file with:

name = "world"
message = "Hello, " + name + "!"
print(message)

Line by line:

  • name = "world" — store the text "world" in a variable called name.
  • message = "Hello, " + name + "!" — build a new string and store it in message.
  • print(message) — show message in the terminal.

Run it from inside the hello_uv folder:

Terminal window
uv run python main.py

You should see:

Hello, world!

uv run runs Python using your project’s .venv — you do not need to run source .venv/bin/activate first.

If you get No such file or directory, make sure you ran cd hello_uv and that main.py is saved in that folder.


Step 3 — Optional: Check Which Python You Are Using

Section titled “Step 3 — Optional: Check Which Python You Are Using”

Goal: Confirm Python is coming from .venv, not macOS system Python.

This step is optional. Skip it if the script already printed Hello, world! and you want to keep moving.

Terminal window
uv run python -c "import sys; print(sys.executable)"

You should see a path that includes hello_uv and .venv. That means your project environment is in use.

Another way some tutorials use — turn the environment on manually, then turn it off:

Terminal window
source .venv/bin/activate
which python
python main.py
deactivate

After activate, your shell prompt may show (.venv). The which python path should end with hello_uv/.venv/bin/python.


Goal: Add an age variable and read both values from the keyboard when you run the script.

Update main.py to:

name = input("Your name: ")
age = input("Your age: ")
message = "Hello, " + name + "! You are " + age + " years old."
print(message)
LineWhat it does
input("...")Pauses and reads one line from the keyboard. Always returns a string, even for age.
message = ...Builds one string from name and age, then print shows it in the terminal.

Run it:

Terminal window
uv run python main.py

Type a name and age when prompted. Example session:

Your name: Ada
Your age: 25
Hello, Ada! You are 25 years old.

Step 5 — Basic Validation on name and age

Section titled “Step 5 — Basic Validation on name and age”

Goal: Print an error instead of the greeting when input does not look right.

Rules for this walkthrough:

  • Name: letters only — use isalpha() on the string (no spaces or digits in this simple check).
  • Age: digits only — use isdigit() before you use the value.

Both are string methods — functions you call on a str value with dot notation (name.isalpha()). The official Python docs list all of them under built-in string methods (isalnum(), isnumeric(), isspace(), and others).

Wrap the greeting in if / elif / else so you only build message when both checks pass:

name = input("Your name: ")
age = input("Your age: ")
if not name.isalpha():
print("Error: name must contain letters only.")
elif not age.isdigit():
print("Error: age must be a number.")
else:
message = "Hello, " + name + "! You are " + age + " years old."
print(message)

Plain English:

  • if not ... — if the name fails, print one error and skip the greeting.
  • elif — check age only when the name was OK.
  • else — both checks passed; safe to build message and print.

Try it:

  1. Valid input — Ada and 25 — you see the greeting.
  2. Invalid name — Ada3 — only Error: name must contain letters only.
  3. Invalid age — twenty — only Error: age must be a number.

input() has no “int mode” — every line you read is a str, even when it looks like a number ("25", not 25). That is why Step 5 checks age.isdigit() on the string first.

When you need to do math, convert after the check with int():

age = input("Your age: ")
if age.isdigit():
age_num = int(age) # now it's an int
print(age_num + 1) # 26

In the greeting script above, keeping age as a string in message is fine ("You are 25 years old."). Use int(age) only when you need numeric comparisons or arithmetic.

Check input as soon as it enters your program — the same idea as validating an API request before you use it deeper in the stack, kept tiny here.


Goal: Ask Python to verify your message was built correctly before printing it.

An assert line means: “stop with an error if this is not true.” Useful for a tiny script; later you will use a test file instead.

Add one line in the else branch, after you build message:

name = input("Your name: ")
age = input("Your age: ")
if not name.isalpha():
print("Error: name must contain letters only.")
elif not age.isdigit():
print("Error: age must be a number.")
else:
message = "Hello, " + name + "! You are " + age + " years old."
assert message == "Hello, " + name + "! You are " + age + " years old."
print(message)

Run it again (valid input at the prompt):

Terminal window
uv run python main.py

You should still see your greeting. To see AssertionError, change the right-hand side of the assert to a different string — that is the check catching a mismatch.


Goal: Run checks in a separate file so your main script stays simple.

pytest runs test functions in files whose names start with test_. Online tutorials often say pip install pytest; with uv you run:

Terminal window
uv add --dev pytest

The --dev flag means “only needed for development/testing,” not for running the app in production.

Wrap interactive code so pytest does not wait for input

Section titled “Wrap interactive code so pytest does not wait for input”

When pytest loads main.py, Python runs the whole file. If input() sits at the top level, tests would pause for keyboard input.

Add default values at the top and move the interactive part under if __name__ == "__main__":. Remove the assert from Step 6 — the test file will cover those checks.

name = "world"
age = "30"
message = "Hello, " + name + "! You are " + age + " years old."
if __name__ == "__main__":
name = input("Your name: ")
age = input("Your age: ")
if not name.isalpha():
print("Error: name must contain letters only.")
elif not age.isdigit():
print("Error: age must be a number.")
else:
message = "Hello, " + name + "! You are " + age + " years old."
print(message)

Plain English: if __name__ == "__main__": means “only run the indented lines when I execute this file directly (uv run python main.py), not when something else imports this file.” The defaults at the top are what pytest reads.

In the same folder as main.py, create a new file test_main.py:

from main import age, message, name
def test_message():
assert message == "Hello, world! You are 30 years old."
def test_name():
assert name == "world"
def test_age():
assert age == "30"
def test_validation_examples():
assert "Ada".isalpha()
assert not "Ada3".isalpha()
assert "25".isdigit()
assert not "twenty".isdigit()

What this means:

  • from main import age, message, name — read the default variables from main.py (pytest loads main.py without running the input() block).
  • def test_message():, def test_name():, and so on — pytest looks for functions whose names start with test_. You are not writing app logic here; this is pytest’s required shape. You will learn def properly in Language basics.
  • test_validation_examples — rehearses the same .isalpha() and .isdigit() checks from Step 5 using fixed strings (no keyboard input).

Run tests:

Terminal window
uv run pytest
uv run pytest -v

Expected:

4 passed

  • Language basics — variables, if / elif / else, loops, and later def functions.
  • Process log files — a longer stdlib script; save it as another .py file in the same project and run with uv run python process_logs.py.
  • Install another packageuv add package-name (see Translating pip commands to uv if a tutorial says pip install).
  • mkdir + uv init + uv venv — create a project with its own Python in .venv/.
  • uv run python main.py — run your script using that environment.
  • input() — read a line from the user as a string.
  • .isalpha() / .isdigit() — quick shape checks on strings.
  • if / elif / else — run the greeting only when validation passes.
  • assert — a one-line “this must be true” check; fine for learning, pytest scales better later.
  • if __name__ == "__main__": — run code only when the file is executed directly, not when imported by tests.
  • uv add --dev pytest then uv run pytest — finds test_*.py files and runs functions named test_....
TermPlain meaning
venv (.venv/)A private Python + packages folder for this project only.
uv runRun a command inside the project venv without activating it manually.
inputBuilt-in that reads one line from the keyboard and returns a string.
validationChecking that data looks right before you use it.
elif“Else if” — try the next condition only when the previous if was false.
pytestA tool that finds and runs test files.
importLoad code or variables from another file in the same project.