初级程序员实战教程(六)

简介: 教程来源 https://wkmsa.cn/ 本系列实战项目涵盖通讯录系统(JSON文件版)、学生成绩管理系统(SQLite数据库版)及调试测试技术。项目结构清晰、代码简洁,含增删改查、模糊搜索、统计分析、CSV导出等功能,配套print/pdb/unittest/doctest等调试测试方法,适合Python初学者学习与扩展。

十二. 实战项目一:通讯录系统(文件版)

这是一个功能完整的命令行通讯录,支持增删改查、模糊搜索、JSON 持久化。

import json
import os

class Contact:
    def __init__(self, name, phone, email=""):
        self.name = name
        self.phone = phone
        self.email = email

    def to_dict(self):
        return {"name": self.name, "phone": self.phone, "email": self.email}

    @staticmethod
    def from_dict(data):
        return Contact(data["name"], data["phone"], data.get("email", ""))

    def __str__(self):
        return f"{self.name} | {self.phone} | {self.email}"

class AddressBook:
    def __init__(self, filename="contacts.json"):
        self.filename = filename
        self.contacts = []   # 存储 Contact 对象
        self.load()

    def load(self):
        if not os.path.exists(self.filename):
            return
        try:
            with open(self.filename, "r", encoding="utf-8") as f:
                data = json.load(f)
                self.contacts = [Contact.from_dict(item) for item in data]
            print(f"加载了 {len(self.contacts)} 个联系人")
        except Exception as e:
            print(f"加载失败: {e}")

    def save(self):
        with open(self.filename, "w", encoding="utf-8") as f:
            json.dump([c.to_dict() for c in self.contacts], f, ensure_ascii=False, indent=2)
        print("已保存")

    def add(self, name, phone, email=""):
        # 检查重复
        if any(c.name == name for c in self.contacts):
            print(f"联系人 {name} 已存在")
            return False
        self.contacts.append(Contact(name, phone, email))
        self.save()
        print(f"添加成功: {name}")
        return True

    def delete(self, name):
        for i, c in enumerate(self.contacts):
            if c.name == name:
                del self.contacts[i]
                self.save()
                print(f"已删除 {name}")
                return True
        print(f"未找到 {name}")
        return False

    def search(self, keyword):
        """支持模糊搜索(不区分大小写)"""
        keyword_lower = keyword.lower()
        results = [c for c in self.contacts if keyword_lower in c.name.lower() or keyword_lower in c.phone]
        if not results:
            print("无匹配结果")
        else:
            print(f"找到 {len(results)} 个联系人:")
            for c in results:
                print(c)
        return results

    def list_all(self):
        if not self.contacts:
            print("通讯录为空")
            return
        print("\n===== 通讯录 =====")
        for c in sorted(self.contacts, key=lambda x: x.name):
            print(c)
        print(f"共 {len(self.contacts)} 人\n")

def main():
    book = AddressBook()
    while True:
        print("\n1.添加 2.删除 3.搜索 4.显示全部 5.保存 0.退出")
        choice = input("请选择: ").strip()
        if choice == "1":
            name = input("姓名: ").strip()
            phone = input("电话: ").strip()
            email = input("邮箱(可选): ").strip()
            book.add(name, phone, email)
        elif choice == "2":
            name = input("要删除的姓名: ").strip()
            book.delete(name)
        elif choice == "3":
            kw = input("搜索关键字: ").strip()
            book.search(kw)
        elif choice == "4":
            book.list_all()
        elif choice == "5":
            book.save()
        elif choice == "0":
            book.save()
            print("再见")
            break
        else:
            print("无效选项")

if __name__ == "__main__":
    main()

项目亮点:

使用 JSON 持久化,人类可读。

面向对象分离 Contact 和 AddressBook 职责。

模糊搜索、重复检查、自动排序显示。

代码约 100 行,非常适合初学者阅读和扩展。

十三. 实战项目二:学生成绩管理系统

使用 SQLite 数据库替代文件存储,支持复杂查询、统计分析、成绩报表导出 CSV。
13.1 准备工作
SQLite 是 Python 内置数据库,无需安装。

import sqlite3
import csv
from datetime import datetime

