Academy Cs Cmu Edu Cheat Sheet

10 min read

You're a high school CS teacher. You're staring at a lesson plan for Monday's CS Academy module and you can't remember — does drawRect take (x, y, width, height) or (x, y, x2, y2)? It's Sunday night. But you're tired. The documentation is somewhere in the teacher portal. You just want a quick answer.

That's exactly why the CMU CS Academy cheat sheet exists Simple, but easy to overlook..


What Is CMU CS Academy

Carnegie Mellon University's Computer Science Academy — usually just called CS Academy — is a free, browser-based curriculum for teaching introductory computer science. It runs entirely in the cloud. Because of that, no installs. No environment headaches. Students write Python code in a custom editor that renders graphics instantly on a canvas.

The program started around 2018 as a response to a real problem: most high schools wanted to offer CS but didn't have qualified teachers or accessible curriculum. CMU built something different. Not a textbook. Plus, not a video series. An interactive platform where students write code from day one.

There are two main courses:

  • CS1 — the full-year intro course. Still, covers variables, conditionals, loops, functions, lists, dictionaries, basic algorithms, and a final project. Now, - CS0 — a lighter, semester-long version. Same core ideas, less depth. Designed for middle school or exploratory high school electives.

No fluff here — just what actually works.

Both use a custom graphics library built on top of Python. That library — the cmugraphics package (formerly graphics.py in earlier versions) — is where the cheat sheet becomes essential.


Why the Cheat Sheet Matters

Here's the thing: CS Academy's documentation is actually good. In real terms, searchable. On the flip side, well-organized. But it's comprehensive. When a student asks "how do I make a circle follow the mouse?" you don't want to read three pages of event-handling theory. You want the method name. The parameter order. A tiny code snippet.

That's the gap the cheat sheet fills.

It's not a replacement for the docs. Students tape it inside their notebooks. Teachers print it. And it's a quick-reference layer — the sticky note you keep on your monitor. Some schools laminate it The details matter here..

And because CS Academy updates its library occasionally (the jump from graphics.py to cmugraphics broke a few method names), a current cheat sheet saves you from teaching deprecated syntax.


What the Cheat Sheet Actually Covers

### Core Graphics Primitives

These are the building blocks. Every shape, every drawing command Easy to understand, harder to ignore..

Method Parameters Notes
drawRect x, y, width, height, fill=None, border=None, borderWidth=1 Origin is top-left. fill and border take color strings or RGB tuples.
drawCircle cx, cy, radius, fill=None, border=None, borderWidth=1 Center-based. That said, not bounding-box. Here's the thing —
drawOval cx, cy, radiusX, radiusY, fill=None, border=None, borderWidth=1 Ellipse. Day to day, two radii.
drawLine x1, y1, x2, y2, fill='black', lineWidth=1 Simple. No arrowheads.
drawPolygon points, fill=None, border=None, borderWidth=1 points is a list of (x, y) tuples. Minimum 3.
drawLabel text, x, y, fill='black', size=12, font='arial', bold=False, italic=False, rotate=0 Text rendering. rotate in degrees.

Quick tip: All drawing methods return a shape object. You can store it — rect = drawRect(10, 10, 50, 50) — and later modify properties like rect.fill = 'red'. But most beginners don't need this. Just redraw That's the part that actually makes a difference..

### Color Handling

CS Academy accepts colors in three forms:

  • Named colors'red', 'blue', 'lightGreen', 'gold' (case-insensitive, camelCase or lowercase both work)
  • RGB tuples(255, 0, 0) for red. Values 0–255. Also, - RGBA tuples(255, 0, 0, 128) for semi-transparent. Alpha 0–255.

No hex strings. No HSL. Keep a small palette handy:

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
GRAY  = (128, 128, 128)

### Mouse & Keyboard Events

The event model is polling-based in the main loop, but CS Academy also supports callback-style handlers. Both work. Mixing them gets messy.

Polling (inside onStep or a loop):

mouseX, mouseY = getMousePosition()
mousePressed = isMousePressed()
keys = getKeysPressed()  # returns set of key strings like {'w', 'space'}

Callbacks (register once, usually in onAppStart):

def onMousePress(x, y):
    # handle click

def onKeyPress(key):
    # key is a string: 'a', 'Enter', 'Space', 'ArrowLeft', etc.

Common keys to know:

  • Letters: 'a' through 'z' (always lowercase)
  • Arrows: 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'
  • Special: 'Enter', 'Space', 'Escape', 'Tab', 'Backspace', 'Shift', 'Control', 'Alt'
  • Numbers: '0''9' (top row), 'Numpad0''Numpad9'

### Animation Loop

