From 8a633e5b5768ccbe232d70252c52895c46250f4d Mon Sep 17 00:00:00 2001 From: Jono Spiro Date: Fri, 6 Aug 2004 20:32:45 +0000 Subject: [PATCH] svn: r154 --- .../mztake/demos/random/random-Xs-test-v2.ss | 115 ++++++++++++++++++ collects/mztake/demos/random/random-Xs.ss | 8 +- collects/mztake/demos/random/random.png | Bin 0 -> 19281 bytes 3 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 collects/mztake/demos/random/random-Xs-test-v2.ss create mode 100644 collects/mztake/demos/random/random.png diff --git a/collects/mztake/demos/random/random-Xs-test-v2.ss b/collects/mztake/demos/random/random-Xs-test-v2.ss new file mode 100644 index 0000000000..fda11eaf83 --- /dev/null +++ b/collects/mztake/demos/random/random-Xs-test-v2.ss @@ -0,0 +1,115 @@ +#| The program being debugged (a module in the file "random-xs.ss") runs an infinite loop, + binding "x" to a random number between [0,100) each iteration. + + This MzTake script draws a histogram of the values of x seen over time, + in sync with the execution of "random-xs.ss". This will run until one + bar reaches the top of the screen. + + This histogram provides three pieces of information: + * Each bar represents a bin, the height represents how many times + that "random" number was generated. + + * The brighter the blue, the faster that bin is growing compared + to the others. The darker, the slower. + + * You can see a history of speeds over time based on how the colors + change in each bin. + + Try looking for small groupings of bins where all are light, or all + are dark -- these represent trends in the numbers. + + Look for tortoises that stay low and black, and hares which are very + active and bright. + + Notice how the bottom tends to be rather patchy with lots of color + variation (the "start-up" phase of the random number generator), + and then towards the middle of the screen, most of the blues have + settled down and evened out. + + The bars drag a bit when moving upwards (the height goes up by 2, but + the redrawing of the latest color goes down 10 pixels) so that you can + spot vertical and horizontal trends more easily. |# + + +(require (lib "graphics.ss" "graphics") + #| Needed for open-graphics, open-viewport, and draw-solid-ellipse |# + + (lifted mzscheme + hash-table-for-each + make-hash-table + hash-table-put! + hash-table-get)) +#| "Lifted" is explained in FrTime's own documentation (plt/collects/frtime/doc.txt) + Quickly put, lifting extends the functions listed above so they can take FrTime time-varying + values (such as MzTake traces) as arguments. |# + + + +(open-graphics) +(define window (open-viewport "Debugger" 600 500)) +((draw-viewport window) (make-rgb 0.95 0.95 0.95)) +#| This file doesn't animate a list of objects since the number of + objects quickly reaches the thousands (slowing drawing time severly), + and they are stationary -- so we just keep drawing the circles at + their new heights based on the value in the hashtable. + + See the doc for more information on this kind of drawing. |# + + + +(define-mztake-process p ("random-Xs.ss" [x-trace 4 6 bind 'x])) +#| * Create a process to debug random-xs.ss + + * Add a tracepoint at line 4, column 6; in the program, + this is right before the next iteration of the loop is called, + ->(loop (random 200)) + + * At this tracepoint, define "x-trace" to a FrTime eventstream that + recieves events containing the latest value of "x" seen, + every time the code at line 4, column 6, is reached. |# + +(define largest-bin 0) +(define valcount (make-hash-table)) +#| this will hold the counts for the histogram + x is the key, and the number of times x shows up is the value |# + +(define total-count (count-b x-trace)) + +(printf-b "count: ~a" total-count) +#| prints the count of how many events x-trace got, + aka how many values are in the histogram and on the screen. |# + + +(hold (x-trace . -=> .(printf-b "highest bin count: ~a" largest-bin))) +#| Prints out the largest count every time we get a new x-trace event |# + + +(map-e (lambda (x) + (let ([new-cnt (add1 (hash-table-get valcount x (lambda () 0)))]) + + (when (zero? (modulo (value-now total-count) 1000)) + (hash-table-for-each + valcount + (lambda (x v) + (let ([color (min 1 (* 50 (/ v 1000)))]) + ((draw-solid-rectangle window) (make-posn (* x 6) + (- 500 (* 10 (/ (value-now total-count) 1000)))) + 6 10 ;; width height + (make-rgb 0 (* 0.75 color) color))))) + (set! valcount (make-hash-table)) + (set! largest-bin 0)) + + (when (> new-cnt largest-bin) (set! largest-bin new-cnt)) + ; keep track of the largest count + + (hash-table-put! valcount x new-cnt))) + ;; increment the value in the hashtable, starting from 0 if none exists. + + x-trace) +#| Every time x-trace gets a new value, take this latest value and pass it to a function + which increments the count in the hashtable, and draws a circle in the window at + (* x 6) pixels from the left, and the height is (2 * the latest count in the hashtable for that x), + making a color (MAKE-RGB) that is lighter based on how fast it is growing. |# + + +(start/resume p) ;; Start the process for random-xs.ss \ No newline at end of file diff --git a/collects/mztake/demos/random/random-Xs.ss b/collects/mztake/demos/random/random-Xs.ss index 794c2fb9be..90dcb6e84f 100644 --- a/collects/mztake/demos/random/random-Xs.ss +++ b/collects/mztake/demos/random/random-Xs.ss @@ -1,5 +1,5 @@ -(module |random-Xs| mzscheme - (define (run) - (let loop ([x (random 100)]) - (loop (random 100)))) +(module |random-Xs| mzscheme + (define (run) + (let loop ([x (random 100)]) + (loop (random 100)))) (run)) \ No newline at end of file diff --git a/collects/mztake/demos/random/random.png b/collects/mztake/demos/random/random.png new file mode 100644 index 0000000000000000000000000000000000000000..e7097bb5bf8e04e69af9d0966bf94306de81a427 GIT binary patch literal 19281 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