12 周课程 / 第 1 周 10 分钟阅读

第 1 周:程序、变量与条件

本周从第一条可运行语句开始。目标不是背语法,而是能预测程序按什么顺序执行、每一步数据怎样变化,以及条件为什么进入某个分支。

建议用时:8-10 小时。

本周目标#

学完本周,你应该能够:

  • 按从上到下的顺序解释一段简单程序。
  • 创建变量,判断常见数据类型,并完成必要的类型转换。
  • 正确使用算术、比较、逻辑和赋值运算符。
  • 使用 f-string、format() 和 % 三种方式格式化输出。
  • 使用 if、elif、else 完成多分支判断。
  • 阅读并区分缩进、名称、类型和值错误。
  • 独立完成成绩等级、温度换算和三角形判断。

1.1 程序是什么#

Python 程序由一条条语句组成。程序通常从上到下执行,遇到条件语句时只进入符合条件的分支。

print("开始")
score = 86
print("分数是", score)
print("结束")

运行结果是:

开始
分数是 86
结束

三条最基本的规则#

  1. Python 区分大小写,Score、score 和 SCORE 是三个不同名称。
  2. 普通语句要独占一行,行首空格决定它属于哪个代码块。
  3. # 后面的内容是注释,不会影响程序结果。
# 计算总价
price = 12.5
count = 3
total = price * count
print(total)  # 37.5

注释适合说明原因。不要把每一行代码机械地翻译成中文。

执行顺序要和纸面推演一致#

阅读代码时,不要一眼看完整段后猜结果。准备一张表,逐行记录变量当前值:

执行到 price count total 屏幕输出
第 2 行后 12.5 未定义 未定义 无
第 3 行后 12.5 3 未定义 无
第 4 行后 12.5 3 37.5 无
第 5 行后 12.5 3 37.5 37.5

这种“变量跟踪表”是后续推演循环、排序和函数调用的基础。

1.2 变量、值与类型#

变量可以理解成“名字指向一个值”。赋值语句不是数学等式。

x = 5
x = x + 1
print(x)  # 6

第二行的含义是:先计算右边的 x + 1,得到 6,再让左边的名称 x 指向 6。

同一个变量可以先后指向不同类型的值:

value = 10
print(type(value).__name__)  # int

value = "10"
print(type(value).__name__)  # str

常见基本类型#

类型 含义 例子 type(x).__name__
int 整数 7、-3、0 int
float 浮点数 3.14、2.0、1e3 float
str 字符串 "Python"、""、'7' str
bool 布尔值 True、False bool
NoneType 表示“没有值” None NoneType

判断类型可以用:

age = 16
height = 1.68
name = "小林"
passed = True

print(type(age).__name__)       # int
print(type(height).__name__)    # float
print(type(name).__name__)      # str
print(type(passed).__name__)    # bool
print(type(None).__name__)      # NoneType

id 是什么#

id(x) 返回对象在当前运行中的身份标识。它主要用来说明两个名称是否指向同一个对象,不等同于比较值。

a = [1, 2]
b = a
c = [1, 2]

print(a == b)  # True,内容相同
print(a == c)  # True,内容相同
print(a is b)  # True,指向同一对象
print(a is c)  # False,分别是两个列表

不要用 id 判断两个值是否相等。比较内容使用 ==;判断是否为同一个对象使用 is。考试中若要求输出 id,通常只考“两个名称是否指向同一对象”或“是否重新创建对象”。

变量命名#

Python 常用命名风格:

  • 普通变量和函数使用小写下划线:student_name、calculate_total。
  • 类名使用大驼峰:Student、BookRecord。
  • 常量使用全大写:MAX_SCORE。

比赛中如果题目已经给出 findMax、searchAll 这样的驼峰名称,要保留题目名称。平时优先使用符合 Python 习惯的 snake_case,同一份程序内不要频繁混用风格。

名称应当表达含义:

# 较好
math_score = 88

# 不推荐
a = 88

1.3 输入、转换与输出#

input() 会读取一行文字,返回值永远是字符串。

name = input("请输入姓名:")
print("你好," + name)

如果需要计算,必须先转换类型:

age_text = input("请输入年龄:")
age = int(age_text)

print(age + 1)

直接写 age_text + 1 会产生 TypeError,因为字符串和整数不能相加。

