World: r4wp
[Rebol School] REBOL School
older newer | first last |
Endo 27-Jun-2012 [465x2] | Anyone has a good idea to count number of values in a block? Ofcourse it is not difficult to write, but I want to ee some clever ideas :) >> b: ["a" k 99 k k 99 55 "a" 1] >> count-values b == ["a" 2 k 3 99 2 55 1] ;value-count |
* ee = see | |
Sunanda 27-Jun-2012 [467] | I'm a regular user of Joel's 'tally function: http://www.rebol.org/ml-display-message.r?m=rmlKDDS |
MaxV 27-Jun-2012 [468] | WOW! |
Endo 27-Jun-2012 [469x2] | I wrote another function which returns in the above format, so I can SELECT/SKIP 2, to get the number of occurence of the value, and it doesn't use SORT, uses REMOVE-EACH instead. it: >> f: func [b /local c r n1 n2] [r: copy [] foreach v unique b [c: copy b n1: length? c remove-each w c [v = w] n2: length? c append r reduce [v n1 - n2]] r] >> a: [a b c c a a b b c d d e e e f f h f f g h] >> f a == [a 3 b 3 c 3 d 2 e 3 f 4 h 2 g 1] |
Oh small mistake, no need to COPY each time: this is much better: f: func [b /local c r n1 n2] [r: copy [] foreach v unique b: copy b [n1: length? b remove-each w b [v = w] n2: length? b append r reduce [v n1 - n2] ] r ] | |
Maxim 27-Jun-2012 [471] | that is a massively interesting mail from Joel Neely. He is one of the old-time rebolers I miss most. He has a very good sense of how to explain his points. |
Endo 27-Jun-2012 [472] | Interesting, my tally function and Joel's, work almost in same speed, 53 sec. for 1 million execution for both. |
Maxim 27-Jun-2012 [473] | just found a very handy idiom ( not new, just rarely discussed and possibly missed by many ): help function! this lists all known functions in the global scope (same for help native! help action!) obviously you can do this for all datatypes, so its very handy to get the names of stuff you often forget, like the internal color names (help tuple! ) |
Ladislav 27-Jun-2012 [474x4] | Interesting, my tally function and Joel's, work almost in same speed, 53 sec. for 1 million execution for both. - I guess that the version using SORT should be much faster. |
As far as I remember, it should be available from the ML as well. | |
Aha, I checked and Joel's code actually *is* using SORT, which means it is O(n * log n) algorithm. While, at the same time, the above REMOVE-EACH is O(n * n), which is *much* slower as far as I am concerned. | |
Sorry, I meant that the above REMOVE-EACH based algorithm can be roughly O(n * n) | |
Steeve 27-Jun-2012 [478x2] | (Search for fast-tally in Altme groups) using the unique trick: fast-tally: func [b [block!] /local u i] [ b: sort b u: unique b i: 1 until [ b: any [find b u/2 tail b] u/1: as-pair u/1 negate i - i: index? b tail? u: next u ] head u ] And also, the radix algo is pretty good (if the max value is not too large) radix: func [b [block!] /local u maxv] [ maxv: 0 foreach v b [maxv: max maxv v] u: head insert/dup make block! maxv 0 maxv foreach v b [ u/:v: u/:v + 1 ] u ] |
in R2, use maximum-of instead of: >> foreach v b [maxv: max maxv v] | |
Ladislav 27-Jun-2012 [480x3] | FAST-TALLY does not look like being universal. (I suppose it is designed to work only for B's containing integers...) |
...and its speed cannot exceed the speed of more universal tallies in a significant way | |
...the RADIX algorithm looks even less universal (needs positive integers I guess) | |
Steeve 27-Jun-2012 [483] | Well, if you want to say that these algos need adaptations to fit every ones needs, you're right ) |
Ladislav 28-Jun-2012 [484x2] | I wanted to tell that they are too specialized while bringing no speed advantage compared to Joel's code. |
However, Joel's TALLY is not universal either. Joel criticized the problem with exceptions of the LESSER? function in his ML posting. But there are also exceptions related to the EQUAL? function which make his implementation non-universal (for some blocks B their elements are incomparable using the EQUAL? function). Such blocks cannot be processed using Joel's TALLY. | |
Arnold 29-Jun-2012 [486] | Found the way to use labels that are indexed: I already had them in a panel like this panel-1: panel [across space 0x0 label "_" label "_" label "_" label "_" ; just use an underscore to see it on screen label "_" label "_" label "_" label "_" ] in a function change them like this f: func [] [ for n 1 8 1 [ waarde: to-string pick randwaarden n ; randwaarden is a block of values do rejoin ["panel-1/pane/" n "/text: " waarde]]] ; I always use rejoin in these situations. |
Henrik 29-Jun-2012 [487] | This is REBOL, so no need to DO strings. It's slower and costs memory: f: does [ repeat n length? panel-1/pane [ label/:n/text: to-string pick randwaarden n ] show panel-1 ] |
Arnold 29-Jun-2012 [488] | I am glad there is always a better way to be found! That solution is more scalable in the funtion part. Now I'll be off looking for an easy way to add extra labels on the fly. Guess that must be possible by adding a block [label "_"] to the pane? |
Henrik 29-Jun-2012 [489x3] | You can do that, although that requires you to re-layout the pane. I don't know the code behind the panel, so that may or may not be the best way to do it. It's not the fastest way though. You can manually add a face object to the pane block, but you will then have to calculate its offset, initialize it by hand and resize the parent panel to fit the new face. |
But remember that the panel block as described with [across space 0x0 label "_" ... etc. is only a description. Adding something to that block will not affect your current layout. The LAYOUT function parses the block into a tree of objects (faces), which then can be displayed with VIEW. | |
So, you either re-build that layout, or you manipulate the face object tree directly. | |
Arnold 29-Jun-2012 [492] | main: layout block view main ...function or other action for computing what block should become... main: layout block ;set it again unview/all view main |
Henrik 29-Jun-2012 [493] | you can make it a bit smoother than that by wrapping the whole thing in a panel and assigning a new face tree to that panel every time. Then you won't need to close and reopen the window. |
Arnold 29-Jun-2012 [494] | Like that? |
Henrik 29-Jun-2012 [495x3] | try this interactive test: view layout [p: panel [button]] escape to console and type: p/pane: get in layout/tight [field 100] 'pane show p |
This replaces the pane in the panel P. | |
Then you will of course need to resize the panel and the window. | |
Arnold 29-Jun-2012 [498] | Within a panel sure would be smoother. Some larger layouts would require resizing as well. The example did what was to be expected. And I learned how to return to the running REBOL script after escaping in the terminal window! |
Henrik 29-Jun-2012 [499x2] | it's a great way to interactively test and workout techniques for updating layouts. |
when escaping to the console, events are no longer processed in the window. to continue getting events in the window, type: do-events | |
Arnold 30-Jun-2012 [501] | I changed 1 label the font/color by setting panel1/pane/:n/text/font/color: white and now all text fields including ones not on the panel are written in white. :-( |
Henrik 30-Jun-2012 [502x3] | That is another attribute of VID, which is that many faces share the same font object. Update one, updates all font objects. The purpose of this is to save memory, but it comes off more as inconvenient, when doing things like this. |
Update one, updates all font objects. => "Update one, updates all faces." | |
You can copy the font object with something like this: label "boo" with [font: make font []] There are other ways to trigger copying the font object during the layout process, but I can't exactly remember how, right now. | |
Arnold 30-Jun-2012 [505] | If I could switch it from a text to a label it would be nice. As yet I have this puzzling experience: REBOL [] high-on: high-on-odd: false swap-even: func [/local n] [ either high-on [for n 2 8 2 [ panel-rechts/pane/:n/font/color: 'white] high-on: false ][ for n 1 7 2 [ panel-rechts/pane/:n/font/color: 'black] high-on: true ] show panel-rechts] swap-odd: func [/local n] [ either high-on-odd [for n 1 7 2 [panel-rechts/pane/:n/font/color: 'white panel-rechts/pane/:n/style: 'lbl-h-la-white] high-on-odd: false ][for n 1 7 2 [panel-rechts/pane/:n/font/color: 'black panel-rechts/pane/:n/style: 'lbl-h-la-normal] high-on-odd: true] show panel-rechts] spiegel-styles: stylize [ lbl-h-la-normal: text left middle 40x100 lbl-h-la-white: label left middle 40x100] view layout [styles spiegel-styles across panel-rechts: panel [below space 0x0 lbl-h-la-white "_" lbl-h-la-white "_" lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal "_"] return button "Even" [swap-even] button "Odd" [swap-odd] button "Debug" [print dump-face panel-rechts print panel-rechts/pane/1/font/color print panel-rechts/pane/1/color print panel-rechts/pane/1/style] ] Where the first two labels change when button Odd is clicked. and then stay unchanged and the debug button shows the changes as expected (by me) |
Henrik 30-Jun-2012 [506x3] | You can't simply switch the style by putting a new word in the STYLE facet. Each style is a prototype object with very different code to manage its internals. Generating a style using layout therefore involves getting a face from the style library, performing a set of operations on it for correct size and offset and run its initialization procedure. Only then is it inserted at the right localtion in the pane of the parent panel. |
(But otherwise, it would be handy, if you could just do that :-)) | |
You can study different styles using GET-STYLE. For example: probe get-style 'field It's a bit misleading, though, as many styles share the same code. To really see how styles are built, you need to read the sourcecode for VID. | |
Arnold 30-Jun-2012 [509x2] | That is now on the wish-list! |
When I name the labels lr1 thru lr8 and use the trick I found on www.pat665.free.fr/gtk/rebol-view.html which is w: to-word rejoin ["lr" n] (for n is 1, 2, 3 or 8 you get the picture.) and f: get :w f/font/color: white and directly show the label: show f I can set them seperately. But it is a bit ugly to do it like this if I may say so. | |
Sujoy 3-Jul-2012 [511x3] | Hi! Have a quick question: |
Hi! Have a quick question: | |
i have a block of objects: each object is constructed like... c: #object! [ name: "wonderwoman" attribs: [ Y1991: #object! [ a: 1 n: 2] Y1992: #object! [ a: 1 n: 2] ] ] i need to sort the series based on fields of the attribs inner object i dont want to create a new series...any ideas? | |
Maxim 3-Jul-2012 [514] | use the /compare refinement of sort (which can be a function). |
older newer | first last |