Python Starter Course — + Full Notes

Topics • 3 samples per topic • 2 Projects • ⭐ Appendix
Course Completion Document

, Python Explorers! 🎓🐍

You have successfully reached the end of the Python Starter Course. This page contains: introductions, explanations, importance, 3 code samples per topic, and full projects you can run in VS Code.

✅ Fundamentals 🧠 Logic + Debugging 🧩 Lists + Dicts 📁 File Save/Load 🏗️ StudentDB Capstone ⭐ Undo/Redo Appendix
“Every expert was once a beginner who didn’t quit.”

1) Introduction

This course took you from “I have never coded before” to “I can build working Python programs.” We focused on foundations: logic, clean code, and confident debugging.

Key message: You don’t need to memorize everything. You need to understand and practice.

2) Importance of Python

Python is popular because it is readable and powerful. These basics support automation, web, data science, AI, and interviews.

  • Automation: scripts, reports, file handling
  • Web: backend APIs and dashboards
  • Data Science & AI: analysis, ML, NLP
  • Testing/DevOps: scripting and tooling
“If you can think clearly, Python helps you build clearly.”

3) Topics Learned (Introduction • Explanation • Importance + 3 Code Samples each)

Each topic includes 3 small runnable samples. Use Copy or Download buttons for each.

✅ Topic 1: Python Basics
Introduction

Python runs code top-to-bottom and uses indentation to define blocks.

Explanation
  • Indentation matters: it forms code blocks.
  • Comments explain intent to humans.
  • Readability reduces bugs.
Importance

Clean basics make every future topic easier.

Sample 1 — Hello World + comments
python • t1_s1_hello.py
# This is a comment
print("Hello, Python Starter Course!")
Sample 2 — Indentation demo
python • t1_s2_indent.py
print("Start")
if True:
    print("Inside if block (indented)")
print("End")
Sample 3 — Variables + print
python • t1_s3_vars.py
course = "Python Starter"
batch = "7 PM"
print(course, "-", batch)
✅ Topic 2: Input, Print & f-strings
Introduction

Input makes programs interactive; output should be readable.

Explanation
  • input() returns a string.
  • print() displays values.
  • f"..." formats text using variables.
Importance

Every user-facing program uses clean I/O.

Sample 1 — Basic input + print
python • t2_s1_io.py
name = input("Enter your name: ")
print("Welcome,", name)
Sample 2 — f-string formatting
python • t2_s2_fstring.py
city = "Varanasi"
print(f"I love {city}!")
Sample 3 — converting input to number
python • t2_s3_convert.py
age = int(input("Enter age: "))
print(f"Next year you will be {age + 1}")
✅ Topic 3: Variables & Data Types
Introduction

Variables store values; data types define how Python treats those values.

Explanation
  • int, float, str, bool
  • Type conversion: int(), float(), str()
  • Inspect type: type()
Importance

Correct types prevent common bugs (like adding strings to numbers).

Sample 1 — type() demo
python • t3_s1_type.py
x = 10
y = 3.14
z = "hi"
print(type(x), type(y), type(z))
Sample 2 — bool + comparisons
python • t3_s2_bool.py
marks = 78
is_pass = marks >= 40
print(is_pass)
Sample 3 — conversion pitfalls
python • t3_s3_pitfall.py
a = "10"
b = "20"
print(a + b)      # string concatenation -> "1020"
print(int(a) + int(b))  # numeric addition -> 30
✅ Topic 4: Operators & Precedence (BODMAS)
Introduction

Operators let programs calculate, compare, and combine conditions.

Explanation
  • Arithmetic: + - * / % // **
  • Comparison: == != < > <= >=
  • Logical: and, or, not
  • Precedence affects results; parentheses make intention clear.
Importance

Correct math and correct conditions depend on precedence.

