Tag Archives: Debug It

Recreating a Python Simulation in Scratch

Cooriemungle_Water_Tank_Cow_Monster-wikimedia-commonsIn my last post, I added my own modifications to the tutorial  Making Breakout by Leonel at codeNtronix.   He also has a number of tutorials about drawing 3D graphics using python and pygame.  I was intrigued by his simulation of a 3D Starfield made using Python and Pygame.  (Thanks Leonel for creating such useful tutorials).

 

His simulation uses a few basic 3D to 2D algorithms, which I don’t fully understand but they are effective at creating the desired effect.  He created this effect with just 80 lines of source code,  Click here to download the full source code from CodeNTronics.

I analysed the code myself to see if I could recreate this simulation in Scratch.

3D Starfield

Scratch Code:  Takes 31 lines of code and painted backdrop and sprite costume in the paint editor.starfield-scratch-stage-codestarfield-scratch-starsprite-code

 

Python code:  81 lines from CodeNTronics, with comments added by me.

# """
# 3D Starfield Simulation
# Developed by Leonel Machava <leonelmachava@gmail.com>
#
# http://codeNtronix.com
# http://twitter.com/codentronix
# """
import pygame, math
from random import randrange

class Simulation:
    def __init__(self, num_stars, max_depth):  # SM- each star needs an individual variable for x,y,depth.  
        pygame.init()   # SM-- does a bunch of pygame stuff to set up screen and clock.

        self.screen = pygame.display.set_mode((640, 480))
        pygame.display.set_caption("3D Starfield Simulation (visit codeNtronix.com)")

        self.clock = pygame.time.Clock()
        self.num_stars = num_stars
        self.max_depth = max_depth

        self.init_stars()  # SM- Tells the program to make the list of stars

    def init_stars(self):
        """ Create the starfield """
        self.stars = []
        for i in range(self.num_stars):
            # A star is represented as a list with this format: [X,Y,Z]
            star = [randrange(-25,25), randrange(-25,25), randrange(1, self.max_depth)]
            self.stars.append(star)

    def move_and_draw_stars(self):
       # """ Move and draw the stars   """   SM Converts the xy coordinates to cartesian to centre stars on screen
        origin_x = self.screen.get_width() / 2
        origin_y = self.screen.get_height() / 2

        for star in self.stars:
            # The Z component is decreased on each frame. SM-- Star Moves closer
            star[2] -= 0.19

            # If the star has past the screen (I mean Z<=0) then we
            # reposition it far away from the screen (Z=max_depth)
            # with random X and Y coordinates.
            if star[2] <= 0:
                star[0] = randrange(-25,25)
                star[1] = randrange(-25,25)
                star[2] = self.max_depth

            # Convert the 3D coordinates to 2D using perspective projection.
            k = 128.0 / star[2]   # SM I don't know where Leonel got this constant 128/depth but it works
            x = int(star[0] * k + origin_x)  #SM-- moves starfield origin towards centre of screen
            y = int(star[1] * k + origin_y)

            # Draw the star (if it is visible in the screen).
            # We calculate the size such that distant stars are smaller than
            # closer stars. Similarly, we make sure that distant stars are
            # darker than closer stars. This is done using Linear Interpolation.
            if 0 <= x < self.screen.get_width() and 0 <= y < self.screen.get_height():
                size = (1 - float(star[2]) / self.max_depth) * 5
                shade = (1 - float(star[2]) / self.max_depth) * 255
                self.screen.fill((shade,shade,shade),(x,y,size,size))

    def run(self):
        """ Main Loop """
        while 1:
            # Lock the framerate at 50 FPS.
            self.clock.tick(50)

            # Handle events.
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return

            self.screen.fill((0,0,0))
            self.move_and_draw_stars()
            pygame.display.flip()

if __name__ == "__main__":
    Simulation(256, 32).run()

Reflection:

