May I give up in exercise 43? It was really hard, even I cannot understand exercise 41 as a whole program. I could understand part by part but the logic behind the whole program is difficult to understand. I decided to continue and stuck again in exercise 43
In a wordā¦No. Iām not well verse with words or tact. I am currently struggling with the same areas. I say currently as in the past two to three monthsā¦again. (This is my third time through the book to this point because, in short, āLifeā happens and I have too man 0 days and I become rusty and go back to refresh or just start over.) Lately, as I have been running ex41.py in python, it has helped me start to piece things together as I struggle with understanding the engine. Each chapter interduces you to something you will use or you will use something you have been introduced to. If we skipped say, functions, you would be lost every time we saw foo()
.
Maybe go back to ex41, go over it and note what you do not understand yet and study it. Go over the videos. Look it up. Then maybe 42 makes more sense. What doesnāt, look it up, study it, go over the videos. Then maybe ex43 makes more senseā¦rinse, wash, repeat, repeat.
Each time I go over something I donāt understand it makes a little more sense each time. Like dictionaries, I thought I was going to quit on those, but over time they made sense. As I keep repeating these chapters I get more and more from it and I WILL get these (and that damn engine) as will you.
Keep at it.
I am most certain others will have more articulate and wiser response, with better advice.
Sorry if I read a bit rambly and possibly incoherent, Iāve been up for 20 hrs with 3hrs sleep, Iāll probably read this tomorrow night and wonder what the hell I was saying.
Also, came across this when looking for Chuchillās words and died laughing.
but I didnāt want to seem condescending or belittling.
Iāve got an idea:
You arenāt clear on how the Engine class works right? Now, thereās a huge chance that this is because itās confounded with all the other code so thatās too much information.
What if you created a new python file with only the Engine in it. Itās pretty small, so then your job is to get a game to work using the Engine class but not looking at my code very much. The key to this is to start small and only call functions in the Engine, get it to actually run with a single room class, and slowly get it working.
Next tactic is to copy my game, but do it from the outside without using any of my code and design. First, copy the game using what you know, with if-statements and functions. Then, copy the game but use classes and try to make it work.
When I say ācopyā though I donāt mean go copy the code Iāve written. Thatās not working. What I mean is take my file and run it, study it, copying my text and what happens in each room like youāre a gamer and you donāt have the code. Then, do your own replica using the text and make it work the same.
The reason these two approaches work is they remove information thatās confusing so you can focus only on one particular thing. In the first case, itās just how the Engine works by isolating the Engine on its own and getting it to work. In the second case itās creating a similar game using only your existing knowledge, which teaches you the structure of the game without confusing you with the Engine.
Last little tidbit, when you say you donāt understand the engine have you been running it with printing out every function call? Or, are you staring at the screen trying to read it without running it? If youāre doing the latter then thatās why you canāt figure it out.
How about, try running it under pdb and tracing through it pdb ā The Python Debugger ā Python 3.9.7 documentation
You can tell pdb to stop at any function in the Engine, and to print out and watch variables, then you can step through and study each individual step to see whatās going on. You can watch every variable change and each line of code run. If the raw command line style of pdb doesnāt work, then this might:
Basically, Iām suggesting you do both remove information with my first two suggestions, then increase information with my last suggestion.
Try that, then come back and I have one more thing I can suggest.
in here:
class Map (object):
def __init__(self,start_scene):
self.start_scene = start_scene #it will give a_map.start_scene = ācentral_corridorā, won't it?
def next_scene(self,scene_name): #what this function will do?
val = Map.scenes.get(scene_name) # i guess it try to fetch the value from .get("central_corridor"), so val = CentralCorridor() (?)
return val
def opening_scene(self): #i also donāt get what this function will do
return self.next_scene(self.start_scene)
a_map = Map(ācentral_corridorā)
a_game = Engine(a_map)
a_game.play()
Hereās some reply comments, and then some questions for you to study:
class Map (object):
def __init__(self,start_scene):
#Q: it will give a_map.start_scene = ācentral_corridorā, won't it?
#A: Yes, that's correct, here's how you can see that yourself:
print(">>> Map.__init__: start_scene is", start_scene)
self.start_scene = start_scene
print("<<< Map.__init__ exit: self.start_scene is", self.start_scene)
# Q: what this function will do?
# A: Given a scene name it will look the scene up in the Map.scenes dict
def next_scene(self, scene_name):
#Q: i guess it try to fetch the value from .get("central_corridor"), so val = CentralCorridor() (?)
#A: Yes, it uses .get on the Map.scenes dict to find the one that you've mapped to "central_corridor"
# but, that's just the first call. Later calls change it as you enter new rooms. Here's how you can
# see that:
print(">>> Map.next_scene: scene_name is", scene_name)
val = Map.scenes.get(scene_name)
print("<<< Map.next_scene: return val is", val)
return val
# Q: i also donāt get what this function will do
# A: It takes the self.start_scene you set in Map.__init__ (see above) and then looks that
# up using Map.next_scene to find the first scene to show the player. Here's how you can
# see that for yourself.
def opening_scene(self):
print(">>> Map.opening_scene: self.start_scene is", self.start_scene)
val = self.next_scene(self.start_scene)
print("<<< Map.opening_scene: returning val is (for first scene)", val)
a_map = Map(ācentral_corridorā)
a_game = Engine(a_map)
a_game.play()
My questions back to you:
- Iāve said in the past that you canāt see what the value of something is by reading the code, and that you have to print everything. Did you do any printing like I have here (and was only showing me the relevant code), or did you not print anything and try to figure it out by reading it?
- If you didnāt have print() statements like I have here printing out every variable in every function, then can you explain why you missed this instruction from me? Maybe I need to do a whole course on just doing this, but Iām pretty sure Iāve said and demonstrated this quite a lot.
- Have you written out the steps that are happening here in a list on paper? That might help you understand since I think what you donāt get is that one function is calling another function or using the results of a previous call. Something like this:
- a_map = Map(ācentral_corridorā) calls Map.init with ācentral corridorā.
- Map.init sets self.start_scene
- Engine calls a_map.start_scene
- Engine calls a_map.next_scene
The print statements Iāve shown you here basically do this. If you run this (after fixing it for your code) youāll see a log of every function call and every variable passed to that function. If you then write these out on paper as steps the program is taking you might finally see whatās happening.
Let me know your answers.
Edit: My editor uses 4 spaces for python indenting so you might have to fix it, but you should probably add these print statements manually to your code instead of pasting mine.
- I do every example you gaveā¦ Sometimes I improvise on something simple, but when it getting more difficult, I still type it and try to understand what does that mean. I also printed out like what you did in the example. The problem I found last few days was I still have a trouble to understand where the code will go after executing one particular code especially in ex43 since there were too many class (I found that the knowledge gap between the previous example was too big). I found a guy try to draw a map how the code works and just realized it jumped back and forth between Engine and Map class, Iāll try to figure it out today.
- Yes i tried to type it was helpful to build my basic understanding. But again, the code in exercise 43 still seems too much for me who ever just had done basic coding in 8 years ago. Yes you are right, I am still a bit confused if there is one function calling another function. I do understand the concept of calling a function with ādef y(x):ā but with a āclass X(object):ā is something new for me.
Okay I get it done finally. Now I could understand the flow and logic of the whole program but that was because you already typed it in the book so the reference and guidance is there. But if you didnāt put anything there, I couldnāt imagine how I can make the code by myself. Especially the code in class Map and Engine will require me to think āfuturisticallyā in order to make it work simultaneously
The key to building more complex things like this is realizing that nobody sits down and makes something complex right away. Itās built up over time as you work and need to solve problems. So, to make something like this donāt try to make it at the start. Pick a specific problem and make a small simple solution to part of the problem, then organically add in complexity as you need it.
In this case, I started with just a simple thing that ran each scene in order. Thatās easy since itās just the scene classes and a list. Then I needed a way for a scene to say whatās the next scene and that led me to making the Map in a first version. Then the Map needed to be run so that made the Engine. Then I kept working on that and slowly got what you have here.
Also, keep in mind this feeling of āIāll never make anything that complex!ā is a matter of perspective. Right now you donāt have a lot of experience of it seems complex. In a few years youāll have the problem that all of your code is too complex (because intermediate programmers love showing off with insanely complex code).
Finally, remember that you shouldnāt be trying to write straight code. Even now when I code something Iām not clear on I do this:
- Write out what I want it to do in plain English.
- Turn that plain English into comments.
- Write simple pseudo code under the comments.
- Turn the pseudo code into real code one bit at a time running it after each change.
- When itās all working, delete the comments that arenāt documentation.
Try that on a few little problems.