chat gpt python (chatgpt帮助学习python编程)

使用chatgpt便携python程序包,怎么在python上使用chatgpt

四、在 ChatGPT 的帮助下调试您的代码

遇到错误是编程中的正常和预期部分。错误消息可以帮助您找出出了什么问题,并为您提供修复当前问题的指引。

如果您不知道如何处理回溯信息,通常可以通过网络搜索找到一些好的建议。然而,如果您没有遇到过这种错误,很难确定哪个链接与您特定的错误真正相关。

ChatGPT为您添加了一个新选项。当您遇到程序中的错误时,可以将您的代码和回溯信息复制到聊天界面,并向ChatGPT编程导师询问该怎么办。

例如,假设您在Python REPL中编写脚本,在其中要收集用户输入并对其进行计算。但是您遇到了一个异常,具体是TypeError:

>>> current_age = input("Enter your current age: ")
Enter your current age: 36
>>> print("Next year you'll be:", current_age + 1)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

如果您不知道如何解读这个回溯信息,那么您可以将所有内容复制并将其作为消息发送给ChatGPT。您的Python编程导师ChatGPT将给您提供详尽的答案,指出代码中的问题,并用清晰简洁的语言解释为什么会发生这种情况。它甚至会给您一个修复了您遇到的错误的示例代码:

你:

>>> current_age = input("Enter your current age: ")
Enter your current age: 36
>>> print("Next year you'll be:", current_age + 1)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

ChatGPT:您看到的错误信息是因为current_age被视为字符串,但您试图将一个整数值添加到它上面。要解决这个问题,您可以在执行相加操作之前使用int()函数将current_age转换为整数形式。以下是修正后的代码:

current_age = input("Enter your current age: ")
next_year_age = int(current_age) + 1
print("Next year you'll be:", next_year_age)

首先,它会提示用户输入他们的年龄,然后使用int()将输入转换为整数类型。然后将1与整数值相加,最后使用print()将结果以字符串形式打印出来。

ChatGPT给出的回答对于您遇到的错误提供了实质性的帮助。关于如何将Python输入读取为整数的建议接近于编程导师在面对面时可能会给予您的建议,如果他们是友善的人的话!

注意:一个有经验的导师可能会给出一个略有不同的解决方案,通过在将用户输入分配给current_age之前将其转换为整数来改进上述代码:

current_age = int(input("Enter your current age: "))
print("Next year you'll be:", current_age + 1)

使用这种解决方案,可以通过确保current_age在整个程序中始终是整数类型来提高代码的类型安全性。

ChatGPT背后的LLM并不知道关于您的任何信息。它甚至不以人类思维方式了解任何事情。尽管如此,它能够立即组合合理的令牌,解决您的错误,并为您的代码问题提供个性化的帮助。

现在你可能会说Python已经知道这段代码有什么问题,并用简洁的语言在错误消息中告诉你。但是ChatGPT可以做更多事情,不仅能够在代码上下文中解释回溯消息,还可以指出语法错误——也就是编写无效Python代码,Python解析器无法理解的错误。

也许你想将Python当作计算器使用,并试图将一个数字除以另一个数字:

>>> 3 : 4
  File "<input>", line 1
  3 : 4
  ^
SyntaxError: illegal target for annotation

嗯...这里有什么无效的语法呢?是不是您没有正确记住基本的数*运学**算?现在可以向ChatGPT询问一下这个除法出了什么问题。请将上面代码块的所有内容,包括错误消息,粘贴到ChatGPT界面中。您将会得到一个有用的解释作为答案:

ChatGPT: 您收到的错误消息表明您尝试以无效的方式使用了注解语法。在Python中,冒号(:)在多种情况下都被使用,如定义函数或类的签名、创建序列的切片或创建字典。

然而,在您的代码中,您在两个整数之间使用了冒号,这在Python中不是有效的语法。如果您想表示两个数字之间的比率或分数,可以使用除法运算符(/)代替。例如:

ratio = 3 / 4
print(ratio) # Output: 0.75