The python program presents a much more realistic starfield and is much more versatile. But the scratch program accomplishes the same task in 1/4 the length and it is much easier for me to tinker with the variables and formulas to change the appearance in SCRATCH. It is an accomplishment that I can understand enough of Python to recreate the essential features of a program in SCRATCH. To use the analogy of spoken languages, I think that I have progressed to the point that I can understand a bit of what I read and hear in PYTHONESE, but I cannot yet speak it like a native. This is very good progress for 10 days. To extend the spoken language analogy, one of the common exercises for people learning a second language is to translate passages from one language to another.  That is exactly what I attempted here, and I am quite satisfied with the results.

Week 3 Roundup

This week has been quite busy at work with finishing report cards and all the end of the year assemblies and activities.  Just 4 teaching days and 1 PA day to go.

On to my CCOW activities this week.

Cumulative Activity: Games:  In this week’s “big project”, you’ll develop a game — a Scratch project that includes interactions between sprites, score, and levels.

Follow My Song

I was quite excited to try coding a classic pattern game like Simon.  I also wanted it to be a bit of a musical primer so I based the tones on a pentatonic scale.  The game does not have overt scores or levels but it does change in difficulty and speed as the pattern gets longer and longer.  This game is a classic.  Simple enough to need no instructions other than “Follow My Song”, but difficult enough to keep people wanting to play it more.