Sample 1 — arithmetic + // and %
python • t4_s1_arith.py
n = 17
print("q:", n // 5, "r:", n % 5)
Sample 2 — precedence demo
python • t4_s2_prec.py
print(2 + 3 * 4)      # 14
print((2 + 3) * 4)    # 20
Sample 3 — logical operators
python • t4_s3_logic.py
age = 20
has_id = True
print(age >= 18 and has_id)
✅ Topic 5: Conditional Statements (if/elif/else)
Introduction

Conditionals let programs choose different actions based on rules.

Explanation
  • if checks a condition
  • elif checks additional conditions
  • else catches everything else
Importance

Discounts, grading, eligibility, menus—everything uses conditionals.

Sample 1 — pass/fail
python • t5_s1_passfail.py
m = int(input("Marks: "))
if m >= 40:
    print("Pass")
else:
    print("Fail")
Sample 2 — elif ladder
python • t5_s2_elif.py
n = int(input("Number: "))
if n > 0:
    print("Positive")
elif n < 0:
    print("Negative")
else:
    print("Zero")
Sample 3 — ternary operator
python • t5_s3_ternary.py
age = int(input("Age: "))
msg = "Adult" if age >= 18 else "Minor"
print(msg)
✅ Topic 6: Loops (for/while) + break/continue
Introduction

Loops repeat tasks—essential for menus, patterns, searching, and validation.

Explanation
  • for loops over a range or collection
  • while loops until a condition becomes false
  • break stops; continue skips one iteration
Importance

Most “real” programs run in loops (menus and repeated operations).

Sample 1 — for with range()
python • t6_s1_for.py
for i in range(1, 6):
    print(i)
Sample 2 — while validation loop
python • t6_s2_while.py
while True:
    s = input("Type YES to continue: ").strip().upper()
    if s == "YES":
        break
    print("Try again!")
Sample 3 — continue example
python • t6_s3_continue.py
for n in range(1, 11):
    if n % 2 == 1:
        continue
    print("even:", n)
✅ Topic 7: Strings
Introduction

Strings handle names, IDs, messages, file content, and user input.

Explanation
  • Indexing/slicing for parts of text
  • Methods: strip(), lower(), replace(), split()
Importance

Text processing is everywhere: search, cleaning, formatting.

Sample 1 — strip + lower
python • t7_s1_strip_lower.py
s = "  HeLLo  "
print(s.strip().lower())
Sample 2 — slicing
python • t7_s2_slice.py
text = "Programmer's Picnic"
print(text[:10])
print(text[-5:])
Sample 3 — split and join
python • t7_s3_split_join.py
name = "A B C"
parts = name.split()
print(parts)
print("-".join(parts))
✅ Topic 8: Lists, Tuples, Dictionaries
Introduction

Data structures store multiple values and model real-world data.

Explanation
  • List: ordered, mutable
  • Tuple: ordered, immutable
  • Dict: key-value database-style structure
Importance

Projects become possible when you can store and organize data.

Sample 1 — list operations
python • t8_s1_list.py
nums = [10, 20, 30]
nums.append(40)
nums.remove(20)
print(nums)
Sample 2 — tuple unpacking
python • t8_s2_tuple.py
t = ("S101", "Aarav", 78)
sid, name, marks = t
print(sid, name, marks)
Sample 3 — dict as mini DB
python • t8_s3_dict.py
db = {}
db["S101"] = {"name": "Aarav", "age": 15}
print(db["S101"]["name"])
✅ Topic 9: Functions
Introduction

Functions make code reusable and projects manageable.

Explanation
  • Define with def
  • Parameters and return values
  • Organize projects into modules/functions
Importance

Functions are the difference between “scripts” and “software”.

Sample 1 — simple function
python • t9_s1_func.py
def greet(name):
    return f"Hello, {name}"

print(greet("Champak"))
Sample 2 — function with default
python • t9_s2_default.py
def power(a, b=2):
    return a ** b

print(power(5))
print(power(2, 3))
Sample 3 — small modular menu
python • t9_s3_menu.py
def show_menu():
    print("1) Hello  2) Exit")

while True:
    show_menu()
    c = input("Choice: ").strip()
    if c == "1":
        print("Hello!")
    elif c == "2":
        break
✅ Topic 10: Debugging & Errors
Introduction

Errors are normal. Debugging is how programmers improve programs.

Explanation
  • Syntax errors: code can’t run
  • Runtime errors: crashes during execution
  • Logical errors: wrong output
Importance

Debugging skill builds confidence and speed.

Sample 1 — try/except for safe input
python • t10_s1_try.py
try:
    n = int(input("Enter number: "))
    print(10 / n)
except ValueError:
    print("Not a number!")
except ZeroDivisionError:
    print("Cannot divide by zero!")
Sample 2 — print tracing
python • t10_s2_trace.py
total = 0
for i in range(1, 6):
    total += i
    print("i:", i, "total:", total)
Sample 3 — avoid KeyError with get()
python • t10_s3_get.py
db = {"S101": "Aarav"}
print(db.get("S999", "Not found"))
✅ Topic 11: File Handling (Save/Load)
Introduction

Files let programs store data after closing.

Explanation
  • Write text logs or data files
  • Use JSON for readable storage
  • Use Pickle for binary storage
Importance

Persistence turns scripts into real applications.

Sample 1 — write a text file
python • t11_s1_write.py
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("Python Starter Course\n")
print("Saved notes.txt")
Sample 2 — read a text file
python • t11_s2_read.py
with open("notes.txt", "r", encoding="utf-8") as f:
    print(f.read())
Sample 3 — save/load JSON
python • t11_s3_json.py
import json

data = {"course": "Python Starter", "batch": "7 PM"}
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded)
“Now you can read code, write code, and fix code — that’s real progress.”

