Three Stooges Driver — Entry Log
TTG’s prompt • C.R.A.F.T. critique • Java teaching notes • Vibe-coding ideas
Entry-specific companion to the Tool Time chatlog
Entry-specific development log for Tool Time Entry #6: Three Stooges Driver. This is the first Tool Time entry with no p5.js — pure Java. The main Tool Time chatlog documents the venue-level decision to add Java-only entries.
This log covers: TTG’s prompt with C.R.A.F.T. critique and grade, design decisions, the intentional compile-error teaching point, and ready-to-use C.R.A.F.T. prompt examples for students who want to upgrade the code.
You are helping me as a web developer, APCS(Java) teacher and co-developer at TNT. You have the context of the Tool Time ecosystem, its accompanying chatlog and a previous entry featuring ‘Purple Rain.’ This time, however, we are featuring a Java snippet that we want to upgrade. We’d like to be able to copy it into JDoodle and run it but it’s pretty lean so we’re hoping to inspire our APCS novices to ‘vibe code’ it to a better place! I’ve provided a background image for the hero and the entry card that’s Stooge thematic. The snippet features the comedy troupe: The Three Stooges. Since there is no p5js this time, we just need to showcase the Java code attached. Use the same style we used in our app featuring Grayson’s song. The Java code is shown with the blue striped source code with the copy button. Let’s call this file: threeStoogesOriginal.html with affiliated threeStoogesOriginalStyles.css and threeStoogesOriginalScripts.js. As we did for Beau’s work, we also want a threeStoogesChatlog.html with threeStoogesChatlogStyles.css. Since this is the first time we are offering a Tool Time entry that’s not p5js (its solely Java), let’s update our toolTimeChatlog.html file to celebrate this new facet. It was developed by me, TechToolsGuru also, so it’s not novice based this time. Add this prompt to our Tool Time chatlog and our threeStoogesChatlog and as before, critique the prompt and give it a grade. After novices get help from their AI-Assistant, they should be able, to add additional ‘stooges’ to an ArrayList without any duplicates, and have better understanding of what the main header means in Java driver code when it says: public static void main(String args[]). Therefore, give them some ideas on what to mention to AI to get this app to be more impressive. Encourage them to look at our movie clips page for our ‘TNT Legacy Thanksgiving’ entry because it links to some Three Stooges antics they might enjoy!
A strong, context-rich prompt that draws on the accumulated Tool Time institutional knowledge. Three clear roles, named deliverables, and a specific pedagogical target. First APCS Java entry prompt in the series.
✅ Strengths
public static void main(String[] args) — specific, testable, APCS-appropriate targets. This is the strongest pedagogical constraint in the series.⚠️ Growth Areas
System. out.println contains a space that is poor style (though Java’s spec allows whitespace between tokens, and JDoodle/CodeHS run it without error). The prompt does not acknowledge this — it was left to AI analysis to flag. Stating “the code has a deliberate space on line 6 between System. and out” would eliminate any ambiguity about whether to fix it or preserve it as a teaching point.args[] does not work naturally in JDoodle’s web interface. Acknowledging this in the prompt would have allowed the entry to address the workaround (hardcode names first) more explicitly from the start.Grade rationale: A−. The pedagogical targets (ArrayList, main signature) elevate this above previous entry prompts. The style-issue gap is notable because it required independent discovery — and then turned out not to be a compile error at all in JDoodle/CodeHS (see Session 3). The JDoodle friction was anticipated in the response but not pre-addressed in the prompt.
Line 6 of the original Java contains System. out.println with a space between System. and out. This was initially flagged as a compile error — but after live testing in JDoodle and CodeHS Sandbox, it turned out to compile and run successfully in both venues. Java’s specification permits whitespace between tokens; the dot . is a separator, and whitespace around separators is legal.
Decision: preserve the space exactly but reframe the teaching moment from “compile error” to style issue. The code runs — but a human reader will do a double-take, a strict linter will flag it, and a code reviewer will ask why it’s there. Removing the space is still a worthwhile first exercise in reading code carefully and following Java conventions.
Purple Rain used a split layout (code left, live canvas right). Three Stooges has no visual output — Java console programs print to stdout, not to a pixel canvas. The showcase card uses full-width code display. This is the correct layout for all future Java-only Tool Time entries.
Target 1: public static void main(String[] args) — explained word-by-word in the Your Turn section. Students are given both the explanation and a suggested AI prompt to explore it further.
Target 2: ArrayList without duplicates — the no-duplicate pattern using contains() before add() is shown in a code block. Students are challenged to extend the Stooges list, add Shemp, then add a Scanner for keyboard input.
Two Stooges movie clip links in the Your Turn section: the TNT Legacy Thanksgiving page (features Stooges comedy clips) and “Swingin’ the Alphabet” (Stooges doing a nested-loop algorithm set to music). Both links open in a new tab since they are on separate pages in the TNT ecosystem.
“You are a patient APCS Java teacher. I have a Java driver class that reads three stooge names from command-line args and prints them, but it has a compile error. (1) Identify and fix the error. (2) Explain every word in public static void main(String[] args) using a simple analogy. (3) Show a version that hardcodes the names as local String variables so I can run it in JDoodle without command-line args.”
This prompt hits all three targets: fix, explain, and make it runnable.
“You are a patient APCS Java teacher. I have a Three Stooges driver class that stores stooge names as separate String variables. Refactor it to use an ArrayList<String> that prevents duplicates using .contains() before each .add(). Include Moe, Larry, Curly, and Shemp. Try adding Moe twice to demonstrate the duplicate guard. Show the complete updated class with a comment explaining what contains() does. Keep it under 30 lines.”
Tests: import, ArrayList declaration, for-each loop, contains guard, duplicate test.
“You are a patient APCS Java teacher. I have a Stooges ArrayList program. Add a Scanner so I can type stooge names from the keyboard. The program should keep accepting names until I type ‘done’. Each name should only be added once (no duplicates). Print the final list when done. Show the complete class with comments.”
Tests: Scanner, while loop, String comparison with .equalsIgnoreCase(), break/sentinel pattern.
Curious how a real vibe-code session actually plays out? TechToolsGuru ran all four stages above — starting from the original crasher, finishing with a fully defensive ArrayList + case-insensitive duplicate guard — using Raina in Magic School’s Code Craft Studio. Each prompt is shown with the AI’s complete code response, a C.R.A.F.T. critique, and a grade. The page closes with a post-session analysis and concrete improvements to the final Stage 4 code.
What is the entry icon for the Stooges card? I don’t recognize it; alternative: a drama sad/laughing mask if that exists?
The original entry icon was 🥟 — which renders as 🥟, a dumpling. Completely wrong for the Three Stooges. The code point was off by one character during entry. This is a good reminder to always preview emoji characters; Unicode code points are not memorable and a single digit difference produces a wildly different glyph.
The theater masks emoji 🎭 🎭 is the perfect replacement: the Stooges are a theatrical comedy troupe with roots in vaudeville, and the comedy/tragedy masks are the universal symbol of theatrical performance. The emoji reads immediately as “performance,” which is exactly what Tool Time entries celebrate.
Lesson: When pasting Unicode code points by hand, verify the rendered glyph immediately. The character preview in VS Code’s hover tooltip is the fastest way to avoid deploying a dumpling when you meant a theater mask.
The header information for the stooges app is left-shifted; for consistency with other entries, it should be centered. Can you make that adjustment?
margin: 0 auto on .hero-contentThis is a classic CSS centering trap. The hero uses two different centering mechanisms that serve different purposes, and the fix requires both:
/* BEFORE — hero-content left-shifted despite text-align: center */
.hero-content {
text-align: center; /* centers inline content (text, icons) WITHIN block */
max-width: 760px; /* ← constrained width, but block itself was left-aligned */
}
/* AFTER — one line added */
.hero-content {
text-align: center;
max-width: 760px;
margin: 0 auto; /* centers the BLOCK ITSELF within its parent */
}
Why it looked left-shifted: #hero is a flex container with justify-content: center — this centers Bootstrap’s .container (which is full-width). But inside the container, .hero-content has max-width: 760px. Without margin: 0 auto, that narrower block defaults to left-alignment within the container. The text inside was centered (via text-align), but the content block itself was hugging the left edge.
The teachable pattern:
text-align: center— centers inline content (text, icons) within a block element.margin: 0 auto— centers the block element itself within its parent container.
Both threeStoogesOriginalStyles.css and threeStoogesChatlogStyles.css were updated simultaneously since the chatlog hero uses the same pattern.
I actually ran the code in JDoodle and in CodeHS Sandbox, and the space after the . did not cause a problem. Since those are currently the venues I’ll be using, our narrative needs to be adjusted.
Live testing in JDoodle and CodeHS Sandbox confirmed: System. out.println with the space runs without error. This required updating the narrative in both the entry page and this chatlog.
Why it compiles: Java’s specification defines whitespace as a token separator, and the dot . is itself a separator token. Whitespace between tokens is permitted by the grammar — so System . out . println ( … ) is legal Java. Modern compilers (including those used by JDoodle and CodeHS) follow this correctly. Older or stricter tools might warn, but they should still compile it.
Why it’s still worth noting: Legality and good practice are not the same thing. The space will confuse any human reader, will be flagged by style linters (e.g., Checkstyle), and signals that the author either didn’t notice it or didn’t care. The teaching value shifts from “find the bug before it bites you” to “read code like a professional — a reviewer will ask about this.”
Changes made: The red warning box in the entry page was reworded from “Compile Error” to “Style Issue,” the icon changed from a bug 🐛 to an eye 👁️, and the text was updated to reflect that JDoodle/CodeHS will run it. The Session 1 design-decision box and the prompt critique were updated to match. The attr-strip no longer says “space bug.”
At this stage of this app, I want the novices to ‘figure out’ how to either make the JDoodle interface work (there is a field for ‘Input arguments’) or to use AI to ‘code around’ the problem should the args array be empty. I want that functionality in the code, not removed. That was largely the point of this exercise. It’s true, as you said, that JDoodle doesn’t ‘use real command-line args’ (the terminal is not apparent) but its interface allows the args use nonetheless. So, the challenge becomes: 1. Can you use JDoodle with the code as is? (Yes you can) 2. What if you are in an environment without the use of ‘Input arguments’ or a terminal with ‘command-line-args’ — what can you do then?! That’s where ‘Al’ (AI) can offer help. 3. Once all that work is done, what happens if someone attempts to add a stooge to the array? It’s size is set, so we’ll need to bring in ArrayLists. 4. After that, what happens if someone attempts to load a stooge into the AL that’s already there? 5. What about case sensitivity? These are the issues I envision will make this an interesting Tool Time adventure. Other ideas on your part are welcome too. Add this to the chatlog and critique it/grade it as well.
The strongest pedagogical prompt in this entry’s chatlog. Five numbered learning stages, each one a natural consequence of the previous, each one forcing a new Java concept. This is curriculum design embedded in a prompt.
✅ Strengths
⚠️ Growth Areas
Grade rationale: A. Five numbered, sequentially causal challenges is curriculum design at its best — each stage produces the exact problem that motivates the next. The JDoodle correction and the args-preservation constraint show careful thinking about what the exercise is actually teaching.
Stage 1 — JDoodle works as-is
The original code uses args[0], args[1], args[2]. JDoodle has an “Input arguments” field. Students type Moe Larry Curly into it and the code runs immediately — no changes needed. This validates the design: the command-line args pattern is intact and real. First lesson: read the tool’s interface before assuming something won’t work.
Stage 2 — What if there’s no args field?
In many classroom environments (certain IDEs, web-based sandboxes, AP Classroom), there is no way to pass command-line arguments. Running the code as-is throws an ArrayIndexOutOfBoundsException — a crash, not a compile error. The AI challenge: “Add a fallback so the program uses hardcoded names if args.length < 3, and command-line names if they are provided.” Students learn defensive programming and the args.length check in one step.
Stage 3 — Bridge args[] into an ArrayList + three levels of printing
Keep args[] exactly as it is. Create an empty ArrayList<String> and populate it with a for-each loop over args. Then add Shemp manually. After that, print both structures and compare: println(args) produces a memory address like [Ljava.lang.String;@6d06d69c because Java arrays do not override toString(). println(stooges) produces [Moe, Larry, Curly, Shemp] because ArrayList does override toString(). A printArrayList() static method with an indexed for-loop then gives full control: one name per line, numbered. Three print strategies, three different results, one important lesson about what toString() does and why it matters.
Stage 4 — Prevent duplicates
Now that we have an ArrayList, try adding Moe twice. The list allows it: [Moe, Larry, Curly, Moe]. There is only one Moe. The fix: check !list.contains(name) before each list.add(name). Simple, clean, introduces one of the most important ArrayList patterns in APCS. The AI challenge: “Add a no-duplicate guard using .contains() and print a message if the name was rejected.”
Stage 5 — Case sensitivity
Now try adding "moe" (lowercase). .contains("moe") returns false because Java’s String.equals() is case-sensitive. "Moe" and "moe" are different strings. The duplicate guard fails. The AI challenge: “Normalize all stooge names to title case before checking and adding, so ‘MOE’ and ‘moe’ are both treated as ‘Moe’.” Introduces toLowerCase(), toUpperCase(), and the concept of normalization.
- Stage 6:
ArrayIndexOutOfBoundsExceptionanatomy. When Stage 2’s args crash fires, students see a stack trace for the first time. Reading a stack trace is a fundamental skill. Ask AI: “Explain the stack trace I got. What is line number telling me? What isArrayIndexOutOfBoundsException?” - Stage 7: Sorting the roster. Once the list has five Stooges, ask AI to sort it alphabetically. Introduces
Collections.sort()and the concept that an ArrayList isn’t ordered by default. - Stage 8: Enhanced for-each vs indexed loop. Printing the list with
for (String s : stooges)vsfor (int i = 0; i < stooges.size(); i++). When would you use each? What if you need the index? - Stage 9: Build a
Stoogeclass. Each Stooge has a name and a specialty (Moe — boss/slapper; Larry — victim; Curly — nyuk nyuk). AnArrayList<Stooge>replacesArrayList<String>. Generics,toString()override, object-oriented thinking. The full APCS journey from primitive to OOP in one exercise.
This page fails to validate probably because of a < in the HTML rather than an HTML entity. There were 3 errors: I think that was the cause.
The validator did report three errors, and KLP correctly diagnosed the pattern (one malformed character cascading into multiple errors). The actual culprit was not a bare < but a semicolon inside a closing tag:
<!-- Wrong: --> <code>"Moe"</code; ← semicolon inside the tag name <!-- Fixed: --> <code>"Moe"</code> ← proper closing tag
The HTML parser sees </code; as an end tag with the name code; — which does not exist. This produces a cascade of three validation errors:
- End tag
</code;>is not a valid tag name. - The unclosed
<code>is still considered open. - The text “ are all treated the same” after the semicolon now parses in an unexpected context.
The DWR lesson: One misplaced character inside a tag can cascade into several validator errors that all look unrelated. When the validator flags multiple errors close together, look for a single malformed tag at the top of the cluster — fixing it often clears all of them at once. In this case, the semicolon crept in when rapidly typing the closing </code> tag next to a sentence that ended with a semicolon in the source text.
Many novices are unfamiliar with the antics of The Three Stooges. That said, while we have a link to a page that links to some movie clips that feature them, let’s add a link in our SPARK bar, Stooge Antics with a movie icon to the left of it, that encourages novices to visit the page we find at: _LegacyTNT/movie_clips/stoogeTurkey.html Add this prompt to our stooges chatlog along with its grade and critique.
A compact, purposeful iterative prompt. Its strongest quality is that it leads with the pedagogical why before stating the what — “novices are unfamiliar with the antics” is the reasoning, and the chip is the solution. It also references the existing link structure, so the AI knows the current state without having to discover it. The exact target URL eliminates all ambiguity about destination.
✅ Strengths
_LegacyTNT/movie_clips/stoogeTurkey.html — no guessing, no browsing required. The target path is the most important single fact in a “add a link” prompt.⚠️ Growth Areas
fa-film, fa-video, fa-clapperboard, and others. The intent is clear enough to resolve correctly, but “use the fa-film icon already in the page” would have been more precise and consistent.target="_blank") — but the prompt does not say so. Adding “open in a new tab” or “follow the same pattern as the other external links on this page” removes any ambiguity._LegacyTNT/movie_clips/stoogeTurkey.html is given from the site root; the HTML file lives two levels down in ToolTime/StoogesDriverJava/, so the correct relative path is ../../_LegacyTNT/…. This is a developer translation step, not a real gap at TTG’s level, but it’s worth naming explicitly in a teaching context.Grade rationale: B+ — The upfront motivation and exact URL elevate this above a plain B. The established TNT workflow context means the missing role is not a practical problem. The icon ambiguity and new-tab omission are the only genuine gaps at this experience level.
The .lang-idea-strip chips were all <span> elements. Converting the new Stooge Antics entry to an <a class="lang-idea"> anchor provides the link behavior without any visual change to the chip itself. The anchor inherits all the existing .lang-idea padding, border, and color rules.
Two CSS rules were added to threeStoogesOriginalStyles.css to handle the anchor-specific behavior: text-decoration: none (so the chip doesn’t show an underline) and a hover transition that deepens the sepia background and shifts text to cream — matching the interactive feel of other sepia-toned links on the page.
The fa-film icon was chosen as it is already used in the same .your-turn-card section (“Need Stooge inspiration?” paragraph), making the visual language consistent. target="_blank" rel="noopener noreferrer" follows the page’s existing convention for all cross-section links.
Path resolved: _LegacyTNT/movie_clips/stoogeTurkey.html from root → ../../_LegacyTNT/movie_clips/stoogeTurkey.html relative to ToolTime/StoogesDriverJava/.
Actually, I may have misspoke. I wanted it in what you described as the ‘back bar’ right underneath the main nav bar area. Please relocate it and update our chatlog.
The link was moved from the .lang-idea-strip inside the .your-turn-card to the .st-back-bar immediately below the main navbar — the persistent navigation strip that holds Tool Time Home and Entry Chatlog. It now sits as a third link inside the same inner div that wraps those two anchors, separated by the same gap: 1.25rem spacing.
The back bar’s existing .st-back-bar a rule already applies color: var(--st-sepia) and a hover transition to cream, so no additional CSS was needed. The two a.lang-idea rules added in Session 6a were removed as dead code.
Why the back bar is the better home: The back bar is visible at every scroll position on the page (it sits just below the sticky navbar). A novice who arrives and immediately wonders “who are these people?” can find the clip link before reading a single paragraph. The .lang-idea-strip is useful as a topic-idea prompt, not as a navigation anchor — a clickable external link belongs in the navigation layer, not the content layer.
grade-b-plus CSS ClassAfter Session 6 was logged, KLP noticed the B+ grade badge in the Session 6 critique box was rendering without its circular styling — just plain text, no background, no border, no color. The other grade badges (A− and A) displayed correctly. The cause: .grade-b-plus was defined in threeStoogesVibeCodeResultsStyles.css (created at the same time as the vibe code results page) but was never added to threeStoogesChatlogStyles.css, which is the stylesheet this page actually loads.
The chatlog CSS only contained two grade rules — .grade-a and .grade-b. When the Session 6 markup referenced grade-b-plus, the browser found no matching rule and fell back to an unstyled div. The fix was a single line added to threeStoogesChatlogStyles.css:
.grade-b-plus { background: rgba(66,135,200,0.20); border: 2px solid #5ba3d9; color: #5ba3d9; }
The S.P.A.R.K. lesson: This is the Refine step in action — a visual inconsistency spotted after the fact, diagnosed to its root (a CSS class defined in one stylesheet but not mirrored to another), and corrected with a minimal, targeted change. When introducing a new utility class in any stylesheet, check every other stylesheet in the project that might need the same class. Cross-file consistency gaps are among the quietest bugs a browser will silently ignore.