How to write scripts in Python

Your guide to writing Python scripts. Learn different methods, get useful tips, see real-world applications, and debug common errors.

How to write scripts in Python
Published on: 
Tue
Mar 10, 2026
Updated on: 
Wed
Apr 1, 2026
The Replit Team

Python scripts automate tasks and solve complex problems, a core skill for any developer. They offer a powerful way to execute code for everything from simple jobs to intricate workflows.

Here, you'll learn essential techniques and tips. We'll cover real-world applications and debugging advice to help you write effective and reliable Python scripts for your own projects.

Creating a simple script

# hello_world.py
print("Hello, World!")
print("This is my first Python script")--OUTPUT--Hello, World!
This is my first Python script

The hello_world.py file illustrates a script in its most basic form. It's simply a sequence of commands that the Python interpreter runs in order. Using the print() function provides immediate feedback by displaying text in the console, a crucial tool for tracking a script's execution and output.

The output shown below the code isn't just a result; it confirms the script's top-to-bottom execution flow. This sequential processing is the foundation upon which you'll build more complex logic and automation.

Essential scripting techniques

To move beyond simple sequential commands, you'll need to make scripts interactive, work with files, and organize your logic into reusable functions.

Using command-line arguments with sys.argv

import sys

script_name = sys.argv[0]
arguments = sys.argv[1:]
print(f"Script name: {script_name}")
print(f"Arguments: {arguments}")--OUTPUT--Script name: script.py
Arguments: ['arg1', 'arg2', 'arg3']

To make a script interactive, you can use sys.argv to process command-line arguments. It’s a list containing everything typed on the command line to run the script.

  • The first item, sys.argv[0], is always the script's name.
  • Everything after that is an argument you've passed. The code uses a slice, sys.argv[1:], to grab all of them.

This allows you to pass data into your script from the outside, making it far more dynamic and reusable for different tasks.

Reading and writing files

# Open a file for writing
with open("data.txt", "w") as file:
file.write("Line 1: Python scripting is fun\n")
file.write("Line 2: It's easy to work with files")

# Read the file contents
with open("data.txt", "r") as file:
content = file.read()
print(content)--OUTPUT--Line 1: Python scripting is fun
Line 2: It's easy to work with files

Working with files is a common scripting task. The with open() statement is the modern, reliable way to do it, as it automatically closes the file for you once you're done. This is crucial for preventing errors and data loss.

  • The "w" mode is for writing—it will create a file or overwrite an existing one.
  • The "r" mode is for reading data from a file.

Once a file is open, you can use methods like file.write() to save data or file.read() to load its contents into a string.

Using functions to organize your code

def greet(name):
return f"Hello, {name}!"

def calculate_square(number):
return number ** 2

name = "Alice"
number = 5
print(greet(name))
print(f"The square of {number} is {calculate_square(number)}")--OUTPUT--Hello, Alice!
The square of 5 is 25

Functions are key to keeping scripts organized. By defining a block of code with def, you create a reusable component that performs a specific task. The greet() and calculate_square() functions each encapsulate a single piece of logic, which they provide back using the return statement.

This approach makes your main script much cleaner and easier to understand. Instead of a long list of commands, you simply call the functions you need.

  • Reusability: You can call a function multiple times without rewriting its code.
  • Readability: The main script becomes a high-level summary of what's happening.

Advanced scripting approaches

With those essential techniques covered, you can now focus on making your scripts more robust, portable, and user-friendly for real-world deployment.

Creating executable scripts with shebang

#!/usr/bin/env python3

import os
import platform

print(f"Running on {platform.system()}")
print(f"Current working directory: {os.getcwd()}")
print(f"Python version: {platform.python_version()}")--OUTPUT--Running on Linux
Current working directory: /home/user/scripts
Python version: 3.9.5

