![]() |
Forum Index : Microcontroller and PC projects : AI research project for this month
![]() ![]() |
|||||
Author | Message | ||||
stef123 Regular Member ![]() Joined: 25/09/2024 Location: United KingdomPosts: 89 |
Thats another and huge Problem with LLMs. If there isn't a large code base with which to train an LLM, it can't respond to that code. The best thing to do, in principle, would be to invent a specific LLM code, which would then be run locally through an interpreter or cross-compiler - instead of putting the cart before the horse. Recently i also ran into a problem which my LLMs couldn´t solve. I understand C++ and so by that Arduino Code - up to a certain point, but i don't like to write it because of the finicky upper/lowercase Syntax and other weird constructions. Props to the People who write it with joy, i would go crazy. So i am somehow a noob in this field - no problem for me , on the other hand i can write for example ARM-Assembly which in turn some others can't. So in Arduino i was trying to put together a string including decimals and floats from uint8_t and float variables, by using snprintf , which eventually exits an STM32 on one of its serial ports. It sucessfully printed out the chars and also decimals, but no floats, LLMs were thinking here and there, coming up with crazy solutions, but nothing usable. I was already at the point where i was about to give up, because it didn't make any sense anymore. The final Solution was simple: The Problem was the Library i've used, newlib-nano, which doesn't fully include handling of floats in order to keep the code small (if 4K counts on a 128K Micro). So the LLMs - which i previously told on which Micro i am and which Platform i was using - could -in theory- easily figure out that this could be related to a wrong library. but didn´t get it. If i could ask an LLM -directly- if a wrong library could be the issue, then they would deliver the correct answer: Float is disabled by default - or use dtostrf. Thats a key problem: In theory they "know" the answer, but don´t get the link, because nobody told them to create a Link between A and B, neither by hand, or by training data. Edited 2025-05-30 14:47 by stef123 |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
"AI-generated code could expand the pool from 30 million to a billion developers, unlocking personalised software everywhere." Exponential View PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
English as a programming language I've written maybe 3 very simple Python programs in my life, and haven't touched it in years. But apparently python is the programming language of AI. In Google Gemini, I made this request: Please produce python code for a raspberry pi which will read a file containing lines like the following one and produce a line chart graph with 6 lines labeled "Upper", "Middle", "South", "Lower", "Side", and "East": 250628144138 14.8 223 15.1 9.8 207 21.2 10.5 238 22.7 8.8 136 15.4 10.2 334 32.8 9.7 184 18.9 Data items are separated by one or more spaces. The 7th and 8th characters in the first data item are the hour of the day ("00" - "23") and the 9th and 10th are the time in minutes. These make up the horizontal axis of the graph. Note that the horizontal spacing must account for 60 minutes to the hour, not 100. The numbers to be plotted for each time slot are the 3rd, 6th, 9th, 12th, 15th, and 18th data items. The file to be read will be named "/home/nn/panels.txt". The output file will be named "/home/nn/panels.html". I have 6 mini solar panels placed variously on the front of my barn, nominal 18V max, less than 2-3 watts. I want to chart production over the course of a day so that I can understand shading over time. It has been almost totally overcast today, with a short period of very weak sun. Here is the code which Gemini produced: import plotly.graph_objects as go # --- Configuration --- # Input file containing the data input_file_path = "/home/nn/panels.txt" # Output HTML file for the graph output_file_path = "/home/nn/panels.html" # --- Data Processing --- # Lists to store the parsed data from the file # The x_axis will store time in a format Plotly understands (HH:MM) x_axis_times = [] # Dictionaries to hold the data for each of the 6 lines plot_data = { "Upper": [], "Middle": [], "South": [], "Lower": [], "Side": [], "East": [] } print(f"Attempting to read data from: {input_file_path}") try: with open(input_file_path, 'r') as f: for line_num, line in enumerate(f, 1): # Skips empty lines if not line.strip(): continue # Split the line into parts. Handles one or more spaces. parts = line.split() # A valid line must have at least 18 data items if len(parts) < 18: print(f"Warning: Skipping malformed line #{line_num}. Not enough data items.") continue try: # --- 1. Extract Time for the X-axis --- timestamp_str = parts[0] if len(timestamp_str) < 10: print(f"Warning: Skipping malformed line #{line_num}. Timestamp is too short.") continue # Extract hour (characters 7-8) and minute (characters 9-10) hour = int(timestamp_str[6:8]) minute = int(timestamp_str[8:10]) # Format as "HH:MM". This ensures the chart handles time correctly # (e.g., it knows 60 minutes are in an hour). x_axis_times.append(f"{hour:02d}:{minute:02d}") # --- 2. Extract Data for the Y-axis --- # The values to be plotted are the 3rd, 6th, 9th, 12th, 15th, and 18th items. # Python list indices are 0-based, so we access parts[2], parts[5], etc. plot_data["Upper"].append(float(parts[2])) plot_data["Middle"].append(float(parts[5])) plot_data["South"].append(float(parts[8])) plot_data["Lower"].append(float(parts[11])) plot_data["Side"].append(float(parts[14])) plot_data["East"].append(float(parts[17])) except (ValueError, IndexError) as e: print(f"Warning: Skipping malformed line #{line_num}. Error processing data: {e}") continue except FileNotFoundError: print(f"Error: The input file was not found at {input_file_path}") print("Please make sure the file exists and the path is correct.") exit() # --- Graph Creation --- if not x_axis_times: print("Error: No valid data was read from the file. Cannot generate a graph.") exit() print(f"Successfully processed {len(x_axis_times)} data points.") print("Generating the line chart...") # Create a new figure fig = go.Figure() # Add each of the 6 lines (traces) to the figure fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["Upper"], mode='lines', name='Upper')) fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["Middle"], mode='lines', name='Middle')) fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["South"], mode='lines', name='South')) fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["Lower"], mode='lines', name='Lower')) fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["Side"], mode='lines', name='Side')) fig.add_trace(go.Scatter(x=x_axis_times, y=plot_data["East"], mode='lines', name='East')) # --- Final Touches --- # Update the layout with titles and axis labels fig.update_layout( title='Panel Data Readings Over Time', xaxis_title='Time of Day (HH:MM)', yaxis_title='Data Value', legend_title='Panel Location', font=dict( family="Courier New, monospace", size=14, color="RebeccaPurple" ) ) # By providing time as "HH:MM" strings, Plotly automatically sets the # x-axis type to 'category' or 'date', correctly spacing the time values # and solving the "60 minutes per hour" requirement. # --- Output --- # Write the figure to an HTML file try: fig.write_html(output_file_path) print(f"Success! Graph has been saved to: {output_file_path}") except Exception as e: print(f"Error: Could not write the output file. {e}") I changed only the paths of the input and output files to fit my Pi. Here is my data for the 2+ hours I had the program working (6 INA226 current monitors calculating current through 12V-24V LED modules being read by an ESP32-C3Supermini): 250628134452 14.9 230 15.4 9.8 212 21.6 10.5 249 23.6 8.8 134 15.2 10.2 336 32.9 9.8 188 19.2 250628134752 14.5 205 14.2 9.7 194 19.9 10.4 220 21.1 8.8 125 14.2 10.1 293 29.1 9.7 172 17.7 250628135254 14.6 212 14.5 9.8 199 20.4 10.4 223 21.3 8.8 126 14.3 10.1 287 28.5 9.7 177 18.2 250628135554 14.5 206 14.2 9.7 193 19.8 10.4 219 21.0 8.8 125 14.2 10.1 293 29.1 9.7 172 17.7 250628135854 14.2 190 13.3 9.7 180 18.5 10.4 204 19.7 8.8 120 13.6 10.0 282 28.1 9.7 160 16.5 250628140154 13.7 161 11.7 9.6 156 16.1 10.3 177 17.2 8.7 105 12.1 10.0 261 26.2 9.6 139 14.5 250628140454 14.0 175 12.5 9.7 166 17.2 10.4 193 18.6 8.7 108 12.3 10.0 279 27.8 9.6 148 15.3 250628140754 14.2 187 13.2 9.7 176 18.2 10.4 205 19.7 8.8 118 13.4 10.1 301 29.8 9.7 157 16.2 250628141054 14.0 176 12.5 9.7 168 17.3 10.4 193 18.7 8.8 110 12.6 10.0 276 27.5 9.6 149 15.4 250628141354 14.4 201 13.9 9.7 190 19.4 10.4 216 20.7 8.8 118 13.5 10.1 289 28.7 9.7 167 17.3 250628141654 14.8 226 15.2 9.8 211 21.5 10.5 237 22.6 8.8 132 14.9 10.1 310 30.6 9.8 186 19.1 250628141954 14.6 211 14.5 9.8 198 20.3 10.5 224 21.4 8.8 127 14.4 10.1 308 30.5 9.7 177 18.1 250628142254 15.1 243 16.1 9.8 226 22.9 10.6 255 24.2 8.8 140 15.8 10.2 344 33.7 9.8 201 20.5 250628142724 16.0 307 19.2 10.0 288 28.7 10.7 321 29.9 8.9 178 19.9 10.4 424 40.8 10.0 257 25.8 250628143024 16.1 312 19.4 10.0 293 29.3 10.8 327 30.4 8.9 178 19.9 10.4 414 39.9 10.0 262 26.3 250628143324 16.0 308 19.2 10.0 291 29.0 10.8 330 30.6 8.9 182 20.3 10.4 420 40.4 10.0 259 26.0 250628143624 15.3 259 16.9 9.9 242 24.5 10.6 276 26.0 8.9 156 17.6 10.3 378 36.8 9.8 216 21.9 250628144438 14.2 187 13.2 9.7 178 18.3 10.4 203 19.6 8.8 119 13.5 10.1 293 29.1 9.7 158 16.3 250628144738 14.0 177 12.6 9.7 170 17.5 10.3 192 18.5 8.8 112 12.8 10.0 276 27.5 9.6 150 15.6 250628145038 13.6 154 11.3 9.6 150 15.7 10.3 170 16.5 8.7 101 11.5 9.9 242 24.3 9.6 134 14.0 250628145338 13.8 164 11.9 9.6 159 16.5 10.3 178 17.3 8.7 104 11.9 9.9 245 24.6 9.6 141 14.7 250628145638 14.0 176 12.6 9.7 169 17.5 10.3 188 18.2 8.8 112 12.7 10.0 253 25.3 9.6 150 15.6 250628145938 13.6 153 11.3 9.6 150 15.6 10.3 167 16.3 8.7 102 11.7 9.9 227 22.9 9.6 134 14.0 250628150238 13.3 138 10.4 9.6 137 14.3 10.2 152 14.9 8.7 94 10.7 9.8 208 21.1 9.5 122 12.7 250628150538 12.9 122 9.4 9.5 123 12.9 10.1 136 13.4 8.7 85 9.8 9.8 190 19.4 9.5 109 11.5 250628150838 12.8 113 8.9 9.5 115 12.1 10.1 126 12.5 8.7 79 9.1 9.7 172 17.7 9.5 103 10.9 250628151138 12.8 116 9.0 9.5 118 12.4 10.1 128 12.7 8.7 79 9.1 9.7 165 17.0 9.5 105 11.1 250628151438 13.3 139 10.4 9.6 138 14.4 10.2 152 14.8 8.7 89 10.3 9.8 193 19.7 9.6 123 12.8 250628151738 13.7 159 11.6 9.6 155 16.1 10.3 173 16.8 8.7 100 11.5 9.9 225 22.8 9.6 137 14.3 250628152038 13.9 171 12.3 9.7 164 17.0 10.3 186 18.0 8.8 108 12.4 10.0 254 25.5 9.6 146 15.2 250628152338 13.9 172 12.3 9.7 166 17.2 10.3 186 18.0 8.8 109 12.5 10.0 251 25.2 9.6 148 15.3 250628152638 14.1 184 13.0 9.7 176 18.1 10.4 197 19.0 8.8 115 13.1 10.0 264 26.4 9.7 156 16.2 250628152938 14.2 187 13.2 9.7 179 18.4 10.4 197 19.0 8.8 116 13.3 10.0 260 26.1 9.7 159 16.4 250628153238 14.0 177 12.7 9.7 171 17.6 10.3 189 18.3 8.8 112 12.8 10.0 251 25.2 9.7 152 15.8 250628153538 13.5 148 11.0 9.6 146 15.2 10.2 161 15.8 8.7 99 11.3 9.9 219 22.2 9.6 130 13.6 250628153838 13.0 124 9.5 9.5 125 13.1 10.1 137 13.5 8.7 85 9.8 9.8 184 18.9 9.5 111 11.7 250628154138 12.9 120 9.3 9.5 122 12.8 10.1 132 13.0 8.7 82 9.4 9.7 174 17.9 9.5 108 11.4 250628154438 13.1 128 9.8 9.5 128 13.4 10.2 141 13.9 8.7 87 10.0 9.8 193 19.7 9.5 114 12.0 250628154738 12.7 109 8.6 9.5 112 11.8 10.1 124 12.2 8.6 77 8.9 9.7 175 17.9 9.5 100 10.5 250628155038 12.4 96 7.8 9.4 100 10.6 10.0 111 11.0 8.6 70 8.1 9.7 154 16.0 9.4 89 9.4 It ran with no changes. I copied the output html file to /var/www/html, and it immediately displayed when I entered the URL: ![]() I am very impressed. It no doubt would have taken me many hours to produce this chart using MMBasic DOS or MMB4L or lua or php. All I did was provide a sufficiently complete specification and some data. I like that it was able to pick out the data from my saying use the 3rd, 6th, 9th, 12th, 15th, and 18th words in each line. (Now if I can just teach it to code using MMB4L.) PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
AI writes MMBasic code After getting Google Gemini 2.5 Pro to write python code to chart my mini-solar panels current on an ILI9341 over the course of a day, I asked it to do the same for an ILI9488. 3+ hours later and 4 different ili9488.py drivers, it had still not drawn a line or written text to the LCD, and it gave up. It said that the fourth driver had derived from MMBasic source code (because I had shown that MMBasic could write the ILI9488 screen on the same hardware). (I doubt that it had looked at the MMBasic source, because it later said that it could not look at external sources). So I asked it to write MMBasic code for the ILI9488, and it said it could. I gave it an 8-line program which illustrated all the graphical elements. cls line 48,0,48,272 ' draw vertical axis line line 48,272,mm.hres,272 ' draw horizontal axis line Text MM.HRes/2,0,"Panel Output July 4, 2025",c,2,,rgb(yellow) ' print heading text 60,278," 9",V,1 ' print first time vertically text 8,36,"1400",,1 ' print first (highest) milliwatt reading dim integer mv(16)=(270,250,200,180,185,150,125,200,110,85,70,180,170,200,240,270,270) ' points to plot line plot mv(),,50,20,,,rgb(yellow) ' plot the points Not to laugh but it was 20+ painful versions before it was actually plotting, and Version 26 gave a good plot. Version 33 got some labelling tweaks finalized (279 lines of code): ![]() Although I gave it a link to the MMBasic PicoMite User Manual, it said it was not able to use it to check syntax. Here's the code. I haven't gone through it in detail, but it seems not too bad. (Code at end of post.) When done, I asked if it would remember what it had learned about MMBasic. It said that in a new "Conversation", it would not. I asked it to produce a "Do Not Use" cheat sheet which I could feed it in a future "Conversation" so the same errors would not be repeated. It said that was a good idea, and this is what it produced: ## Updated MMBasic "Do Not Use" List Declarations and Scope CONST [data_type] Invalid: CONST INTEGER FOO = 10 or CONST STRING FOO = "bar" Correct Approach: CONST does not take a data type. Use CONST FOO = 10. LONGINT Invalid: DIM LONGINT MyVar Correct Approach: MMBasic does not have a LONGINT type. Use INTEGER for 32-bit integers. DIM array(0) Invalid: DIM MyArray(0) Correct Approach: Array dimensions must be 1 or greater. Use DIM MyArray(1) for a placeholder that a command like a custom Split can work with. DIM Parts$(...) inside multiple subroutines Risky: Using the same array name with DIM inside different subroutines can cause "already declared" errors due to MMBasic's variable scope rules. Correct Approach: Use unique names for local arrays in each subroutine (e.g., FParts$, LParts$). Passing arrays to subroutines: SUB MySub MyArray() Risky: Can cause "Incompatible type" errors, especially if the array is also declared globally or locally in the calling code block. Correct Approach: A more robust method is to make the array a true global variable (declared at the top level) and have the subroutines access it directly without passing it as a parameter. Control Flow WHILE...WEND Invalid: WHILE condition ... WEND Correct Approach: Use the DO WHILE...LOOP structure. IF condition: statement Invalid: Using a colon : after an IF condition without THEN. Correct Approach: IF statements require the THEN keyword. Use IF condition THEN statement for a single line, or a multi-line IF...ENDIF block. Built-in Functions (or Lack Thereof) SPLIT, TRIM$, REPLACE$, MAP, CEIL, FLOOR Invalid: These common functions do not exist in MMBasic. Correct Approach: They must be implemented as custom FUNCTION or SUB routines using primitive commands. UBOUND(array) Invalid as a general tool. While it works on locally-defined arrays, it can fail with an "Array dimensions" error when used on an array passed as a parameter to a subroutine. Correct Approach: The size of an array must be known from its DIM statement or tracked with a separate variable. When needed inside a subroutine, pass the size as an additional parameter. FREEFILE Invalid: This function does not exist. Correct Approach: Use a literal, fixed number for the file handle (e.g., OPEN file AS #1). DATE$(string$) to parse Invalid: Using DATE$ with a string argument does not parse it. Correct Approach: DATE$ only returns the current system date. To parse a date from a string, you must use LEFT$, MID$, and VAL() to extract the components manually. I asked it if it could use MMB4L on a linux device or MMB4W on Windows to check syntax. It said it couldn't (although it can and does produce and run python code when you ask it to do some research and produce an Excel chart). I think it can check syntax on C code as well. So it was a painful session, but I learned a lot and had a good outcome. The steps were not too different from my own coding process--use F10 AUTOSAVE to throw code into the PicoMite, then fix syntax errors, then fix logic errors. Thoughts for future use I wonder if feeding it one of the recent MMBasic "help" files would enable it to avoid incorrect syntax. It's not hard to conceive that a near-future coding AI could have access to run MMB4L or MMB4W code in a sandbox to fix syntax errors before presenting code to the user. Conclusion Anyway, it was an interesting and fun effort. So now I have a somewhat capable and somewhat imbecilic junior programmer assistant for $.70 a day. More than what I had hoped for when I started this tread, but also in some ways less. Everything is happening fast. ' MMBasic Solar Panel Plotter (Version 33) OPTION EXPLICIT ' --- Configuration --- CONST PLOT_MARGIN = 48 CONST DATA_FILE = "panels.txt" ' --- Global Variables --- DIM STRING DateStr, Title DIM FLOAT MinVal, MaxVal, StartMins, EndMins DIM INTEGER PointCount DIM INTEGER OrderMap(5) ' --- Define the 6 plot series properties --- DIM INTEGER Colors(5) = (RGB(YELLOW), RGB(RED), RGB(GREEN), RGB(BLUE), RGB(CYAN), RGB(MAGENTA)) DIM STRING Labels$(5) = ("LowerLt", "UpperRt", "LowerRt", "South", "Roof", "UpperLt") ' --- Array for month names --- DIM STRING Months$(11) = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December") ' --- Main Program --- AnalyseData IF PointCount > 1 THEN FindOrder DIM FLOAT s1(PointCount), s2(PointCount), s3(PointCount), s4(PointCount), s5(PointCount), s6(PointCount) LoadData s1(), s2(), s3(), s4(), s5(), s6() DrawScreen s1(), s2(), s3(), s4(), s5(), s6() ENDIF END ' ================================================================= ' SUBROUTINES AND FUNCTIONS ' ================================================================= ' --- Custom String Functions --- FUNCTION LTrim$ (in$) LOCAL INTEGER i FOR i = 1 TO LEN(in$) IF MID$(in$, i, 1) <> " " THEN EXIT FOR NEXT i LTrim$ = RIGHT$(in$, LEN(in$) - i + 1) END FUNCTION FUNCTION RTrim$ (in$) LOCAL INTEGER i FOR i = LEN(in$) TO 1 STEP -1 IF MID$(in$, i, 1) <> " " THEN EXIT FOR NEXT i RTrim$ = LEFT$(in$, i) END FUNCTION FUNCTION Trim$ (in$) Trim$ = RTrim$(LTrim$(in$)) END FUNCTION FUNCTION Replace$(Source$, Find$, ReplaceWith$) LOCAL INTEGER P P = INSTR(Source$, Find$) DO WHILE P > 0 Source$ = LEFT$(Source$, P - 1) + ReplaceWith$ + MID$(Source$, P + LEN(Find$)) P = INSTR(Source$, Find$) LOOP Replace$ = Source$ END FUNCTION FUNCTION Split(Text$, Delimiter$, ResultArray$(), MaxParts) LOCAL INTEGER P, I LOCAL STRING Temp$, Work$ Work$ = Trim$(Text$) DO WHILE INSTR(Work$, " ") > 0 Work$ = Replace$(Work$, " ", " ") LOOP I = 0 DO P = INSTR(Work$, Delimiter$) I = I + 1 IF I > MaxParts THEN EXIT DO IF P > 0 THEN ResultArray$(I) = LEFT$(Work$, P - 1) Work$ = RIGHT$(Work$, LEN(Work$) - P) ELSE ResultArray$(I) = Work$ EXIT DO ENDIF LOOP Split = I END FUNCTION FUNCTION Map(val, in_min, in_max, out_min, out_max) IF in_max - in_min = 0 THEN Map = out_min ELSE Map = (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min ENDIF END FUNCTION ' --- Pass 1: Read the file to get metadata --- SUB AnalyseData LOCAL INTEGER I, HH, MM, DD, YY, NumParts, P, DataIdx(5) = (3, 6, 9, 12, 15, 18) LOCAL FLOAT Val LOCAL STRING T$, Line$ DIM STRING Parts$(30) OPEN DATA_FILE FOR INPUT AS #1 MinVal = 99999: MaxVal = -99999: PointCount = 0: StartMins = 0 DO WHILE NOT EOF(1) LINE INPUT #1, Line$ IF Trim$(Line$) <> "" THEN PointCount = PointCount + 1 NumParts = Split(Line$, " ", Parts$(), 30) IF NumParts > 17 THEN IF DateStr = "" THEN T$ = Parts$(1) YY = VAL(LEFT$(T$, 2)) MM = VAL(MID$(T$, 3, 2)) DD = VAL(MID$(T$, 5, 2)) DateStr = Months$(MM - 1) + " " + STR$(DD) + ", 20" + STR$(YY) ENDIF T$ = Parts$(1) HH = VAL(MID$(T$,7,2)): MM = VAL(MID$(T$,9,2)) IF StartMins = 0 THEN StartMins = HH * 60 + MM EndMins = HH * 60 + MM FOR I = 0 TO 5 Val = VAL(Parts$(DataIdx(I))) IF Val < MinVal THEN MinVal = Val IF Val > MaxVal THEN MaxVal = Val NEXT I ENDIF ENDIF LOOP CLOSE #1 PRINT "Found "; PointCount; " data points. Range: "; MinVal; " to "; MaxVal END SUB ' --- Read file to determine the plot order --- SUB FindOrder LOCAL INTEGER i, j, c, NumParts, P, temp, DataIdx(5) = (3, 6, 9, 12, 15, 18) LOCAL FLOAT val LOCAL STRING Line$, T$ ' CORRECTED: Renamed Parts$ to FParts$ to avoid conflict DIM STRING FParts$(30) DIM INTEGER CrossingIndex(5) FOR i = 0 TO 5 OrderMap(i) = i CrossingIndex(i) = 99999 NEXT i OPEN DATA_FILE FOR INPUT AS #1 c = 0 DO WHILE NOT EOF(1) LINE INPUT #1, Line$ c = c + 1 IF Trim$(Line$) <> "" THEN NumParts = Split(Line$, " ", FParts$(), 30) IF NumParts > 17 THEN FOR i = 0 TO 5 IF CrossingIndex(i) = 99999 THEN val = VAL(FParts$(DataIdx(i))) IF val > 200 THEN CrossingIndex(i) = c ENDIF NEXT i ENDIF ENDIF LOOP CLOSE #1 ' Sort the OrderMap array based on the crossing points (Bubble Sort) FOR i = 0 TO 4 FOR j = 0 TO 4 IF CrossingIndex(OrderMap(j)) > CrossingIndex(OrderMap(j+1)) THEN temp = OrderMap(j) OrderMap(j) = OrderMap(j+1) OrderMap(j+1) = temp ENDIF NEXT j NEXT i END SUB ' --- Pass 2: Re-read file to load data into arrays in sorted order --- SUB LoadData s1(), s2(), s3(), s4(), s5(), s6() LOCAL INTEGER C, NumParts, P, I, DataIdx(5) = (3, 6, 9, 12, 15, 18) LOCAL STRING Line$, T$ DIM STRING LParts$(30) DIM FLOAT TempData(5) OPEN DATA_FILE FOR INPUT AS #1 C = 0 DO WHILE NOT EOF(1) LINE INPUT #1, Line$ IF Trim$(Line$) <> "" THEN C = C + 1 NumParts = Split(Line$, " ", LParts$(), 30) IF NumParts > 17 AND C <= PointCount THEN FOR i = 0 to 5 TempData(i) = VAL(LParts$(DataIdx(i))) NEXT i s1(C) = TempData(OrderMap(0)) s2(C) = TempData(OrderMap(1)) s3(C) = TempData(OrderMap(2)) s4(C) = TempData(OrderMap(3)) s5(C) = TempData(OrderMap(4)) s6(C) = TempData(OrderMap(5)) ENDIF ENDIF LOOP CLOSE #1 END SUB ' --- Draw the complete screen with axes, labels, and plots --- SUB DrawScreen s1(), s2(), s3(), s4(), s5(), s6() LOCAL FLOAT y_range_max, y_range_min, x_inc, val LOCAL INTEGER PlotHeight, PlotWidth, y_pos, x_pos, hh, LastLabelX, i, idx LOCAL STRING TimeStr DIM INTEGER p1(PointCount), p2(PointCount), p3(PointCount), p4(PointCount), p5(PointCount), p6(PointCount) y_range_max = INT(MaxVal / 200) * 200: IF y_range_max < MaxVal THEN y_range_max = y_range_max + 200 y_range_min = INT(MinVal / 200) * 200: IF y_range_min > MinVal AND y_range_min > 0 THEN y_range_min = y_range_min - 200 PlotHeight = MM.VRes - (2 * PLOT_MARGIN): PlotWidth = MM.HRes - (2 * PLOT_MARGIN) CLS LINE PLOT_MARGIN, PLOT_MARGIN, PLOT_MARGIN, MM.VRes - PLOT_MARGIN LINE PLOT_MARGIN, MM.VRes - PLOT_MARGIN, MM.HRes - PLOT_MARGIN, MM.VRes - PLOT_MARGIN Title = "Panel Output " + DateStr + " -- mWatts" TEXT MM.HRes/2, 5, Title, C, 1, , RGB(WHITE) FOR val = y_range_min TO y_range_max STEP 200 y_pos = Map(val, y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) IF y_pos >= PLOT_MARGIN THEN TEXT 0, y_pos - 4, STR$(val) LINE PLOT_MARGIN - 4, y_pos, PLOT_MARGIN, y_pos NEXT val LastLabelX = -100 FOR hh = (StartMins / 60) TO (EndMins / 60) x_pos = Map(hh * 60, StartMins, EndMins, PLOT_MARGIN, MM.HRes - PLOT_MARGIN) IF x_pos > LastLabelX + 20 THEN TimeStr = STR$(hh) TEXT x_pos, MM.VRes - PLOT_MARGIN + 8, TimeStr, C LINE x_pos, MM.VRes - PLOT_MARGIN, x_pos, MM.VRes - PLOT_MARGIN + 4 LastLabelX = x_pos ENDIF NEXT hh ' --- Draw Legend using the sorted OrderMap --- FOR i = 0 to 5 idx = OrderMap(i) y_pos = i * (MM.FontHeight + 4) TEXT MM.HRes - 1, y_pos, Labels$(idx), R, , , Colors(idx) NEXT i ' --- Manually scale data into new pixel-coordinate arrays --- FOR i = 1 TO PointCount p1(i) = Map(s1(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) p2(i) = Map(s2(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) p3(i) = Map(s3(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) p4(i) = Map(s4(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) p5(i) = Map(s5(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) p6(i) = Map(s6(i), y_range_min, y_range_max, MM.VRes - PLOT_MARGIN, PLOT_MARGIN) NEXT i x_inc = (MM.HRes - 2 * PLOT_MARGIN) / (PointCount - 1) LINE PLOT p1(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(0)) LINE PLOT p2(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(1)) LINE PLOT p3(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(2)) LINE PLOT p4(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(3)) LINE PLOT p5(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(4)) LINE PLOT p6(), PointCount, PLOT_MARGIN, x_inc, 1, 1, Colors(OrderMap(5)) END SUB ~ Edited 2025-07-05 23:07 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
With a Pico 2 flashed with MMBasic, I issued "LIST commands" and scraped the TeraTerm screen and saved "commands.txt" and then "LIST functions" and saved that as "functions.txt". I downloaded electricat's help.txt file from here: https://www.thebackshed.com/forum/ViewTopic.php?TID=17777&PID=237581#237581#237581 I had to edit lightly. I removed the OPTION entries, and because AUTOSAVE choked on /hex, I edited or deleted the entries which had that (and something else involving "/"). I uploaded those three files to Gemini and told it to use only the commands and functions in those files, and to look into help.txt to find clues for syntax (and said that for many commands it might need further help with syntax and meaning of parameters). It said it understood and would use the proper commands and functions. I then fed it this specification: The flags of Germany, France, Russia, Italy, The Netherlands, Belgium, Sweden, Norway, and Ukraine can all be drawn using the line command (with width specified) and the defined colors. For fun, please produce an MMBasic program filling the ILI9488 screen with those 9 flags with 3 rows of 3 flags and 4 pixels between each flag and each row. Three versions later (less than 15 minutes), after one syntax error and one misalignment of the flags, this is what it produced: ![]() Pretty impressive, I think. It actually used the BOX command, not the LINE command (it said its misunderstanding of the LINE command with LW parameter had caused the misalignment of Version 2). I did not tell it what colors to use for the flags--it figured that out on its own. Here's the code (120 lines): ' MMBasic Flag Drawing Program (Version 3) OPTION EXPLICIT ' --- Configuration --- CONST Gap = 4 CONST FlagW = 157 CONST FlagH = 104 ' --- Color Definitions --- CONST Black = RGB(0,0,0) CONST White = RGB(WHITE) CONST Yellow = RGB(YELLOW) CONST Red = RGB(RED) CONST Green = RGB(GREEN) CONST Blue = RGB(BLUE) CONST Cyan = RGB(CYAN) CONST Magenta = RGB(MAGENTA) ' --- Global Variables --- DIM INTEGER Row, Col, FlagNumber, x, y ' --- Main Program --- CLS ' --- Nested loops to position the 3x3 grid of flags --- FlagNumber = 1 FOR Row = 0 TO 2 FOR Col = 0 TO 2 ' Calculate the top-left corner for the current flag x = Col * (FlagW + Gap) y = Row * (FlagH + Gap) ' Call the appropriate drawing subroutine for each flag SELECT CASE FlagNumber CASE 1: DrawGermany x, y CASE 2: DrawFrance x, y CASE 3: DrawRussia x, y CASE 4: DrawItaly x, y CASE 5: DrawNetherlands x, y CASE 6: DrawBelgium x, y CASE 7: DrawSweden x, y CASE 8: DrawNorway x, y CASE 9: DrawUkraine x, y END SELECT FlagNumber = FlagNumber + 1 NEXT Col NEXT Row END ' ================================================================= ' SUBROUTINES FOR DRAWING FLAGS (Rewritten with BOX for accuracy) ' ================================================================= SUB DrawGermany(x, y) LOCAL INTEGER StripeH1 = 35, StripeH2 = 34 BOX x, y, FlagW, StripeH1, 0, Black, Black BOX x, y + StripeH1, FlagW, StripeH2, 0, Red, Red BOX x, y + StripeH1 + StripeH2, FlagW, StripeH1, 0, Yellow, Yellow END SUB SUB DrawFrance(x, y) LOCAL INTEGER StripeW1 = 52, StripeW2 = 53 BOX x, y, StripeW1, FlagH, 0, Blue, Blue BOX x + StripeW1, y, StripeW2, FlagH, 0, White, White BOX x + StripeW1 + StripeW2, y, StripeW1, FlagH, 0, Red, Red END SUB SUB DrawRussia(x, y) LOCAL INTEGER StripeH1 = 35, StripeH2 = 34 BOX x, y, FlagW, StripeH1, 0, White, White BOX x, y + StripeH1, FlagW, StripeH2, 0, Blue, Blue BOX x, y + StripeH1 + StripeH2, FlagW, StripeH1, 0, Red, Red END SUB SUB DrawItaly(x, y) LOCAL INTEGER StripeW1 = 52, StripeW2 = 53 BOX x, y, StripeW1, FlagH, 0, Green, Green BOX x + StripeW1, y, StripeW2, FlagH, 0, White, White BOX x + StripeW1 + StripeW2, y, StripeW1, FlagH, 0, Red, Red END SUB SUB DrawNetherlands(x, y) LOCAL INTEGER StripeH1 = 35, StripeH2 = 34 BOX x, y, FlagW, StripeH1, 0, Red, Red BOX x, y + StripeH1, FlagW, StripeH2, 0, White, White BOX x, y + StripeH1 + StripeH2, FlagW, StripeH1, 0, Blue, Blue END SUB SUB DrawBelgium(x, y) LOCAL INTEGER StripeW1 = 52, StripeW2 = 53 BOX x, y, StripeW1, FlagH, 0, Black, Black BOX x + StripeW1, y, StripeW2, FlagH, 0, Yellow, Yellow BOX x + StripeW1 + StripeW2, y, StripeW1, FlagH, 0, Red, Red END SUB SUB DrawSweden(x, y) LOCAL INTEGER CrossW = 20, CrossHOff = 42 BOX x, y, FlagW, FlagH, 0, Blue, Blue ' Background BOX x, y + CrossHOff, FlagW, CrossW, 0, Yellow, Yellow ' Horizontal bar BOX x + 50, y, CrossW, FlagH, 0, Yellow, Yellow ' Vertical bar END SUB SUB DrawNorway(x, y) LOCAL INTEGER CrossW = 24, CrossHOff = 40, InnerCrossW = 12, InnerHOff = 46 BOX x, y, FlagW, FlagH, 0, Red, Red ' Red background BOX x, y + CrossHOff, FlagW, CrossW, 0, White, White ' White horizontal BOX x + 44, y, CrossW, FlagH, 0, White, White ' White vertical BOX x, y + InnerHOff, FlagW, InnerCrossW, 0, Blue, Blue ' Blue horizontal BOX x + 50, y, InnerCrossW, FlagH, 0, Blue, Blue ' Blue vertical END SUB SUB DrawUkraine(x, y) LOCAL INTEGER StripeH = 52 BOX x, y, FlagW, StripeH, 0, Blue, Blue BOX x, y + StripeH, FlagW, StripeH, 0, Yellow, Yellow END SUB PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
I decided to ask Gemini to do a little independent research as part of its next effort. I gave it this task. Can you read the list of countries by population here: https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population and determine which 9 with the highest population have flags which can be drawn with the BOX command (no angled or curved lines)? So here it had to look at a Wikipedia page listing nations by population, look up their flags, and determine whether the flags could be drawn with just the BOX command. It gave me a list of the top 9. I then gave the specification: Great. Please produce an MMBasic program to draw those maps in the 3x3 configuration, and print in the middle of each map the name of the country and the population. If the text might go through a white area, use black as the color (rgb(black)), if through a black area, use white. Use the BOX command. With the TEXT command, an "alignment" parameter of C will center the top of the text at the x,y point. It produced the 9 flags. Great flags, but you did not include the name of the country and its population centered in each flag. Two glitches later including a mistake on my part (black text on black background), it produced this: ![]() Exactly right. Now go back to the wikipedia page and pick out the 16 countries with the highest population and a flag which can be drawn with the box command, and produce an MMBasic program to draw those on the ILI9488 with 4 rows of 4 flags. ![]() So this is, at the least, something approaching independent (if guided) research. Gemini is somewhat prone to flattery: I was told that I was expert and patient. ' MMBasic Flag Drawing Program (Version 2) ' Draws the 16 most populous countries with BOX-compatible flags in a 4x4 grid. OPTION EXPLICIT ' --- Configuration for a 4x4 grid on a 480x320 display --- CONST Gap = 4 CONST FlagW = 117 ' (480 - 3*Gap) / 4 CONST FlagH = 77 ' (320 - 3*Gap) / 4 ' --- Color Definitions --- CONST Black = RGB(0,0,0) CONST White = RGB(WHITE) CONST Yellow = RGB(YELLOW) CONST Red = RGB(RED) CONST Green = RGB(GREEN) CONST Blue = RGB(BLUE) CONST Ivory = RGB(255, 255, 240) ' A slightly off-white for contrast ' --- Data for Flags (16 countries) --- DIM STRING Names$(15) = ("Indonesia", "Nigeria", "Russia", "Germany", "Thailand", "France", "Italy", "Colombia", "Ukraine", "Poland", "Yemen", "Madagascar", "Ivory Coast", "Mali", "Netherlands", "Chad") DIM STRING Pops$(15) = ("279M", "224M", "144M", "84M", "71M", "65M", "59M", "52M", "43M", "41M", "35M", "30M", "28M", "23M", "18M", "18M") ' --- Global Variables --- DIM INTEGER Row, Col, FlagNumber, x, y, idx ' --- Main Program --- CLS ' --- Nested loops to position the 4x4 grid of flags --- FlagNumber = 1 FOR Row = 0 TO 3 FOR Col = 0 TO 3 x = Col * (FlagW + Gap) y = Row * (FlagH + Gap) idx = FlagNumber - 1 SELECT CASE FlagNumber CASE 1: DrawIndonesia x, y CASE 2: DrawNigeria x, y CASE 3: DrawRussia x, y CASE 4: DrawGermany x, y CASE 5: DrawThailand x, y CASE 6: DrawFrance x, y CASE 7: DrawItaly x, y CASE 8: DrawColombia x, y CASE 9: DrawUkraine x, y CASE 10: DrawPoland x, y CASE 11: DrawYemen x, y CASE 12: DrawMadagascar x, y CASE 13: DrawIvoryCoast x, y CASE 14: DrawMali x, y CASE 15: DrawNetherlands x, y CASE 16: DrawChad x, y END SELECT DrawLabel x, y, Names$(idx), Pops$(idx) FlagNumber = FlagNumber + 1 NEXT Col NEXT Row END ' ================================================================= ' SUBROUTINES ' ================================================================= SUB DrawLabel(x, y, Name$, Pop$) LOCAL INTEGER CenterX, CenterY LOCAL STRING LabelText$ CenterX = x + FlagW \ 2 CenterY = y + FlagH \ 2 LabelText$ = Name$ + " " + Pop$ TEXT CenterX, CenterY - (MM.FontHeight \ 2), LabelText$, C, , , White, Black END SUB ' --- Flag Drawing Subroutines --- SUB DrawIndonesia(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, Red, Red BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, White, White END SUB SUB DrawNigeria(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, Green, Green BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Green, Green END SUB SUB DrawRussia(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, White, White BOX x, y + StripeH, FlagW, StripeH, 0, Blue, Blue BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, Red, Red END SUB SUB DrawGermany(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, Black, Black BOX x, y + StripeH, FlagW, StripeH, 0, Red, Red BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, Yellow, Yellow END SUB SUB DrawThailand(x, y) LOCAL INTEGER h_outer = FlagH * 1/6, h_inner = FlagH * 1/6, h_center = FlagH * 2/6 BOX x, y, FlagW, h_outer, 0, Red, Red BOX x, y + h_outer, FlagW, h_inner, 0, White, White BOX x, y + h_outer + h_inner, FlagW, h_center, 0, Blue, Blue BOX x, y + h_outer + h_inner + h_center, FlagW, h_inner, 0, White, White BOX x, y + h_outer + h_inner + h_center + h_inner, FlagW, h_outer, 0, Red, Red END SUB SUB DrawFrance(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, Blue, Blue BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Red, Red END SUB SUB DrawItaly(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, Green, Green BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Red, Red END SUB SUB DrawColombia(x, y) LOCAL INTEGER h_top = FlagH \ 2, h_bottom = FlagH \ 4 BOX x, y, FlagW, h_top, 0, Yellow, Yellow BOX x, y + h_top, FlagW, h_bottom, 0, Blue, Blue BOX x, y + h_top + h_bottom, FlagW, FlagH - (h_top + h_bottom), 0, Red, Red END SUB SUB DrawUkraine(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, Blue, Blue BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, Yellow, Yellow END SUB SUB DrawPoland(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, White, White BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, Red, Red END SUB SUB DrawYemen(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, Red, Red BOX x, y + StripeH, FlagW, StripeH, 0, White, White BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, Black, Black END SUB SUB DrawMadagascar(x, y) LOCAL INTEGER v_stripe_w = FlagW \ 3 LOCAL INTEGER h_stripe_h = FlagH \ 2 BOX x, y, v_stripe_w, FlagH, 0, White, White BOX x + v_stripe_w, y, FlagW - v_stripe_w, h_stripe_h, 0, Red, Red BOX x + v_stripe_w, y + h_stripe_h, FlagW - v_stripe_w, FlagH - h_stripe_h, 0, Green, Green END SUB SUB DrawIvoryCoast(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, RGB(247,127,0), RGB(247,127,0) ' Orange BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Green, Green END SUB SUB DrawMali(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, Green, Green BOX x + StripeW, y, StripeW, FlagH, 0, Yellow, Yellow BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Red, Red END SUB SUB DrawNetherlands(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, Red, Red BOX x, y + StripeH, FlagW, StripeH, 0, White, White BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, Blue, Blue END SUB SUB DrawChad(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, Blue, Blue BOX x + StripeW, y, StripeW, FlagH, 0, Yellow, Yellow BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, Red, Red END SUB ~ Edited 2025-07-07 22:19 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
dddns Guru ![]() Joined: 20/09/2024 Location: GermanyPosts: 488 |
It reminds me of the classic text adventure games. But why so polite, bet it will work with grammatical imperative and minimum phrasing as well :)) Point it to the source on github and let it crawl and there shouldn't be anymore spoon feeding work left.. and please ask it, what all of this leads to ;) Edited 2025-07-07 23:38 by dddns |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 5050 |
Thank you for this update. I am impressed, especially about the list of "things to avoid" that it created on it's own, and your idea to use that at a next session as a starting point. Volhout PicomiteVGA PETSCII ROBOTS |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
I'm sure that's true, but I don't want to get out of the habit, in case I forget around humans. My wife recently returned from visiting relatives, and remarked that it was nice to be back where someone was polite. It doesn't appear to be that far along at present. Lots of spoon feeding. Lots of apparently unnecessary regressions. Still faster, for some things, than I would be. And not for some others. Do you mean like "Abundance for All" or "Extinction for Humans"? It doesn't have a crystal ball, and I think the path is uncertain. That keeps growing. Since it used, without my telling it to, OPTION EXPLICIT, I've now told it not to use a variable unless it is in a DIM or LOCAL statement (or SUB or FUNCTION parameter). If it follows that directive, it may eliminate a quarter of the errors it has produced. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
dddns Guru ![]() Joined: 20/09/2024 Location: GermanyPosts: 488 |
I mean, that it already takes now all my illusions and dreams. If you ask it to make a "jig saw" game out of your flags example, it would for sure do. So why should I even think of doing it by myself if there is is a much more faster and convenient way? From my point of view this point will come faster than the internet itself, which only took 25 years..like 2,5 years from now on?? And yes, if there is no more sense for life it'll be done. |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
I can't speak for your illusions, but maybe your dreams would need to expand. ;-) I would be happy to have a black box which can write programs as I specify them. I tend to wake up every few days with something else I want to do, and my to-do list becomes ever longer--for programming as well as for real-life projects. I want to say: here is the MMB4L source and here is the source and user manual for the PicoMite's pin IO, and here is the specification for the API for libgpiod: now write code which allows MMB4L to handle a Raspberry Pi's pins the way a PicoMite's are handled. I want to have a self-driving (electric) car available, but don't necessarily want to own one. I want gummint not to get in the way of clean energy. Three examples in Canada: solar panels tariffed at 165%; mini-split heat pump installers must have a 40-months' apprenticeship, whereas in Maine it's 6 months; Alberta community decides solar farm on "second class" farmland not appropriate for the community. What I don't want: for AI to decide (to be able to decide) that to further its goals, all the earth must be turned into gray goo (or any other more differentiated state which excludes humans and has humans not in control). I do think that the threat of human extinction is greater from AI than from climate change (since humans are very adaptable, but might not be able to escape a hyperintelligence which was focused on getting rid of them). Well, that's far afield from tomorrow's task: getting Gemini to be a little better at writing MMBasic code. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
Today's task for Gemini was to get more realistic colors for the 16 flags. I had originally told it to use the named colors: rgb(red), rgb(green), etc. I asked if it could search out flag images on the web and determine the right colors. It said it could, so I set the specification: Please use your understanding of RGB to get a closer match to the actual color as you find flag examples online in the RGB format (e.g., RGB(130,148,5) for dark yellow). Produce a program for that in the 4x4 format last used. So each flag may have a different version of what we might generally call "green". I thought that if it could find appropriate RGB settings, which it quickly did, this would be result in a quick solution. Unfortunately, for reasons which were mostly silly, it took until Version 13. Among the inexplicable regressions were returning to 9 flags in the 3x3 format, omitting the text, and most contradictory to the specification, returning to the named colors after it had successfully drawn using better colors. But here's the final result--first with the named colors on the left, then with more accurate colors: ![]() The reds, greens, yellows, and blues are notably darker. You can see the difference between adjacent blues with Thailand and France and Netherlands and Chad, and greens between Ivory Coast and Mali. Although it was frustrating for it to take so many iterations when it had immediately solved the color problem, the process is pretty straightforward. Usually within a minute of my presenting an error (or a specification), it has new code, which I copy and paste into TeraTerm after F10 AUTOSAVE. Ctrl-Z, run, and there's a new result. The program--now Version 17 (219 lines) because I noticed a problem with the rendering of the Thai flag (the only one with more than 3 boxes to be drawn). ' MMBasic Flag Drawing Program (Version 17) ' Final check and correction of all variable declarations. OPTION EXPLICIT ' --- Configuration --- CONST Gap = 4 CONST FlagW = 117 CONST FlagH = 77 ' --- Accurate Color Definitions --- CONST Black = RGB(0,0,0) CONST White = RGB(WHITE) ' CORRECTED: All required colors are now explicitly defined CONST IndoRed = RGB(206, 17, 38) CONST NgrGreen = RGB(0, 135, 81) CONST RusBlue = RGB(0, 57, 166) CONST RusRed = RGB(213, 43, 30) CONST GerRed = RGB(221, 0, 0) CONST GerYellow = RGB(255, 206, 0) CONST ThaiRed = RGB(165, 25, 49) CONST ThaiBlue = RGB(45, 42, 114) CONST ItaGreen = RGB(0, 146, 70) CONST ItaRed = RGB(206, 43, 55) CONST ColYellow = RGB(252, 209, 22) CONST ColBlue = RGB(0, 56, 147) CONST ColRed = RGB(206, 17, 38) CONST UkrBlue = RGB(0, 91, 187) CONST UkrYellow = RGB(255, 213, 0) CONST PolRed = RGB(220, 20, 60) CONST YemRed = RGB(206, 17, 38) CONST MadRed = RGB(252, 63, 62) CONST MadGreen = RGB(0, 129, 60) CONST IvcOrange = RGB(247, 127, 0) CONST IvcGreen = RGB(0, 158, 96) CONST MaliGreen = RGB(20, 170, 52) CONST MaliYellow = RGB(252, 209, 22) CONST MaliRed = RGB(206, 17, 38) CONST NldBlue = RGB(33, 70, 139) CONST ChadBlue = RGB(0, 32, 91) CONST ChadYellow = RGB(252, 209, 22) CONST ChadRed = RGB(206, 17, 38) ' --- Global Variables --- DIM INTEGER Row, Col, FlagNumber, x, y, idx ' --- Data for Flags --- DIM STRING Names$(15) = ("Indonesia", "Nigeria", "Russia", "Germany", "Thailand", "France", "Italy", "Colombia", "Ukraine", "Poland", "Yemen", "Madagascar", "Ivory Coast", "Mali", "Netherlands", "Chad") DIM STRING Pops$(15) = ("279M", "224M", "144M", "84M", "71M", "65M", "59M", "52M", "43M", "41M", "35M", "30M", "28M", "23M", "18M", "18M") ' --- Main Program --- CLS ' --- Nested loops to position the 4x4 grid of flags --- FlagNumber = 1 FOR Row = 0 TO 3 FOR Col = 0 TO 3 x = Col * (FlagW + Gap) y = Row * (FlagH + Gap) idx = FlagNumber - 1 SELECT CASE FlagNumber CASE 1: DrawIndonesia x, y CASE 2: DrawNigeria x, y CASE 3: DrawRussia x, y CASE 4: DrawGermany x, y CASE 5: DrawThailand x, y CASE 6: DrawFrance x, y CASE 7: DrawItaly x, y CASE 8: DrawColombia x, y CASE 9: DrawUkraine x, y CASE 10: DrawPoland x, y CASE 11: DrawYemen x, y CASE 12: DrawMadagascar x, y CASE 13: DrawIvoryCoast x, y CASE 14: DrawMali x, y CASE 15: DrawNetherlands x, y CASE 16: DrawChad x, y END SELECT DrawLabel x, y, Names$(idx), Pops$(idx) FlagNumber = FlagNumber + 1 NEXT Col NEXT Row END ' ================================================================= ' SUBROUTINES ' ================================================================= SUB DrawLabel(x, y, Name$, Pop$) LOCAL INTEGER CenterX, CenterY, LabelTextLen LOCAL STRING LabelText$ CenterX = x + FlagW \ 2 CenterY = y + FlagH \ 2 LabelText$ = Name$ + " " + Pop$ LabelTextLen = LEN(LabelText$) TEXT CenterX - (LabelTextLen * MM.FontWidth / 2) , CenterY - (MM.FontHeight \ 2), LabelText$, , , , White, Black END SUB ' --- Flag Drawing Subroutines using the BOX command --- SUB DrawIndonesia(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, IndoRed, IndoRed BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, White, White END SUB SUB DrawNigeria(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, NgrGreen, NgrGreen BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, NgrGreen, NgrGreen END SUB SUB DrawRussia(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, White, White BOX x, y + StripeH, FlagW, StripeH, 0, RusBlue, RusBlue BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, RusRed, RusRed END SUB SUB DrawGermany(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, Black, Black BOX x, y + StripeH, FlagW, StripeH, 0, GerRed, GerRed BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, GerYellow, GerYellow END SUB SUB DrawThailand(x, y) LOCAL INTEGER h_outer, h_center, h_inner h_outer = 13 h_inner = 13 h_center = 25 BOX x, y, FlagW, h_outer, 0, ThaiRed, ThaiRed BOX x, y + h_outer, FlagW, h_inner, 0, White, White BOX x, y + h_outer + h_inner, FlagW, h_center, 0, ThaiBlue, ThaiBlue BOX x, y + h_outer + h_inner + h_center, FlagW, h_inner, 0, White, White BOX x, y + h_outer + h_inner + h_center + h_inner, FlagW, 13, 0, ThaiRed, ThaiRed END SUB SUB DrawFrance(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, RusBlue, RusBlue BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, RusRed, RusRed END SUB SUB DrawItaly(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, ItaGreen, ItaGreen BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, ItaRed, ItaRed END SUB SUB DrawColombia(x, y) LOCAL INTEGER h_top = FlagH \ 2, h_bottom = FlagH \ 4 BOX x, y, FlagW, h_top, 0, ColYellow, ColYellow BOX x, y + h_top, FlagW, h_bottom, 0, ColBlue, ColBlue BOX x, y + h_top + h_bottom, FlagW, FlagH - (h_top + h_bottom), 0, ColRed, ColRed END SUB SUB DrawUkraine(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, UkrBlue, UkrBlue BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, UkrYellow, UkrYellow END SUB SUB DrawPoland(x, y) LOCAL INTEGER StripeH = FlagH \ 2 BOX x, y, FlagW, StripeH, 0, White, White BOX x, y + StripeH, FlagW, FlagH - StripeH, 0, IndoRed, IndoRed END SUB SUB DrawYemen(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, YemRed, YemRed BOX x, y + StripeH, FlagW, StripeH, 0, White, White BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, Black, Black END SUB SUB DrawMadagascar(x, y) LOCAL INTEGER v_stripe_w = FlagW \ 3 LOCAL INTEGER h_stripe_h = FlagH \ 2 BOX x, y, v_stripe_w, FlagH, 0, White, White BOX x + v_stripe_w, y, FlagW - v_stripe_w, h_stripe_h, 0, MadRed, MadRed BOX x + v_stripe_w, y + h_stripe_h, FlagW - v_stripe_w, FlagH - h_stripe_h, 0, MadGreen, MadGreen END SUB SUB DrawIvoryCoast(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, IvcOrange, IvcOrange BOX x + StripeW, y, StripeW, FlagH, 0, White, White BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, IvcGreen, IvcGreen END SUB SUB DrawMali(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, MaliGreen, MaliGreen BOX x + StripeW, y, StripeW, FlagH, 0, MaliYellow, MaliYellow BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, MaliRed, MaliRed END SUB SUB DrawNetherlands(x, y) LOCAL INTEGER StripeH = FlagH \ 3 BOX x, y, FlagW, StripeH, 0, RusRed, RusRed BOX x, y + StripeH, FlagW, StripeH, 0, White, White BOX x, y + 2 * StripeH, FlagW, FlagH - 2 * StripeH, 0, NldBlue, NldBlue END SUB SUB DrawChad(x, y) LOCAL INTEGER StripeW = FlagW \ 3 BOX x, y, StripeW, FlagH, 0, ChadBlue, ChadBlue BOX x + StripeW, y, StripeW, FlagH, 0, ChadYellow, ChadYellow BOX x + 2 * StripeW, y, FlagW - 2 * StripeW, FlagH, 0, ChadRed, ChadRed END SUB ~ Edited 2025-07-08 10:51 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3357 |
Today: A new task, as a lark, illustrating some independent investigation. This MMBasic program will be Version 1. Specification: determine how many unique colors there are on the 16 flags; sort them by wavelength into a rainbow arrangement; display a box for each color starting at y=0, depth 100 pixels, width=mm.hres/number-of-colors; below each color box print the country name with an "alignment" in the TEXT command of CT, which is to be centered below the box and printed vertically; avoid syntax errors by confirming that any variables used have been declared and that command or functions used are in the commands and functions text files provided earlier, or are supplied by you, and syntax conforms to the "help" file provided earlier. I thought that if Gemini could sort the rgb colors in the flags in rainbow order, as it quickly showed it could with access to some API which gave it hue, this might be a one-and-done task. Unfortunately, it was Version 10 before it got this: ![]() Errors included undeclared variable (despite the fact that I have told it multiple times to always check before providing code that all variables are in DIM or LOCAL statements), giving country names of "Cyan" and "Magenta", regressing entirely to a version of the flags program, inventing a new parameter for the TEXT command (compounded by my initially saying the "alignment" parameter should be CT instead of CTV), and not sorting in rainbow order (with white and black first). I eventually had to feed it the colors it had used in the flag program: CONST IndoRed = RGB(206, 17, 38) CONST NgrGreen = RGB(0, 135, 81) CONST RusBlue = RGB(0, 57, 166) CONST RusRed = RGB(213, 43, 30) CONST GerRed = RGB(221, 0, 0) CONST GerYellow = RGB(255, 206, 0) CONST ThaiRed = RGB(165, 25, 49) CONST ThaiBlue = RGB(45, 42, 114) CONST ItaGreen = RGB(0, 146, 70) CONST ItaRed = RGB(206, 43, 55) CONST ColYellow = RGB(252, 209, 22) CONST ColBlue = RGB(0, 56, 147) CONST ColRed = RGB(206, 17, 38) CONST UkrBlue = RGB(0, 91, 187) CONST UkrYellow = RGB(255, 213, 0) CONST PolRed = RGB(220, 20, 60) CONST YemRed = RGB(206, 17, 38) CONST MadRed = RGB(252, 63, 62) CONST MadGreen = RGB(0, 129, 60) CONST IvcOrange = RGB(247, 127, 0) CONST IvcGreen = RGB(0, 158, 96) CONST MaliGreen = RGB(20, 170, 52) CONST MaliYellow = RGB(252, 209, 22) CONST MaliRed = RGB(206, 17, 38) CONST NldBlue = RGB(33, 70, 139) CONST ChadBlue = RGB(0, 32, 91) CONST ChadYellow = RGB(252, 209, 22) CONST ChadRed = RGB(206, 17, 38) The process was more frustrating than it should have been, but still pretty quick. I think its finding and sorting on the hue value was creditable--indicative of an ability to search for external means to solve a problem. Here's the final code (63 lines): ' MMBasic Flag Color Spectrum (Version 10) ' Uses a manually sorted list of all unique colors for accuracy. OPTION EXPLICIT ' --- Configuration --- CONST BarH = 100 CONST LabelY = 110 ' --- Manually Sorted Array of Unique Colors from all 16 Flags --- ' Sorted: White, Black, Reds, Oranges, Yellows, Greens, Blues CONST NumColors = 20 DIM INTEGER Colors(NumColors) DIM STRING Names$(NumColors) ' --- Global Variables --- DIM INTEGER i, x, BarW, TxtX, TxtY ' --- Main Program --- ' Read all data from the DATA statements into the arrays FOR i = 1 TO NumColors READ Colors(i), Names$(i) NEXT i CLS BarW = MM.HRes / NumColors FOR i = 1 TO NumColors x = (i - 1) * BarW BOX x, 0, BarW, BarH, 0, Colors(i), Colors(i) TxtX = x + (BarW \ 2) TxtY = LabelY TEXT TxtX, TxtY, Names$(i), CTV, , , RGB(WHITE) NEXT i END ' ================================================================= ' DATA Section ' ================================================================= ' Data is pre-sorted: White, Black, Reds, Orange, Yellows, Greens, Blues DATA RGB(WHITE), "Russia" DATA RGB(0,0,0), "Germany" DATA RGB(165, 25, 49), "Thailand" DATA RGB(174, 28, 40), "Netherlands" DATA RGB(186, 12, 47), "Norway" DATA RGB(206, 17, 38), "Indonesia" DATA RGB(213, 43, 30), "Russia" DATA RGB(220, 20, 60), "Poland" DATA RGB(221, 0, 0), "Germany" DATA RGB(239, 65, 53), "France" DATA RGB(252, 63, 62), "Madagascar" DATA RGB(247, 127, 0), "Ivory Coast" DATA RGB(255, 206, 0), "Germany" DATA RGB(255, 213, 0), "Ukraine" DATA RGB(252, 209, 22), "Colombia" DATA RGB(0, 158, 96), "Ivory Coast" DATA RGB(0, 146, 70), "Italy" DATA RGB(0, 135, 81), "Nigeria" DATA RGB(0, 57, 166), "Russia" DATA RGB(0, 32, 91), "Chad" I notice that although I gave it 28 rgb colors (that it had generated for the flags program), it only displayed 20. It is possible that its hue routine returned the same value for some. I didn't think to ask it if that was what happened. The last part of the specification is boiler-plate which I will include with each new specification. I wish I could just say it once and be done, but that doesn't seem to be the case: avoid syntax errors by confirming that any variables used have been declared and that command or functions used are in the commands and functions text files provided earlier, or are supplied by you, and syntax conforms to the "help" file provided earlier. ~ Edited 2025-07-09 09:29 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |