-2

I'm trying to solve Ex 41 from Zed Shaw's "Learn Python the Hard Way". I have created the file for it. The exercise retrieves a text file from the author's website. When I run it on the command line (Ubuntu) it just kicks me back to the prompt with no visible output.

I'm not sure how to identify what the problem is. I have tried:

  • Checking the code carefully. The code looks identical to the book as far as I can tell.

  • Running it in IDLE instead, produces no output, just returns to the prompt

  • Running python with -v (which didn't produce anything)

  • Changing the URL to https, and

  • Verifying that the word list is available at that URL (it is).

Any other python exercise I have still runs fine. Is there a way to see more output (like a log file, or a method of forcing more output) where I can try to figure out what is going on?

import random
from urllib import urlopen
import sys

WORD_URL = "https://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 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 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(results)

        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"
partial_mask
  • 77
  • 3
  • 12
  • 3
    Is your question about what's going wrong with this specific program, or about general techniques for debugging code that produces no output? It sounds like the second thing to me. – user2357112 Nov 08 '18 at 19:28
  • Okay, got it figured out. – partial_mask Nov 10 '18 at 03:44
  • 2
    All of the `print`s in this code are inside a function that is never called, so you shouldn't expect any output. I think those last 18 lines of code aren't supposed to be indented that far. – jasonharper Nov 10 '18 at 03:54
  • @jasonharper thanks, I can see what you're talking about. I'll look at the last 18 lines. I'm very new to this, and the book's system works by copying code out of the book and then doing things with it to understand how it works; I may have copied it wrong. Thank you! – partial_mask Nov 12 '18 at 21:29

1 Answers1

1

As jasonharper has mentioned, your prints are called inside convert which is not called at all.

If you're looking for a more general method of debugging for something not happening (let's imagine that you have some really big and complicated script), I can suggest you the following one:

  • put print "start" in the beginning of your script and print "end" before the instruction that doesn't seem to be handled
  • run the script to check whether it's ok with your environment (you should see "start" in the output – but if you, say output into a file, then you'll have to change that or monitor the file instead) and whether python doesn't actually come to the instruction of interest (you shouldn't see "end" – otherwise something's wrong with the instruction itself)
  • now start moving print "end": once at a time, move it out of conditional block or loop or move to first line of function definition or from the function definition to the place where it's called. At some point you'll either see that the "end" output appear (in that case check the condition of the block or return statements inside the function other things that can prevent you from getting to the position where you had print "end" previously); or, like in your example, you'll notice that the call is not in your program at all
  • in some cases, it can be useful to move print "start" instead or besides print "end" – but idea is the same: you moving those closer to each other and look for a moment when "start is shown, end is not" situation changes
YakovL
  • 7,557
  • 12
  • 62
  • 102
  • Thanks, I can see what jasonharper and you are both talking about with the `convert` function. And thank you for providing a systematic way to locate the source of an error in my code. This will be extremely helpful. – partial_mask Nov 12 '18 at 21:23
  • @partial_mask keep in mind that I've described a very basic approach which works with no auxiliary tools; you should also google some "python debugging" since there's lots of tools to do it in a more convenient way. Even SO has such threads, but those are most likely off-topic and old, like this one: https://stackoverflow.com/q/1623039/3995261 – YakovL Nov 13 '18 at 12:06
  • Thanks, yes I understand that. It's great to have a reliable approach that doesn't require any tools, and it's easy to see how it would work to identify the location of the problem. Thanks again! @YakovL – partial_mask Nov 25 '18 at 18:17