4) Two Full Projects (Code + Explanations)

Complete runnable programs for VS Code.

Project 1 — Number Guess Game (Full Code)
Concepts used: random, loops, validation, counters, user feedback.
python • project_guess_game.py
import random

def read_int(prompt: str) -> int:
    while True:
        s = input(prompt).strip()
        if s.isdigit() or (s.startswith("-") and s[1:].isdigit()):
            return int(s)
        print("Please enter a valid integer.")

def play_guess_game():
    print("=== Number Guess Game ===")
    print("I am thinking of a number between 1 and 100.")

    secret = random.randint(1, 100)
    attempts = 0

    while True:
        guess = read_int("Your guess: ")
        attempts += 1

        if guess < secret:
            print("Too low! Try again.")
        elif guess > secret:
            print("Too high! Try again.")
        else:
            print(f"Correct! You guessed it in {attempts} attempts.")
            break

    print("Thanks for playing! 🎉")

if __name__ == "__main__":
    play_guess_game()
How it works
  • secret is chosen randomly (1–100).
  • while loop repeats until correct guess.
  • read_int() avoids crashes from wrong input.
  • attempts counts tries.
Project 2 — StudentDB (JSON Menu App) (Full Code)
Concepts used: dict data model, functions, CRUD, menu loop, search, update, delete, JSON save/load.
python • project_studentdb_json.py
import json
from typing import Dict, Any

DB_FILE = "studentdb.json"

def load_db() -> Dict[str, Dict[str, Any]]:
    try:
        with open(DB_FILE, "r", encoding="utf-8") as f:
            data = json.load(f)
        return data if isinstance(data, dict) else {}
    except FileNotFoundError:
        return {}
    except Exception:
        return {}

def save_db(db: Dict[str, Dict[str, Any]]) -> None:
    with open(DB_FILE, "w", encoding="utf-8") as f:
        json.dump(db, f, ensure_ascii=False, indent=2)

def read_nonempty(prompt: str) -> str:
    while True:
        s = input(prompt).strip()
        if s:
            return s
        print("Input cannot be empty.")

def read_int(prompt: str) -> int:
    while True:
        s = input(prompt).strip()
        if s.isdigit() or (s.startswith("-") and s[1:].isdigit()):
            return int(s)
        print("Please enter a valid integer.")

def add_student(db):
    sid = read_nonempty("Student ID: ")
    if sid in db:
        print("This ID already exists. Use Update instead.")
        return
    name = read_nonempty("Name: ")
    clazz = read_nonempty("Class/Section (e.g., 10-A): ")
    age = read_int("Age: ")
    db[sid] = {"id": sid, "name": name, "class": clazz, "age": age}
    print("✅ Student added.")

