Thursday, October 31, 2024

Handling long operations in observer chains

If you have lengthy observer notification chains where observers notify other observers, making the trigger order unpredictable, and these chains include time-consuming operations like updating a map drawing, you can use the following approach to only update the drawing when the last observer in the chain is reached:
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.atomic.AtomicInteger;
public class DrawLast extends Observable implements Observer {
// Global static AtomicInteger to ensure thread safety
public static final AtomicInteger activeDrawingObserverCount = new AtomicInteger(0);
@Override
public void update(Observable o, Object arg) {
// Increment count safely
DrawLast.activeDrawingObserverCount.incrementAndGet();
try {
// Do observer-specific operations
System.out.println("Observer " + this + " is updating...");
// Notify other observers, assuming each follows the same pattern in this update()
setChanged();
notifyObservers();
} finally {
// Decrement count safely in a finally block
int remainingObservers = DrawLast.activeDrawingObserverCount.decrementAndGet();
if (remainingObservers == 0) {
draw(); // Call draw only when all observers are done
}
}
}
private void draw() {
System.out.println("Drawing now that all observers are done.");
}
public static void main(String[] args) {
DrawLast observer1 = new DrawLast();
DrawLast observer2 = new DrawLast();
DrawLast observer3 = new DrawLast(); // Last observer in the chain
// Set up observers to observe each other in a chain
observer1.addObserver(observer2);
observer2.addObserver(observer3);
// Start the chain by notifying observer1
observer1.setChanged();
observer1.notifyObservers();
}
}
view raw DrawLast.java hosted with ❤ by GitHub

Thursday, October 24, 2024

chatGPT 4o vs o1-preview

I normally use chatGPT 4o because it is much faster than o1-preview. Today I asked 4o the following:

Write a function that performs the following 2 byte hex to 2 byte signed int transformations:
0x801D --> -29
0x811D --> -285
0x821D --> -541
0xFF1D --> -32541
0x001D --> 29
0xAA1D --> -10781
0x101D --> 4125

It wrote a function that resulted in the following, mostly wrong, output:

-32739
-32483
-32227
-227
29
-21987
4125

I fed this output back, and it apologized and rewrote something slightly different, but the output was still wrong. I repeated the steps, and I got responses like 'I see the issue more clearly now' and 'Thank you for your patience,' but the output remained incorrect. When I fed the same prompt to o1-preview, it solved the problem in a single iteration. Here is the final python function (sign-magnitude representation):

def hex_to_signed_int(N):
    isNegative = N & 0x8000 # equivalent to "N >= 0x8000"
                            # 0x8000=1000 0000 0000 0000
    if isNegative:
        magnitude = N & 0x7FFF # 0x7FFF=0111 1111 1111 1111
        return -magnitude
    else:
        return N

test_values = [0x801D, 0x811D, 0x821D, 0xFF1D, 0x001D, 0xAA1D, 0x101D]

for val in test_values:
    print(f"0x{val:04X} --> {val:05} --> {hex_to_signed_int(val)}")