常用转换#

print(int("25"))       # 25
print(int(3.9))        # 3,向零截断
print(float("2.5"))    # 2.5
print(str(100))        # "100"
print(bool(0))         # False
print(bool(1))         # True
print(bool(""))        # False
print(bool("0"))       # True,非空字符串

int("3.5") 会报 ValueError,因为字符串本身不是整数格式。先把 "3.5" 转成 float,再视需求转成 int。

三种格式化输出#

题目常要求固定文字和变量一起输出。下面三种方式都要认识。

方式一:f-string#

name = "李雨"
score = 91
print(f"{name}的成绩是{score}分")

结果:

李雨的成绩是91分

保留两位小数:

rate = 0.875
print(f"{rate:.2f}")  # 0.88

方式二:format()#

name = "李雨"
score = 91
print("{}的成绩是{}分".format(name, score))
print("{0}得到{1:.1f}分".format(name, score))

方式三:百分号格式#

print("%s的成绩是%d分" % ("李雨", 91))
print("%.2f" % 0.875)  # 0.88
print("2026", "10", "26", sep="-")  # 2026-10-26
print("第一行", end=" ")
print("第二行")

结果:

2026-10-26
第一行 第二行

sep 控制多个参数之间的分隔符,end 控制输出结尾。没有指定时,sep 是空格,end 是换行。

1.4 运算符#

算术运算符#

运算符 含义 例子 结果
+ 加或拼接 7 + 2 9
- 减 7 - 2 5
* 乘或重复 7 * 2 14
/ 除法 7 / 2 3.5
// 整除 7 // 2 3
% 取余数 7 % 2 1
** 幂 3 ** 2 9

注意:/ 的结果总是浮点数,即使正好除尽:

print(8 / 2)       # 4.0
print(type(8 / 2).__name__)  # float

整数和浮点数混合运算,结果通常是浮点数:

print(5 + 2.0)     # 7.0

字符串使用 + 表示拼接,使用 * 表示重复:

print("Py" + "thon")  # Python
print("ab" * 3)       # ababab

运算优先级#

常见顺序是:

  1. 括号。
  2. 幂 **。
  3. 正负号。
  4. 乘、除、整除、取余。
  5. 加、减。
  6. 比较运算。
  7. not。
  8. and。
  9. or。

不确定时加括号。括号不会扣分,错误优先级会改变结果。

print(2 + 3 * 4)     # 14
print((2 + 3) * 4)   # 20
print(2 ** 3 ** 2)   # 512,幂从右向左结合

赋值运算符#

x = 10
x += 3       # 等价于 x = x + 3
x -= 2
x *= 4
x //= 2
print(x)     # 22

手推时每次只改一个值:

语句后 x
x = 10 10
x += 3 13
x -= 2 11
x *= 4 44
x //= 2 22

常见算术错误#

# print(5 / 0)       # ZeroDivisionError
# print("5" + 2)     # TypeError
# print(int("2.5"))  # ValueError

1.5 布尔值与条件#

条件表达式的结果是 True 或 False。

比较运算符#

运算符 含义
== 等于
!= 不等于
> 大于
< 小于
>= 大于或等于
<= 小于或等于

= 是赋值,== 是比较。这是最容易混淆的两个符号。

逻辑运算符#

  • and:两边都为真,结果才为真。
  • or:至少一边为真,结果就为真。
  • not:取反。
score = 82
attendance = 0.95

print(score >= 60 and attendance >= 0.8)  # True
print(score >= 90 or attendance >= 0.9)   # True
print(not score >= 90)                    # True

Python 会进行短路判断:and 左边为假时,不再计算右边;or 左边为真时,不再计算右边。基础题先按普通逻辑理解,遇到函数调用或异常时才需要关注短路。

if、elif、else#

score = 86

if score >= 90:
    level = "优秀"
elif score >= 80:
    level = "良好"
elif score >= 60:
    level = "及格"
else:
    level = "不及格"

print(level)  # 良好

执行规则:

  1. 从上往下检查条件。
  2. 进入第一个为真的分支。
  3. 该分支执行完后,跳过同组后面的分支。
  4. 如果所有 if/elif 都为假,才进入 else。

因此上面的 score >= 80 不需要再写 score < 90,因为程序能到这里就说明前面的 score >= 90 已经不成立。