def list_students(db):
    if not db:
        print("No students found.")
        return
    print("\n--- All Students ---")
    print(f"{'ID':<10} {'Name':<22} {'Class':<10} {'Age':<5}")
    print("-" * 52)
    for sid, s in db.items():
        print(f"{sid:<10} {s.get('name',''):<22} {s.get('class',''):<10} {str(s.get('age','')):<5}")
    print("-" * 52)

def search_student(db):
    if not db:
        print("No students found.")
        return
    q = read_nonempty("Search by ID or Name: ").lower()
    found = []
    for sid, s in db.items():
        if q in sid.lower() or q in str(s.get("name", "")).lower():
            found.append(s)
    if not found:
        print("No matching student found.")
        return
    print("\n--- Search Results ---")
    for s in found:
        print(f"ID: {s.get('id')} | Name: {s.get('name')} | Class: {s.get('class')} | Age: {s.get('age')}")

def update_student(db):
    sid = read_nonempty("Enter ID to update: ")
    if sid not in db:
        print("Student not found.")
        return
    s = db[sid]
    print("Leave blank to keep current value.\n")
    name = input(f"Name ({s.get('name')}): ").strip()
    clazz = input(f"Class/Section ({s.get('class')}): ").strip()
    age_s = input(f"Age ({s.get('age')}): ").strip()

    if name: s["name"] = name
    if clazz: s["class"] = clazz
    if age_s:
        if age_s.isdigit() or (age_s.startswith("-") and age_s[1:].isdigit()):
            s["age"] = int(age_s)
        else:
            print("Invalid age. Keeping old value.")
    db[sid] = s
    print("✅ Student updated.")

def delete_student(db):
    sid = read_nonempty("Enter ID to delete: ")
    if sid not in db:
        print("Student not found.")
        return
    confirm = read_nonempty(f"Type YES to delete {sid}: ")
    if confirm.upper() == "YES":
        del db[sid]
        print("🗑️ Student deleted.")
    else:
        print("Delete cancelled.")

def menu():
    db = load_db()
    while True:
        print("\n=== StudentDB Menu ===")
        print("1) Add Student")
        print("2) List Students")
        print("3) Search Student")
        print("4) Update Student")
        print("5) Delete Student")
        print("6) Save & Exit")
        print("7) Exit without Saving")

        choice = read_nonempty("Choose (1-7): ")

        if choice == "1":
            add_student(db)
        elif choice == "2":
            list_students(db)
        elif choice == "3":
            search_student(db)
        elif choice == "4":
            update_student(db)
        elif choice == "5":
            delete_student(db)
        elif choice == "6":
            save_db(db)
            print(f"✅ Saved to {DB_FILE}. Goodbye!")
            break
        elif choice == "7":
            print("Goodbye!")
            break
        else:
            print("Invalid choice. Try again.")

if __name__ == "__main__":
    menu()
Project explanation
  • DB model: dictionary {student_id: record}
  • CRUD: Add, list/search, update, delete
  • Persistence: JSON keeps data after closing

5) Message

Thank you for your consistency, curiosity, and practice. You have completed the first major milestone of programming.

“You don’t have to be perfect. You just have to keep building.”

With pride and best wishes,
— Python Starter Course Team
Programmer’s Picnic 🧺🐍

⭐ Appendix Projects Advanced / Capstone

Advanced StudentDB versions featuring Undo/Redo and Save/Load.

Undo/Redo concept: Before every change, store a snapshot into Undo stack. Redo is cleared on new change. Undo restores previous snapshot; Redo restores next snapshot.
Appendix A — StudentDB (Pickle) with Undo/Redo
File: saves as studentdb.pkl (binary).
python • studentdb_pickle_undo_redo.py
import pickle
import os
import copy

FILE_NAME = "studentdb.pkl"

def load_db():
    if os.path.exists(FILE_NAME):
        try:
            with open(FILE_NAME, "rb") as f:
                db = pickle.load(f)
            return db if isinstance(db, dict) else {}
        except Exception:
            return {}
    return {}