The #!/usr/bin/env python3 line is a shebang. It's a special instruction for Unix-like systems that turns your file into an executable script. This allows you to run it directly from your terminal, making your script feel more like a native command-line application.

  • Instead of typing python3 your_script.py, you can simply run ./your_script.py after making the file executable.
  • Using env makes the script portable by automatically finding the python3 interpreter in the user's system path.

Implementing error handling and logging

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

try:
result = 10 / 0
except ZeroDivisionError as e:
logging.error(f"Error occurred: {e}")

logging.info("Script execution completed")--OUTPUT--2023-09-28 14:23:45,123 - ERROR - Error occurred: division by zero
2023-09-28 14:23:45,124 - INFO - Script execution completed

Robust scripts anticipate and handle failures gracefully. The try...except block is your safety net—it lets you run code that might fail and defines a fallback plan if an error occurs. Instead of crashing, your script catches the exception, like the ZeroDivisionError, and continues running.

Logging is a more powerful way to track script activity than using print().

  • It creates structured, timestamped messages for easier debugging.
  • You can use different levels, like logging.INFO for routine updates and logging.error for critical failures.

Using argparse for professional command-line interfaces

import argparse

parser = argparse.ArgumentParser(description="A sample script with arguments")
parser.add_argument("--name", default="World", help="Name to greet")
parser.add_argument("--repeat", type=int, default=1, help="Number of times to repeat")

args = parser.parse_args()
for _ in range(args.repeat):
print(f"Hello, {args.name}!")--OUTPUT--Hello, Alice!
Hello, Alice!
Hello, Alice!

While sys.argv is functional, argparse is the standard for building professional command-line interfaces. It’s a powerful module that automatically generates help messages and handles input validation. You define the arguments your script expects, and argparse does the heavy lifting.

  • The add_argument() method defines flags like --name and --repeat.
  • You can specify a type, like int for validation, and provide a default value if an argument isn't given.

Finally, parser.parse_args() reads the command line and returns an object with your arguments ready to use.

Move faster with Replit

Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. You don't need to worry about environment configuration or pip installs; you can just start building.

Instead of piecing together techniques like file handling and argument parsing yourself, you can use Agent 4 to build a complete application. Describe the tool you want to create, and Agent will take it from an idea to a working product.

  • A command-line utility that uses argparse to convert units, such as currency or measurements.
  • A log processor that reads raw text files, filters for ERROR level messages, and outputs a structured summary.
  • A batch file organizer that takes a folder path and a naming convention from sys.argv to rename dozens of files at once.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

As your scripts become more complex, you'll run into common issues like off-by-one errors, TypeError exceptions, and dictionary KeyError problems.

Fixing off-by-one errors in loops

An off-by-one error is a classic logic mistake where a loop runs one too many or one too few times. It often happens due to incorrect range boundaries, like with Python's range() function. The code below intends to print numbers 1 through 10.

for i in range(1, 10):
print(i, end=" ")

The problem is that Python's range() function stops before its second argument, so the loop only runs from 1 to 9. The corrected code below makes a simple change to fix this.

for i in range(1, 11):
print(i, end=" ")

The fix works by changing range(1, 10) to range(1, 11). Since Python's range() function stops just before its upper limit, the loop now correctly includes the number 10. You'll often run into this when dealing with list indices or setting loop boundaries. It’s a good habit to double-check your start and end values to ensure your loops run the exact number of times you intend.

Fixing TypeError when combining different data types

A TypeError is a common roadblock that appears when you try to mix incompatible data types, like adding a number to a string. Python is strict about this to prevent unexpected behavior, as operators like * work differently for numbers and strings.

The code below demonstrates this issue. It attempts to calculate a total cost by multiplying two values from the input() function, but it doesn't work as expected.

quantity = input("Enter quantity: ")
price = input("Enter price: ")

total = quantity * price
print(f"Total cost: {total}")

The input() function returns text, not numbers. Using the * operator on two strings causes repetition instead of mathematical multiplication, leading to unexpected output. The corrected code below shows how to handle this properly.