My imagination kept introducing `feature creep’   with ideas like making alternate costumes for the sprites like piano keys, guitar frets and flute and trumpet fingerings, and making a standard set of variables so that I could code a kind of framework or API to make music games using scratch.  In the end, it was enough of a challenge just to try to make compact, simple code to show the sprites, change their colors, and detect key presses and see if they match a pre determined pattern.  I ended up making 8 almost identical sprites (one for each note in a major scale).  I am pretty sure I could have done this using lists, multiple clones of one sprite, and variables to change the color and tone of each sprite.  In the end it was just easier to duplicate 1 sprite 8 times and change the code for each individual note.

Somewhere between the keypress and my broadcast to check it against the random list of the computer’s pattern, a glitch appeared in that it does not call game over until one press after you make a mistake.  Thus if you make a mistake on the last note of a pattern, you get to go to the next level.  I have not figured out how to solve it because I can’t find the error in my reasoning or in my code to check the pattern.

One of my third grade students told me that I should just say that this is part of the game, because it is fair to give people 2 chances.  I think I’ll stick with her answer, although the glitch is still bugging me.

Readings:  Illich, I. (1971). Deschooling society (Chapter 6). New York, NY: Harper & Row.

I have not had alot of time to flesh out my thoughts, but I’ve been thinking about how much Illych’s article on education webs foretold what we are doing here.  We have a MOOC with over 1900 members, from all over the world.  We are the self selected peer group, the facilitators are  expert support. We have wikipedia, coursera, and quick access to almost all academic literature, books, and media throughout history at our fingertips.   I think Illych would have quickly grasped the possibilities of the Internet for self-directed learning.   How else does our experience in this course resemble what Illych was describing?

Subtasks

  1. I made a post with this week’s Debug it activities on Sunday.
  2. Levels— I read through this activity and but did not do the assignment of looking for different ways people code levels using scratch.  I think I have a good handle on different ways to have levels in games with increasing speed, increasing difficulty, a change of scene or more adversaries with greater skills.
  3. Score:   In this activity, we needed to remix Fish Chomp by adding a score using variables.   Here is mine:

 

I added a countdown timer to make the game last for 60 seconds, and gave one point for each fish caught. I also added a global High Score Variable stored in the cloud. That means that you can compete against other scratchers for world bragging rights.

I added a Start Game broadcast for the purple fish because for some reason I had to press the green flag twice to get them to move and react with the yellow fish. It didn’t do that in the sample code, so I think it was something to do with my timer code or my if-then-else blocks.

Questions:     What is a variable? A variable is a letter or name that can have a “variety” of values.  Its value can vary.
 How would you explain variables to young learners?  I think that giving variables literal names like ‘score’ and ‘time-left’ can help them to make the connection between what is going on in the game and the idea of variables in math class.  I think the first time the concept of variables really clicked for me was when I was 12 or 13 and learning to program simple games in BASIC.  I think the same thing could happen using SCRATCH with young children.

4.  Interactions:  In this activity, we were given 9 specific tasks to try to code.  Here are my Interactions:

 

  •  Questions: Which puzzles did you work on?,       What was your strategy for solving the puzzles?     Which puzzles, if any, helped you think about your game project?

I got cute and tried to do them all in one project.  This was actually more difficult because some of the activities interacted with the others, creating more complexity.  After about 2-1/2 hours, I stopped with about 6 of them done.   Below each task I reflect on how I did it and answer the questions.

    • Whenever you press the B key, the sprite gets a little bigger. Whenever you press the S key, the sprite gets a little smaller.    This was pretty straightforward.  I programmed the cat to grow and shrink with these keys, and made it move with the arrow keys.
    • Whenever the sprite hears a loud sound, it changes color.  I did not do this one, but I have a pretty good idea how I would do it with the sensing blocks.
    • Whenever the sprite is in the top 25% of the screen, it says “I like it up here.”
      I made a sloping background and had the cat say this above about y 100.  The hardest part of coding this was the code to make sure the characters could not walk into the sky.  I did this with a `not touching green statement` so that it would also not walk through other sprites.
    • When the sprite touches something blue, it plays a high note. When the sprite touches something red, it plays a low note.
      I did not code this one either.  
    • Whenever two sprites collide, one of them says: “Excuse me.”
      Done.
    • Whenever the cat sprite gets near the dog sprite, the dog turns and runs from the cat.
      I had the dog move towards the cat then turn a 180 and move back 50 steps.  It fulfils the task but makes for a yo-yo frenetic effect.
    • Whenever you click on the background, a flower appears at that spot.
      I used clones of one flower sprite.  When the stage is clicked it chooses a random color and size.  I also had a random location, then changed it to the position of the mouse pointer as per then instructions.
    • Whenever you click on a sprite, all other sprites do a dance.
      I did not do this, but I think I was going to do a loop with the whirl effect forward and back on the flowers.  I did end up using this technique with a looks block in my `Follow my song` game the next day so thinking about this challenge helped.
    • Whenever you move the mouse-pointer, the sprite follows but doesn’t touch the mouse-pointer.  At first I had the cat then the dog follow the mouse pointer, then I added the butterfly because it was tricky to add this code along with the other things I had the cat and dog doing.

Random Coding Fun

Last week, the facilitators introduced a change to the process of submitting and reviewing design notebooks.  Now we just need to submit the link to our design notebook (or noteblog), then choose peer notebooks ourselves from a numbered list of all the submitted notebooks for the week.  One of the participants on the forums requested a way to choose a random notebook on the forums.   kb8ywp used SCRATCH to code a perfectly useful, but visually plain  Random Notebook Number Generator

On a whim, I remixed it to add a bunch of randomly placed notebooks, and included a cloud variable which remembers when someone enters the number of notebooks for the week, so you only need to re-enter that number if it has changed.  My changes were mostly cosmetic, and not needed, but it made for a fancier Random Notebook Number Generator remix.

Here it is nearly midnight on a Friday night. I think my CCOW week 3 is finished. I`m looking forward to the next three weeks and my self-directed project, but I still have no idea what that might be. I`m sure something will come to me. And only one more week of doing both schoolwork and workshop work. Yipee.

Week 3 Debug It

DebuggingTime for Week 3’s Debug it activities.  I love how the facilitators use broken code to teach new coding concepts in this workshop.

Here are this week’s challenges.

  • Debug each of the five Scratch programs in the Week 3 Debug It! studio.
    • Debug It! 1
      In this project, the “Inventory” list should be updated every time Scratch Cat picks up a new item. But Scratch Cat can only pick up the laptop. How do we fix the program?
    • Debug It! 2
      In this project, Scratch Cat gets 10 points for collecting Yellow Gobos and loses 10 points for colliding with Pink Gobos. But something isn’t working. How do we fix the program?
    • Debug It! 3
      In this project, Scratch Cat is thinking of a number between 1 and 10. But something is wrong with the guess checking — it doesn’t work consistently. How do we fix the program?
    • Debug It! 4
      In this project, the “# of hits” display should increase by 1 every time the Scratch Cat is hit by a tennis ball. But the “# of hits” increases by more than 1 when Scratch Cat is hit. How do we fix the program?
    • Debug It! 5
      In this project, Scratch Cat is navigating a maze to get to the yellow rectangle. But Scratch Cat can walk through walls. How do we fix the program?

None of the challenges stumped me this week.  In fact I usually found the bug on my first pass through the code.   I think I have internalized many great problem solving strategies over the years.  But for debugging and when looking at code I tend to ask myself 3 questions?

  • What is this code supposed to do?
  • What is it actually doing?
  • How can I fix it?

This can then lead to:

  • How else can I fix it? 
  • Or: What is the simplest fix?
  • And: How can I change or extend the code from here?

I think it is important to teach children that in programming, as in life, there are many different ways to get to the desired outcome, and some are easier than others.

Here are my solutions and reflections on the challenges.

Debug-It 3.1 remix In the code for sprite4 (the laptop), it looked for when it was touching (sprite1– the cat) then disappeared and added the laptop to the inventory.
The code for sprite 2 (cheesy puffs) was looking for when it touched sprite 3 (the lamp) were and the code sprite 3 (the lamp) or was waiting to touch sprite 4- the laptop. Because only scratch moved, he only ever picked up the laptop. Solution– change the code blocks for sprite 2 and sprite 3 to look for when they touched sprite 1.

Tip– change your sprite names to descriptive names like cat, laptop, etc… so it is easier to see where there may be an error.

Debug-It 3.2 remix In the code for the yellow sprites, if it was touching the cat, there was a block that said to add 10 points to the score then hide. In the code of the pink sprites it said to wait for touching the cat then gave no further directions. I added the blocks to add -10 points to the score and hide the sprite to each pink sprite. Problem solved.

*Note to self. In the example they set up separate code for 6 pink and 6 yellow sprites. I think you could add more variety to the game, and less chance of bugs by using the clone sprite function and some random generators for to vary the number of each kind of sprite, their location, and even how often they appear on screen.

Debug-It 3.3 remix: Simple error. In the code checking if the secret number was greater than the guess it checked if it was < the guess. I just had to change the code block to if secret number > guess.

*note to self: I suppose I could have just reversed the conditions to ‘if guess is < secret#’ and that would have had the same effect.

Debug-It 3.4 remix: What was happening is that the hits kept incrementing while the ball was crossing Scratch for multiple hitcounts for each contact. I added a block of right after the hit count incremented and before the repeat. This made the counter increment only once for each contact.

Note to self: It would be neat if the ball bounced off of scratch when it hit him. One method I saw online was to add “point to sprite1” then “turn 180%” to have it bounce off the other sprite in a roughly realistic bounce. I think the accuracy of the bounce would depend on how large the sprites are and how scratch determines the location of a sprite. How does it do that? Does it use one of the outmost corners for the x,y value or a mean of the x and y values? I need to do some research and experimenting on this one.

Debug-It 3.5 remix:: I added this code to detect when Scratch is touching green walls. Forever {{If touching green then move -10 steps]}
*An alternate would be to only let him move if he is touching the white path. This would enable him to navigate a multicolored maze, as long as the path was white.

CCOW Week 2 Debug It

I’m loving these debug it activities. It is a great way to teach problem solving strategies and lateral thinking. It is also a great way to introduce need coding concepts.

2.1:  Original project: Debug-It 2.1 by karenb   My solution: Debug-It 2.1 remix

My Solution:
1st try- move define block code to stage… no change.
2nd try- copy define block code over to Gobo… no meow.
3rd try– drag sound “meow” from Scratch sound window to Gobo sprite icon. Success!

2.2: Original project: Debug It! 2.2 My solution: Debug-It 2.2 remix

My Solution:
The original counting code was set to always repeat (10).
I dragged the blue (answer) oval into the repeat block.
Success!
(And I added a trumpet sound when scratch is finished– Just because).

2.3: Original project:Debug It! 2.3 My solution: Debug-It 2.3 remix

My Solution:
The original code has no pauses after each talk statement and the broadcasts to call the other sprites are sent in no particular order.
Solution:
Add a wait 1 second after each statement and broadcast.
Place the podcast block for each sprite directly after Scratch calls them.

2.4: Original project: Debug It! 2.4  My solution:Debug-It 2.4 remix

My Solution:
In the script for SCRATCH Cat after he say’s jump, I added a
[broadcast (jump)] block.

2.5: Original project:Debug It! 2.5 My solution: Debug-It 2.5 remix

My Solution:
This one was trickier.

I added a little script for each background:
When Background switches to (x) –> hide dinosaur — stop (all)–

For the auditorium block I added a show block just before the dinosaur.

Week 1 DeBugIt

Summary of the Debug It  activity:

Debug each of the five Scratch programs in the Week 1 Debug It! studio.

    • Debug It! 1
      When the green flag is clicked, both Gobo and Scratch Cat should start dancing. But only Scratch Cat starts dancing! How do we fix the program?

    My solution:  This was an easy one.  I clicked on the sprite for gobo and it’s script did not have a ‘when green flag clicked’ block on top of the code so I added it.

    • Debug It! 2
      In this project, when the green flag is clicked, the Scratch Cat should start on the left side of the stage, say something about being on the left side, glide to the right side of the stage, and say something about being on the right side. It works the first time the green flag is clicked, but not again. How do we fix the program?

    My solution:   At the beginning of the script, right after the ‘when green flag clicked’ block,  I added a block to ‘go to x:-120, y:0’.  This will give him a starting position on the left.

    • Debug It! 3
      The Scratch Cat should do a flip when the space key is pressed. But when the space key is pressed, nothing happens! How do we fix the program?

    debugit1.3

    Iniitial code:  This one stumped me.  I tried it with and without the top block, I tried placing in a when green flag block, I even tried replacing the 4 blocks with 4 “point in direction __’ blocks. Then I tried it with only 3 blocks and the problem became apparent.  The code was working just fine– just too quickly for the eye to see.

Solution: Put one ‘Turn 90 degress’ block and a ‘wait 0.25’ seconds block in a ‘repeat 4’ block.

    • Debug It! 4
      In this project, the Scratch Cat should pace back and forth across the stage, when the Scratch Cat is clicked. But the Scratch Cat is flipping out — and is walking upside down! How do we fix the program?

    debugit4

Another simple fix.  Click on the little blue ‘i’ on Sprite 1 below the stage to open up sprite properties.  Change rotation style from the circle (360 degrees) to the <-> symbol.   It will now just turn left and right.

    • Debug It! 5
      In this project, when the green flag is clicked, the Scratch Cat should say ‘Meow, meow, meow!’ in a speech bubble and as a sound. But the speech bubble happens before the sound — and the Scratch Cat only makes one ‘Meow’ sound! How do we fix the program?

    debugit5

I rearranged the blocks from Say -> Repeat -> Play ->   to  Repeat [ -> Say-> Play]

Questions:

 What is one debugging strategy that you used?
     How would you help someone else learn how to debug a project?

I have difficulties answering because I just did it.  But my problem solving process seems to ask myself a series of questions:

  1. What is the code supposed to do?
  2. What does it actually do?
  3. Are there any obvious errors in spelling, order or logic?
  4. How can I fix the errors?
  5. How can I work around the errors?

Obviously it is more desirable to fix the problem, but sometimes a workaround will allow you to achieve the intended results (although it may not fix the underlying problem, and it may create more problems).

 

In answer to the second question, I would help someone debug a project by saying the above internal dialogue outloud, so that they can see that debugging is a process of asking questions and trying out different solutions.