FTC Judge vs Judge Advisor

I’ve been judging FTC (FIRST Tech Challenge) competitions for many years. It’s a lot of fun. The kids tell you about their robot and outreach and learnings and more. You also negotiate with other judges to determine the award winners. And the day ends with some super excited kids finding out the result. It’s a great day.

There’s also a judge advisor role. The description includes

The Judge Advisor coordinates the judging process, which includes facilitating group deliberation sessions, ensuring the award decisions are made, and the awards script is written. Sometimes the Judge Advisor trains judges and can help in scheduling the judging interviews. The Judges, Judge Advisor Assistant, and Judge Match Observers look to the Judge Advisor for training materials, schedules, and other general questions throughout the
event.

I was asked a few years ago about being Judge Advisor and passed. I like judging a lot. The judge advisor doesn’t get to interview the teams or make any decisions/negotiate. They are a manager and facilitator.

I got to the event on Saturday and was greeted with the event coordinators telling me their judge advisor couldn’t come unexpectedly and could I do it. I said yes. While it isn’t my first choice of role, I am qualified to. I was also the most experienced judge in the room (by a good amount.) I also appreciate that they asked/told me in the form of a question. If they had asked me two weeks ago, I’d have said no because there was still time to find someone more excited about the role. Day of, choices are limited!

What’s interesting about the combination of managing and facilitating is that I very much like facilitating and very much dislike managing. I was able to train folks, form groups, enforce standards and keep things on track.

I definitely relied on crowd sourcing. I wrote constraints on the board and explained what I was trying to accomplish for groups. Having a dozen people “check your work” real time is great quality control!

Overall, it was fine. We accomplished what we needed to and the judges/event staff were happy with how things went. But I still greatly prefer judging and will continue signing up as a judge for future events!

ChatGPT for education – is it like a calculator?

At the NYC FRC (FIRST Robotics Challenge) local kickoff, there was a speaker from Columbia about AI. The target audience was high school students. He said two things that stuck with me. First was:

Self awareness is the ability to imagine yourself in the future; the farther in the future, the more self aware

He also noted that his dog can imagine himself about a minute in the future. Like eating the food about to come. Humans can imagine further out of course.

The other was about AI being like a calculator. I like that analogy. It shows that using ChatGPT isn’t a replacement for learning how to write/code/etc. We don’t let kids use a calculator on tests until they already know how to add. And you don’t want to have to go to a calculator or pull out your phone to add 5 + 8!

toList() vs collect(Collectors.toList())

I had some extra time this week so went through a bunch of Sonar findings. One was interesting – in Java 17 you can use .toList() instead of .collect(Collectors.toList()) on a stream.

[Yes, I know this was introduced in Java 16. I live in a world where only LTS releases matter]

Cool. I can fix a lot of these without thinking. It’s a search and replace on the project level after all. I then ran the JUnit regression tests and got failures. That was puzzling to me because I’ve been using .toList() in code I write for a good while without incident.

After looking into it, I found the problem. .toList() guarantees the returned List is immutable. However, Collectors.toList() makes no promises about immutability. The result might be immutable. Or you can change it freely. Surprise?

That’s according to the spec. On the JDK I’m using (and Jenkins is using), Collectors.toList() was returning an ArrayList. So people were treating the returned List as mutable and it was working. I added a bunch of “let’s make this explicitly mutable” and then I was able to commit.

Here’s an example that illustrates the diference

import java.util.*;
import java.util.stream.*;

public class PlayTest {

	public static void main(String[] args) {

		var list = List.of("a", "b", "c");
		var collectorReturned = collector(list);
		var toListReturned = toList(list);
		
		System.out.println(collectorReturned.getClass());  // ArrayList (but doesn't have to be)
		System.out.println(toListReturned.getClass());  // class java.util.ImmutableCollections$ListN
		
		collectorReturned.add("x");
		System.out.println(collectorReturned);  // [bb, cc, x]
		toListReturned.add("x");  // throws UnsupportedOperationException

	}

	private static List<String> toList(List<String> list) {
		return list.stream()
				.filter(s -> ! s.equals("a"))
				.map(s -> s + s)
				.toList();
	}

	private static List<String> collector(List<String> list) {
		return list.stream()
				.filter(s -> ! s.equals("a"))
				.map(s -> s + s)
				.collect(Collectors.toList());
				
	}

Collectors.toList() also makes no promises about serializablity or thread safety but I wasn’t expecting it to.