I was happy making tables with a primary key and short names, their IDs placed into an aggregate table of like-minded integers, but the dropdown progression of classification made me go with a CSV-formatted, duplicate-value – but unique index – approach. Ultimately, the gestalt of the choices made in each dropdown corresponds to one ID, rather than a choice table with three columns of ints.
To the user, there is no useful meaning to have each choice in its own table, separated. It was only because I wanted to avoid repeats that I would conjure a single, simple table for each. Compare the following, where t is a table and ta is an aggregate table:
select id from t where d1 = 'a' and d2 = 'b' and d3 = 'c';
select id from ta where
ta.d1 = (select id from t1 where t1.d1 = 'a') and
ta.d2 = (select id from t2 where t2.d1 = 'b') and
ta.d3 = (select id from t3 where t3.d1 = 'c');
Where I populated table t with this CSV-formatted data:
The letters themselves representing longer but repeated strings, although the table enforces the unique index constraint across (d1,d2,d3) – so (a,a,b) couldn’t appear more than once.
The data is only significant to metrics when b or c is reached by the paths of aa, ab or ac.
I’ve replaced my notebook with looseleaf and a binder: it’s cheaper, easily organized, and larger. It’s sketches next to improvised tables next to columned entries, empty rows between blue-lined tracts.
I also moved the computer to a separate area, a remote desk, like in the timeshare days of old: computing as a utility, mainframe invests of reflection upon input and output, fingers less so on keys and more resting with laid arms, while brain bucks and sways. My criteria before heading the three feet to sit at the machine is to come with scrawled notes of sample programs, to reproduce them from my observations. It is not typing blindly the listings in books, but reproductions from an interpretation of the original, an apt avout before the domain of the Ita.
Writing notes about code lets you draw diagrams. For OOP, that’s lines to sequence method invokes, “:instance” boxes with a trail down and an arrow to the normal, a scribbled “restoreScreen()” above it. For a brief moment, you’re Lions and you’re annotating UNIX for a generation.
I thought about if I had enough content to sustain this blog. About private notes. About significance and the shared net. About little updates and large plans, about daily writes the worth of its spent. If this is my one outlet, then I ought to continue. I still type faster than I write, and alliteration needs allowance for Flow.
How do you store an outline in a database?
You have some options:
- Store common strings in organized tables. This requires domain knowledge and further requirements gathering. Together, you and the stakeholder hammer out a cleaner ontology, resulting in three tables: Planet, Place, Method.
- Populate from a CSV file, even if there are repeats. So you could have (Delivery,Mapping,Online), (Carryout,Heat,Metrics), etc. Each ID in the database refers to a certain combination.
- Refer to a lookup table whose columns include table name (Method, Delivery, Carryout) and the index as foreign key (A, B, C). With this approach, you will need to enforce that ([Method],Carryout,C) is not allowed.
I decided to go with CSV text files to populate the tables because they are canonical sources and changing them will be easy – as long as only three (I-III) columns are used. I could also temporarily do things like ([Method],[Delivery],Carryout–Metrics–Measuring) if I wanted to maintain a two-level format, if it was a one-time thing.
The plan is to populate dropdowns depending on the user’s choice, progressively allowing only certain values. For example, choosing Delivery would only allow Mapping, Metrics or Heat in the second dropdown.
An AutoIt event would trigger on dropdown selection to populate each choice.
Threads get to access shared data. They may preempt and do processing for different contexts. The tricky part is synchronizing writes so that updates are sane. One example is failing to mark a critical section for a player’s coordinates: the x is updated, but another thread preempts and reads the old y location.
AutoIt is essentially single-threaded, but a server-side task lets you handle lookups or I/O-blocked activities while the user’s view remains responsive. Given a table t,
col 1 col 2 col 3
----- ----- -----
2913 1311 NULL
The user app inserts into the table for values in col 1 and col 2. His view gets refreshed and looks like this:
data 1: ______ (awaiting next input)
data 2: ______ (awaiting next input)
| SUBMIT |
ListView of work
col 1 col 2 col 3
----- ----- -----
2913 1311 ''
On the server-side, you have a AutoIt app that runs a ODBC select * from t, and perhaps runs a network task that looks up information based on data 2913 and 1311:
Dim $dbConn = ...
Local $query = "select col1, col2 from t where col3 = " & _
Chr(39) & Chr(39)
; iterate array and RunWait() with lookup script
; insert into t1 set col3 = 'OCCUPADO' where col1 = 2913 and
; col2 = 1311
A little bit later, the user’s ListView populates with data for col 3.
Refreshing a large data set can make the user app less responsive, so it may be preferable to have a separate app that only sleeps and refreshes a ListView. Then you have an “input app” and a “view app.” The view app lets you market “real-time updates” as a feature, even though it is polling with Sleep().
I’m trying to avoid eating out for lunch: the money saved isn’t per week, but over two weeks. I can stretch gas to two weeks too: accelerating to highway speeds, to and from restaurants, subtracts almost an additional week without refueling. Conserving gas saves money, but I also want to save time.
When I had a 30-minute lunch, I pushed for a full hour. Now I see that spending a whole hour on lunch during a pay period deprives me of five hours of work, and for nothing less than greed over discretionary miscellany. Driving around during lunch eats into that time, so I’m better served eating in-house.
Saving that money is even more imperative now, because I’m paying my parents rent. I do it gladly, because it prevents me from impulsive purchases. I also won’t have any savings, but that aligns well with the bootstrap coder who survives on his trusty mechanical keyboard and instinctive intuition.
It’s not future-forward thinking; I may not be in enough simulated poverty to be willing to learn the newest trending technologies.
WordPress and its “title-first” insistence is common: command-line text editors insist on a filename up-front. Microsoft Word and Excel let you open blank files first and save later. The point is I seem to have this habit of titling posts with what I intended to write, but the content becomes a lead-in; the post becomes an introduction. Then I have to follow up with the actual-real post. I guess content-wise it is a good approach, but not one I would have deliberately adopted. Being conscious of it now, well.
How do you fairly distribute x units based on y expectations across z dimensions? For example, if you finish four units of A in thirty minutes and the status quo is eight units of A in an hour, what does that mean; isn’t that equivalent?
I wrote a program where you can fiddle with time increments. One hour is too coarse-grained; you can calculate smaller intervals. Set them up as UpDown widgets; in AutoIt, each adjustment fires an event. You can have a table where inputs are
- expected output
- hours worked
- actual reported output
- number of increments to allocate
When you run across z > 1 dimensions, scratch out an algorithm to distribute the times fairly: as much as needed to hit as many goals as possible, leaving more greens than reds for the managers to mull over. Now people can work on different things throughout the day and be favorably credited for all of them (or as many as).
The other cool thing is that it reminds me of memory allocation, of bin packing. You have some time units that need to be spread out across different quantity “bins” in order to solve a linear system.
I’m really liking the concept of the “intermediate program,” where you create a GUI that gradually lets you discover the problem space. Each button is a parameterized command, repeatable and faster than typing. There’s no real design constraint; you can put buttons, lists and input fields anywhere. It’s a throwback to elaborate GUIs that I saw when I was younger; we probably won’t see them now with today’s minimalist philosophy.
The intermediate program is formalized terminal I/O: you click a button and output goes somewhere. A table gets loaded; an array gets filled: these populate into lists. Other buttons check database connections, the presence of files, and other utility tasks. Sticking to MVC, refactoring could lead to command-line diagnostic tools. I never thought of working backwards from a GUI to prototype console utils! What an adventure.
I’m starting to adopt a plurality model of thought when it comes to problem-solving: instead of building one program, there ought to be the expectation of many programs. Each one lets you explore the problem space in a different context. Initially, you have a program that just spits output and checks things. Later, you fragment, generalize, or specialize.
That’s what I meant: programs to explore a problem space: not one program, but many. It may seem like a GUI that has to grow by width and height to accommodate features is a creeping prototype on its way to monolithism. The first-time user would look at the thing, bewildered, and wonder where to begin.
For left-to-righters, it would seem to first look at the upper left and the corners. They’re not going to stop and read the docs. So once all the fancy, navel-gazing tools are built, it’s time to recycle and reuse – well, my hope lies in refactoring, that before the stage at which the application becomes a giant mixer of sliders, knobs and buttons, I will have re-written a generalized tool above it, so that we can all be sound engineers without a studio.
I’ve been pushing CLI for automation and scripting. It’s a plus, but exploration takes a certain ratcheting, a discrete sense, of interactive step-wise inflection. Programming as brainstorm. Event-driven programming as graphical REPL. Then we haven’t moved away from computes; we’ve shifted the interface up.
Later, when the process can be repeated in perfect manner manually, when all our human rules can be caught by code, we can automate.
I made a big compromise today and went with a GUI first instead of CLI. Instead of smaller tools with exact execution and mindful documentation, I went with buttons: a button to create tables, another to check for the right files, yet a third for checking the input file for errors. Those results all populated themselves from temporary arrays into list boxes, and in one pane I had the output of three equivalent commands.
Even moreso, there was a synergy among them: one list box to tell from a file, another to retrieve rows from a key-value table, and the third to list the difference. I could wrap these up into a single invocation, scripted, like ruminants’ bones thrown in a pile to be scraped over like shamans of old; yet here they were in neat lines.
Since the app is MVC, the view can be converted to console-output results. Bonus points for porting it to cygwin a la perl and curses. Even more for deploying it in production, blue-yellow windows, block cursor and all. But that’s not the thrust of this post at all –
The point is that I found a use for GUIs: to explore and inspect pieces of an application space. In this case, a database that needed to be populated with good data, and this middle step where I could inspect things. Previously, I was gung-ho about automation, full-steam ahead, and the subsequent oracular divinations regarding bad inserts.
This is more of a REPL philosophy. Where you can put numbers in a stack, one at a time, and reflect on the results. The computer waits on you.
One of the early exercises in “C++ in Action” is to implement a complement ~ operation in the stack-storage calculator. The example given is a 4-bit number 13 1101b whose complement is 2 0010b. However, the calculator returns -14.
sizeof(int) returns 4, so integer types are four bytes on my machine. That’s 32 bits. A for loop can generate a table of complements from 0 to 100; the pattern that plays is the sign bit is flipped and then 1 is added.
Flip the sign bit and add 1.
0: 1 0000000 00000000 00000000 00000000
-1: 1 0000000 00000000 00000000 00000001
1: 0 0000000 00000000 00000000 00000001
-2: 1 0000000 00000000 00000000 00000010
2: 0 0000000 00000000 00000000 00000010
-3: 1 0000000 00000000 00000000 00000011
~0 = -1
~1 = -2
~2 = -3
~13 = -14