缩进不是装饰#

if score >= 60:
    print("及格")
    print("可以进入下一阶段")
print("程序结束")

前三行中的两个 print 属于条件分支;最后一个 print 在分支外,无论条件真假都会执行。

嵌套条件#

is_member = True
amount = 120

if is_member:
    if amount >= 100:
        print("会员满减 20 元")
    else:
        print("会员未满 100 元")
else:
    print("非会员")

嵌套层数最好不要超过两三层。能用 and 写清的条件,优先组合起来。

1.6 读懂报错与独立调试#

报错不是失败信号,而是定位线索。先读最后一行异常类型,再往上看文件名、行号和出错语句。

报错 常见含义 第一检查点
SyntaxError 语法不完整 冒号、括号、引号是否配对
IndentationError 缩进不一致 是否统一使用 4 个空格
NameError 使用了未定义名称 拼写、大小写、赋值顺序
TypeError 类型不支持该操作 是否把字符串当数字
ValueError 类型正确但内容无法转换 int() 中是否不是整数
ZeroDivisionError 除以零 除数是否可能为 0

例如:

age_text = "16"
print(age_text + 1)

会产生 TypeError。修复方式是 int(age_text) + 1。

三段式排错法#

  1. 确定位置:报错指向哪一行?
  2. 确定值:这一行用到的每个变量现在是什么类型、什么值?
  3. 最小修改:只改一处,再运行,观察是否解决。

可以在关键语句前打印中间值:

score = 78
bonus = 5
final_score = score + bonus
print("调试:final_score =", final_score)

调试完成后删除临时输出,避免最终答案多出不该有的内容。

如果使用带断点的编辑器,可以在目标行暂停程序,再逐行执行,观察变量面板。断点的作用是让程序停下来检查状态,不是自动修复错误。

1.7 本周作品一:成绩等级#

需求#

输入一个整数成绩:

  • 90-100:优秀。
  • 80-89:良好。
  • 60-79:及格。
  • 0-59:不及格。
  • 其他成绩:输出“成绩无效”。

拆步骤#

  1. 读取成绩。
  2. 转换为整数。
  3. 先判断成绩是否在 0-100。
  4. 再按从高到低的顺序判断等级。
  5. 输出结果。

参考程序#

score_text = input("请输入成绩:")
score = int(score_text)

if score < 0 or score > 100:
    print("成绩无效")
elif score >= 90:
    print("优秀")
elif score >= 80:
    print("良好")
elif score >= 60:
    print("及格")
else:
    print("不及格")

必测数据#

输入 期望输出 测试重点
100 优秀 上边界
90 优秀 等级边界
89 良好 等级边界下方
60 及格 及格边界
59 不及格 不及格边界上方
0 不及格 下边界
-1 成绩无效 非法输入
101 成绩无效 非法输入

1.8 本周作品二:温度换算#

摄氏度和华氏度的换算关系:

华氏度 = 摄氏度 * 9 / 5 + 32
摄氏度 = (华氏度 - 32) * 5 / 9

下面的程序把摄氏度转换为华氏度,保留一位小数:

celsius = float(input("请输入摄氏度:"))
fahrenheit = celsius * 9 / 5 + 32
print(f"{celsius:.1f} 摄氏度 = {fahrenheit:.1f} 华氏度")

输入 25 时,输出是:

25.0 摄氏度 = 77.0 华氏度

注意:如果题目指定输出格式,就严格按题目中的空格、冒号、单位和换行输出。

1.9 本周作品三:三角形判断#

三条边能组成三角形的条件是:

  • 三条边都大于 0。
  • 任意两边之和大于第三边。
a = float(input("请输入第一条边:"))
b = float(input("请输入第二条边:"))
c = float(input("请输入第三条边:"))

if a <= 0 or b <= 0 or c <= 0:
    print("边长必须大于 0")
elif a + b > c and a + c > b and b + c > a:
    print("可以组成三角形")
else:
    print("不能组成三角形")

测试数据:

a b c 期望
3 4 5 可以组成三角形
1 1 1 可以组成三角形
1 2 3 不能组成三角形
0 4 5 边长必须大于 0

进一步变式:判断等边、等腰、普通三角形时,先确保能组成三角形,再判断边的关系。浮点数不要随手用 == 比较,正式题如果都是整数,可以保留整数输入。

