Scratch is a programming language that is visual and block-based. Developed by MIT and targeted at kids from 8 to 16, but also used by Harvard in week 0 of intoduction to computer science. I am currently taking CS50 with a study group == great reason to play with Scratch this week.

The requirements for Problem Set 0 are open-ended to create a game, interactive story, animation or whatever project you want. I went for implementing a classic, but using cheesecake because that's my naming tradition. Write a program that can count to 100. Replace multiples of 3 with cheese, multiples of 5 with cake, and multiples of both 3 and 5 with cheesecake. πŸ˜‹

tl;dr πŸ‘‰ scratch.mit.edu/projects/459683594


Inspired by FizzBuzz In Too Much Detail πŸ’™ β€” let's dig deeper into doing this in Scratch.

The first working one I made:

when 🟒 clicked
set i to 0
repeat until i = 100
  change i by 1

  if (i mod 3) = 0 or (i mod 5) = 0 then
    if (i mod 15) = 0 then
      say CHEESECAKE! for 2 seconds
    else
      if (i mod 3) = 0 then
        say cheese for 1 seconds
      if (i mod 5) = 0 then
        say cake for 1 seconds
  else
    say i for 1 seconds

Hm… 🀨 2 if else and 2 if and 5 groups of modulo-in-boolean blocks? Something seems overly complicated and weirdly nested. Surely this can be improved?

The second version I ended up with:

when 🟒 clicked
set i to 0
repeat until i = 100
  change i by 1

  if (i mod 3) = 0 or (i mod 5) = 0 then
    if (i mod 3) = 0 and not (i mod 5) = 0 then
      say cheese for 1 seconds
    if (i mod 5) = 0 and not (i mod 3) = 0 then
      say cake for 1 seconds
    if (i mod 15) = 0
      say CHEESECAKE! for 2 seconds
  else
    say i for 1 seconds

3 if blocks stacked up nicely, wrapped inside a single if else. These controls seem more readable. But those conditions are no fun at all, counting a total of 7 modulo-in-boolean groups.

πŸ€”

Both those versions seemed to warrant improvements β€”Β but exactly how wasn't obvious to me. I kept moving around the blocks to a script I expected to work, only for the output to contain different forms of duplication. Why was this more elaborate than for example a Python implementation?

A-ha. Scratch 3.0 doesn't have an elseif. I was trying to check for multiple conditions without nesting, when that is just not available in this language. The If () Then, Else (block) is a control that can check for one condition, there's no way I check for two conditions simultaneously.

JS doesn't have an elseif keyword either, but examples from MDN show this chaining:

if (condition1)
  statement1
else if (condition2)
  statement2
else if (condition3)
  statement3
else
  statementN

But when that same nesting is indented properly, it looks like this:

if (condition1)
  statement1
else
  if (condition2)
    statement2
  else
    if (condition3)
// and so on

🀯

When my brain understood properly that if else was all I had in this language β€” and that the blocks basically makes it look different than it does the way it might in JavaScript β€” it was easier to stop trying to reach for something not there, and instead figure out how to optimize what I had.

Third and improving:

when 🟒 clicked
set i to 0
repeat until i = 100
  change i by 1

  if (i mod 3) = 0 then
    if (i mod 5) = 0 then
      say CHEESECAKE! for 2 seconds
    else
      say cheese for 1 seconds
  else
    if (i mod 5) = 0 then
      say cake for 1 seconds
    else
      say i for 1 seconds

We now have 3 if else and 3 modulo-in-boolean. Much better!! But kinda arranged "more clever" than necessary? I think I prefer this next way of using one additional level of nesting, but with the benefit of a nice pattern to how if else if else if else are nested. πŸ‘‡

Fourth and favourite implementation:

when 🟒 clicked
set i to 0
repeat until i = 100
  change i by 1

  if (i mod 15) = 0 then
    say CHEESECAKE! for 2 seconds
  else
    if (i mod 3) = 0 then
      say cheese for 1 seconds
    else
      if (i mod 5) = 0 then
        say cake for 1 seconds
      else
        say i for 1 seconds

Check it out on scratch.mit.edu/projects/459683594

Are there any other ways this can be improved?

Variables?

When starting out, I misunderstood and thought I had read that variables in Scratch could only store numbers. But I can delare variables for strings too, so let's see what that looks like…

String concatenation?

Nope, I can declare variables for cheese and cake, but I can't use the + operator to say cheesecake. The sprite will then say 0. I will just leave the words directly in the say blocks. (EDIT: ah, there is a join but having to declare and then set variables to cheese and cake, not really an improvement of this script.)

Lists?

I grabbed the () Mod () block quickly here. But it was different when learning Python a couple of years ago. The modulo operator had been mentioned, but I probably had no clue how to use for anything. When baking a cheesecake at the time, I used range() with step to create three different lists containing the multiples. What would that approach look like here? Scratch doesn't show the relevant blocks initially for some reason β€” you have to create a list first. But there are list blocks available!

Block hacking?

The Scratch forums talk about hacking blocks, that produces some interesting solutions to implementing FizzBuzz. But it is time for me to crawl out of this rabbit hole. Week 1 of CS50 with C awaits!


Questions I may or may not come back to

  • Is there a straight foreward way to get version control of a SB3 file?
  • How does the custom block with a boolean work?
  • What needs to be in place to use different sprites, but not change them between two adjacent multiples? For example that the character's mouth stays open between 5 and 6.
  • …and would it be fun to create a project with multiple sprites to emulate the real life group word game, or would that just make me re-evaluate my life choices?!? 😁

Scratch is fun!

I would have loved for this to have been my introduction to programming concepts. There is something interesting about seeing loops, conditions and statements in blocks like this β€” and now that I have played around with Scratch, it will influence how I doodle out concepts on paper while coding.