class StudentDB:
    def __init__(self, db_name="students.db"):
        self.conn = sqlite3.connect(db_name)
        self.cursor = self.conn.cursor()
        self._create_table()

    def _create_table(self):
        self.cursor.execute("""
            CREATE TABLE IF NOT EXISTS students (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL UNIQUE,
                score REAL NOT NULL,
                class_name TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        self.conn.commit()

    def add_student(self, name, score, class_name=None):
        try:
            self.cursor.execute(
                "INSERT INTO students (name, score, class_name) VALUES (?, ?, ?)",
                (name, score, class_name)
            )
            self.conn.commit()
            print(f"添加成功: {name}")
            return True
        except sqlite3.IntegrityError:
            print(f"学生 {name} 已存在")
            return False

    def delete_student(self, name):
        self.cursor.execute("DELETE FROM students WHERE name = ?", (name,))
        self.conn.commit()
        if self.cursor.rowcount > 0:
            print(f"已删除 {name}")
        else:
            print(f"未找到 {name}")

    def update_score(self, name, new_score):
        self.cursor.execute("UPDATE students SET score = ? WHERE name = ?", (new_score, name))
        self.conn.commit()
        if self.cursor.rowcount > 0:
            print(f"{name} 成绩已更新为 {new_score}")
        else:
            print(f"未找到 {name}")

    def query(self, name):
        self.cursor.execute("SELECT * FROM students WHERE name = ?", (name,))
        row = self.cursor.fetchone()
        if row:
            print(f"ID: {row[0]}, 姓名: {row[1]}, 成绩: {row[2]}, 班级: {row[3]}, 创建时间: {row[4]}")
        else:
            print("未找到")

    def show_all(self, order_by="score DESC"):
        self.cursor.execute(f"SELECT name, score, class_name FROM students ORDER BY {order_by}")
        rows = self.cursor.fetchall()
        if not rows:
            print("暂无数据")
            return
        print("\n===== 学生成绩表 =====")
        print(f"{'姓名':<10} {'成绩':<8} {'班级':<10}")
        print("-" * 30)
        for name, score, cls in rows:
            print(f"{name:<10} {score:<8} {cls if cls else '':<10}")
        print(f"共 {len(rows)} 条记录\n")

    def statistics(self):
        self.cursor.execute("SELECT COUNT(*), AVG(score), MAX(score), MIN(score) FROM students")
        count, avg, max_score, min_score = self.cursor.fetchone()
        if count == 0:
            print("无数据")
            return
        print(f"学生人数: {count}")
        print(f"平均分: {avg:.2f}")
        print(f"最高分: {max_score}")
        print(f"最低分: {min_score}")

        # 查询最高分学生
        self.cursor.execute("SELECT name FROM students WHERE score = ?", (max_score,))
        top_students = [row[0] for row in self.cursor.fetchall()]
        print(f"最高分学生: {', '.join(top_students)}")

    def export_csv(self, filename="report.csv"):
        self.cursor.execute("SELECT name, score, class_name, created_at FROM students ORDER BY score DESC")
        with open(filename, "w", newline="", encoding="utf-8") as f:
            writer = csv.writer(f)
            writer.writerow(["姓名", "成绩", "班级", "创建时间"])
            writer.writerows(self.cursor.fetchall())
        print(f"报表已导出到 {filename}")

    def close(self):
        self.conn.close()

# 命令行交互部分与之前类似,此处省略,请自行扩展

十四. 调试与测试

14.1 使用 print 调试

def calculate(nums):
    print(f"[DEBUG] nums: {nums}")   # 打印变量
    total = sum(nums)
    print(f"[DEBUG] total: {total}")
    return total

14.2 使用 pdb 断点调试

import pdb

def buggy_function(x):
    pdb.set_trace()   # 程序在此暂停
    result = x / 0
    return result

常用命令:

n (next): 执行下一行

s (step): 进入函数内部

c (continue): 继续运行直到下一个断点

p 变量 (print): 打印变量值

q (quit): 退出

14.3 单元测试(unittest)

import unittest

def add(a, b):
    return a + b

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)
        self.assertEqual(add(-1, 1), 0)

    def test_add_negative(self):
        self.assertLess(add(-5, -2), 0)

if __name__ == "__main__":
    unittest.main()

14.4 doctest(文档测试)

def multiply(a, b):
    """
    返回两数乘积。
    >>> multiply(3, 4)
    12
    >>> multiply(-1, 5)
    -5
    """
    return a * b

if __name__ == "__main__":
    import doctest
    doctest.testmod()

来源:
https://aescc.cn/

相关文章
|
4月前
|
Linux 程序员 网络安全
初级程序员必备的十大技能之基础 Linux 命令(一)
教程来源 https://qcycj.cn/ 本文系统讲解程序员必备的Linux核心命令,涵盖文件操作、文本处理、权限管理、进程与网络工具等,结合原理、参数详解及实战案例,助你高效部署、排查与运维——无论用Windows还是macOS,Linux都是程序员不可或缺的“第二操作系统”。
|
3月前
|
JSON 程序员 开发工具
初级程序员实战教程(一)
教程来源 https://zlpow.cn/ 零基础Python入门教程,手把手教环境搭建、语法详解与实战开发。含300+行可运行代码及详细注释,涵盖变量、函数、OOP、调试测试、Git等核心内容,并完成通讯录与学生成绩系统两大项目。
|
3月前
|
程序员 Python
初级程序员实战教程(二)
教程来源 bncne.cn 本节详解Python核心运算符:算术(含//、%特殊规则)、比较(支持字符串字典序)、逻辑(含短路特性)、赋值(含海象运算符:=)及位运算;并涵盖输入输出与多种格式化打印方式,内容系统实用,适合零基础到进阶学习。
|
3月前
|
存储 缓存 Java
程序员必备的十大技能(进阶版)之底层计算机原理(二)
教程来源 http://bncne.cn/ 本文详解计算机内存层次结构与指令集原理:从寄存器到硬盘的存储金字塔,剖析缓存行、伪共享、内存一致性模型及屏障机制;涵盖x86-64汇编基础、C/Java代码映射、JNI内联汇编调用,助力高性能编程优化。
|
4月前
|
程序员 Shell 持续交付
初级程序员必备的十大技能之开发工具熟练使用(二)
教程来源 https://zlpow.cn/ 命令行是程序员高效开发的“第二语言”:涵盖文件操作、进程管理、网络诊断、管道重定向、Shell脚本及终端增强工具,助你快速定位问题、批量处理任务、自动化部署,全面提升系统操控力与生产力。
|
3月前
|
JSON 程序员 数据格式
初级程序员实战教程(五)
教程来源 https://vrhyh.cn/ 本教程涵盖Python核心进阶主题:文件读写(文本/CVS/JSON)、异常处理(捕获、抛出、断言)、面向对象编程(类、属性装饰器、类/静态方法、继承、魔术方法),代码简洁规范,适合巩固实战能力。
|
3月前
|
存储 程序员 Shell
初级程序员实战教程(七)
教程来源 https://ltglu.cn/ 版本控制是程序员必备技能,Git作为主流分布式系统,支持代码备份、协同开发、分支管理与审计追踪。本节涵盖安装配置、三大区域(工作区/暂存区/仓库)、提交/回退/分支/远程协作等90%日常场景,附大量实战命令。
|
3月前
|
程序员 Python
初级程序员实战教程(三)
教程来源 https://tmywi.cn/ 本节详解Python流程控制与核心数据结构:条件语句(if/elif/else、三元表达式)、循环(while/for、break/continue/else)及常见陷阱;深入讲解列表、元组、字典、集合和字符串的创建、操作、遍历与高级用法(推导式、切片、字典合并等),实用性强。
|
3月前
|
程序员 Python
初级程序员实战教程(四)
教程来源 https://oplhc.cn/ 本节详解Python函数与模块化编程:涵盖函数定义/调用、六类参数(位置、关键字、默认、*args、**kwargs及组合)、返回值与LEGB作用域规则、lambda匿名函数、递归原理及装饰器入门;并系统介绍模块导入、`if __name__ == &quot;__main__&quot;`机制、包结构与第三方库管理。
|
3月前
|
安全 Java 程序员
程序员必备的十大技能(进阶版)之网络与高并发原理(三)
教程来源 https://zlpow.cn/ Java并发编程深度剖析涵盖JMM内存模型、volatile内存屏障、synchronized锁升级优化、AQS源码机制、线程池调优及伪共享问题,系统揭示多线程安全与高性能底层原理。