Ex41 - Struggling to find my errors

I manually typed all the code out to match Zed’s to the best of my ability: In Powershell Im getting an error:

PS C:\Users\jharr\lpthw> python oop_test.py english Traceback (most recent call last):
File “oop_test.py”, line 73, in
question, answer = convert(snippet, phrase)
ValueError: not enough values to unpack (expected 2, got 1)

It seems its not returning but one value. Also, I dont understand in the function why two lists are created but only one of them are returned? Ill paste the whole script with lines for reference. If anyone is using Atom, is there a debugger or a way to step through the script as it compiles so I can watch what list isnt getting built? I think thats the problem, but I cant be sure. I need to see whats going on. Ex41(oop_test.py):

import random
2 from urllib.request import urlopen
3 import sys
4
154 LEARN PYTHON 3 THE HARD WAY
5 WORD_URL = “http://learncodethehardway.org/words.txt
6 WORDS = []
7
8 PHRASES = {
9 “class %%%(%%%):”:
10 “Make a class named %%% that is-a %%%.”,
11 “class %%%(object):\n\tdef init(self, )" :
12 “class %%% has-a init that takes self and *** params.”,
13 “class %%%(object):\n\tdef (self, @@@)":
14 “class %%% has-a function *** that takes self and @@@ params.”,
15 "
= %%%()”:
16 “Set *** to an instance of class %%%.”,
17 “***.***(@@@)”:
18 “From *** get the *** function, call it with params self, @@@.”,
19 "***.
= ‘***’”:
20 “From *** get the *** attribute and set it to ‘***’.”
21 }
22
23 # do they want to drill phrases first
24 if len(sys.argv) == 2 and sys.argv[1] == “english”:
25 PHRASE_FIRST = True
26 else:
27 PHRASE_FIRST = False
28
29 # load up the words from the website
30 for word in urlopen(WORD_URL).readlines():
31 WORDS.append(str(word.strip(), encoding=“utf-8”))
32
33
34 def convert(snippet, phrase):
35 class_names = [w.capitalize() for w in
36 random.sample(WORDS,
snippet.count("%%%"))]
37 other_names = random.sample(WORDS,
snippet.count("***"))
38 results = []
39 param_names = []
40
41 for i in range(0, snippet.count("@@@")):
42 param_count = random.randint(1,3)
43 param_names.append(’, '.join(
44 random.sample(WORDS, param_count)))
45
46 for sentence in snippet, phrase:
47 result = sentence[:]
48
49 # fake class names
50 for word in class_names:
51 result = result.replace("%%%", word, 1)
52
53 # fake other names
54 for word in other_names:
55 result = result.replace("***", word, 1)
56
57 # fake parameter lists
58 for word in param_names:
59 result = result.replace("@@@", word, 1)
60
61 results.append(result)
62
63 return results
64
65
66 # keep going until they hit CTRL-D
67 try:
68 while True:
69 snippets = list(PHRASES.keys())
70 random.shuffle(snippets)
71
72 for snippet in snippets:
73 phrase = PHRASES[snippet]
74 question, answer = convert(snippet, phrase)
75 if PHRASE_FIRST:
76 question, answer = answer, question
77
78 print(question)
79
80 input("> “)
81 print(f"ANSWER: {answer}\n\n”)
82 except EOFError:
83 print("\nBye")

I have more questions about this script, but Im just trying to get it to run properly first. Thanks in advance.

Is this your code or did you copy and paste the code from the book?

If you can’t find any errors in your script you could try to diff it against the original:

There is pdb. I don’t know much about it, haven’t used it myself.

@Jharris4854 if you are using python3.7 or higher, chuck some breakpoints in the code. But I expect Atom has them. I don’t use Atom but try clicking on the line column as that seem universal on IDEs.

https://www.python.org/dev/peps/pep-0553/

I haven’t seen this exercise in years, but whenever that error comes up, it’s because there are not enough returned values to assign.

question, answer = convert(snippet, phrase)

convert only returns one value. The system is telling you that you are assigning two variables , question and answer to a function call that only returns one value. edit Zed’s code does return two values for results

Hope that helps.

I see that this is what Zed’s code does too, So I’m gonna run it and see whats up. Otherwise I’m really curious also how two values are returning from one variable (results = []). It’s a list, so why are two values assignable?

I have a feeling the indentation is wrong for line 61 and the results.append(result) is outside of your for loop, giving only one result to append to the results.

@nellietobey you were right about the indentation on line 60(in my script). I was up all night working on it and I missed that. THANK YOU. I see what the script is suppose to now but I dont fully understand how the data moves through it to provide the output it does. I know you can unpack a list into to variables, but I need to see it in action to fully comprehend the values that should be returned. I learned java with netbeans bc i ran everything in debugging mode, using step in/step out. Thats how I will learn python. I need a good gui app so I can view multiple objects in the code simultaneously. I downloaded pycharm jetbrains. Is that a good one?

1 Like

Next time Ill do that. Im using windows 10 but I installed the ubuntu shell. Im sure I can use diff with that. Thanks for the response

Thank you for that link! Im going to try that. Im using python 3.8. So, I can use breakpoint() and pdb? I will try them both. Debuggers are my go to for teaching myself coding/programming and understanding how data is processed through the program.Thats how I learned Java in Netbeans. It was a lifesaver.

@zedshaw Knowing what this script does now, I think its amazing how you’re using it to teach proper syntax for accessing object attributes…THANK YOU for designing this and using it in the exercises!!

While Im still on this exercise, how should I interpret the line: question, answer = answer, question? What is getting assigned to what?

It’s just a neat little trick to swap variables.

I actually just discovered that lol. I had to create my own lil debugging with a bunch of print statements. I finally understand this script. Thank you for your responses and input.

PyCharm is pretty good and getting familiar with it helps with the all other JetBrains IDEs.

Or stick with Vim (that incidentally can be mocked in PyCharm).

I don’t use debuggers, print() is my debugger. To each their own. I find I learn way more about whats going on with print than if a debugger is doing all the work for me. But I also learned most of my python without a ‘interactive’ editor that would point things out for me. Just recently started using visual studio, and sometimes just sometimes I’d rather be back in an editor that didn’t always try to ‘help’ me (bluefish, atom, notepad). Try it out sometime. Take a bit of code, in notepad, or atom, and see how much you can debug without a debugger or the hints from the editor. You might find that useful in learning whats going on too. Sometimes a debugger won’t pick up a ‘bug’ because what you wrote is valid, it’s just not what you intended.
–A computer will do exactly what you tell it to, always.
This is where the human error comes in.

Agreed but the ability to view/change values on the fly is the strength of a debugger, even pdb.

1 Like

Ive been doing that for awhile. Its how I first learned to find my errors. I did the print statement thing this time but if I get to the point where I have to analyze more the 500 lines its just too time consuming for me. I learned more about how data gets processed with the debugger than with the print statements in a much shorter amount of time. I can see all data state info at each occurence. It even gives me inside information as to how the IDE makes calls to access modules if you configure it that way. Its just my preference I guess. Different strokes I guess but thanks for the tip. I finally got PYcharm to work with the 3.8 interpreter(it defaults to 2.7 which is useless to me). Anyway thanks again for the advice.

1 Like

Another awesome way to see what your program does is to use pdb with set.trace().

Set the following on top of your code:

import pdb
pdb.set_trace()

and you can step through your code one call at a time. Type “n” (for next) and press Enter for each step.

Hat tip to @ulfen69 for this (Very confused how my code executes through my script)
Here are the docs for Python3.6: https://docs.python.org/3.6/library/pdb.html

1 Like

What is invaluable for me in a debugger is the ability to see the state information for every variable at each line. Its nice drilling into functions and seeing the code from imported modules but seeing the values at any given moment in time is how Ive learned and understood whats going on the best. I tried out pdb…does it do that? I couldnt find a command to accomplish that.

Maybe that is what you’re looking for p expression:
https://docs.python.org/3.6/library/pdb.html#pdbcommand-p

Hello @Jharris4854

I guess that @nellietobey ’s suggestion suits your needs best.
I also put in print statements in the code to see what result I got while coding.
I use to put in both the object to watch and a ”comment”

this_year = 2019
next_year = this_year + 1
print(next_year, ”next_year”)

Here I expect to see 2020. If not, I did something wrong.
But then I hopefully find it quickly.