这会将整数3除以整数4,并返回一个表示商的浮点数。然后,您可以将此值存储在变量中,或直接在代码中使用它。

同样,ChatGPT编程导师找出了代码中的问题,演示了如何修复它,并提供了简明扼要的解释。使用ChatGPT来调试Python的SyntaxError也适用于比上面示例更复杂的代码。

如果您没有得到与问题相关的结果,那么可以给您发布的错误消息添加更多上下文。在这个例子中,您可以添加一句话来澄清您想要进行除法运算,比如我正在尝试除以两个数字,然后我得到了这个错误。

谨防错误的解决方案

就像以前学到的一样,您始终需要检查收到的答案是否准确。ChatGPT经常会产生对您输入的错误答案的幻觉。例如,尝试将以下错误的导入语句和其错误消息作为提示运行:

>>> from collections import chainmap
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ImportError: cannot import name 'chainmap' from 'collections'
  ⮑ (/Users/martin/.pyenv/versions/3.11.0/lib/python3.11/collections/__init__.py

Python的collections模块有一个类似的名称,但大小写不同,是ChainMap。解决这个ImportError的方法是修复您导入的名称的大写。这是一个小而直接的修复,但ChatGPT采取了另一种方法。

ChatGPT:错误消息表明存在导入collections模块中的chainmap函数的问题。从Python 3.3开始,collections模块提供了chainmap函数。

如果您使用的是Python 3.3或更高版本,仍然看到此错误消息,则可能是您的Python安装出现了问题。尝试更新或重新安装Python。

如果您使用的是不支持chainmap的早期版本的Python,可以使用其他方法,例如创建一个将多个字典中的值合并在一起的字典,如下所示:

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
combined_dict = dict(dict1, **dict2)

这样创建一个名为combined_dict的新字典,其中包含来自dict1和dict2的所有键值对。如果某个键存在于两个字典中,则dict2中的值将覆盖dict1中的值。

ChatGPT并没有建议将chainmap的大写改为ChainMap。它正确地推理出自Python 3.3以来,在collections中一直存在名为ChainMap的名称。然而,它继续建议,如果您在Python 3.3或更新版本上遇到此错误,则可能存在Python安装问题。

然后,ChatGPT继续建议您重新安装Python或将两个字典合并为一个,但这甚至不能复制ChainMap的功能。虽然您可以从这些建议中学到一些东西,但这并不是您的代码编程导师ChatGPT给出的好建议。

注意:您能否借助之前学到的一些提示工程技术,让ChatGPT给出正确的建议?尝试提供更多上下文,要求它逐步推理,或者要求列出collections中所有可用的名称。然后再次提问。

ChatGPT可能会给出恰到好处的建议,也可能会引导您走入偏离轨道的地方。当您把ChatGPT作为Python编程导师时,您始终需要清楚地意识到,界面背后的LLM只是根据概率预测下一个标记。它可能听起来令人信服,但完全可能是错误的。

通过SyntaxError的建议,您可以看到ChatGPT在Python知道出了问题却无法告诉您具体出了什么问题的情况下,给出了解释和解决方案。

但是ChatGPT可以更进一步,帮助您处理Python甚至不知道出了问题的代码错误。ChatGPT可以帮助您识别代码中的逻辑错误。有逻辑错误的代码通常可以正常运行,但输出结果与预期不符。找到和修复这类错误可能很困难。

假设您正在进行Python编程面试的练习。您正在尝试实现一个处理FizzBuzz挑战的函数,根据数字是否可被三整除、可被五整除,或者可同时被三和五整除,返回相应的字符串"fizz"、"buzz"或"fizz buzz"。您编写了一个运行起来似乎没问题的脚本:

# fizzbuzz.py
def fizzbuzz(number):
    if number % 3 == 0:
        return "fizz"
    elif number % 5 == 0:
        return "buzz"
    elif number % 15 == 0:
        return "fizz buzz"
    else:
        return number

这看起来很不错,但如果您使用一些示例输入调用fizzbuzz()函数,您会注意到您没有始终得到所期望的输出:

>>> fizzbuzz(3)
"fizz"
>>> fizzbuzz(5)
"buzz"
>>> fizzbuzz(15)
"fizz"

为什么fizzbuzz(15)没有返回预期的字符串"fizz buzz"?请将代码示例粘贴到与ChatGPT的对话中,看看语言模型给出了什么答案:

ChatGPT:fizzbuzz函数接收一个输入数字,并根据其是否能被3整除、能被5整除或者能同时被3和5整除来返回相应的字符串:"fizz"、"buzz"或"fizz buzz"。

然而,当前的实现存在一个bug。检查数字是否能被15整除的if条件应该放在检查数字能否被3和5整除的条件之前。这是因为能被15整除的数字也能被3和5整除,而当前的实现会对这样的数字返回"fizz"或"buzz",而不是"fizz buzz"。

下面是修正后的实现代码:

def fizzbuzz(number):
    if number % 15 == 0:
        return "fizz buzz"
    elif number % 3 == 0:
        return "fizz"
    elif number % 5 == 0:
        return "buzz"
    else:
        return number

通过这个修正,该函数应该按预期工作。

ChatGPT能够发现您代码中的逻辑错误。它可能成功是因为这是一种常见的编程任务,在模型训练的语料库中可能有许多解决方案和解释。不过,FizzBuzz并不是唯一的示例,ChatGPT的建议将能帮助您至少了解在代码中查找隐藏的逻辑错误的方向。

五、将程序与 ChatGPT 配对并编写更好的代码

您已经了解到ChatGPT如何帮助您调试代码以构建更健壮的程序。您可以将该工具用于一次性的问题,就像这样。但是ChatGPT也可以与您合作,随时改进您编写的代码,并帮助您学习更好的实践方法和编码风格。您可以像与编程导师一起进行代码编写的情况下使用它。

在这个示例中,您正在开发一个猜数字游戏。您已经完成了游戏的实现,并且它运行得很好:

import random

num = random.randint(1, 100)
i = None

while i != num:
    i = int(input("Guess the number: "))
    if i < num:
        print("Too low")
    elif i > num:
        print("Too high")
    else:
        print("Correct!")

有了这个正常工作的代码示例,您可以转到ChatGPT,看看您的个人编码导师是否对如何改进这段代码有一些建议。您可以直接粘贴代码示例,然后提问“如何改进这段代码?”您可能会得到一些有用的建议。

不过,在本节中,您可以更加具体地告诉ChatGPT您希望进行哪些方面的改进。上面的代码片段中,变量的命名并不是非常描述性。但是正如许多程序员可能会同意的那样,命名是有困难的!

ChatGPT基于大型语言模型,所以命名应该是其擅长的任务之一!尝试向ChatGPT询问它如何为您重命名对象:

你:

import random

num = random.randint(1, 100)
i = None

while i != num:
    i = int(input("Guess the number: "))
    if i < num:
        print("Too low")
    elif i > num:
        print("Too high")
    else:
        print("Correct!")

我应该如何改进代码示例中的变量命名?

ChatGPT:num和i这两个变量的用途有些明确。然而,您可以改进它们的名称以使代码更易读和自解释。以下是一个示例:

import random

random_number = random.randint(1, 100)
user_guess = None
while user_guess != random_number:
    user_guess = int(input("Guess the number: "))    
    if user_guess < random_number:    
        print("Too low")    
    elif user_guess > random_number:    
        print("Too high")
    else:
        print("Correct!")

在这个版本中,变量random_number和user_guess的名称更加描述性,一眼就能理解。它们清楚地说明了变量保存的值以及在代码中的用途。

ChatGPT帮助您通过将变量的命名方式改为更具描述性的方式来重构代码。因为您的编码导师似乎是一个很好的沟通者,您还要求他改进用户与该程序进行交互时的消息:

您:您能改进用户在与该程序交互时看到的消息吗?

ChatGPT: 当然可以!下面是使用更加用户友好的消息更新后的代码示例:

import random

random_number = random.randint(1, 100)
user_guess = None

while user_guess != random_number:
    user_guess = int(input("Guess a number between 1 and 100: "))    
    if user_guess < random_number:    
        print("Your guess is too low. Try again!")    
    elif user_guess > random_number:    
        print("Your guess is too high. Try again!")    
    else:    
        print("Congratulations, you guessed the number correctly!")

在这个更新后的版本中,用户会收到提示“猜一个1到100之间的数字”,以清晰地指明他们应该猜测的值范围。错误猜测的消息也已经更新,提供更具体的反馈信息。

例如,如果用户猜的数字太低,程序将打印消息“你猜的数字太小了,请再试一次!”同样地,如果用户猜的数字太大,程序将打印消息“你猜的数字太大了,请再试一次!”。

这些消息将帮助用户理解为什么他们的猜测是错误的,并告诉他们如何调整下一次猜测的策略。

ChatGPT在您的代码中添加了更好的用户消息,使其更易理解。此外,对于其他人来说,您的游戏可能会更有趣。现在,如果您想在不同的Python模块中重用此代码,一个很好的第一步是将代码重构为可导入的函数。

这种改变除了使代码更模块化外,还带来了一些优势。使用函数可以使您的代码更易读、可重用和组织良好。虽然您已经知道如何编写Python函数,但也许ChatGPT可以帮助您完成这一步:

您:您能将代码重构为一个函数吗?

ChatGPT: 当然可以!下面是重构为函数形式的代码示例:

import random

def guess_the_number():
    random_number = random.randint(1, 100)
    user_guess = None
    
    while user_guess != random_number:
        user_guess = int(input("Guess a number between 1 and 100: "))
        if user_guess < random_number:
            print("Your guess is too low. Try again!")
        elif user_guess > random_number:
            print("Your guess is too high. Try again!")
        else:
            print("Congratulations, you guessed the number correctly!")

现在您可以调用guess_the_number()来开始游戏。这个函数会生成一个1到100之间的随机数,提示用户猜一个数字,并根据猜测是太低、太高还是正确提供反馈。

使用函数可以使得在程序的其他地方或者其他程序中重复使用这段代码更加容易。它还使得代码更易于理解和修改,因为功能被封装在一个具有清晰名称的单个函数中。

如果您采用了建议的代码,那么现在您可以导入您的Python程序,并通过调用guess_the_number()来开始游戏了。不过,目前这个函数的能力很有限。通过在调用函数时不硬编码范围,而是允许用户添加它,可以使函数更灵活。

您可以要求ChatGPT为您进行更改,只需输入一个使用清晰语言和指令的特定提示:

您:请对代码进行重构,将1和100作为默认参数。还可以使用f-string来修复输入文本消息。

ChatGPT: 当然可以!以下是使用默认参数和f-string对代码进行重构后的版本:

import random

def guess_the_number(low=1, high=100):
    random_number = random.randint(low, high)    
    user_guess = None
    
    while user_guess != random_number:    
        user_guess = int(input(f"Guess a number between {low} and {high}: "))        
        if user_guess < random_number:
            print("Your guess is too low. Try again!")
        elif user_guess > random_number:
            print("Your guess is too high. Try again!")
        else:
            print("Congratulations, you guessed the number correctly!")

在这个更新后的版本中,low和high被添加为guess_the_number()函数的默认参数。现在随机数会使用这些参数来生成,因此您可以在调用函数时指定不同的数字范围。

输入提示也使用了f-string来在消息中包含low和high的值,以便更容易理解用户应该猜测的值的范围。

您现在可以调用guess_the_number()而不带参数来使用默认的1到100的范围,或者可以指定自己的范围,例如guess_the_number(10, 50)来使用10到50的范围。

这个游戏进展得很顺利!在这一步中,您提出了一个非常具体的问题。ChatGPT通常擅长回答这类问题。但是当您提出一个常见的问题时,即使您的提示不太准确,也可能会得到不错的结果。

目前您的函数没有返回值,这意味着如果您要构建一个有多轮游戏的程序,您无法跟踪已猜过的数字。不过,也许您还没有听说过Python的返回语句,只知道如何描述您想要的功能。那么,您继续向ChatGPT询问如何操作,使用一个普遍性的问题:

您:我应该如何保存生成的随机数?

ChatGPT: 保存生成的随机数的一种方法是从guess_the_number()函数中返回它。以下是进行了更新的代码版本:

import random

def guess_the_number(low=1, high=100):
    random_number = random.randint(low, high)
    user_guess = None
    
    while user_guess != random_number:
        user_guess = int(input(f"Guess a number between {low} and {high}: "))
        if user_guess < random_number:
            print("Your guess is too low. Try again!")
        elif user_guess > random_number:
            print("Your guess is too high. Try again!")
        else:
            print("Congratulations, you guessed the number correctly!")
            
    return random_number

在这个更新后的版本中,用户猜测正确数字后,随机数会从guess_the_number()函数中返回。您现在可以像这样调用函数

random_number = guess_the_number()
print(f"The randomly generated number was {random_number}.")

这将把随机生成的数字存储在random_number变量中,并在用户猜对数字后打印出来。

请注意,如果需要以后再次使用,您也可以将random_number保存到文件或数据库中。

现在您可以使用函数的返回值来跟踪用户猜测的数字,例如。您在向ChatGPT提问时甚至没有提及返回值!然而,由于这是一个常见的处理所描述任务的方式,ChatGPT已经根据返回值构建了一个解决方案。

注意:请记住,如果您提问具体问题并提供更多上下文,通常会得到更好的结果;而如果您的提示模糊或过于笼统,可能会收到不正确或不相关的回答。

最后,为函数添加文档字符串和类型提示也很不错,所以你问ChatGPT:

您:您能为函数添加文档字符串和类型提示吗?

ChatGPT: 当然,以下是带有类型提示和文档字符串的更新代码:

import random

def guess_the_number(low: int = 1, high: int = 100) -> int:
    """
    Plays a guessing game where the user must guess a random number between
    `low` and `high`. Returns the randomly generated number.

    Args:
        low (int): The lowest possible number in the range (default 1).
        high (int): The highest possible number in the range (default 100).

    Returns:
        int: The randomly generated number.

    """
    random_number = random.randint(low, high)
    user_guess = None

    while user_guess != random_number:
        user_guess = int(input(f"Guess a number between {low} and {high}: "))
        if user_guess < random_number:
            print("Your guess is too low. Try again!")
        elif user_guess > random_number:
            print("Your guess is too high. Try again!")
        else:
            print("Congratulations, you guessed the number correctly!")

    return random_number

在这个版本中,我们给函数的参数和返回值添加了类型提示。我们还添加了一个文档字符串来描述函数的功能、接受的参数以及返回的内容。

使用类型提示和文档字符串可以让您的代码更清晰易懂,特别是当您与团队合作或与他人分享代码时。

看起来非常不错!ChatGPT创建了一个几乎符合多行文档字符串规范的Google风格文档字符串,并添加了有用的类型提示。

注意:生成的文档字符串缺少第一行摘要,摘要应该能够在一行内完成,在更详细地描述函数的功能之前。您可以继续向ChatGPT询问如何添加该摘要行吗?

利用ChatGPT来为代码编写文档对于不喜欢撰写文档的开发人员来说是一个很好的帮助。借助ChatGPT,您可以提高代码库的质量和可访问性,而无需花费太多时间在自己不热衷的任务上。

注意:在这里,你利用了ChatGPT的对话性质来逐步改善你的代码,并且LLM保持了先前提示的上下文。最终,当包含所有输入和输出的总提示变得过大时,你会遇到限制。ChatGPT将停止使用你提供的起始文本。对于GPT-3来说,截断点在2048个标记处。

在本节中,你对代码没有进行太多更改。它的功能与开始时相似。然而,通过向你的ChatGPT编程导师询问其意见,你找到了改进和重构代码以实现更好可维护性和可重用性的方法。