¿Cómo leer el código del ejercicio 41 de Learn Python de la manera más difícil?

Estoy tratando de entender el siguiente código y lo estoy pasando mal. ¿Puede alguien ayudarme a entender respondiendo un par de preguntas?

Sé que FRASES (una variable) contiene un diccionario, por lo que “class %%% (%%%)” se asigna a “Crear una clase llamada %%% que es-a %%%”.

¿Las líneas (línea 2-13) también crean clases o son simplemente como “cadenas”? Porque parece que podría estar creando clases, pero no estoy seguro.

También sé que %%%, * y @@@ realmente serán reemplazados por palabras reales en algún lugar del código, pero no sé cómo ni dónde, porque todo parece muy confuso.

Entonces, ¿alguien puede ayudarme? ¡Gracias!

1 PHRASES = { 2 "class %%%(%%%):": 3 "Make a class named %%% that is-a %%%.", 4 "class %%%(object):\n\tdef __init__(self, ***)" : 5 "class %%% has-a __init__ that takes self and *** parameters.", 6 "class %%%(object):\n\tdef ***(self, @@@)": 7 "class %%% has-a function named *** that takes self and @@@ parameters.", 8 "*** = %%%()": 9 "Set *** to an instance of class %%%.", 10 "***.***(@@@)": 11 "From *** get the *** function, and call it with parameters self, @@@.", 12 "***.*** = '***'": 13 "From *** get the *** attribute and set it to '***'." 14 } 

Ah, y aquí está el código completo en caso de que lo necesite:

 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 '***'." } PHRASE_FIRST = False if len(sys.argv) == 2 and sys.argv[1] == "english": PHRASE_FIRST = True 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[:] for word in class_names: result = result.replace("%%%", word, 1) for word in other_names: result = result.replace("***", word, 1) for word in param_names: result = result.replace("@@@", word, 1) results.append(result) return results 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" 

Las líneas están creando un diccionario de cadenas con claves que tienen una syntax similar a una definición de clase Python válida y valores que describen lo que están haciendo.

Por ejemplo, "class %%%(object):\n\tdef __init__(self, ***)"

Se convierte

 class %%%(object): def __init__(self, ***) 

También sé que %%% , *** y @@@ realmente serán reemplazados por palabras reales en alguna parte del código, pero no sé cómo ni dónde, porque todo parece muy confuso.

Este bit es bastante obvio, por ejemplo:

 result = result.replace("@@@", word, 1) 

Las palabras se WORD_URL = "http://learncodethehardway.org/words.txt" de WORD_URL = "http://learncodethehardway.org/words.txt" .

Básicamente lo que hace el script es:

  1. Importar módulos (random, urllib y sys).
  2. definir alguna variable + crear una lista
  3. crear un diccionario. Aquí aparecen las clases y los símbolos *** o %%%, pero como cadenas, nada mágico.
  4. Se define un conjunto de funciones y bucles para cambiar el flujo de salida.

Si llama al script (digamos desde la línea de comandos, python oop_test.py ), se le preguntarán las preguntas de manera abstracta y luego las respuestas estarán en inglés.

Sin embargo, si llama al script definiendo el argv a inglés python oop_test.py english , obtendrá las preguntas en inglés y la respuesta deberá ser de forma abstracta.

El bloque de funciones da la lógica al flujo. El bloque final try / except llama a las funciones y al diccionario + el módulo aleatorio para aleatorizar las palabras importadas desde la url.