Code, Click, Spin:

Code, Click, Spin:

Bridging Computer Science, Design, Math, and Physics to build a Digital Spinner


Author: Avi Megiddo

Introduction

Integrating technology in education is about more than just using new tools; it's about enhancing the way we teach and learn. This article focuses on a practical project: creating an interactive spinner that can be used in classrooms or software applications/platforms such as Scratch and other web applications. The spinners themselves, the code that creates them (which can be customized, for example, to someone's color palette/naming/numbering preferences), and the Dynamic Spinner Scratch project offer a wide range of educational applications. Beyond these, the project serves as an interdisciplinary example, integrating elements of math (probability and statistics), computer science (coding and software development), art (design principles and color theory), and even language arts (narrative storytelling through interactive choices).

YouTube demo link:


Other software application/platform ideas where this can be used include games, for example, Scratch games involving prizes), decision-making tools (for example: spinners can serve as impartial decision-makers for group activities, project topic selections, or deciding the order of presentations), and Art and Design; spinners could determine themes, color schemes, or the code can be adapted to produce SVG files for laser cutting.

Each of these applications not only makes learning more interactive and fun but also demonstrates the versatility of coding and design skills in solving real-world problems. By integrating such projects into the curriculum, educators can provide students with meaningful opportunities to apply their knowledge across disciplines, preparing them for the complexities of the modern world.

The tool uses visual programming in Scratch to allow for dynamic interaction, simulating physical forces through variables and loops. It also utilizes a Python function written with ChatGPT to generate the spinners 2 through 40 spinner sectors (wedges or slices) for a range of applications. The function can be run in Google Colab, a cloud-based Python notebook environment that empowers users to execute code, share work, and access a vast array of computational resources — all within a browser.

Using Scratch for the initial design, and then leveraging Python code generated through conversation with ChatGPT, made to run with Google Colab proved successful. This project illustrates how educators can develop/utilize engaging and educational software. It's especially relevant for teachers involved in MYP Design and DP Computer Science, showcasing a blend of programming, design, math, and physics. This article will explore the project from inception to realization, detailing each stage's technical and educational merits.


Making the Spinners

Programmatically-generated spinners? ? Avi Megiddo 2024