def save_db(db):
    with open(FILE_NAME, "wb") as f:
        pickle.dump(db, f)

def input_int(prompt):
    while True:
        s = input(prompt).strip()
        if s.isdigit() or (s.startswith("-") and s[1:].isdigit()):
            return int(s)
        print("Please enter a valid number.")

def snapshot(db):
    return copy.deepcopy(db)

def push_undo(undo_stack, redo_stack, db):
    undo_stack.append(snapshot(db))
    redo_stack.clear()

def add_student(db, undo_stack, redo_stack):
    push_undo(undo_stack, redo_stack, db)
    roll = input_int("Enter roll: ")
    if roll in db:
        print("Roll already exists. Use update option.")
        return
    name = input("Enter name: ").strip()
    marks = input_int("Enter marks (0-100): ")
    db[roll] = {"roll": roll, "name": name, "marks": marks}
    print("Student added.")

def view_all(db):
    if not db:
        print("No records found.")
        return
    print("\n--- All Students ---")
    for roll in sorted(db.keys()):
        s = db[roll]
        print(f"Roll: {s['roll']} | Name: {s['name']} | Marks: {s['marks']}")

def update_student(db, undo_stack, redo_stack):
    roll = input_int("Enter roll to update: ")
    if roll not in db:
        print("Student not found.")
        return
    push_undo(undo_stack, redo_stack, db)
    s = db[roll]
    new_name = input(f"Name ({s['name']}): ").strip()
    new_marks = input(f"Marks ({s['marks']}): ").strip()
    if new_name:
        s["name"] = new_name
    if new_marks:
        if new_marks.isdigit() or (new_marks.startswith("-") and new_marks[1:].isdigit()):
            s["marks"] = int(new_marks)
        else:
            print("Invalid marks. Keeping old value.")
    db[roll] = s
    print("Student updated.")

def delete_student(db, undo_stack, redo_stack):
    roll = input_int("Enter roll to delete: ")
    if roll not in db:
        print("Student not found.")
        return
    push_undo(undo_stack, redo_stack, db)
    del db[roll]
    print("Student deleted.")

def do_undo(db, undo_stack, redo_stack):
    if not undo_stack:
        print("Nothing to undo.")
        return db
    redo_stack.append(snapshot(db))
    db = undo_stack.pop()
    print("Undo done.")
    return db

def do_redo(db, undo_stack, redo_stack):
    if not redo_stack:
        print("Nothing to redo.")
        return db
    undo_stack.append(snapshot(db))
    db = redo_stack.pop()
    print("Redo done.")
    return db

def main():
    db = load_db()
    undo_stack = []
    redo_stack = []
    print("StudentDB (Pickle) loaded. Records:", len(db))

    while True:
        print("""
=========================
   StudentDB (Pickle)
=========================
1. Add Student
2. View All Students
3. Update Student
4. Delete Student
5. Undo
6. Redo
7. Save
8. Save & Exit
9. Exit (No Save)
""")
        choice = input("Choose option: ").strip()

        if choice == "1":
            add_student(db, undo_stack, redo_stack)
        elif choice == "2":
            view_all(db)
        elif choice == "3":
            update_student(db, undo_stack, redo_stack)
        elif choice == "4":
            delete_student(db, undo_stack, redo_stack)
        elif choice == "5":
            db = do_undo(db, undo_stack, redo_stack)
        elif choice == "6":
            db = do_redo(db, undo_stack, redo_stack)
        elif choice == "7":
            save_db(db); print("Saved.")
        elif choice == "8":
            save_db(db); print("Saved. Bye!"); break
        elif choice == "9":
            print("Bye! (Not saved)"); break
        else:
            print("Invalid choice.")

if __name__ == "__main__":
    main()
Appendix B — StudentDB (JSON) with Undo/Redo
File: saves as studentdb.json (readable).
python • studentdb_json_undo_redo.py
import json
import os
import copy

FILE_NAME = "studentdb.json"