1.10 独立练习#

先关闭答案,在纸上推演,再运行验证。

A. 快速判断题#

  1. type(int("12") + 3.0).__name__ 是什么?

  2. x = 5; x //= 2; x **= 2 后,x 是多少?

  3. "7" + "3" 与 "7" * 3 分别是什么?

  4. bool("0") 是 True 还是 False?

  5. 判断成绩是否合法,应该写 0 <= score <= 100 吗?

  6. score = 85 时,下面的程序输出什么?

    if score >= 60:
        print("及格")
    if score >= 80:
        print("良好")
    

B. 编程题#

  1. 输入两个整数,输出它们的和、差、积、商和余数。
  2. 输入一个整数,判断它是奇数还是偶数。
  3. 输入三个整数,输出最大值。要求不使用 max()。
  4. 输入用户年龄,判断是否满足 12 <= age <= 18。
  5. 输入年月,按“2026 年 10 月”的格式输出。
  6. 输入一个三位整数,分别输出百位、十位和个位数字。
  7. 输入三个边长,输出是否能组成三角形。

1.11 练习答案与解释#

A. 快速判断题答案#

  1. float。int("12") 得到 12,整数与浮点数相加得到 15.0。

  2. 4。5 // 2 是 2,随后 2 ** 2 是 4。

  3. 分别是 "73" 和 "777"。两个字符串使用 + 表示拼接,使用 * 表示重复。

  4. True。字符串 "0" 不为空,所以它的布尔值为真。

  5. 可以。这是 Python 允许的连续比较,等价于 0 <= score and score <= 100。

  6. 输出两行:

    及格
    良好
    

    这是两个独立的 if,不是 if/elif,所以两个分支都可能执行。

B. 编程题参考答案#

  1. 基本运算:

    a = int(input())
    b = int(input())
    print(a + b)
    print(a - b)
    print(a * b)
    print(a / b)
    print(a % b)
    

    除数 b 不能为 0。正式题如果可能出现 0,需要先判断再计算。

  2. 奇偶判断:

    number = int(input())
    if number % 2 == 0:
        print("偶数")
    else:
        print("奇数")
    
  3. 三个数最大值:

    a = int(input())
    b = int(input())
    c = int(input())
    
    if a >= b and a >= c:
        maximum = a
    elif b >= a and b >= c:
        maximum = b
    else:
        maximum = c
    
    print(maximum)
    
  4. 年龄范围:

    age = int(input())
    if 12 <= age <= 18:
        print("是青少年")
    else:
        print("不在范围内")
    
  5. 格式化输出:

    year = int(input())
    month = int(input())
    print(f"{year} 年 {month} 月")
    
  6. 三位数拆位:

    number = int(input())
    hundreds = number // 100
    tens = number // 10 % 10
    ones = number % 10
    print(hundreds, tens, ones)
    
  7. 三角形判断参考 1.9 节。

1.12 常见错误清单#

  • 把 = 当比较,或在条件里用了赋值。
  • 忘记转换 input() 的字符串结果。
  • 在 if、elif、else 后面漏写冒号。
  • 缩进数量不一致,或条件外语句误缩进。
  • 使用中文标点作为代码符号。
  • 把 3.0 // 2 误认为字符串操作。
  • 多个独立 if 和 elif 混用,导致执行了不止一个分支。
  • 输入 100 但输出格式多一个空格或缺少单位。

1.13 过关检查#

不看书完成以下检查,全部通过后再进入第 2 周:

  • 能解释 /、//、%、** 的区别。
  • 能说出 5 种常见类型及 type(x).__name__ 的结果。
  • 能把字符串输入转换成整数并完成计算。
  • 能使用三种格式化方式输出固定小数位。
  • 能区分 if 与 elif 的执行差异。
  • 能阅读 NameError、TypeError 和 ValueError 并说出原因。
  • 能不运行代码,正确推演一段包含 6 个分支的等级判断程序。
  • 独立写出成绩等级和三角形判断,且通过边界测试。
  • 错题记录中至少有一条完整的“报错原文、原因、修改方式”。

第 2 周开始前,把本周代码中至少一个作品关掉资料重写一次。重写不是背代码,而是重新按“输入、处理、输出”设计程序。

本周进度

完成讲义、练习和验收后再标记。