Every CS Academy program runs on a frame loop. You don't write while True:. You define callbacks:

def onAppStart(app):
    app.counter = 0
    app.circleX = 200

def onStep(app):
    app.In practice, counter += 1
    app. circleX += 2
    if app.circleX > 400:
        app.

def redrawAll(app):
    drawCircle(app.circleX, 200, 20, fill='blue')
    drawLabel(f'Frames: {app.counter}', 200, 50)

onStep fires ~30 times per second by default. Change it with app.stepsPerSecond = 60 in onAppStart.

Pro tip: Keep redrawAll pure — no state changes. All mutation happens in onStep, `onMouse

Press, or onKeyPress. This separation prevents flickering and race conditions. When you need precise timing—like a bouncing ball or rotating shape—store its state in appvariables and compute new positions inonStep. For smoother motion, increase stepsPerSecond` to 60 or 120.

Most guides skip this. Don't.

### Event-Driven Design Patterns

Most interactive apps follow a simple pattern: store state in app, react to events, update state, redraw. Here's a button example:

def onAppStart(app):
    app.buttonX = 100
    app.buttonY = 100
    app.buttonWidth = 80
    app.buttonHeight = 30
    app.buttonPressed = False

def onMousePress(app, x, y):
    if (app.buttonX <= x <= app.buttonX + app.buttonWidth and 
        app.buttonY <= y <= app.buttonY + app.buttonHeight):
        app.

def onStep(app):
    if app.buttonPressed:
        app.buttonX += 5
        if app.buttonX > 500:
            app.