def load_db():
    if os.path.exists(FILE_NAME):
        try:
            with open(FILE_NAME, "r", encoding="utf-8") as f:
                db = json.load(f)
            return db if isinstance(db, dict) else {}
        except Exception:
            return {}
    return {}

def save_db(db):
    with open(FILE_NAME, "w", encoding="utf-8") as f:
        json.dump(db, f, indent=2, ensure_ascii=False)

def input_int(prompt):
    while True:
        s = input(prompt).strip()
        if s.isdigit() or (s.startswith("-") and s[1:].isdigit()):
            return int(s)
        print("Please enter a valid number.")

def snapshot(db):
    return copy.deepcopy(db)

def push_undo(undo_stack, redo_stack, db):
    undo_stack.append(snapshot(db))
    redo_stack.clear()

def add_student(db, undo_stack, redo_stack):
    push_undo(undo_stack, redo_stack, db)
    roll = input_int("Enter roll: ")
    key = str(roll)
    if key in db:
        print("Roll already exists. Use update option.")
        return
    name = input("Enter name: ").strip()
    marks = input_int("Enter marks (0-100): ")
    db[key] = {"roll": roll, "name": name, "marks": marks}
    print("Student added.")

def view_all(db):
    if not db:
        print("No records found.")
        return
    print("\n--- All Students ---")
    for k in sorted(db.keys(), key=lambda x: int(x)):
        s = db[k]
        print(f"Roll: {s['roll']} | Name: {s['name']} | Marks: {s['marks']}")

def update_student(db, undo_stack, redo_stack):
    roll = input_int("Enter roll to update: ")
    key = str(roll)
    if key not in db:
        print("Student not found.")
        return
    push_undo(undo_stack, redo_stack, db)
    s = db[key]
    new_name = input(f"Name ({s['name']}): ").strip()
    new_marks = input(f"Marks ({s['marks']}): ").strip()
    if new_name:
        s["name"] = new_name
    if new_marks:
        if new_marks.isdigit() or (new_marks.startswith("-") and new_marks[1:].isdigit()):
            s["marks"] = int(new_marks)
        else:
            print("Invalid marks. Keeping old value.")
    db[key] = s
    print("Student updated.")

def delete_student(db, undo_stack, redo_stack):
    roll = input_int("Enter roll to delete: ")
    key = str(roll)
    if key not in db:
        print("Student not found.")
        return
    push_undo(undo_stack, redo_stack, db)
    del db[key]
    print("Student deleted.")

def do_undo(db, undo_stack, redo_stack):
    if not undo_stack:
        print("Nothing to undo.")
        return db
    redo_stack.append(snapshot(db))
    db = undo_stack.pop()
    print("Undo done.")
    return db

def do_redo(db, undo_stack, redo_stack):
    if not redo_stack:
        print("Nothing to redo.")
        return db
    undo_stack.append(snapshot(db))
    db = redo_stack.pop()
    print("Redo done.")
    return db

def main():
    db = load_db()
    undo_stack = []
    redo_stack = []
    print("StudentDB (JSON) loaded. Records:", len(db))

    while True:
        print("""
=========================
    StudentDB (JSON)
=========================
1. Add Student
2. View All Students
3. Update Student
4. Delete Student
5. Undo
6. Redo
7. Save
8. Save & Exit
9. Exit (No Save)
""")
        choice = input("Choose option: ").strip()

        if choice == "1":
            add_student(db, undo_stack, redo_stack)
        elif choice == "2":
            view_all(db)
        elif choice == "3":
            update_student(db, undo_stack, redo_stack)
        elif choice == "4":
            delete_student(db, undo_stack, redo_stack)
        elif choice == "5":
            db = do_undo(db, undo_stack, redo_stack)
        elif choice == "6":
            db = do_redo(db, undo_stack, redo_stack)
        elif choice == "7":
            save_db(db); print("Saved.")
        elif choice == "8":
            save_db(db); print("Saved. Bye!"); break
        elif choice == "9":
            print("Bye! (Not saved)"); break
        else:
            print("Invalid choice.")

if __name__ == "__main__":
    main()