Libraryless. Click here for Pure Java version (4205L/29K/102K).
1 | !759 |
2 | |
3 | static JTable table; |
4 | static JTextArea chat; |
5 | static JTextField input; |
6 | static File logFile; |
7 | static new L<S> log; |
8 | static L<S> recommendations; |
9 | |
10 | static int listDelay = 2000, listMakingTimeout = 2000; |
11 | static int maxListLength = 100; |
12 | |
13 | static Bool thinking; |
14 | static bool updateOnce = true; |
15 | static new Thinker thinker; |
16 | |
17 | static S systemPrefix = "[system]"; |
18 | |
19 | p-awt { |
20 | //substanceLAF("EmeraldDusk"); // Too dark! |
21 | substanceLAF("ChallengerDeep"); |
22 | loadLog(); |
23 | |
24 | thinker.startUp(log); |
25 | |
26 | table = tableWithTooltips(); |
27 | chat = autoScroll(wordWrapTextArea()); |
28 | chat.setText(joinLines(log)); |
29 | input = new JTextField; |
30 | JFrame frame = showFrame(vgrid(centerAndSouth(chat, input), table)); |
31 | //setFrameIconLater(frame, "#1003593"); |
32 | |
33 | onEnter(input, r { |
34 | post(); |
35 | }); |
36 | |
37 | onDoubleClick(table, voidfunc(int row) { |
38 | chooseSuggestion(row); |
39 | }); |
40 | |
41 | for (int i = 1; i <= 12; i++) { |
42 | final int _i = i; |
43 | registerFunctionKey(frame, i, r { |
44 | chooseSuggestion(_i-1); |
45 | }); |
46 | } |
47 | |
48 | fillList(); |
49 | |
50 | input.requestFocus(); |
51 | } |
52 | |
53 | static S getInput() { |
54 | ret joinLines(" # ", input.getText().trim()); |
55 | } |
56 | |
57 | static void post() { |
58 | S i = getInput(); |
59 | if (inputAllowedByUser(i)) |
60 | post(i); |
61 | } |
62 | |
63 | svoid chooseSuggestion(int row) { |
64 | L<S> line = getTableLine(table, row); |
65 | if (line == null) ret; |
66 | S s = line.get(0); |
67 | if (empty(s)) ret; |
68 | input.setText(s); |
69 | post(); |
70 | } |
71 | |
72 | static bool inputAllowedByUser(S i) { |
73 | ret !swic(i, systemPrefix); |
74 | } |
75 | |
76 | static void postSystemMessage(S msg) { |
77 | post(systemPrefix + " " + msg); |
78 | } |
79 | |
80 | static void post(S i) { |
81 | S s = i + "\n"; |
82 | chat.append(s); |
83 | appendToFile(logFile, "[" + chatTime() + "] " + s); |
84 | synchronized(mc()) { |
85 | log.add(i); |
86 | } |
87 | input.selectAll(); |
88 | updateOnce = true; |
89 | action(i); |
90 | } |
91 | |
92 | static void action(S s) { |
93 | if (!s.startsWith("!")) ret; |
94 | s = dropPrefix("!", s); |
95 | new Matches m; |
96 | if "start program *" { |
97 | S progID = m.fsi(0); |
98 | S title = getSnippetTitle(progID); |
99 | // TODO: Show author! |
100 | S msg = "Run program " + progID + " - " + title + "?"; |
101 | if (confirmOKCancel(chat, msg)) { |
102 | postSystemMessage("Starting program " + progID + " - " + quote(title)); |
103 | nohupJavax(progID); |
104 | } else |
105 | postSystemMessage("Program start cancelled by user (was: " + progID + ")"); |
106 | } |
107 | } |
108 | |
109 | static void fillList() { |
110 | bool t = shouldUpdateList() || updateOnce; |
111 | updateOnce = false; |
112 | if (neq(t, thinking)) { |
113 | thinking = t; |
114 | setFrameIcon(table, t ? "#1003603" : "#1003593"); |
115 | } |
116 | |
117 | if (!t) |
118 | againl8r(); |
119 | else thread "Fill List" { |
120 | final new L<S> data; |
121 | thinker.makeListData(data); |
122 | |
123 | dataToTable_uneditable(table, data); |
124 | againl8r(); |
125 | } |
126 | } |
127 | |
128 | static void againl8r() { |
129 | swingAfter(table, listDelay, r { fillList(); }); |
130 | } |
131 | |
132 | static bool shouldUpdateList() { |
133 | ret getFrame(table).isFocused() |
134 | && !mouseInComponent(table); |
135 | } |
136 | |
137 | // also called from outside |
138 | static L<S> loadLog() { |
139 | if (logFile == null) |
140 | logFile = getProgramFile("log.txt"); |
141 | for (S s : toLines(loadTextFile(logFile))) pcall { |
142 | log.add(substring(s, s.indexOf(']')+1).trim()); |
143 | } |
144 | ret log; |
145 | } |
146 | |
147 | !include #1003606 // GenTesting |
148 | |
149 | sclass Thinker { |
150 | new MultiSet<S> scores; |
151 | new MultiSet<S> quickScores; |
152 | int quickAnalysisDepth = 100; |
153 | int logLengthSeen; |
154 | |
155 | void startUp(L<S> log) { |
156 | final L<S> _log = cloneList(log); // Clone to be safe |
157 | |
158 | thread "Full Scoring!" { |
159 | scores = makeGT().scoreGenerators(_log); |
160 | } |
161 | } |
162 | |
163 | GenTesting makeGT() { |
164 | ret new GenTesting(voidfunc(L<Gen> gens, L<S> log) { makeGenerators(gens, log); }); |
165 | } |
166 | |
167 | void updateQuickScores() { |
168 | if (l(log) > logLengthSeen) { |
169 | logLengthSeen = l(log); |
170 | quickScores = makeGT().scoreGenerators(getLastFromLog(quickAnalysisDepth)); |
171 | } |
172 | } |
173 | |
174 | // also called from outside |
175 | void recommendSolver(S solverID) { |
176 | if (!isRecommendedSolver(solverID = fsi(solverID))) { |
177 | print("Adding recommended solver: " + solverID); |
178 | logQuoted("recommendations.txt", solverID); |
179 | } else |
180 | print("Solver already recommended: " + solverID); |
181 | } |
182 | |
183 | bool isRecommendedSolver(S solverID) { |
184 | ret contains(scanLog("recommendations.txt"), fsI(solverID)); |
185 | } |
186 | |
187 | // Scoring formula! |
188 | int formula(S genName) { |
189 | ret quickScores.get(genName)+scores.get(genName); |
190 | } |
191 | |
192 | L<Gen> sortGenerators(L<Gen> gens, final MultiSet<S> scores) { |
193 | ret sortedList(gens, func(Gen a, Gen b) { |
194 | formula(b.name)-formula(a.name) |
195 | }); |
196 | } |
197 | |
198 | void makeListData(L l) { |
199 | try { |
200 | updateQuickScores(); |
201 | new L<Gen> gens; |
202 | makeGenerators(gens, log); |
203 | gens = sortGenerators(gens, scores); |
204 | if (empty(gens)) { |
205 | l.add(ll("No generators")); |
206 | ret; |
207 | } |
208 | |
209 | long timeout = now() + listMakingTimeout; |
210 | int i = -1; |
211 | new HashSet<S> seen; |
212 | while (now() < timeout && l(l) < maxListLength && nempty(gens)) { |
213 | i = (i+1) % l(gens); |
214 | Gen gen = gens.get(i); |
215 | try { |
216 | S s = cast callF(gen.func); |
217 | if (empty(s) || seen.contains(s)) |
218 | gens.remove(i); |
219 | else { |
220 | seen.add(s); |
221 | int k = l(l)+1; |
222 | S key = k <= 12 ? "F" + k : null; |
223 | l.add(litorderedmap("Suggestion", s, "Suggester", gen.name, "Key", key)); |
224 | } |
225 | } catch { |
226 | gens.remove(i); |
227 | } |
228 | } |
229 | } catch e { |
230 | printStackTrace(e); |
231 | l.add(e.toString()); |
232 | } |
233 | } |
234 | } |
235 | |
236 | // CREATIVE PART! |
237 | |
238 | // put func {}'s returning a string in there |
239 | static void makeGenerators(L<Gen> l, final L<S> log) { |
240 | gen(l, "hello random", func { "Hello " + randomID(10) }); |
241 | gen(l, quine(func { last(log) })); |
242 | gen(l, quine(func { oneOf(log) })); |
243 | gen(l, "1 assoc", oneAssoc(log)); |
244 | gen(l, "most popular", mostPopular(log)); |
245 | addLoadedSolvers(l); |
246 | } |
247 | |
248 | svoid addLoadedSolvers(L<Gen> l) { |
249 | if (recommendations == null) { |
250 | recommendations = new L; |
251 | for (S s : scanLog("recommendations.txt")) |
252 | if (isSnippetID(s)) |
253 | recommendations.add(s); |
254 | } |
255 | |
256 | for (final S solverID : recommendations) |
257 | gen(l, solverID, func { |
258 | O c = hotwireCached(solverID); |
259 | ret call(c, "calc", log); |
260 | }); |
261 | } |
262 | |
263 | static O oneAssoc(final L<S> log) { |
264 | ret func { |
265 | for (int i = l(log)-2; i >= 0; i--) |
266 | if (eqic(log.get(i), last(log))) |
267 | ret log.get(i+1); |
268 | null; |
269 | }; |
270 | } |
271 | |
272 | static O mostPopular(final L<S> log) { |
273 | ret func { |
274 | ret new MultiHashSet<S>(log).getMostPopularEntry(); |
275 | }; |
276 | } |
277 | |
278 | synchronized static L<S> getLastFromLog(int n) { |
279 | ret cloneList(getLast(log, n)); |
280 | } |
Began life as a copy of #1003678
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003684 |
Snippet name: | "Random" v5 (with "quick scores") |
Eternal ID of this version: | #1003684/1 |
Text MD5: | 5861b7c6e426c9e20e178aac1e3a53a7 |
Transpilation MD5: | ab1af3bb49220884da1cfb3deb39c5b5 |
Author: | stefan |
Category: | javax / talking robots |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-07-25 21:41:20 |
Source code size: | 6711 bytes / 280 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 521 / 633 |
Referenced in: | [show references] |