2

I am having trouble understanding how one of the for loops works in Learn Python the Hard Way ex.41. http://learnpythonthehardway.org/book/ex41.html Below is the code from the lesson.

The loop that I am confused about is for i in range(0, snippet.count("@@@")): Is it iterating over a range of 0 to snippet (of which there are 6 snippet), and adding the extra value of the count of "@@@"? So for the next line of code param_count = random.randint(1,3) the extra value of "@@@" is applied? Or am I way off!?

Cheers Darren

import random
from urllib import urlopen
import sys

WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []

PHRASES = {
    "class %%%(%%%):":
       "Make a class named %%% that is-a %%%.",
    "class %%%(object):\n\tdef __init__(self, ***)" :
      "class %%% has-a __init__ that takes self and *** parameters.",
    "class %%%(object):\n\tdef ***(self, @@@)":
      "class %%% has-a function named *** that takes self and @@@ parameters.",
    "*** = %%%()":
      "Set *** to an instance of class %%%.",
    "***.***(@@@)":
      "From *** get the *** function, and call it with parameters self, @@@.",
    "***.*** = '***'":
      "From *** get the *** attribute and set it to '***'."
}

# do they want to drill phrases first
PHRASE_FIRST = False
if len(sys.argv) == 2 and sys.argv[1] == "english":
    PHRASE_FIRST = True

# load up the words from the website
for word in urlopen(WORD_URL).readlines():
    WORDS.append(word.strip())


def convert(snippet, phrase):
    class_names = [w.capitalize() for w in
                   random.sample(WORDS, snippet.count("%%%"))]
    other_names = random.sample(WORDS, snippet.count("***"))
    results = []
    param_names = []

    for i in range(0, snippet.count("@@@")):
        param_count = random.randint(1,3)
        param_names.append(', '.join(random.sample(WORDS, param_count)))

    for sentence in snippet, phrase:
        result = sentence[:]

        # fake class names
        for word in class_names:
            result = result.replace("%%%", word, 1)

        # fake other names
        for word in other_names:
            result = result.replace("***", word, 1)

        # fake parameter lists
        for word in param_names:
           result = result.replace("@@@", word, 1)

        results.append(result)

    return results


# keep going until they hit CTRL-D
try:
    while True:
        snippets = PHRASES.keys()
        random.shuffle(snippets)

        for snippet in snippets:
            phrase = PHRASES[snippet]
            question, answer = convert(snippet, phrase)
            if PHRASE_FIRST:
                question, answer = answer, question

            print question

            raw_input("> ")
            print "ANSWER:  %s\n\n" % answer
except EOFError:
    print "\nBye"
4

2 回答 2

3

snippet.count("@@@")"@@@"返回出现的次数snippet

如果"@@@"出现 6 次,则 for 循环从 0 迭代到 6。

于 2013-08-31T03:01:33.240 回答
0

“try except”块运行程序,直到用户点击 ^ D。

“try”中的“While True”循环将 PHRASES 字典中的键列表存储到片段中。每次键的顺序都不同(因为随机播放方法)。该“While循环”中的“for循环”是遍历每个片段并对该片段的键和值调用convert方法。

所有“转换方法”都会用 url 单词列表中的随机单词替换该键和值的 %%%、*** 和 @@@,并返回一个由两个字符串组成的列表(结果):一个从键和一个从值。

然后程序将其中一个字符串打印为问题,然后获取用户输入(使用 raw_input("> ")),但无论用户输入什么,它都会打印另一个返回的字符串作为答案。

在 convert 方法中,我们有三个不同的列表:class_names、other_names 和 param_names。为了制作class_names,程序计算该键(或值,但无论如何它们中的%%% 的数量相同)的%%% 的数量。class_names 将是一个大小为 %%% 的随机单词列表。

other_names 又是一个随机的单词列表。多少字?在键(或值)中找到的 *** 的数量,不管是哪一个,因为它在它们的任何对中都是相同的

param_names 是一个大小为找到的@@@ 数量的字符串列表。每个字符串由一个、两个或三个不同的单词组成,用 , 分隔。

“结果”是一个字符串。该程序遍历三个列表(class_names、param_names 和 other_names),并将结果字符串中的某些内容替换为它已经准备好的内容。然后将其附加到结果列表中。(for sentence in snippet, phrase:) 循环运行两次,因为 'snippet' 和 'phrase' 是两个不同的字符串。因此,“结果”字符串被制作了两次(一个用于问题,一个用于回答)。

我将这个程序的一部分放到一个较小的子程序中,以阐明如何从 url 中的随机单词中创建一定大小的列表:

https://github.com/MahshidZ/python-recepies/blob/master/random_word_set.py

最后,我建议将打印语句放在您需要更好理解的代码中的任何位置。举个例子,对于这段代码,我打印了一些变量来准确了解正在发生的事情。这是在没有调试器的情况下进行调试的好方法:(在我的代码中查找布尔变量 DEBUG)

DEBUG = 1
if DEBUG:
  print "snippet: " , snippet
  print "phrase: ", phrase
  print "class names: ", class_names
  print "other names: " , other_names
  print "param names: ", param_names
于 2014-05-18T23:12:20.550 回答