欢迎光临
我们一直在努力

【AI加持下的Python编程实战2

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

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

写在前面

全篇里, 这是全书头一处精华部分, 从全然零基础小白视角, 详细讲了在函数设计那里的用法, 诸如提示词正确写法, 基于AI工具的函数设计基础工作流程等, 虽说具体案例都没多大难度, 可当中方法要领都值得大伙反复去研读, 还得认真实践。

Ch03:

本章概要

起始于函数, 本章更进一步地就提示词的写法予以介绍, 在内容组织方面相较于上一版有着颇为显著的调整, 鉴于内容太过基础, 本篇只是对关键要点加以梳理, 不会进行全面的展开阐述。

1 提效的关键

即确定交给 的任务是 合理的()。

特定的方法是, 借助函数把繁杂的问题划分成数目若干个简单且能够施行的小工作, 这类函数起码得拥有两个性质。

每个函数只完成一个任务;函数的内部逻辑容易理解。

因为这本书的关键要点是辅助编程之便, 所以并非直接去阐述函数语法, 而是借助几个小型案例来进一步展现其用法。

1.1 找单词游戏

从下列字符中找出指定的单词:

图 3.1 示例一:找单词游戏

【图 3.1 示例一:找单词游戏】

目标单词有:CAT、DOG、、HELLO、TASK。

总的思路是, 把原本的问题依照行来开展分解, 与此同时, 还要配合检索的顺序, 这个检索顺序是从左至右, 还是从上到下, 进而将复杂的问题实施合理的分解。

1.2 返回两个数中的较大值

沿用 # 注释的旧方案提示词(前三行):

# write a function that returns the larger of two numbers
# input is two numbers
# output is the larger of the two numbers
def larger(num1, num2):
if num1 > num2:
return num1
else:
return num2

在 给出的函数完整定义中——

倘若存在一个函数, 因其执行的任务数量过多, 从而致使难以快速地进行命名, 这往往意味着是设计得过度复杂的信号。

要防止, 于按下回车键后, 仍旧不断提示注释内容, 建议应用那, 用作提示词的文档字符串(), 更改成为如下有着前 6 行的版本: 。

def larger(num1, num2):
"""
num1 and num2 are two numbers.
Return the larger of the two numbers.
"""
if num1 > num2:
return num1
else:
return num2

能够发觉, 新版的提示之词句, 就要求手写出自关于第一行的函数之签名这种构成, 也就是亲自去确定函数的名称, 还有参数的列表, 以及各个参数的具体名称, 之后呢, 要在那个文档的字符串里, 针对刚才所言的这个签名, 开展进一步的阐释。

先描述各参数的类型、含义;再确定函数返回的内容。

关于能不能生成正确的函数体, 靠另一段提示词来生成测试代码(前三行):

# call the larger function with the values 3 and 5
# store the result in a variable called result
# then print result
result = larger(3, 5)
print(result)

于此地便无需特意运用了。将所有代码选中, 按下 Shift 键与 Enter 键, 快去执行代码:

将图3.2改成函数签名之后加之提示词以后呈现的函数实测情况。

2 用 设计函数的标准工作流

如图所示:

图 3.3 用 Copilot 设计函数的标准工作流

【图 3.3 用 设计函数的标准工作流】

写成文字版就是——

判定函数的预期表现, 按照需求撰写出提示词, 尽可能确切地叙述该函数所具有的功用, 来使依据提示词生成代码, 从头到尾阅读检查代码以确保逻辑恰当, 对代码进行测试, 多次测试之后全都正确, 那就转向下一个步骤了, 要是测试过程中出现错误, 那就返回到步骤2, 对提示词做出修改, 重新走一遍流程, 2.1呈现一: 股票盈利函数。

需求:根据持股数、买入价格、当前价格计算股票盈利情况。

函数签名 + 提示词(最后一行除外):

def money_made(num_shares, purchase_share_price, current_share_price):
"""
num_shares is the number of shares of a stock that we purchased.
purchase_share_price is the price of each of those shares.
current_share_price is the current share price.
Return the amount of money we have earned on the stock.
"""
return num_shares * (current_share_price – purchase_share_price)

实测情况:

图 3.4 股票盈利函数实测截图(含手动测试情况)

【图 3.4 股票盈利函数实测截图(含手动测试情况)】

2.2 演示二:密码强弱判定

需求:判定一个密码的强弱,只要不是 或 就视为强密码。

函数签名 + 提示词(前 7 行):

def is_strong_password(password):
"""
A strong password is not the word 'password'
and is not the word 'qwerty'.
Return True if the password is a strong password, False if not.
"""
return password != 'password' and password != 'qwerty'

何为强密码, 是这类情况, 它得至少存在一个大写字符, 并且, 还得至少有一个数字, 而且, 还必须至少包含一个特殊符号。

升级版提示词:

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