The idea was to converse with ChatGPT to write the code that creates spinners up to 40 slices/sectors/wedges.? This would make the sector size of the 40-participant spinner 360/40 = 9 degrees to work with for adding the number and the virtual spinning peg, represented by a metallic color circle (this circle color is used by the code as a trigger to make the ticking sound as each peg hits the flapper.? More on the Scratch part later. The task was to create the spinners programmatically, with random colors, and get the code to save them to my desktop in a folder, with a consistent file name convention.? If this task proved successful, I could import them into Scratch as spinner sprite costumes, and call them dynamically based on the length of a list of names entered by a user (the participant list).?

The goal was to create a Scratch project in which the teacher/user can simply type or paste a comma or space-delimited list of students,? and Scratch functions would do the rest; parse the input string and convert it to a list, and determine its length, and get a spinner with the corresponding number of sectors.

Colaboratory and ChatGPT

I wanted a function that can be copied + pasted into Colaboratory,? "just press play", and have it generate the spinners from 2 to 40 sectors, with numbers, and dots representing pegs/handles to simulate where the user would hold and spinner if it were real.

Colaboratory, or "Colab" for short, is an educational tool that is particularly useful for coding in Python. It's a free, cloud-based platform that allows users to write and execute Python code through their browser. It is especially beneficial in educational settings for a few key reasons:

  • Accessibility: Colab runs on the cloud and is accessible from any computer with internet access, which means students and educators don't need to install Python or other libraries on their local machines. This also facilitates easier sharing and collaboration.
  • Integration with Google Drive: Since it integrates seamlessly with Google Drive, educators and students can easily save, share, and comment on notebooks, similar to other Google Suite applications.
  • No Setup Required: Colab comes pre-installed with many libraries, eliminating the need for complex setup processes. Educators can focus on teaching programming concepts rather than troubleshooting installation issues.

Python Function in Colab

Conversing with ChatGPT, I was able to successfully code a Python function that generates my desired range of spinners up to 40 sectors, with different numbers of slices, colors, and metallic pegs, outputting them as PNG files in a zipped folder. Here’s an overview of the function and its components:

  • generate_random_color: Generates a random hex color for the spinner slices.
  • generate_random_metallic_color: Chooses a random metallic color for the pegs, enhancing the visual appeal.
  • generate_spinners_png_enhanced: The core function that creates a series of spinner images with varying numbers of slices. It performs the following steps: It sets up a figure with Matplotlib, ensuring the aspect ratio is equal and axes are turned off for a clean visual. A loop creates individual slices (wedges) with unique colors and places numbers on them, adjusting font size for readability. Pegs are added to each slice, using a metallic color for visual effect. The spinners are saved as PNG files and then zipped together for easy download. Integration with Google Colab's files.download allows for direct downloading of the zip file when run in Colab.

import matplotlib.pyplot as plt
import numpy as np
import os
from matplotlib.patches import Wedge, Circle
import matplotlib.patheffects as PathEffects
import shutil

def generate_random_color():
    """Generate a random hex color."""
    return "#{:06x}".format(np.random.randint(0, 0xFFFFFF))

def generate_random_metallic_color():
    """Generate a random metallic color (gold, silver, or gray)."""
    metallic_colors = ["#ffd700", "#c0c0c0", "#808080"]
    return np.random.choice(metallic_colors)

def generate_spinners_png_enhanced(num_slices_start, num_slices_end, filenames_prefix, output_zip):
    temp_dir = 'spinners_png_enhanced'
    os.makedirs(temp_dir, exist_ok=True)

    for num_slices in range(num_slices_start, num_slices_end + 1):
        fig, ax = plt.subplots()
        ax.set_aspect('equal')
        ax.axis('off')
        fig.set_size_inches(6, 6)

        radius = 1  # Standard radius for simplicity
        border_width = 0.05  # Width for the border
        peg_radius = 0.05  # Radius for the dowel rod peg circle

        # Draw the spinner border
        border = Circle((0, 0), radius + border_width, color='black')
        ax.add_patch(border)

        # Generate a random color for the pegs
        peg_color = generate_random_metallic_color()

        for i in range(num_slices):
            color = generate_random_color()
            start_angle = i * (360 / num_slices)
            end_angle = (i + 1) * (360 / num_slices)
            wedge = Wedge(center=(0, 0), r=radius, theta1=start_angle, theta2=end_angle, facecolor=color)
            ax.add_patch(wedge)

            # Calculate the angle and position for the text
            text_angle = np.radians((start_angle + end_angle) / 2)
            text_x = 0.85 * radius * np.cos(text_angle)
            text_y = 0.85 * radius * np.sin(text_angle)

            # Set font size relative to number of slices
            min_font_size = 12  # Adjust as needed for visibility in Scratch
            font_size = max(min_font_size, radius * 0.1 * 20 / np.sqrt(num_slices))
            text = ax.text(text_x, text_y, str(i + 1), ha='center', va='center', 
                           color='white', fontsize=font_size)
            # Create a text outline for readability
            text.set_path_effects([PathEffects.withStroke(linewidth=3, foreground='black')])

            # Add pegs
            peg_x = radius * np.cos(text_angle)
            peg_y = radius * np.sin(text_angle)
            ax.add_patch(Circle((peg_x, peg_y), peg_radius, color=peg_color))

        plt.xlim(-1.2, 1.2)
        plt.ylim(-1.2, 1.2)
        filename = f'{filenames_prefix}_{num_slices}_slices.png'
        filepath = os.path.join(temp_dir, filename)
        plt.savefig(filepath, bbox_inches='tight', transparent=True)
        plt.close()

    # Zip all the PNG files
    shutil.make_archive(temp_dir, 'zip', temp_dir)
    
    # This function assumes you're using this in a Google Colab environment. 
    # If you're not, you'll need to find another way to download the files.
    try:
        from google.colab import files
        files.download(temp_dir + '.zip')
    except ImportError:
        print(f"The zip file is saved as {temp_dir + '.zip'}.")
        print("This environment doesn't support automatic downloads.")

# Example usage to generate a zip file of enhanced spinner PNGs
generate_spinners_png_enhanced(2, 40, 'spinner_enhanced', 'spinners_enhanced.zip')
        

Detailing the Spinner Creation Function

This function is designed to generate an interactive classroom spinner, focusing on practicality for class sizes up to 40 students. Each spinner sector, calculated to be 9 degrees for clear visibility, represents a student with unique colors and pegs for easy identification.

The user interface prioritizes direct interaction, considering enhancements like Scratch's color sensing for dynamic user engagement. Development benefited from iterative conversations with ChatGPT, focusing on refining technical and user experience aspects. The result is a Python function tailored for educational use, facilitating the creation of customizable spinners.

Python Function Breakdown

Here's how the Python function generate_spinners_png_enhanced works, step by step:

  • Setting Up: The function begins by creating a temporary directory where the generated spinner images will be stored. This organizational step is crucial for managing the files efficiently.
  • Creating Spinner Images: For each number of slices (from num_slices_start to num_slices_end), the function creates a new image. It uses matplotlib to draw each spinner, ensuring the visual elements are proportionally sized and correctly positioned. Drawing the Spinner: Each sector's color is randomized, ensuring a vibrant and engaging spinner. The border and pegs receive special treatment—the border is consistently black for visibility, while pegs are metallic-colored for an appealing contrast. Adding Text: The numbers placed within each sector are carefully sized to be readable regardless of the spinner's size. This clarity is vital for ensuring each student can easily find their corresponding sector.
  • Final Touches and Distribution: After creating all the necessary images, they are saved to the temporary directory and then compressed into a zip file for easy distribution. This step is particularly thoughtful, considering the function's intended use in educational settings where resources need to be shareable.



Key components of the Python function

Each snippet of code plays a crucial role in the spinner's creation, so we'll explore them with the mindset of teaching and understanding their significance.

Initializing the Environment

import matplotlib.pyplot as plt
import numpy as np
import os
from matplotlib.patches import Wedge, Circle
import matplotlib.patheffects as PathEffects
import shutil        

Explanation: Before we start creating anything, we need to prepare our toolbox. This means importing libraries—collections of pre-written code that we can use to perform common tasks. matplotlib is a library for creating visualizations, numpy (abbreviated as np) helps us with mathematical operations, and os and shutil are used for handling files and directories. Think of these imports as gathering your art supplies before you start painting.

Generating Colors

def generate_random_color():
 """Generate a random hex color."""
 return "#{:06x}".format(np.random.randint(0, 0xFFFFFF))        

Explanation: This function is our paint mixer. Colors on computers are often represented in hexadecimal format (a base-16 number system). This function picks a random number between 0 and 16777215 (which is FFFFFF in hex) and formats it as a hex color string. Each time you call this function, you get a new, random color for a spinner sector.

def generate_random_metallic_color():
 """Generate a random metallic color (gold, silver, or gray)."""
 metallic_colors = ["#ffd700", "#c0c0c0", "#808080"]
 return np.random.choice(metallic_colors)        

Explanation: Here, we're selecting a color for the pegs, but we want them to stand out. We choose from a small list of 'metallic' colors to make them visually distinct from the sectors. Using np.random.choice, we pick one at random each time we generate a spinner.

Main Function to Generate Spinners

def generate_spinners_png_enhanced(num_slices_start, num_slices_end, filenames_prefix, output_zip):
 temp_dir = 'spinners_png_enhanced'
 os.makedirs(temp_dir, exist_ok=True)        

Explanation: This is the starting point where we begin crafting our spinners. We create a temporary directory to store our images. If it doesn't exist, os.makedirs creates it for us. This keeps our files organized and in one place, making cleanup and retrieval straightforward.

Drawing the Spinner

for num_slices in range(num_slices_start, num_slices_end + 1): fig, ax = plt.subplots() ax.set_aspect('equal') ax.axis('off') fig.set_size_inches(6, 6)

for num_slices in range(num_slices_start, num_slices_end + 1):
 fig, ax = plt.subplots()
 ax.set_aspect('equal')
 ax.axis('off')
 fig.set_size_inches(6, 6)        

Explanation: For each spinner, we start by setting up a drawing space (fig) and a drawing surface (ax). We ensure the spinner is drawn in equal proportion (not stretched or squashed) and without any axes for a clean look. The size of the figure is set to be large enough to detail, but not so large it becomes cumbersome to work with.

Creating Each Sector

for i in range(num_slices):
 color = generate_random_color()
 start_angle = i * (360 / num_slices)
 end_angle = (i + 1) * (360 / num_slices)
 wedge = Wedge(center=(0, 0), r=radius, theta1=start_angle, theta2=end_angle, facecolor=color)
 ax.add_patch(wedge)        

Explanation: Here, we're slicing the spinner. Each loop iteration creates a new sector (wedge) with a unique color. The angles are calculated based on the number of slices, ensuring each sector is evenly spaced around the circle. This is a bit like cutting a pie into equal pieces, where each piece gets its own unique flavor (color).

Adding Text and Pegs

text = ax.text(text_x, text_y, str(i + 1), ha='center', va='center', 
 color='white', fontsize=font_size)
text.set_path_effects([PathEffects.withStroke(linewidth=3, foreground='black')])        

Explanation: Each sector gets a number, placed in the center for easy reading. The text function puts a number in each sector, and we use path effects to outline the text, making it stand out against the background. This is akin to labeling each pie piece so everyone knows which piece they're getting.

The placement of the text can be adjusted programmatically here, with larger numbers yielding text closer to the circumference.

    text_x = 0.9 * radius * np.cos(text_angle)
    text_y = 0.9 * radius * np.sin(text_angle)        
Spinner text circumference ? Avi Megiddo 2024


Wrapping Up the function

Explanation: Once all spinner images are created, we package them into a zip file:shutil.make_archive(temp_dir, 'zip', temp_dir)shutil.make_archive(temp_dir, 'zip', temp_dir)

shutil.make_archive(temp_dir, 'zip', temp_dir)        


Scratch Implementation

In Scratch, I've utilized event listeners, variables, control flow, and broadcasts to create an interactive spinner that responds to user input. The spinner's appearance and behavior change dynamically based on the number of participants, with a visual display of participants' names and a simulated physical interaction of spinning and slowing down due to friction.

The ticking sound and the animation of the spinner's pegs add a layer of realism, and holding down the spacebar or mouse button increases the force on the spinner, which is visualized through a slider on the screen.

User Interaction and Interface

The spinner is designed with a user-friendly interface. Students can add their names to a participant list, which dynamically alters the spinner's sectors. Each sector corresponds to a participant, creating a visual representation of equal opportunities for selection.

A key feature is the force slider, akin to a throttle, allowing students to control the power applied to the spinner. By pressing and holding the spacebar or mouse button, we can simulate adding force to the spinner, as participants rotate the spinner the other way to gain momentum.? This is visually represented by the force slider's increasing value. These three options for tactile interaction enhance engagement, as students can feel the cause-and-effect relationship between their actions and the spinner's motion.??

UI and UX of the Dynamic Spinner

When it comes to user interface (UI) and user experience (UX) in educational tools, it's crucial to create an environment that is not only visually appealing but also intuitive for the users—in this case, the students and teachers. The spinner tool achieves this through interactive elements that respond to user input in a clear and meaningful way.

Scratch spinner initial UI? ? Avi Megiddo 2024


Dynamic Spinner Selection

Dynamic Spinner's design is not static; it changes based on the number of participants. This is achieved by the ingenious use of Scratch's 'costumes'—essentially different appearances for the spinner. Each costume represents a different number of sectors, and the program switches costumes to match the length of the participant list.

Generating the Correct Spinner

  • Dynamically choosing the spinner: A smart UI feature of the tool is its ability to 'generate' the correct spinner based on the number of participants. It does this by switching the spinner's 'costume' to match the length of the participant list, a method that's both efficient and elegant.


Switch costume to length of participant list? ? Avi Megiddo 2024


This approach frees us from excess work, leveraging Scratch's capabilities to produce a dynamic, responsive experience; just paste or type the participant list with spaces or commas. Through the Scratch interface, educators can effortlessly generate a spinner tailored to their class size, from 2 to 40 students.

Physics Simulation in Scratch

The Scratch platform is not only a tool for teaching coding but also serves as a virtual laboratory for exploring physical phenomena. In this project, fundamental physics concepts are brought to life through code, allowing students to observe and interact with simulations of force and friction.

Physics Behind the Spinner

The physics simulated in your Scratch project is translated into a visual representation in the Python function. While Scratch allows for interactive manipulation of the spinner with a simulation of force and friction, the Python function creates static images that represent the potential states of the spinner.

Simulating Force

The force applied to the spinner is controlled by user input, either through the spacebar or mouse click. This action increases the 'force' variable within the program, accelerating the spinner. The visual feedback through the force slider allows students to see the direct correlation between the amount of force applied and the speed of the spinner. Letting go of the spacebar, or unclicking the mouse/trackpad releases the spinner. The counter-clockwise turning of .2 degrees is meant to simulate raising the peg up to get a big spin with lots of momentum.


Code snippet illustrating force application ? Avi Megiddo 2024


The Force Slider

An integral part of the spinner's UI is the 'force' slider, which visually represents the power being applied to the spinner. Here's how it enhances the UX: users can press and hold the spacebar or mouse button to increase the 'force' variable, with the slider on the screen moving in correspondence. This gives a tangible sense of control over the spinner as if they're physically spinning it in the real world. As the force increases, users see the slider fill up, providing instant visual feedback. This immediate response is gratifying and keeps users engaged in the activity.

force variable as slider input type

Friction and Deceleration

Once the input stops, the spinner doesn't halt abruptly. Instead, it decelerates gradually, simulating the effect of friction. In the code, this is represented by a 'friction' variable, which users can adjust, and a 'force' variable that decreases over time, reducing until the motion ceases. The deceleration process provides an observable phenomenon that educators can use to discuss the principles of friction and its role in motion.

Code snippet illustrating force decrease due to friction ? Avi Megiddo 2024


The code snippet is designed to mimic the effect of a decreasing force acting on the spinner as it slows down. Initially, the spinner turns by a number of degrees determined by the 'force' variable. With each iteration, 'friction' reduces the 'force', resulting in smaller turns until the force is insufficient to make another turn, at which point the spinner stops. While this doesn't explicitly calculate angular velocity, it creates a similar effect: as the available force decreases, the rate of turning (akin to angular velocity) also decreases, providing a practical demonstration of deceleration in a physical system.

Visual List of Participants

In addition to the spinner, the tool displays a list of participants on the screen. This not only ensures transparency in the random selection process but also aids in the learning process. As the spinner slows and selects a sector, students can easily map the outcome to a name on the list, reinforcing the connection between visual cues and data.

In the next section, we'll delve into the physics behind the spinner's motion and how it’s simulated in Scratch, providing students with an intuitive understanding of fundamental concepts like force and friction.

Parsing the Participant List

The participant list is another key aspect of the UI, playing a dual role in both the function and appearance of the spinner:

  • Data Structure and Input: Behind the scenes, the list of participant names—entered as a comma or space-delimited string—needs to be parsed and converted into a list data structure. This is fundamental because lists in Scratch, like arrays in other programming languages, are versatile structures that can store multiple items such as student names.

continued below
Scratch function to parse the comma or space-delimited input string ? Avi Megiddo 2024


Visual Mapping: On the screen, the list is essential for mapping the outcome of the spinner to a participant's name. For instance, if the spinner lands on number 7, everyone can quickly look at the list and see who is associated with that number. This direct correlation between the spinner and the list ensures transparency and fairness in the selection process.


spinner with participant list ? Avi Megiddo 2024


User-Centric Design: This approach keeps the user's needs at the forefront. Educators don't have to manually adjust the tool for different class sizes; the program automatically presents the appropriate spinner. It's a fine example of user-centered design, where the tool adapts to the user's context without additional effort from them.

The combination of these UI/UX features makes the spinner tool not just a functional accessory for the classroom but also a delightful interactive experience. It demonstrates how thoughtful design considerations can lead to an educational tool that's both useful and engaging.

Sound Interaction with Spinner Movement

The snippet of Scratch code you're referring to seems to control the auditory feedback when the spinner is in motion. Here's a breakdown of the logic based on standard Scratch programming patterns:


Event Listener: The when I receive a spinning block is triggered when the 'spinning' message is broadcasted. This typically occurs when the spinner starts its motion, and it sets the stage for what happens next.


Layer Control: The go to front layer block ensures that the sprite responsible for the sound is visually on top of all others. This is more about visual stacking order than sound, but it's useful if the sprite changes visually when the sound plays.



Continuous Checking: The forever loop suggests that the following checks are continuously performed as long as the spinner is spinning.

Color Touch Detection: The if [touching color] conditional checks seem to monitor whether the sprite is touching a particular color. If the spinner has colored sectors and the sprite (perhaps a pointer or peg) touches one of these colors, it triggers the next actions.

Changing Costume: The next costume block typically changes the sprite's appearance. In the context of sound timing, this could be a visual cue synchronized with the sound effect, like a brief flash or bounce to simulate the peg hitting a divider on the spinner.

Sound Timing: The wait until [not [touching color]] block pauses the script until the sprite is no longer touching the color, which likely corresponds to the peg passing a sector boundary on the spinner.


Once it passes, the start sound block plays a click sound, simulating the tactile feedback of a real spinner peg hitting the flapper.

From a teaching perspective, this code is a perfect demonstration of how to synchronize audio with visual elements, a concept that's common in UI/UX design. It's about timing and feedback—critical components in creating an engaging and interactive experience. For students, understanding these concepts can be quite enlightening, tying together elements of design, user experience, and the technical aspects of programming.

The important part is that if we just check for 'touching' of the peg colors, it will tick the whole time the flapper is touching the virtual pegs that slow these contest/raffle spinners.? However, by using wait until not touching, we only make the sound once a flapper touched AND cleared the stick. This functionality helps simulate a physical spinner's behavior and sound digitally.

Implementing the Spinner Flapper in Scratch

In the context of Scratch, here's how the logic simulates the interaction between the spinner and the flapper:

  • Continuous Detection: The forever loop is constantly checking for the condition where the sprite (acting as the spinner flapper) touches a color (representing the pegs on the spinner).
  • Sound Trigger: The if touching color block triggers the next costume change and sound but only if the sprite is currently touching one of the peg colors.
  • One-Time Sound Play: The key to making the sound play just once per touch, rather than continuously, is the wait until not touching color block. It ensures that the clicking sound is not repeated while the sprite is still in contact with the peg's color.

Wait until not touching color

Realistic Ticking: By waiting until the flapper sprite is not touching the peg's color, you ensure the click sound only plays when a peg goes by the flapper, not while it's still in contact. It's this detail that contributes to a realistic ticking sound, just as you would hear on a physical spinner.

Scratch code for spinner flapper interaction ? Avi Megiddo 2024



This approach is an excellent practical example of conditional logic in programming and can be a valuable teaching point. It reflects the importance of precise control flow to create desired behaviors in digital simulations. By carefully structuring when and how events are triggered in a program, students can recreate complex real-world interactions, such as the spinner and flapper mechanism, in a virtual setting.

The user experience can be fine-tuned with attention to detail. In this case, getting the timing right for the spinner's clicking sound is a small but significant aspect of making the digital spinner feel more authentic.

Decreasing Force Each Rotation

The first snippet shows a loop where the force is decreased as the spinner rotates:

repeat until (force - friction < 0)

turn (force - friction) / 5 degrees


Set force to force minus friction





Calculating the winner automatically: the math

  • Manual Orientation: Since I couldn’t get the code to do it, I had to manually adjust the initial position of each spinner image so that the sector border between the last and first numbers is at the top. This ensures that when you start the spin in Scratch, it begins from a known position, namely with the first sector’s right edge lined up with the flapper:


Orienting the spinners ? Avi Megiddo 2024


After some thought and research, it made sense to move the pegs to the start of each sector, multiple reasons for this improvement;? Originally, the pegs were situated at the central dividing line of each sector. They are now repositioned to where the boundary lines between adjacent sectors intersect with the outer edge of the spinner. When a peg passes the flapper, this marks the starting point, or minimum angle of a sector to be the winner.



Pegs at sector intersections and auto-orienting the spinners? ? Avi Megiddo 2024


Calculating the winner by counting pegs

A student asked why we can’t count the pegs that pass by the flapper to determine the winner, instead of calculating degrees rotated.? While in theory, it is an excellent idea, it introduces complexity in terms of programming and may lead to less accurate results. Here’s why:


Data Processing Speed: When a spinner is rotating quickly, the script would need to keep an accurate count of the fast-moving pegs. This requires the program to have a very high refresh rate to capture each peg as it passes by a certain point. If the spinner is moving too fast, it could surpass the processing speed, leading to missed counts and inaccurate results.??

Tracking degrees does not require this, as the degrees are tracked by copying the degrees rotated to make the spinner spin:


There is no need to track each detection of the flapper touching peg color; instead, it is coded in that when the spinner turns (force - friction) / coefficient degrees, the degrees change identically.? So the more precise the spinner costumes are, the more precise the spinner will be.? And they are precise, as they too were made programmatically (no human hand was involved in making lines, measuring, rotating, or adjusting).

Boundary Conditions: When a peg lands exactly on the boundary between two colors, it could be challenging for a simple counting mechanism to determine which color is the winner. The pegs have some diameter and the flapper has some width; the spinner wheel could stop in the middle. A mathematical calculation based on degrees is more precise and can clearly define which sector the flapper points to, even in those boundary cases.

Simplicity and Efficiency: Calculating the winner based on the angle (degrees) is a more straightforward approach. The spinner's final angle can be easily divided by the angle of each sector to determine the winning sector.

Programmatic Consistency: Using angles for calculation ensures consistency and fairness in the result. Each spin will be judged by the same criteria, without the risk of miscounting or the influence of spin speed.

User Experience: For the users, especially in an educational setting, it’s important that the outcome is clear and the process is transparent. The angle-based calculation allows students to easily understand and trust the fairness of the outcome since it can be explained and understood mathematically.

In essence, while the peg-counting method is an interesting concept, it introduces potential inaccuracies and complexities that are efficiently resolved by calculating the winning sector based on the spinner's final resting angle. This method is both precise and straightforward, making it an excellent teaching tool for illustrating probability, randomness, and fairness in games of chance.


Tracking Rotation in Scratch: In Scratch, you can keep track of the degrees rotated during the spin. When the spinning stops, you have a record of the total rotation.

With the known starting orientation and the total degrees rotated, you can calculate which sector the flapper points to when the spinner stops. This can be done by dividing the total rotation by the degrees per sector and then using the modulo operation to get the remainder, which corresponds to the position on the spinner. Scratch has a ‘ceiling’ function that can effectively give the sector number where the flapper is! Here is a preview of the math; more on this later!


calculating the winning number


Resetting the Spinner: After each spin, you can reset the spinner to its starting orientation, ready for the next spin. This could be simply setting the rotation back to zero or to the initial offset if needed.



The Role of the Interior Angle

In a circle, if you want to divide it into equal sectors for each participant, you calculate the interior angle for each sector. The circle has 360 degrees, so if you divide that by the number of participants, you get the angle for each sector. For example, if you have 10 participants, each sector's interior angle would be 360 / 10=36 degrees.

The Modulo Operation

The modulo operation, represented in mathematics as mod, gives us the remainder after division. In the context of the spinner, we use modulo to disregard full rotations. For instance, if your spinner has rotated 750 degrees, you don't need to account for the full two rotations (ignore the fact that 360 goes into 750 twice before that to yield 720; we don’t care about those 2 full spins of 360); we're only interested in the remaining 30 degrees to determine the winner. So,

750 mod??360 = 30 degrees??

This is the equivalent of saying, "after spinning around completely, how far has it gone past the last full circle?"

Meanwhile, you might ask “why don’t I get 30 when I divide 750 by 360?

750 / 360  = 2.08333333333        

That is because mod is a mathematical operation that gives us the remainder after division. But it's specifically talking about the remainder in whole numbers, not the decimal part.? So we need to do one more calculation, and that is multiply .08333… by 360 to see what fraction of 360 is left over:

.08333... x 360 = 30        

When you divide one number by another, you get a quotient and sometimes a remainder. If we're using whole numbers, the remainder is what's left over after dividing as many times as you can without going over. For instance, if we divide 10 by 3, we can fit 3 into 10 three times (which is 9), and we have a remainder of 1.

However, when we're dealing with division that results in a decimal (like 5.255444 when you divide 1891.96 by 360), we're looking at it a bit differently:


Here, instead of thinking about how many whole times 360 can fit into 1891.96, we're considering how much of a full rotation (360 degrees) is left after we've done all the whole rotations we can.

So, if you spin a wheel and it turns 5 full times (which would be 5 times 360 degrees), plus a bit more, that "bit more" is the decimal part multiplied by 360. In this case, 0.255444 of another full 360-degree turn.

Now, modulo — often written as mod — is a mathematical operation that gives us the remainder after division. But it's specifically talking about the remainder in whole numbers, not the decimal part. It's like asking, "After turning fully for 5 times, what's the angle for that 'bit more' of the turn?"

So when we do 1891.96 mod 360, we're saying, "If we ignore all the full 360-degree turns, what's the angle that's left over?" And that's 91.96 degrees. It's the angle past the last full turn the spinner made. Here's the math behind it:

When you multiply 0.255444 by 360, you're converting that fraction of a full turn back into degrees, which gives us 91.96 degrees.

That's the actual angle we need to figure out where on the spinner we've landed. It tells us how far past the last full 360-degree turn we've gone.

For a classroom spinner, this matters because it tells us which sector the spinner is pointing to when it stops. If the spinner has, for example, 25 sectors, we'd then divide this remaining angle (91.96 degrees) by the angle for each sector (which would be 360 degrees divided by 25) to figure out the winning sector.

Using mod helps us work with just the relevant part of the spinner's rotation — the part that determines the outcome. It's a practical way to simplify problems that involve repeated actions, like spinning, to find out what's happening at the end of those actions.

Here's how it might look in Scratch pseudocode:

Set total_degrees to 1891.96
Set full_rotations to floor(total_degrees / 360)
Set remaining_degrees to total_degrees - (full_rotations * 360)        

Here is the Scratch implementation:



  • Degrees Turned: This is a running total of how far the spinner has rotated in degrees since the start of the spin.
  • Degrees Turned / 360: This calculation determines how many full 360-degree rotations have been completed. It's like asking "How many full circles has the spinner completed"?
  • Remainder x 360: Here, we're calculating the leftover degrees after the full rotations have been accounted for. This is done by subtracting the number of full rotations (found using the floor function, which rounds down to the nearest whole number) times 360 from the total degrees turned. Essentially, this is the manual way to find the modulo if Scratch hadn't provided a direct block for it, and it is a way of understanding what mod is.
  • Degrees Mod 360: This block directly calculates the modulo, which is the remainder of the division of degrees turned by 360. This gives us the position of the spinner in degrees after the last complete rotation.
  • Remaining Degrees / Interior Angle: This block calculates how many sectors the final part of the rotation spans by dividing the degrees mod 360 (the remaining degrees after full rotations) by the interior angle of each sector.
  • Set Interior Angle: This block calculates the angle for each sector based on the number of participants. Its simply 360 divided by the number of sectors (participants), giving the angle size of each sector.
  • Set Winning Number: This block should take the result of the remaining degrees / interior angle calculation and round it up to the nearest whole number using the ceiling function. This determines the winning sector because Scratch sectors start counting from 1, not 0.
  • Set Winner: This block assigns the winner by retrieving the participant's name associated with the winning number from the list.
  • To clarify, with the spinner oriented so that the first sector starts at the top, as the spinner turns clockwise, you can use these calculations to track which sector passes the flapper last. When the spinner stops, the degrees mod 360 gives the exact position within the circle, and by dividing this by the interior angle, you find out how many sectors it has passed.
  • The use of the ceiling function ensures that even if the spinner lands just past the start of a sector, it will be correctly counted as landing in that sector and not the previous one. This method allows for precise determination of the winning sector based on the degrees turned, which is essential for ensuring the spinner's fairness and functionality in a classroom activity.

Calculating the Winning Sector

Once we have the final angle after the last complete rotation (using modulo), we need to figure out how many interior angles fit into this final angle. This tells us how many sectors the spinner has passed. Mathematically, if your interior angle is 36 degrees and the final angle is 30 degrees,

30 / 36 ≈ 0.83

This means the first number won since we haven’t passed 36 (the first sector). This is why we use the ceiling function since we need to round up to the nearest whole number.??

The Ceiling Function

The ceiling function comes into play here. It rounds up to the nearest whole number. If the spinner points to any part of the first sector, even if it's only rotated 1 degree, it is still in the first sector, not the zeroeth. So, for our spinner,

?30 / 36? = 1? (“the ceiling of 30 divided by 36 is 1”).

The ceiling function ensures that if the spinner lands anywhere within a sector, it's counted as landing on that sector, and not the previous one, since our first sector is 1, not 0.


Closing Remarks

This is how I implemented a spinner in Scratch that also determines the winner of the spin. It's a clever combination of geometry (with the circle and interior angles), arithmetic (with the division and ceiling function), and number theory (with the modulo operation). By understanding these concepts, you can see how mathematics is not just abstract numbers and figures but can be applied to create useful tools and fun and interactive experiences.

And there you have it! After walking through the function step by step, we've seen how some key lines of code contribute to the creation of a unique and functional classroom tool. It's a vivid reminder that, in programming, our efforts to automate processes can yield incredibly rewarding results. With just a simple click of a button, we're able to generate all 40 spinners with extreme accuracy and precision—a task that, if done by hand, would have required considerable time, effort, and meticulous attention to detail.

This Dynamic Spinner project is a testament to the power of combining creativity with computational thinking. It demonstrates not just the utility of programming in solving real-world problems but also the beauty of turning complex challenges into simple, elegant solutions. For educators and students alike, seeing this application come to life underscores the value of perseverance in coding. The hard work is indeed worth it when you can see your ideas materialize into tools that enhance learning and engagement in the classroom.







要查看或添加评论,请登录

Avi Megiddo的更多文章

  • From Scissors to Scripts

    From Scissors to Scripts

    A Sorting Games Implementation in Google Slides Sorting and categorizing activities are a cornerstone of education…

  • Classroom Groups Manager: Seating Charts in Google Slides

    Classroom Groups Manager: Seating Charts in Google Slides

    by Avi Megiddo, MYP Design Teacher, Kaohsiung American School Creating balanced student groups can be a time-consuming…

  • NY Times Connections Game in Google Sheets

    NY Times Connections Game in Google Sheets

    Introduction The New York Times has long been a leader in word games, captivating players with titles like Spelling…

  • MakeWords: Implementing a Classic Pen & Paper Game in Google Sheets

    MakeWords: Implementing a Classic Pen & Paper Game in Google Sheets

    Introduction Word games have always been a popular form of entertainment and education, with classics like Boggle…

  • A Wordle for Google Sheets Adventure

    A Wordle for Google Sheets Adventure

    By Avi Megiddo Introduction Creating a Wordle game in Google Sheets, with ChatGPT was a real back-and-forth. ChatGPT…

  • Student Comment Generator

    Student Comment Generator

    Harnessing Automation for Fair & Efficient Student Feedback In the educational landscape, providing individualized and…

    1 条评论
  • Enhancing Emotional Intelligence in the Classroom - the Mood Meter Google Sheets App

    Enhancing Emotional Intelligence in the Classroom - the Mood Meter Google Sheets App

    Enhancing Emotional Intelligence in the Classroom The Mood Meter Google Sheets App Have you ever wondered how the…

  • Aquarium of Appreciation

    Aquarium of Appreciation

    This project was called "Box of Thanks" for most of its design cycle, until a deep dive down the rabbit hole of name…

    1 条评论
  • Tournaments in Google Sheets

    Tournaments in Google Sheets

    Google Sheets is a game-changer for managing tournament brackets. Welcome to the world of tournament brackets…

  • Google Sheets Word-Search Maker

    Google Sheets Word-Search Maker

    Create custom word search puzzles with ease in Google Sheets, using this tool. With just a few simple steps, you can…

社区洞察

其他会员也浏览了