Python Automation Scripts for Beginners: 10 Scripts That Save Hours Every Week
What if you could eliminate two hours of repetitive computer tasks every single day? That is exactly what Python automation scripts for beginners can do.
Python is the most popular language for automation because of its readable syntax, massive library ecosystem, and ability to interact with files, emails, websites, and APIs with just a few lines of code. You do not need years of experience to start automating. If you can write a basic Python function, you can automate real tasks today.
This guide gives you 10 complete, ready-to-use automation scripts. Each one solves a real problem, includes full source code, and teaches you a different automation skill.
Why Python for Automation in 2026?
Python dominates the automation space for several clear reasons:
- Built-in standard library handles files, folders, emails, and system operations without installing anything
- Third-party packages like
requests,schedule, andopenpyxlextend capabilities infinitely - Cross-platform compatibility means scripts work on Windows, macOS, and Linux
- AI integration allows you to add intelligent decision-making to your automation workflows
Whether you want to automate your personal workflow or build automation tools for your job, these scripts give you the foundation.
Setting Up Your Automation Environment
Before writing any scripts, set up a clean project environment:
# Create a project directory
mkdir python_automation
cd python_automation
# Create a virtual environment (recommended)
python -m venv .venv
# Activate it
# macOS/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate
# Install common automation libraries
pip install requests schedule openpyxl python-dotenv Pillow PyPDF2
For a detailed guide on virtual environments, see our complete venv Python tutorial.
Script 1: Automatic File Organizer
Problem: Your Downloads folder is a chaotic mess of files.
Solution: A script that automatically sorts files into categorized subfolders.
"""
file_organizer.py - Automatically sort files by type into organized folders.
"""
import os
import shutil
from pathlib import Path
from datetime import datetime
# Configuration: Define file categories and their extensions
FILE_CATEGORIES = {
"Images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".ico"],
"Documents": [".pdf", ".doc", ".docx", ".txt", ".xlsx", ".xls", ".pptx", ".csv"],
"Videos": [".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv"],
"Audio": [".mp3", ".wav", ".flac", ".aac", ".ogg", ".wma"],
"Archives": [".zip", ".rar", ".7z", ".tar", ".gz", ".bz2"],
"Code": [".py", ".js", ".html", ".css", ".java", ".cpp", ".json", ".xml"],
"Installers": [".exe", ".msi", ".dmg", ".deb", ".rpm"],
}
def get_category(file_extension):
"""Determine which category a file belongs to based on its extension."""
for category, extensions in FILE_CATEGORIES.items():
if file_extension.lower() in extensions:
return category
return "Other"
def organize_folder(target_folder):
"""
Scan the target folder and move each file into a categorized subfolder.
Skips directories and hidden files.
"""
target_path = Path(target_folder)
if not target_path.exists():
print(f"Error: Folder '{target_folder}' does not exist.")
return
moved_count = 0
skipped_count = 0
print(f"\nOrganizing: {target_path}")
print("-" * 50)
for item in target_path.iterdir():
# Skip directories, hidden files, and this script itself
if item.is_dir() or item.name.startswith("."):
skipped_count += 1
continue
# Determine the category
category = get_category(item.suffix)
# Create the category subfolder if it does not exist
category_folder = target_path / category
category_folder.mkdir(exist_ok=True)
# Handle filename conflicts
destination = category_folder / item.name
if destination.exists():
stem = item.stem
suffix = item.suffix
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
destination = category_folder / f"{stem}_{timestamp}{suffix}"
# Move the file
shutil.move(str(item), str(destination))
print(f" Moved: {item.name} -> {category}/")
moved_count += 1
print(f"\nDone! Moved {moved_count} files. Skipped {skipped_count} items.")
if __name__ == "__main__":
# Default to Downloads folder - change this path as needed
downloads_folder = str(Path.home() / "Downloads")
organize_folder(downloads_folder)
How to use: Run it manually whenever your Downloads folder gets messy, or set it up as a scheduled task (see Script 10).
Script 2: Bulk File Renamer
Problem: You have 200 photos named “IMG_20260101_123456.jpg” and want them renamed to “vacation_001.jpg”, “vacation_002.jpg”, etc.
"""
bulk_renamer.py - Rename multiple files with a consistent naming pattern.
"""
import os
from pathlib import Path
def bulk_rename(folder, prefix, start_number=1, extension_filter=None):
"""
Rename all files in a folder with a sequential pattern.
Args:
folder: Path to the folder containing files
prefix: New name prefix (e.g., "vacation")
start_number: Starting number for the sequence
extension_filter: Only rename files with this extension (e.g., ".jpg")
"""
folder_path = Path(folder)
if not folder_path.exists():
print(f"Error: Folder '{folder}' not found.")
return
# Get and sort files
files = sorted(folder_path.iterdir())
if extension_filter:
files = [f for f in files if f.suffix.lower() == extension_filter.lower()]
else:
files = [f for f in files if f.is_file()]
if not files:
print("No matching files found.")
return
print(f"Renaming {len(files)} files with prefix '{prefix}'...\n")
# Determine zero-padding width based on total file count
padding = len(str(len(files) + start_number))
renamed_count = 0
for index, file_path in enumerate(files, start=start_number):
new_name = f"{prefix}_{str(index).zfill(padding)}{file_path.suffix}"
new_path = file_path.parent / new_name
file_path.rename(new_path)
print(f" {file_path.name} -> {new_name}")
renamed_count += 1
print(f"\nRenamed {renamed_count} files successfully.")
if __name__ == "__main__":
# Example usage
target = input("Enter folder path: ").strip()
name_prefix = input("Enter new name prefix: ").strip()
ext = input("Filter by extension (e.g., .jpg) or press Enter for all: ").strip()
bulk_rename(target, name_prefix, extension_filter=ext if ext else None)
Script 3: PDF Merger
Problem: You need to combine multiple PDF files into a single document.
"""
pdf_merger.py - Combine multiple PDF files into one document.
Requires: pip install PyPDF2
"""
from PyPDF2 import PdfMerger
from pathlib import Path
def merge_pdfs(folder, output_name="merged_output.pdf"):
"""Merge all PDF files in a folder into a single PDF."""
folder_path = Path(folder)
# Find all PDFs and sort them alphabetically
pdf_files = sorted(folder_path.glob("*.pdf"))
if not pdf_files:
print("No PDF files found in the specified folder.")
return
print(f"Found {len(pdf_files)} PDF files to merge:\n")
merger = PdfMerger()
for pdf in pdf_files:
print(f" Adding: {pdf.name}")
merger.append(str(pdf))
output_path = folder_path / output_name
merger.write(str(output_path))
merger.close()
print(f"\nMerged successfully into: {output_path}")
if __name__ == "__main__":
folder = input("Enter folder containing PDFs: ").strip()
merge_pdfs(folder)
Script 4: Image Resizer and Compressor
Problem: You need to resize 50 images for your website to reduce load times.
"""
image_resizer.py - Batch resize and compress images for web use.
Requires: pip install Pillow
"""
from PIL import Image
from pathlib import Path
def resize_images(input_folder, output_folder, max_width=1200, quality=85):
"""
Resize all images in a folder to a maximum width while maintaining aspect ratio.
Saves compressed versions to the output folder.
"""
input_path = Path(input_folder)
output_path = Path(output_folder)
output_path.mkdir(parents=True, exist_ok=True)
image_extensions = {".jpg", ".jpeg", ".png", ".webp", ".bmp"}
images = [f for f in input_path.iterdir() if f.suffix.lower() in image_extensions]
if not images:
print("No images found.")
return
print(f"Processing {len(images)} images (max width: {max_width}px, quality: {quality}%)...\n")
total_saved = 0
for img_path in images:
with Image.open(img_path) as img:
original_size = img_path.stat().st_size
# Calculate new dimensions maintaining aspect ratio
if img.width > max_width:
ratio = max_width / img.width
new_height = int(img.height * ratio)
img = img.resize((max_width, new_height), Image.LANCZOS)
# Save with compression
output_file = output_path / img_path.name
if img_path.suffix.lower() in {".jpg", ".jpeg"}:
img.save(output_file, "JPEG", quality=quality, optimize=True)
elif img_path.suffix.lower() == ".png":
img.save(output_file, "PNG", optimize=True)
else:
img.save(output_file, quality=quality)
new_size = output_file.stat().st_size
saved = original_size - new_size
total_saved += saved
print(f" {img_path.name}: {original_size//1024}KB -> {new_size//1024}KB (saved {saved//1024}KB)")
print(f"\nTotal space saved: {total_saved//1024}KB ({total_saved//1048576}MB)")
if __name__ == "__main__":
input_dir = input("Input folder: ").strip()
output_dir = input("Output folder: ").strip()
resize_images(input_dir, output_dir)
Script 5: CSV Report Generator
Problem: You have raw data in a CSV and need to generate a formatted summary report.
"""
csv_reporter.py - Generate summary reports from CSV data files.
"""
import csv
from pathlib import Path
from collections import Counter
from datetime import datetime
def generate_report(csv_file):
"""Read a CSV file and produce a summary report."""
file_path = Path(csv_file)
if not file_path.exists():
print(f"Error: File '{csv_file}' not found.")
return
with open(file_path, "r", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
rows = list(reader)
if not rows:
print("CSV file is empty.")
return
columns = list(rows[0].keys())
print(f"\n{'='*60}")
print(f" CSV REPORT: {file_path.name}")
print(f" Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
print(f"{'='*60}")
print(f"\n Total rows: {len(rows)}")
print(f" Columns: {', '.join(columns)}")
# Analyze each column
print(f"\n COLUMN ANALYSIS:")
print(f" {'-'*50}")
for col in columns:
values = [row[col] for row in rows if row[col].strip()]
unique_count = len(set(values))
empty_count = len(rows) - len(values)
print(f"\n [{col}]")
print(f" Unique values: {unique_count}")
print(f" Empty/missing: {empty_count}")
# Try numeric analysis
try:
numeric_values = [float(v) for v in values]
avg = sum(numeric_values) / len(numeric_values)
print(f" Min: {min(numeric_values)}, Max: {max(numeric_values)}, Avg: {avg:.2f}")
except ValueError:
# Non-numeric: show top 5 most common values
most_common = Counter(values).most_common(5)
print(f" Top values: {', '.join(f'{v}({c})' for v, c in most_common)}")
print(f"\n{'='*60}\n")
if __name__ == "__main__":
file = input("Enter CSV file path: ").strip()
generate_report(file)
Script 6: Automated Email Sender
Problem: You need to send personalized emails to a list of contacts.
"""
email_sender.py - Send personalized emails from a template.
Uses environment variables for credentials (never hardcode passwords).
"""
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_email(recipient, subject, body, sender_email, sender_password):
"""Send a single email using Gmail SMTP."""
msg = MIMEMultipart()
msg["From"] = sender_email
msg["To"] = recipient
msg["Subject"] = subject
msg.attach(MIMEText(body, "html"))
try:
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(sender_email, sender_password)
server.send_message(msg)
print(f" Sent to: {recipient}")
return True
except Exception as e:
print(f" Failed for {recipient}: {e}")
return False
def send_bulk_emails(contacts, subject_template, body_template):
"""
Send personalized emails to a list of contacts.
contacts: List of dicts with 'name' and 'email' keys
subject_template: Subject with {name} placeholder
body_template: HTML body with {name} placeholder
"""
# Load credentials from environment variables (NEVER hardcode these)
sender_email = os.environ.get("SENDER_EMAIL")
sender_password = os.environ.get("SENDER_APP_PASSWORD")
if not sender_email or not sender_password:
print("Error: Set SENDER_EMAIL and SENDER_APP_PASSWORD environment variables.")
print("For Gmail, use an App Password (not your regular password).")
return
print(f"\nSending {len(contacts)} emails...\n")
success_count = 0
for contact in contacts:
subject = subject_template.format(name=contact["name"])
body = body_template.format(name=contact["name"])
if send_email(contact["email"], subject, body, sender_email, sender_password):
success_count += 1
print(f"\nDone: {success_count}/{len(contacts)} emails sent successfully.")
if __name__ == "__main__":
# Example contacts list
contacts = [
{"name": "Alice", "email": "alice@example.com"},
{"name": "Bob", "email": "bob@example.com"},
]
subject = "Hello {name} - Quick Update"
body = """
<h2>Hi {name},</h2>
<p>This is an automated email sent from a Python script.</p>
<p>Best regards,<br>Your Python Automation</p>
"""
send_bulk_emails(contacts, subject, body)
Security note: Never put passwords in your code. Use environment variables or a .env file with python-dotenv.
Script 7: Website Uptime Monitor
Problem: You want to know immediately when your website goes down.
"""
uptime_monitor.py - Check if websites are responding and log downtime.
Requires: pip install requests
"""
import requests
import time
from datetime import datetime
from pathlib import Path
URLS_TO_MONITOR = [
"https://pythonforbegineers.com",
"https://google.com",
"https://github.com",
]
LOG_FILE = "uptime_log.txt"
CHECK_INTERVAL = 300 # seconds (5 minutes)
def check_url(url, timeout=10):
"""Check if a URL is responding. Returns (status_code, response_time) or (None, None) on failure."""
try:
start = time.time()
response = requests.get(url, timeout=timeout)
elapsed = time.time() - start
return response.status_code, round(elapsed, 2)
except requests.RequestException:
return None, None
def log_result(url, status, response_time):
"""Log the check result to a file."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if status:
entry = f"[{timestamp}] {url} - Status: {status} - Response: {response_time}s"
else:
entry = f"[{timestamp}] {url} - DOWN - No response"
with open(LOG_FILE, "a") as f:
f.write(entry + "\n")
print(entry)
def run_monitor():
"""Continuously monitor all URLs at the specified interval."""
print(f"Monitoring {len(URLS_TO_MONITOR)} URLs every {CHECK_INTERVAL} seconds...")
print(f"Logging to: {LOG_FILE}")
print("Press Ctrl+C to stop.\n")
try:
while True:
for url in URLS_TO_MONITOR:
status, response_time = check_url(url)
log_result(url, status, response_time)
print(f" Next check in {CHECK_INTERVAL} seconds...\n")
time.sleep(CHECK_INTERVAL)
except KeyboardInterrupt:
print("\nMonitoring stopped.")
if __name__ == "__main__":
run_monitor()
Script 8: Duplicate File Finder
Problem: Your hard drive is full but you suspect there are many duplicate files wasting space.
"""
duplicate_finder.py - Find and report duplicate files based on content hash.
"""
import hashlib
from pathlib import Path
from collections import defaultdict
def get_file_hash(file_path, chunk_size=8192):
"""Calculate MD5 hash of a file's contents."""
hasher = hashlib.md5()
with open(file_path, "rb") as f:
while chunk := f.read(chunk_size):
hasher.update(chunk)
return hasher.hexdigest()
def find_duplicates(folder, min_size_kb=1):
"""
Find duplicate files in a folder (recursive).
Returns groups of files with identical content.
"""
folder_path = Path(folder)
if not folder_path.exists():
print(f"Error: Folder '{folder}' not found.")
return {}
print(f"Scanning: {folder_path} (min size: {min_size_kb}KB)...\n")
# Group files by size first (fast pre-filter)
size_groups = defaultdict(list)
file_count = 0
for file_path in folder_path.rglob("*"):
if file_path.is_file() and file_path.stat().st_size >= min_size_kb * 1024:
size_groups[file_path.stat().st_size].append(file_path)
file_count += 1
print(f" Scanned {file_count} files.")
# Hash only files with matching sizes
hash_groups = defaultdict(list)
hashed_count = 0
for size, files in size_groups.items():
if len(files) > 1: # Only hash if multiple files share the same size
for file_path in files:
file_hash = get_file_hash(file_path)
hash_groups[file_hash].append(file_path)
hashed_count += 1
print(f" Hashed {hashed_count} potential duplicates.\n")
# Filter to only groups with actual duplicates
duplicates = {h: files for h, files in hash_groups.items() if len(files) > 1}
if not duplicates:
print("No duplicates found!")
return {}
# Report findings
total_wasted = 0
print(f" Found {len(duplicates)} groups of duplicate files:\n")
for group_num, (file_hash, files) in enumerate(duplicates.items(), 1):
file_size = files[0].stat().st_size
wasted = file_size * (len(files) - 1)
total_wasted += wasted
print(f" Group {group_num} ({file_size // 1024}KB each, {len(files)} copies):")
for f in files:
print(f" {f}")
print()
print(f" Total wasted space: {total_wasted // 1048576}MB")
return duplicates
if __name__ == "__main__":
target = input("Enter folder to scan: ").strip()
find_duplicates(target)
Script 9: Text File Search (grep Alternative)
Problem: You need to find a specific string across hundreds of code files in a project.
"""
text_search.py - Search for text patterns across files in a directory.
"""
from pathlib import Path
import re
def search_files(folder, pattern, extensions=None, case_sensitive=False):
"""
Search for a text pattern in all files within a folder.
Args:
folder: Directory to search
pattern: Text or regex pattern to find
extensions: List of file extensions to include (e.g., [".py", ".txt"])
case_sensitive: Whether the search is case-sensitive
"""
folder_path = Path(folder)
if not folder_path.exists():
print(f"Error: Folder '{folder}' not found.")
return
flags = 0 if case_sensitive else re.IGNORECASE
compiled_pattern = re.compile(pattern, flags)
total_matches = 0
files_with_matches = 0
print(f"\nSearching for: '{pattern}' in {folder_path}\n")
for file_path in folder_path.rglob("*"):
if not file_path.is_file():
continue
# Filter by extension if specified
if extensions and file_path.suffix.lower() not in extensions:
continue
# Skip binary files
try:
with open(file_path, "r", encoding="utf-8") as f:
lines = f.readlines()
except (UnicodeDecodeError, PermissionError):
continue
file_matches = []
for line_num, line in enumerate(lines, 1):
if compiled_pattern.search(line):
file_matches.append((line_num, line.strip()))
if file_matches:
files_with_matches += 1
total_matches += len(file_matches)
relative_path = file_path.relative_to(folder_path)
print(f" {relative_path}:")
for line_num, content in file_matches[:5]: # Show first 5 matches per file
print(f" Line {line_num}: {content[:100]}")
if len(file_matches) > 5:
print(f" ... and {len(file_matches) - 5} more matches")
print()
print(f"Results: {total_matches} matches in {files_with_matches} files.")
if __name__ == "__main__":
folder = input("Search in folder: ").strip()
pattern = input("Search pattern: ").strip()
ext_input = input("File extensions (comma-separated, or Enter for all): ").strip()
extensions = [e.strip() if e.startswith(".") else f".{e.strip()}"
for e in ext_input.split(",") if e.strip()] if ext_input else None
search_files(folder, pattern, extensions)
Script 10: Task Scheduler (Run Scripts Automatically)
Problem: You want scripts to run automatically at specific times without cron jobs.
"""
scheduler.py - Schedule Python scripts to run at specific times or intervals.
Requires: pip install schedule
"""
import schedule
import time
from datetime import datetime
def daily_backup():
"""Example task: could call your file organizer or any other script."""
print(f"[{datetime.now().strftime('%H:%M:%S')}] Running daily backup...")
# Import and call your other scripts here
# from file_organizer import organize_folder
# organize_folder("/path/to/downloads")
def hourly_check():
"""Example task: website monitoring or data sync."""
print(f"[{datetime.now().strftime('%H:%M:%S')}] Running hourly check...")
def weekly_report():
"""Example task: generate and email a weekly report."""
print(f"[{datetime.now().strftime('%H:%M:%S')}] Generating weekly report...")
# Schedule configuration
schedule.every().day.at("09:00").do(daily_backup)
schedule.every(1).hours.do(hourly_check)
schedule.every().monday.at("08:00").do(weekly_report)
if __name__ == "__main__":
print("Scheduler started. Press Ctrl+C to stop.")
print(f"Scheduled jobs: {len(schedule.get_jobs())}")
for job in schedule.get_jobs():
print(f" - {job}")
print()
try:
while True:
schedule.run_pending()
time.sleep(60) # Check every minute
except KeyboardInterrupt:
print("\nScheduler stopped.")
Combining Scripts: Building a Complete Automation System
The real power of Python automation scripts for beginners comes when you combine multiple scripts into a workflow. Here is an example that chains several scripts together:
"""
morning_routine.py - Run multiple automation tasks as a daily workflow.
"""
from file_organizer import organize_folder
from uptime_monitor import check_url, URLS_TO_MONITOR
from pathlib import Path
def morning_workflow():
"""Execute the complete morning automation routine."""
print("=" * 50)
print(" MORNING AUTOMATION ROUTINE")
print("=" * 50)
# Step 1: Organize downloads
print("\n[Step 1] Organizing Downloads folder...")
organize_folder(str(Path.home() / "Downloads"))
# Step 2: Check website status
print("\n[Step 2] Checking website status...")
for url in URLS_TO_MONITOR:
status, response_time = check_url(url)
if status == 200:
print(f" {url}: OK ({response_time}s)")
else:
print(f" {url}: PROBLEM (status: {status})")
# Step 3: Generate any pending reports
print("\n[Step 3] Checking for pending reports...")
print(" No pending reports today.")
print("\n" + "=" * 50)
print(" Morning routine complete!")
print("=" * 50)
if __name__ == "__main__":
morning_workflow()
FAQ
What is the easiest Python automation script for a complete beginner?
The file organizer (Script 1) is the easiest starting point. It only uses Python’s built-in os, shutil, and pathlib modules with no external dependencies. You can see immediate results in your own Downloads folder, which makes the learning process tangible.
Do I need to learn a framework to automate tasks with Python?
No. All 10 scripts in this guide use only Python’s standard library plus a few lightweight packages. You do not need Django, Flask, or any web framework for automation. The os, pathlib, shutil, smtplib, and csv modules handle 80% of automation tasks.
How do I run Python automation scripts on a schedule?
For simple scheduling within Python, use the schedule library (Script 10). For system-level scheduling, use cron on Linux/macOS (crontab -e) or Task Scheduler on Windows. For cloud-based scheduling, use services like GitHub Actions or AWS Lambda.
Can Python automate tasks in Microsoft Excel?
Yes. The openpyxl library reads, writes, and modifies Excel files (.xlsx) programmatically. You can automate report generation, data formatting, chart creation, and formula insertion without ever opening Excel.
Is it legal to automate web interactions with Python?
It depends on the website. Always check a site’s Terms of Service and robots.txt file before automating interactions. Automating your own accounts and workflows is generally fine. Scraping copyrighted content or bypassing authentication is not. See our Python web scraping tutorial for ethical scraping guidelines.
Next Steps
Start with Script 1 (File Organizer) today. Run it on your actual Downloads folder and watch the magic happen. Once you see the results, you will be motivated to implement the rest.
For more beginner project ideas that combine automation with other skills, check out:
– Python Project Ideas for Beginners 2026
– How to Build a Python Quiz App Step by Step
Last updated: July 2026