quantity = input("Enter quantity: ")
price = input("Enter price: ")

quantity = int(quantity)
price = float(price)

total = quantity * price
print(f"Total cost: {total}")

The fix is to explicitly convert the string values from input() into numbers. By wrapping the quantity in int() and the price in float(), you ensure Python treats them as numerical data. This allows the * operator to perform mathematical multiplication correctly. Always be mindful of data types when processing user input or reading from files, as the data is often text-based and requires conversion before you can perform calculations.

Handling KeyError exceptions in dictionaries

A KeyError is a common exception that occurs when you try to access a dictionary key that doesn't exist. It's a frequent problem when working with data that might be incomplete. The code below triggers this error by requesting a phone key.

user_data = {"name": "Alice", "email": "[email protected]"}

username = user_data["name"]
email = user_data["email"]
phone = user_data["phone"] # Will raise KeyError

print(f"User: {username}, Email: {email}, Phone: {phone}")

The script fails because it tries to access user_data["phone"] directly, assuming the key will always be present. When the key is missing, the program stops with a KeyError. The following code demonstrates a safer approach to this problem.

user_data = {"name": "Alice", "email": "[email protected]"}

username = user_data.get("name", "Unknown")
email = user_data.get("email", "No email provided")
phone = user_data.get("phone", "No phone provided")

print(f"User: {username}, Email: {email}, Phone: {phone}")

The fix uses the dictionary’s .get() method instead of direct key access. This method safely retrieves a value and lets you provide a default, like "No phone provided", if the key is missing. This prevents your script from crashing with a KeyError. You’ll want to use this approach whenever you're working with data where keys might not always be present, such as parsing JSON from an API or processing user-submitted forms.

Real-world applications

Now you can combine these techniques to build scripts that solve practical problems, from analyzing files to scraping web data.

Analyzing file types in a directory with os

You can use the os module to write a script that inventories a directory, counting each file by its extension to give you a summary of its contents.

import os

directory = "./documents"
extension_counts = {}
for filename in os.listdir(directory):
if os.path.isfile(os.path.join(directory, filename)):
ext = filename.split('.')[-1].lower()
extension_counts[ext] = extension_counts.get(ext, 0) + 1

for ext, count in extension_counts.items():
print(f"{ext}: {count} files")

This script systematically processes a directory's contents. It begins by looping through every item found by os.listdir(), and for each one, it uses os.path.isfile() to ignore subdirectories and focus only on files.

  • The file extension is isolated by splitting the filename string and taking the last part with split('.')[-1].
  • The .get() method is key for counting. It safely increments the tally for each extension, preventing a KeyError by defaulting to 0 for any new extension it finds.

Finally, it iterates through the completed dictionary to print the results.

Creating a simple web scraper with requests and re

Combining the requests module to fetch web content with the re module for pattern matching lets you create simple web scrapers to extract data from websites.

import requests
import re

url = "https://en.wikipedia.org/wiki/Python_(programming_language)"
response = requests.get(url)
versions = re.findall(r"Python (\d+\.\d+)", response.text)
unique_versions = set(versions)

print(f"Found {len(versions)} mentions of Python versions:")
for version in sorted(unique_versions):
print(f"- Python {version}")

This script fetches a Wikipedia page's HTML using requests.get(). It then uses re.findall() to search the page's text for a specific pattern: the word "Python" followed by a version number like 3.10. All matching version numbers are collected into a list.

  • To handle duplicates, the list is converted into a set(), which automatically keeps only unique values.
  • Finally, the script sorts these unique versions and prints them out, giving you a clean list of all Python versions mentioned on the page.

Get started with Replit

Now, turn these techniques into a real tool with Replit Agent. Describe what you want to build, like “a script that organizes files by extension” or “a tool to scrape email addresses from a URL.”

Replit Agent will write the code, test for errors, and help you deploy the final application, all from a single prompt. Start building with Replit.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.