Crash on simple program
I am writing my first Python program. The code so far is what is shown below. For right now, it draws a square grid on the left side of the screen, in landscape mode. When I get parts of it working, I will begin to worry about issues like switching from landscape to portrait, but that’s for later. The goal right now is to draw a 6x6 grid and respond to finger touches.
<<How do you use this forum? I can’t scroll it up to see my message as I am typing it in! I lost track of where I was and can’t figure out how to get back to it. Attempts to position the caret seem to just toggle between composition (keyboard active) and display (keyboard gone). Attempts to position the caret are frustrating because instead of dragging the carer, it scrolls the window. And the caret seems to have an off-by-one-line error; when I finally get it positioned, the typing goes into the line avove. And the window does not autoscroll when I’m typing into it, so the bottomost line is invisible behind the keyboard.>>
Before I lost track of where I was, I started to explain that the program crashes after 20 seconds. I’m using the Python 3.x version to run it.
I conjecture two explanations:
There is a bug in Pythonista or Python that I am hitting
I am doing something in this code that is frantically consuming resources, and when they run out, instead of a friendly warning telling me where it failed, it just quits.
The most likely candidate is the second item. Can someone check the code below and see if I have committed some egregious newbie errot?
from scene import * # A square is defined by a tuple # x0, y0, x1, y1, count # class dig (Scene): def setup(self): self.background_color = 'green' def update(self) : width = min(self.size, self.size) background('green') fill('red') stroke(1,1,0) stroke_weight(3) rect(0,0,width,width) print('rect(', 0, ',', 0, ',', width, ',', width, ')') delta = width/6 # draw the vertical grid lines stroke_weight(1) for i in range(1, 6): line(i * delta, 0, i * delta, width) # draw the horizontal grid lines for i in range(1,6): line(0, i * delta, width, i * delta) run(dig())
<<this line was the vestigial line that I lost track of>>
But the problem is that this runs for about 20 seconds,
@supuflounder also, for the classic render loop style code, I believe drawing should go inside draw(), not update(). I don't know if update clears the drawing context each time, so you might be drawing thousands of items.
You might also look into some of node based approaches-- basically you would have a single image representing the board, and sprites representing x or o's.
@cvp: there is no animation because this represents about 2% of the total code that this app will need
@JonB: I based my code on the example found in
It seems to put the drawing code in ‘update’ and there is no ‘draw’ method.
If this is not the correct way to do it, perhaps this example should be changed.
I converted it from ‘update’ to ‘draw’, no joy. Still crashed after 20 seconds. I commented out the print statement, twenty minutes ago, and it is still running. This is sort of scary; how could a print statement cause it to crash? And if the answer is “it filled up the console buffers and ran out of space,” the question then becomes “how could this be allowed to happen?” It could stop logging, it could issue an error message and stop the program, it could start throwing away lines at the beginning. I was using all of these techniques 25 years ago. I could even detect a recursive function running out of stack space, and stop execution. I did that 30 years ago. So I am very disturbed when a program whose purpose it is to help people learn a language can be crashed by too many print statements.
So I tried to use touch_began, and it did not respond to touches. I had put a print statement in,
def touch_began(self, touch): x, y = touch.location print('touch_began [', x, ',' , y, ']')
and if I touched the scene at all, no printout seems to have occurred. Any ideas what I’ve done wrong now?
Some more study suggests that I probably want to represent the 36 squares as ShapeNode subclasses. I am expecting that the list is in Z-order, from bottom to top. What I then want to do is place the animated nodes, a different subclass of ShapeNode, at the end of this list, so they appear on top of the squares. These nodes may be removed by a user action (for example, a successful hit). These shapes may span several squares (they are long and thin, think snakes).
I’ve written a book which had many chapters on graphics APIs in Windows, and pre-retirement I taught courses on this, so I am not a newbie at graphics and animations; my problem is to map what I know to the Pythonista libraries.
I agree, print problem sounds like a bug, though I couldnt reproduce it on my iPad. Maybe log a problem over at the github Pythonista-Issues repo.
As for printing, use single argument print -- i think the scene hijacks the stdout and stderr write, which is called multiple times for multiple argument print, and so only the last one shows. so use
Maybe more useful is a scrolling logging console overlay. Here is a simple one made out of LabelNodes. they scroll when new text is added, and fade and remove after a little time.
btw, stacking height is controlled by a node's z_position, rather than order in a list.
@supuflounder, which class your
touch_beganmethod belongs to?
class dig(Scene) ...other methods, setup, draw,etc. def touch_began(self, touch): x, y = touch.location print('touch_began [', x, ',', y, ']')
This was based on the example found here
again, in this particular case the problem is the use of multiargument print command. see above
I’m not sure what problem you are referring to. The initial problem was (and still is) a tendency to crash if a print statement was used. The suggestion about using the print statement shown was to avoid the crash, but since I have debugged that piece of code, I have no need of that print statement.
The question now is why doesn’t touch_began get called. I fail to see how the suggestion of the print statement solved that. I did make the change, and was completely unsurprised when the solution to problem A did not fix problem B.
@supuflounder In your code, def touch... seems to have same indentation as the class.
If yes, the touch_began does not belong to the class.
If not, forget my unuseless post 😇
touch_began obviously works, in the examples. Without posting an actual example of something that does not work the way you expect, we cannot possibly debug it for you! cvp speculates an indentation problem. I suspected it was being called but you were being fooled by it only printing out ']' (which is what i saw when i ran your touch_began in a minimal scene example).
if you are still having trouble, post a gist.
I would also recommend trying the logging code i posted, which not only will be easier to debug, but comes with a working touch_began.