【AI 加持下的 Python 编程实战 2_05】第四章 + 第五章:读懂 Python 代码——基础语法概述

全新第二版《Learn AI-assisted Python Programming》封面

【全新第二版《Learn AI-assisted Python Programming》封面】

写在前面
本书前三章负责给大家上开胃菜,第四、五章则进一步介绍了读懂 Copilot 回复的 Python 代码所需了解的基础语法。毕竟 AI 工具目前只能起到辅助编程的作用,主体还在人这边。与其费心钻研怎么写好提示词让 Copilot 等工具一气呵成,还不如主动了解 Python 的基础语法来得实惠。真正能将 AI 编程玩出花样的大神没有一个是纯小白。这些内容也是为后续高级话题的展开做铺垫。具有 Python 基础的朋友可以直接跳过,因为确实乏善可陈,都是入门级的知识点。

Ch04: Reading Python code: Part 1

本章概要

  • 为什么理解代码很重要
  • Copilot 解释代码
  • 用函数来分解大型问题
  • 使用变量来存值
  • if 语句来做决策
  • 用字符串存储和操作文本
  • 用列表来收集和操作多个值

1 开宗明义:为什么要读懂代码

这里的 分两个层面:

  1. 知道每句代码的具体功能和作用;
  2. 知道整段代码的目的。

和现实生活中一样,从基层提拔的干部往往更能胜任工作,Copilot 辅助编程更是如此。当提供的程序达不到预期时,与其一味去优化提示词工程直到 Copilot 纠正问题,还不如自己懂点代码,略加修改就能符合要求。

书中给出了读懂代码的三个好处:

  1. 判定代码的准确性:预先排除存在问题的代码;
  2. 提高测试效率:提高测试的针对性和有效性;
  3. 提高 AI 辅助编程的水平:真正擅于利用 Cursor 等 AI 辅助编程工具的人,绝大部分是很懂代码的高级程序员,知道大模型提供的代码能干什么,还缺什么,应该怎么完善等。

正因如此,本书接下来的两章将重点介绍 Python 的核心语法,为后续 Copilot 工具的高级用法作铺垫。

2 让 Copilot 解释代码

主要有三种方式:

  1. 借助右键菜单:选中代码后,从右键菜单选 Copilot ➡️ explain(如图 4.1 所示);
  2. 使用 /explain 指令:如图 4.2 所示;
  3. 自行设计解释提示词:适用于需求较复杂、Copilot 不能完全理解你的意图的情况。

图 4.1 利用 VSCode 右键菜单的 Copilot 解释功能

【图 4.1 利用 VSCode 右键菜单的 Copilot 解释功能】

图 4.2 实测 Copilot 的 explain 指令解释所选代码段

【图 4.2 实测 Copilot 的 explain 指令解释所选代码段】

关于 Copilot 可能出错的问题

诚然 Copilot 并不完美,无法保证每一次给出的代码都是百分百正确的,但就算自己手动上网查找资料,也不能保证百分百正确。若实在信不过 Copilot 给出的回复内容,可以从不同角度多次提问,出错的概率相对更低。

3 Python 基本语法简介(上)

这部分内容非常浅显,主要分五个主题展开:

  1. 函数
  2. 变量
  3. 条件语句
  4. 字符串
  5. 列表

这里仅梳理最关键的知识点。

函数的主要作用是拆解问题,每个函数执行特定的代码块,并将处理结果用 return 语句返回(通常由某个变量接收处理结果)。

除了自定义函数,Python 还提供了大量内置函数以及第三方库函数,其调用和传参方式和自定义函数一致。

Python 中一个等号代表赋值操作符,两个等号才表示相等。

if 语句用于处理逻辑分支,多种情况用 if 和用 elif 书写效果不尽相同:

  • 多个 if 语句在 Python 中会依次执行,只要满足条件即可执行对应的代码块;
  • 多个 elif 组合的语句只是一个独立的 if 语句,一旦满足前面某个条件,后续分支将不再执行。

if 分支语句和函数定义一样,都是通过代码缩进来标识代码块的,即便在 REPL 命令行环境也要确保缩进量的一致。

字符串(String)具有很多内置方法:

>>> 'abc'.isupper()
False                   
>>> 'Abc'.isupper()
False                   
>>> 'ABC'.isupper()
True                    
>>> 'abc'.isdigit()
False
>>> '345bc'.isdigit()
False
>>> '345'.isdigit()
True
>>> 'abc6'.isalnum()
True
>>> 'abc def'.isalnum()
False
>>> 'abcdef#'.isalnum()
False

列表用于操作和管理一组具有某种具体含义和功能的值。列表中的元素值可通过索引(index,从 0 开始计数)来访问。

和字符串一样,列表也有很多内置方法:

>>> books = ['The Invasion', 'The Encounter', 'The Message']
>>> books
['The Invasion', 'The Encounter', 'The Message']
>>> books.append('The Predator')
>>> books
['The Invasion', 'The Encounter', 'The Message', 'The Predator']
>>> books.reverse()
>>> books
['The Predator', 'The Message', 'The Encounter', 'The Invasion']
>>> books[0]
'The Predator'
>>> books[1]
'The Message'
>>> books[2]
'The Encounter'
>>> books[3]
'The Invasion'
>>> books[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> books[-1]
'The Invasion'
>>> books[-2]
'The Encounter'
>>> books[1:3]
['The Message', 'The Encounter']
>>> books[:3]
['The Predator', 'The Message', 'The Encounter']
>>> books[1:]
['The Message', 'The Encounter', 'The Invasion']
>>> books
['The Predator', 'The Message', 'The Encounter', 'The Invasion']
>>> books[0] = 'The Android'
>>> books[0]
'The Android'
>>> books[1] = books[1].upper()
>>> books[1]
'THE MESSAGE'
>>> books
['The Android', 'THE MESSAGE', 'The Encounter', 'The Invasion']

但需要注意的是,列表的值是可变的(mutable),而字符串是不可变的(immutable value):

>>> title = 'The Invasion'
>>> title[0]
'T'
>>> title[1]
'h'
>>> title[-1]
'n'
>>> title[0] = 't'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

Ch05: Reading Python code: Part 2

本章概要

  • 用循环控制代码重复执行的次数
  • 用缩进组织 Python 代码
  • 建立字典来保存成对关联的值
  • 设置文件来读取和处理数据的方法
  • 用模块开辟新的工作领域

本章接上一章介绍的 Python 基础,主要从循环、缩进、字典、文件和模块五个方面进一步介绍了 Python 十大基础语法的后半部分。

1 循环

分类:

  • for 循环:循环次数确定;
  • while 循环:循环次数不确定;

1.1 for 循环

for 循环通过 for-in 结构运行,可作用于字符串:

s = 'vacation'
for char in s:
    print('Next letter is', char)

Next letter is v
Next letter is a
Next letter is c
Next letter is a
Next letter is t
Next letter is i
Next letter is o
Next letter is n

也可以作用于列表:

>>> lst = ['cat', 'dog', 'bird', 'fish']
>>> for animal in lst:
...     print('Got', animal)
...     print('Hello,', animal)
...
Got cat
Hello, cat
Got dog
Hello, dog
Got bird
Hello, bird
Got fish
Hello, fish

此外还能借助索引值遍历列表:

>>> for index in range(0, len(lst)):
...     print('Got', lst[index])
...     print('Hello,', lst[index])
...
Got cat
Hello, cat
Got dog
Hello, dog
Got bird
Hello, bird
Got fish
Hello, fish

其中 range(start, end)Python 内置方法,用于生成 [start, end) 区间内的索引值序列。range(5)range(0, 5) 的简写形式。

1.2 while 循环

当循环次数不确定时,通常用 while 循环控制具体逻辑:

def get_strong_password():
    """
    Keep asking the user for a password until it’s a strong password,
    and return that strong password.
    """
    password = input("Enter a strong password: ")
    while not is_strong_password(password):
        password = input("Enter a strong password: ")
    return password

其中的 is_strong_password() 函数是第三章演示过的密码强弱判定函数(根据最新版 Copilot 回复):

def is_strong_password(password):
    """
    A strong password has at least one uppercase character,
    at least one number, and at least one punctuation.
 
    Return True if the password is a strong password, False if not.
    """
    has_uppercase = False
    has_number = False
    has_punctuation = False
    for char in password:
        if char.isupper():
            has_uppercase = True
        elif char.isdigit():
            has_number = True
        elif char in "!@#$%^&*()_+-=[]{}|;:,.<>?":
            has_punctuation = True
    return has_uppercase and has_number and has_punctuation

只要输入的密码其强度不符合要求,程序就会一直循环,反复提示用户重新输入,直至读到一个强密码。

为防止 while 陷入死循环,也可以人为设置退出条件:

lst = ['cat', 'dog', 'bird', 'fish'] 
index = 0
while index < len(lst):
    print('Got', lst[index])
    print('Hello,', lst[index])
    index += 1

# 运行结果
Got cat
Hello, cat
Got dog
Hello, dog
Got bird
Hello, bird
Got fish
Hello, fish

2 缩进

必须缩进的语法结构:

  • if 语句
  • 函数体
  • 循环体

例如:

hour = int(input('Please enter the current hour from 0 to 23: '))

if hour < 12:
    print('Good morning!')
    print('Have a nice day.')
elif hour < 18:
    print('Good afternoon!')
else:
    print('Good evening!')
	print('Have a good night.')
def larger(num1, num2):
    if num1 > num2:
        return num1
    else:
        return num2
lst = ['cat', 'dog', 'bird', 'fish'] 
index = 0
while index < len(lst):
    print('Got', lst[index])
    print('Hello,', lst[index])
    index += 1

上述结果通过相互嵌套,还能形成更复杂的业务逻辑:

def num_points(word): 
    """ 
    Each letter is worth the following points: 
    a, e, i, o, u, l, n, s, t, r: 1 point 
    d, g: 2 points 
    b, c, m, p: 3 points 
    f, h, v, w, y: 4 points 
    k: 5 points 
    j, x: 8 points 
    q, z: 10 points 

    word is a word consisting of lowercase characters. 
    Return the sum of points for each letter in word. 
    """
    points = 0
    for char in word:  # 函数内的缩进
        if char in "aeioulnstr":  # for 循环内的缩进
            points += 1  # if 语句内的缩进
        elif char in "dg":
            points += 2
        elif char in "bcmp":
            points += 3
        elif char in "fhvwy":
            points += 4
        elif char == "k":
            points += 5
        elif char in "jx":
            points += 8
        elif char in "qz":
            points += 10
    return points

出于可读性考虑的缩进

有些结构不必缩进,但为了美观和方便阅读,也会引入缩进。常见的有长内容行的换行缩进、大段字典声明中的换行缩进等。

例如:

def is_strong_password(password):
 """
 A strong password has at least one uppercase character,
 at least one number, and at least one punctuation.

 Return True if the password is a strong password, 
 False if not.
 """
 return any(char.isupper() for char in password) and \   # 行尾的反斜杠表示续行
        any(char.isdigit() for char in password) and \   # 此处缩进不作要求,仅方便阅读
        any(char in string.punctuation for char in password)

再如:

def num_points(word): 
 """ 
 Each letter is worth the following points: 
 a, e, i, o, u, l, n, s, t, r: 1 point 
 d, g: 2 points 
 b, c, m, p: 3 points 
 f, h, v, w, y: 4 points 
 k: 5 points 
 j, x: 8 points 
 q, z: 10 points 

 word is a word consisting of lowercase characters. 
 Return the sum of points for each letter in word. 
 """ 
 points = {'a': 1, 'e': 1, 'i': 1, 'o': 1, 'u': 1, 'l': 1,     # 字典天然支持多行输入
           'n': 1, 's': 1, 't': 1, 'r': 1,        # 此处缩进不作要求,仅提高可读性
           'd': 2, 'g': 2,
           'b': 3, 'c': 3, 'm': 3, 'p': 3,
           'f': 4, 'h': 4, 'v': 4, 'w': 4, 'y': 4,
           'k': 5,
           'j': 8, 'x': 8,
           'q': 10, 'z': 10}
 return sum(points[char] for char in word)

2.1 循环嵌套中的多级缩进

countries = ['Canada', 'USA', 'Japan']
for country1 in countries:
    for country2 in countries:     # 外层循环所需缩进
        print(country1, country2)  # 内层循环所需缩进
# 运行结果:
Canada Canada
Canada USA
Canada Japan
USA Canada
USA USA
USA Japan
Japan Canada
Japan USA
Japan Japan

2.2 二维列表的遍历

利用 range 和循环嵌套,还能实现二维列表的遍历:

medals = [[2, 0, 2],
          [1, 2, 0],
          [1, 1, 0],
          [0, 1, 0],
          [1, 0, 0]]

for i in range(len(medals)):
    for j in range(len(medals[i])):
        print(i, j, medals[i][j])
# 运行结果:
0 0 2
0 1 0
0 2 2
1 0 1
1 1 2
1 2 0
2 0 1
2 1 1
2 2 0
3 0 0
3 1 1
3 2 0
4 0 1
4 1 0
4 2 0

可见,只有内层循环结束后,外层循环才会开始下一个新值的迭代。

3 字典

字典与列表同样都是可变更值的数据类型,其写法类似 JavaScript 中的对象和 JSON。字典自带两个遍历方法:

freq = {'DNA': 11, 'acquire': 11, 'Taxxon': 13, \
    'Controller': 20, 'morph': 41}
freq.keys()
freq.values()

实测结果:

img5.1

字典的删除用 freq.pop(key) 完成(务必注意大小写):

>>> freq.pop('Controller')
20
>>> freq
{'DNA': 11, 'acquire': 11, 'Taxxon': 13, 'morph': 41}

字典也可参数 for-in 遍历:

>>> for word in freq:
...     print('Word', word, 'has frequency', freq[word])
...
Word DNA has frequency 11
Word acquire has frequency 11
Word Taxxon has frequency 13
Word morph has frequency 6

4 文件操作

两种方式:

  • nfl_file = open('nfl_offensive_stats.csv')
  • with open('nfl_offensive_stats.csv', 'r') as f:(推荐)

第一种写法需要手动关闭文件;第二种会自动关闭。

5 模块

常见的 Python 模块如下:

模块内置模块描述
csv帮助读写和分析 CSV 格式文件
zipfile帮助创建和解压 zip 格式文件
matplotlib用于绘图的图形模块,可作为其他图形库的基础,并提供高级定制功能
plotly用于创建交互式网络图形的绘图模块
seaborn建立在 matplotlib 模块基础上的图形模块,较之 matplotlib 更容易创建高质量的图形
pandas数据处理模块,专门处理与电子表格类似的数据帧(data frame
scikit-learn包含机器学习(从数据中学习并进行预测)的基础工具模块
numpy提供高效数据处理的工具模块
pygame游戏编程模块,可用 Python 构建交互式图形类游戏
django有助于设计网站及 Web 应用的网络开发模块

内置模块需 import 引入后使用;其他模块则需要先安装再导入使用。

借助模块可简化文件读写操作:

>>> import zipfile
>>> zf = zipfile.ZipFile('my_stuff.zip', 'w', zipfile.ZIP_DEFLATED)
>>> zf.write('nfl_offensive_stats.csv')
>>> zf.write('actors.csv')
>>> zf.write('chores.csv')
>>> zf.close()

再如:

def create_zip_file(file_name):
    """
    Add all of the csv files in the current directory to a zip file named file_name.
    If file_name already exists, it will be overwritten. Not included the csv files in the subdirectories.
    The zip file will be created in the current directory.

    Args:
        file_name (str): the name of the zip file to create.
    """
    
    import os
    import zipfile

    # Get the list of all files in the current directory
    files = os.listdir('.')

    # Create a zip file with the specified name
    with zipfile.ZipFile(file_name, 'w') as zipf:
        for file in files:
            # Check if the file is a CSV file
            if file.endswith('.csv'):
                # Add the CSV file to the zip file
                zipf.write(file)
                print(f'Added {file} to {file_name}') 
                
    print(f'Created {file_name} with all CSV files in the current directory.')
    
create_zip_file('my_stuff.zip')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安冬的码畜日常

您的鼓励是我持续优质内容的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值