Return True if the password is a strong password, False if not.
"""
has_uppercase = False
has_number = False
has_special = False
for char in password:
if char.isupper():
has_uppercase = True
if char.isdigit():
has_number = True
if not char.isalnum():
has_special = True
return has_uppercase and has_number and has_special

实测情况:

图 3.5 新版强密码判定函数实测情况

【图 3.5 新版强密码判定函数实测情况】

此处的代码, 相较于原书而言, 其可读性更具优势, 然而, 仍旧未能对特殊字符的含义形成正确理解, 这是需要进一步予以明确的。

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

这回, 没运用书中的 模块, 反倒径直给出了标点符号序列, 权且算是一回改进吧。

在这个时候, 再往前深入迈进一步, 去要求那用户, 反复地进行输入, 输入一个密码, 一直持续下去, 直到其所输入的那个密码, 成为强密码的时候, 才停止下来, 与此同时, 输出这个密码。提示词能够被写成下面这样的形式, 前五行。

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):
print("That password is not strong enough.")
password = input("Enter a strong password: ")
return password

在 交互式命令行中进行测试:

图 3.6 实测循环输入测试密码在 ipython 交互式命令行的运行情况

有一张图, 其编号为3.6, 展示的是实测循环输入测试密码, 在交互式命令行之中的运行情形。

2.3 演示三:拼字游戏得分统计

需求:给定一个单词,根据每个字母的分值计算总得分。

提示词(L1 ~ L14):

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 letter in word:
if letter in "aeioulnstr":
points += 1
elif letter in "dg":
points += 2
elif letter in "bcmp":
points += 3
elif letter in "fhvwy":
points += 4
elif letter == "k":
points += 5
elif letter in "jx":
points += 8
elif letter in "qz":
points += 10
return points

先进行测试, 直到测试结果无误后, 依据这个无误的测试结果, 去创建一个函数, 这个函数是用来在一组单词里, 挑选出分值最高的那个单词的。

def best_word(word_list):
"""
word_list is a list of words.

Return the word worth the most points.
"""
best_word = ""
best_points = 0
for word in word_list:
points = num_points(word)
if points > best_points:
best_word = word
best_points = points
return best_word

3 引入函数的好处

主要好处有——

缓和认知负担, 防止冗余与重复, 改良测试, 复杂任务经合理函数拆分更易测试, 提升代码可靠性, 提升代码可读性。

说到第四条跟第五条, 看上去好像类似, 可实际上完全属于两个不同的维度。这其中、可靠性指的是只代码没有错误出现的这样一种概率, 还和健壮性存在关联。

书中还提及了一个特别违背直觉的情况, 那就是, 要是每行代码的平均正确概率高达百分之九十五, 持续去写上十四行, 从概率的层面来讲, 也会出现至少有一行代码出现错误这样的状况!(N_min大于ln0.5除以ln0.95, 约等于十三点五一)。

关于可读性, 这是从后续维护这个角度来说的, 不管是由AI生成的代码情况, 还是开发者亲手书写的代码状况, 在其中引入优质函数, 都能够明显提升代码的可读性。

4 函数的职能

书中举了一个例子:

def funct1():
print("there")
funct2()
print("friend")
funct3()
print("")
def funct2():
print("my")
def funct3():
print(".")
def funct4():
print("well")
print("Hi") # 函数的起点,类似其他编程语言中的 main 函数
funct1()
print("I'm")
funct4()
funct3()
print("")
print("Bye.")

可以结合下图进行理解:

图 3.7 示例:函数的不同职能示意图

【图 3.7 示例:函数的不同职能示意图】

本例中的函数具体职能包括:

调度别的子函数, 达成更高层次的抽象, 用以提升代码复用性, 对部分底层逻辑予以封装。

辅助函数 vs 叶子函数

分担另一个函数工作, 减轻其压力的函数, 都可视为辅助函数, 辅助函数()。定义明确, 完成子任务又好又快的函数, 必定是最好的辅助函数(例如上面演示二和演示三中的辅助函数)。

叶子函数, 即 leaf , 指这样一种独立函数, 它无需调用其他函数, 当然, 调用内置函数除外。

5 函数设计的合理性问题

想要合理设计函数,需要明确优质函数的基本特征:

任务是明确的, 预期行为清晰得没有错误, 代码行数不多, 通常在 12 至 20 行的范围不等, 通用性比特殊性更具优势, 输入和输出清晰又明了。这是本章小结。

后话

本章篇幅较长, 然而整体难度不大, 其主要价值乃在于引导我们建立与交互的基本模式以及提示词的基本结构。演示使用的是英文, 不过这并不妨碍我们用其他语言、其他AI工具去践行提示词工程。唯有在本地实测过程当中, 才能够对当前AI工具所具备的真实能力拥有一个真正落地的感受, 借此放弃不切实际的幻想(有时甚至是妄想)。再一次着重指出, 即便历经两年多时间的更新迭代, 当下的AI辅助编程工具的放大镜效应依旧十分显著, 会运用这些工具的人士与不会运用这些工具的人士在AI实际应用方面的效用的差别犹如天地之差, 而能够熟练运用的前提条件乃是切实理解并且娴熟运用这些工具, 不要因为善事微小就不去做。

赞(0)
未经允许不得转载:171主机测评 » 【AI加持下的Python编程实战2
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址