def redrawAll(app):
    fill = 'darkGray' if app.buttonWidth, app.', app.buttonX, app.buttonPressed else 'lightGray'
    drawRect(app.buttonY, app.buttonHeight, fill=fill)
    drawLabel('Click me!buttonX + 40, app.

Notice how `onMousePress` only sets a flag, `onStep` handles movement, and `redrawAll` only draws. This keeps logic clean and debuggable.

### ### Working with Paths and Complex Shapes

For anything beyond basic rectangles and circles, use path commands:

```python
def redrawAll(app):
    # Draw a triangle
    drawPath(True, True, 'red', 2, 
             (100, 50), (150, 100), (50, 100))
    
    # Draw a star
    drawPath(True, True, 'yellow', 1,
             (200, 100), (220, 150), (270, 150),
             (230, 180), (250, 230),
             (200, 200), (150, 230),
             (170, 180), (130, 150), (180, 150))

drawPath(filled, closed, color, borderWidth, *points) creates polygons from point lists. That's why the first two booleans control fill and outline. Minimum 3 points required The details matter here..

You can also create reusable shapes:

def drawStar(x, y, radius, fill='yellow'):
    points = []
    for i in range(10):
        angle = i * 3.14159 / 5
        px = x + radius * (0.5 if i % 2 else 1) * math.cos(angle)
        py = y + radius * (0.5 if i % 2 else 1) * math.sin(angle)
        points.append((px, py))
    drawPath(True, True, fill, 1, *points)

### Text and Typography

Labels are your primary text tool. Use them for scores, instructions, and UI elements:

drawLabel('Score: 100', 50, 50, fill='black', size=16, bold=True)
drawLabel('Game Over!', 250, 300, fill='red', size=24, font='arial', bold=True)

For multi-line text, stack labels vertically or use \n in the string. Rotation opens creative possibilities for tilted effects or radial menus.

### Performance and Optimization

Redrawing every frame can get slow with many objects. For static backgrounds, consider redrawing only when needed:

def onAppStart(app):
    app.backgroundRendered = False

def redrawAll(app):
    if not app.Worth adding: backgroundRendered:
        # Draw complex background once
        drawPath(True, True, 'blue', 0, (0, 0), (400, 0), (400, 400), (0, 400))
        app. backgroundRendered = True
    
    # Draw moving elements
    drawCircle(app.playerX, app.

Alternatively, use `redrawForces()` sparingly to trigger immediate redraws when needed.

### ### Debugging and Development Tips

Print statements work in `onStep` and event handlers, but they flood the console. Use labels for visual debugging:

```python
def onStep(app):
    app.debugInfo = f'Mouse: {app.mouseX}, {app.mouseY}'
    # ... game logic ...

def redrawAll(app):
    # ... Which means game drawing ... drawLabel(app.

Use descriptive variable names in `app`. Instead of `app.Because of that, x`, try `app. playerX` or `app.

emyX`. This makes your code much easier to read when you return to it later or share it with others.

When working with complex physics or collision detection, it is helpful to draw "hitboxes" temporarily. By drawing a simple rectangle or circle around your sprites, you can visually confirm if your collision logic aligns with your graphics.

```python
def redrawAll(app):
    # Draw the actual sprite
    drawCircle(app.playerX, app.playerY, 20, fill='blue')
    
    # Debug: Draw the collision hitbox
    if app.debugMode:
        drawCircle(app.playerX, app.playerY, 22, fill=None, borderWidth=1, color='green')

### Summary and Best Practices

Mastering these drawing commands is the foundation of creating engaging, interactive graphics. As you move from simple shapes to complex, animated scenes, keep these core principles in mind:

  1. Layering Matters: Objects drawn later in the redrawAll function will appear "on top" of objects drawn earlier. Always draw your background first and your UI/labels last.
  2. Coordinate Awareness: Remember that the coordinate system typically starts at (0,0) in the top-left corner. Increasing y moves objects down the screen.
  3. Efficiency is Key: Avoid performing heavy mathematical calculations (like trigonometric functions or complex loops) directly inside redrawAll. Calculate these values in onStep and store them in app variables to ensure a smooth frame rate.
  4. Keep it Clean: Use functions to encapsulate complex shapes. If you find yourself writing the same drawPath parameters repeatedly, wrap them in a reusable function to keep your code DRY (Don't Repeat Yourself).

By combining efficient path drawing, thoughtful typography, and optimized rendering loops, you can transform a simple canvas into a dynamic and professional-looking digital environment. Happy coding!

To easily continue the article, here's an expansion focusing on advanced rendering techniques, user experience enhancements, and project structuring:


Advanced Rendering Techniques

While basic shapes form the foundation, combining paths, gradients, and transformations unlocks richer visuals. To give you an idea, creating a pulsating health bar:

def redrawAll(app):  
    # Background gradient  
    drawRectangle(0, 0, app.width, app.height, fill='black', opacity=0.7)  
    # Pulsing health bar (using sine wave for animation)  
    health = app.playerHealth  
    pulse = 0.02 * math.sin(app.frame % 30)  # Smooth animation  
    drawRectangle(10, 10, health * 100 + pulse, 30, fill='red', opacity=0.9)  
    # Rounded corners  
    drawRectangle(10, 10, health * 100 + pulse, 30,  
                  fill='red', opacity=0.9, borderWidth=2, borderColor='black')  
    # DrawLabel(app.playerHealth, 10, 50, fill='white')  

Smooth Animations with Interpolation

Use interpolation to avoid abrupt changes in motion or scaling:

def onStep(app):  
    # Smoothly transition player movement  
    app.playerX = app.playerX * 0.9 + app.targetX * 0.1  
    # Fade out effects  
    app.explosionOpacity = max(0, app.explosionOpacity - 0.05)  
    drawCircle(app.explosionX, app.explosionY, 50,  
               fill='orange', opacity=app.explosionOpacity)  

User Experience: Tooltips and Tooltips

Enhance interactivity with tooltips triggered on hover:

def redrawAll(app):  
    # Draw interactive button  
    drawRectangle(50, 50, 100, 40, fill='green')  
    # Tooltip logic  
    if (app.mouseX >= 50 and app.mouseX <= 150 and  
        app.mouseY >= 50 and app.mouseY <= 90):  
        drawLabel("Click to Start", 50, 100, fill='white')  

Project Structure Best Practices

Organize code into logical sections for scalability:

def initializeGame(app):  
    app.background = 'space.jpg'  # Load image  
    app.player = {'x': 100, 'y': 200, 'health': 100}  
    app.enemies = []  

def onStep(app):  
    # Physics calculations  
    for enemy in app.player['x'], app.enemies:  
        enemy['y'] += 2  # Simple gravity  
        # Collision check  
        if distance(app.player['y'], enemy['x'], enemy['y']) < 30:  
            app.

def redrawAll(app):  
    # Background image  
    drawImage(app.player['x'], app.On top of that, background, 0, 0)  
    # Draw player and enemies  
    drawCircle(app. player['y'], 20, fill='blue')  
    for enemy in app.

### Conclusion  
By mastering drawing commands, optimizing performance, and structuring your code thoughtfully, you can create visually compelling and responsive games. Prioritize clean code, take advantage of Pygame’s capabilities for advanced rendering, and ensure your game runs smoothly across devices. With these tools, your creative vision can truly come to life on screen. Happy coding!  

--- 

This continuation builds on the original article by introducing more sophisticated rendering methods, user interaction elements, and organizational strategies, while maintaining a cohesive flow and avoiding repetition.
This Week's New Stuff

New Arrivals

Related Territory

Related Posts

Thank you for reading about Academy Cs Cmu Edu Cheat Sheet. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home