updated and commented all the demos, renamed higher-order.

svn: r138
This commit is contained in:
Jono Spiro 2004-08-04 19:33:43 +00:00
parent 94cc1c3b72
commit 9fb5cc98c8
12 changed files with 179 additions and 48 deletions

View File

@ -1,24 +1,51 @@
(require (lib "animation.ss" "frtime")) ;; The program being debugged (a module in "highway.ss") generates fake speed readings over and over.
(require (lib "animation.ss" "frtime")) ;; needed for display-shapes
(mztake-process p ("highway.ss" [values-of-speed 3 4 bind 'speed])) (mztake-process p ("highway.ss" [values-of-speed 3 4 bind 'speed]))
#| * Create a process to debug highway.ss
* Add a tracepoint at line 3, column 4; in the program,
this is right before the program sleeps for 1 second.
* At this tracepoint, define "values-of-speed" to a FrTime eventstream that
recieves events containing a single numerical value:
- The (lexically-scoped) current value of the variables `speed' are send
every time the code at line 3, column 4, is reached.
|#
(printf-b "runtime elapsed: ~a" (process:runtime/seconds p))
;; Prints how long the program has been running, in seconds
(printf-b "last ten speeds: ~a" (history-b 10 values-of-speed)) (printf-b "last ten speeds: ~a" (history-b 10 values-of-speed))
;; prints a FIFO list of the last 10 speeds seen
(map (lambda (an-x) (if (< an-x 55) 'ok 'too-fast!!)) (map (lambda (an-x) (if (< an-x 55) 'ok 'too-fast!!))
(history-b 10 values-of-speed)) (history-b 10 values-of-speed))
;; prints a
;; produces a list of shapes to draw/animate, taking in a number for speed
(define (make-speed-gauge speed) (define (make-speed-gauge speed)
(let ([center (make-posn 200 200)]) (let ([center (make-posn 200 200)])
(list (make-circle center 170 "black") (list (make-circle center 170 "black")
(make-circle center 160 "white") (make-circle center 160 "white")
(make-rect (make-posn 0 202) 1000 1000 "white") (make-rect (make-posn 0 202) 1000 1000 "white")
(make-line (make-posn 30 201) (make-posn 370 201) "black") (make-line (make-posn 30 201) (make-posn 370 201) "black")
;; draws the the half-circle guage
;; draws the red line for the current speed
(make-line center (make-line center
(posn+ center (make-posn (- (* 150 (cos (/ speed 30)))) (posn+ center (make-posn (- (* 150 (cos (/ speed 30))))
(- (* 150 (sin (/ speed 30)))))) (- (* 150 (sin (/ speed 30))))))
"red")))) "red"))))
(display-shapes (make-speed-gauge (hold values-of-speed))) (display-shapes (make-speed-gauge (hold values-of-speed)))
#| display-shapes takes a list of objects to draw.
(hold values-of-speed) keeps track of the current value of speed,
as seen on the eventstream, and that is passed to make-speed-guage,
which gets called every time values-of-speed gets a new speed.
|#
(start/resume p) (start/resume p)
;; Start the process for highway.ss

View File

@ -2,4 +2,4 @@
(let loop ([speed 0]) (let loop ([speed 0])
(sleep 1) (sleep 1)
;; Generate some fake speeds readings: ;; Generate some fake speeds readings:
(loop (modulo (current-seconds) 60)))) (loop (* 5 (modulo (current-seconds) 20)))))

View File

@ -1,9 +1,17 @@
; tests catching of anonymously threaded exceptions #| This program starts a thread, the thread raises an exception,
this tests how MzTake catches exceptions, even if they come from
anonymous locations.
We don't even need to bind any variables or add any breaks, we just
run the program and catch the exception it throws.
|#
(mztake-process p ("exception.ss")) (mztake-process p ("exception.ss"))
(printf-b "exception.ss exited? ~a" (process:exited? p)) (printf-b "exception.ss exited? ~a" (process:exited? p))
;; Prints out a behavior that tells you whether the debug-process is still running... ;; Prints out a behavior that tells you whether the debug-process is still running...
(process:exceptions p) (printf-b "last exception seen: ~a" (hold (process:exceptions p)))
;; Prints out the last exception that the program threw
(start/resume p) (start/resume p)

View File

@ -1,6 +1,2 @@
(module exception mzscheme (module exception mzscheme
(thread (lambda () (raise 'first-raise))) (thread (lambda () (raise 'exn:oops-made-a-mztake!))))
;(require (lib "match.ss"))
;(match )
;(printf "dd~a" (random 100))
)

View File

@ -0,0 +1,30 @@
#| This program demonstrates how you can add traces to first class, anonymous functions,
such as those passed to map, and the traces will still respond from anywhere
the code is executed.
This test also shows how you can bind to the same variable at different locations,
and recieve different values, watching how an algorithm unfolds.
Be sure you look at first-class.ss to see where the bindings are taken from, to get
and idea of why they recieve different values from the same "x".
|#
(mztake-process p ("first-class.ss" [x-before-let 3 29 bind 'x]
[x-in-let 4 25 bind 'x]
[x-after-let 5 11 bind 'x]))
(printf-b "Number of times x updates, should be 12: ~a"
(count-e (merge-e x-before-let
x-in-let
x-after-let)))
#| merge-e takes multiple event streams and turns them into one event stream.
count-e then counts how many pings are recieved on all three streams,
in other words, how many times "x" updates in all the traces.
|#
(printf-b "x before let, should be (2 4 6 7): ~a" (history-b 4 x-before-let))
(printf-b "x in let, should be (6 10 14 16): ~a" (history-b 4 x-in-let))
(printf-b "x after let, should be (5 9 13 15): ~a" (history-b 4 x-after-let))
;; Prints out a FIFO list containing the last 4 values seen by each trace.
(start/resume p)

View File

@ -1,16 +0,0 @@
;tests higher order annotation and redefinition of bindings
(mztake-process p ("higher-order.ss" [x-before-let 3 29 bind 'x]
[x-in-let 4 25 bind 'x]
[x-after-let 5 11 bind 'x]))
(printf-b "Number of times x updates, should be 12: ~a"
(count-e (merge-e x-before-let
x-in-let
x-after-let)))
(printf-b "x before let, should be (2 4 6 7): ~a" (history-b 10 x-before-let))
(printf-b "x in let, should be (6 10 14 16): ~a" (history-b 10 x-in-let))
(printf-b "x after let, should be (5 9 13 15): ~a" (history-b 10 x-after-let))
(start/resume p)

View File

@ -1,18 +1,55 @@
#| The program being debugged (a module in the file "montecarlo.ss") runs an infinite loop,
binding "x" and "y" to a random number between [-199,199] each iteration, and "pi"
to the value of pi as calculated using this algorithm.
This MzTake script draws only the points that are deemed *not* within
a radius of 200 pixels from the center of the window.
|#
(require (lib "graphics.ss" "graphics")) (require (lib "graphics.ss" "graphics"))
;; Needed for open-graphics, open-viewport, and draw-solid-ellipse
(open-graphics) (open-graphics)
(define window (open-viewport "Debugger" 400 400)) (define window (open-viewport "Debugger" 400 400))
#| This file doesn't animate a list of objects since the number of
objects quickly reaches the thousands (slowing drawing time severly),
and the dots are stationary -- so we just keep drawing the circles at
the random coordinates that we get from the target program.
See the doc for more information on this kind of drawing.
|#
(mztake-process p ("montecarlo.ss" [x/y/pi-trace 13 18 bind '(x y pi)]))
#| * Create a process to debug montecarlo.ss
* Add a tracepoint at line 13, column 18; in the program,
this is right after the cond determined that the point is not in
the radius of the circle. [else ->(loop ...)]
* At this tracepoint, define "x/y/pi-trace" to a FrTime eventstream that
recieves events containing a list of the latest values of "x" "y" and "pi"
in a list, every time the code at line 13, column 18, is reached.
|#
(mztake-process p ("montecarlo.ss" [x/y/pi-trace 12 18 bind '(x y pi)]))
(define x/y/pi (hold x/y/pi-trace)) (define x/y/pi (hold x/y/pi-trace))
#| The local, time-varying variable "x/y/pi" is now is a FrTime behavior that always
holds the current (latest) list of values from x/y/pi-trace.
|#
(define x (+ 200 (first x/y/pi))) (define x (+ 200 (first x/y/pi)))
(define y (+ 200 (second x/y/pi))) (define y (+ 200 (second x/y/pi)))
(define current-pi (third x/y/pi)) (define current-pi (third x/y/pi))
#| The local, time-varying variables "x" "y" and "current-pi" are bound to
their respective values in the list from x/y/pi.
|#
(printf-b "total points chosen: ~a" (count-b x))
(printf-b "current computed value of pi: ~a" current-pi)
(printf-b "total: ~a" (count-b x))
(printf-b "current pi: ~a" current-pi)
; more negative the better ...down to -14 ; more negative the better ...down to -14
(printf-b "log error: ~a" (log (abs (- current-pi 3.1415926)))) (printf-b "log error: ~a" (log (abs (- current-pi 3.1415926))))
@ -21,5 +58,9 @@
(lambda (x/y) (lambda (x/y)
((draw-solid-ellipse window) (make-posn (first x/y) (second x/y)) ((draw-solid-ellipse window) (make-posn (first x/y) (second x/y))
3 3 "blue"))) 3 3 "blue")))
#| Every time the list (x y) changes (x and y get a new value), take this latest list value ("==>")
and pass it to a function which draws a circle at the x,y coordinates in the list.
|#
(start/resume p) (start/resume p)
;; Start the process for montecarlo.ss

View File

@ -1,5 +1,6 @@
(module montecarlo mzscheme (module montecarlo mzscheme
(random-seed 846259386) ; specially chosen because it isn't terribly erratic ;; a seed specially chosen because it isn't terribly erratic when converging on pi
(random-seed 846259386)
(define (run) (define (run)
(let loop ([hits 1] (let loop ([hits 1]

View File

@ -1,10 +1,19 @@
#| The program being debugged (a module in the file "random-xs.ss") runs an infinite loop,
binding "x" to a random number between [0,199] 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".
|#
(require (lib "graphics.ss" "graphics") (require (lib "graphics.ss" "graphics")
;; Needed for open-graphics, open-viewport, and draw-solid-ellipse
(lifted mzscheme (lifted mzscheme
make-hash-table make-hash-table
hash-table-put! hash-table-put!
hash-table-get)) hash-table-get))
#| #| "Lifted" is explained in FrTime's own documentation (plt/collects/frtime/doc.txt)
"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 Quickly put, lifting extends the functions listed above so they can take FrTime time-varying
values (such as MzTake traces) as arguments. values (such as MzTake traces) as arguments.
|# |#
@ -12,28 +21,58 @@
(open-graphics) (open-graphics)
(define window (open-viewport "Debugger" 600 500)) (define window (open-viewport "Debugger" 600 500))
#| 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.
|#
(mztake-process p ("random-Xs.ss" [x-trace 4 6 bind 'x])) (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 x (hold x-trace)) (define x (hold x-trace))
#| The local, time-varying variable "x" is now is a FrTime behavior that always
holds the current (latest) value of x-trace.
|#
(define valcount (make-hash-table)) (define valcount (make-hash-table))
;; this will hold the counts for the histogram
((changes x) . ==> . (lambda (x) ((changes x) . ==> . (lambda (x)
(hash-table-put! valcount x (add1 (hash-table-get valcount x (lambda () 0)))) (hash-table-put! valcount x (add1 (hash-table-get valcount x (lambda () 0))))
;; increment the value in the hashtable, starting from 0 if none exists.
((draw-solid-ellipse window) (make-posn (* x 3) ((draw-solid-ellipse window) (make-posn (* x 3)
(- 500 (* 3 (hash-table-get valcount x (lambda () 1))))) (- 500 (* 3 (hash-table-get valcount x (lambda () 1)))))
4 4 "blue"))) 4 4 "blue")))
#| Every time the local variable x changes (x-trace gets a new value), take this latest value ("==>")
(define runtime (process:runtime/milliseconds p)) and pass it to a function which increments the count in the hashtable, and draws a circle in the window
(printf-b "~a millisecs per event" (truncate (runtime . / . (add1 (count-e (changes x)))))) at (* x 3) pixels from the left, and the height is (3 * the latest count in the hashtable for that x).
|#
(printf-b "x: ~a" x) (printf-b "x: ~a" x)
(printf-b "count: ~a" (count-e (changes x))) (printf-b "count: ~a" (count-e (changes x)))
#| prints the current value of x and a count of how many times x has changed,
in other words, how many values are in the histogram
|#
(let ([cnt (count-e (changes x))]) (let ([cnt (count-e (changes x))])
(when (= 13000 cnt) (when (= 13000 cnt) (pause p)))
; pause on next breakpoint #| This binds the same type of count seen above to cnt,
(pause p))) when the histogram is showing 13000 values, pause the program
the next time the breakpoint is reached, the 13001st iteration of the loop.
|#
(start/resume p) (start/resume p)
;; Start the process for random-xs.ss

View File

@ -1,5 +1,6 @@
#| * The program being debugged (in the file "sine.ss") is a module that runs an infinite loop, #| The program being debugged (a module in "sine.ss") runs an infinite loop,
binding "x" to a moment in time [-200,200], and "sin-x" to the sin(x) ... over and over. binding "x" to a moment in time [-200,200], and "sin-x" to the sin(x) each iteration.
This MzTake script plots the value of x over time, in sync with the execution of "sine.ss". This MzTake script plots the value of x over time, in sync with the execution of "sine.ss".
|# |#
@ -7,14 +8,14 @@
(mztake-process p ("sine.ss" [sin/x-trace 5 8 bind '(sin-x x)])) (mztake-process p ("sine.ss" [sin/x-trace 5 8 bind '(sin-x x)]))
#| * Create a process to debug for sine.ss #| * Create a process to debug sine.ss
* Add a tracepoint at line 5, column 8; in the program, * Add a tracepoint at line 5, column 8; in the program,
this is right after the let values are bound, ->(if (x ...) this is right after the let values are bound, ->(if (x ...)
* At this tracepoint, define "sin/x-trace" to a FrTime eventstream that * At this tracepoint, define "sin/x-trace" to a FrTime eventstream that
recieves events containing a list of two elements: recieves events containing a list of two elements:
* The (lexically-scoped) current values of the variables `sin-x' and `x' are - The (lexically-scoped) current values of the variables `sin-x' and `x' are
sent as a list every time the code at line 5, column 8, is reached. sent as a list every time the code at line 5, column 8, is reached.
|# |#
@ -27,7 +28,7 @@
(define sin/x (hold sin/x-trace)) (define sin/x (hold sin/x-trace))
;; "sin/x" now is a FrTime behavior that holds the current value of the list (sin-x x) ;; the local variable "sin/x" now is a FrTime behavior that holds the current value of the list (sin-x x)
(define sin-x (+ 200 (first sin/x))) (define sin-x (+ 200 (first sin/x)))

View File

@ -221,6 +221,10 @@ can be used interactively in the interactions pane.
Kills the target process and releases all resources Kills the target process and releases all resources
it used -- you cannot start/resume after a kill. it used -- you cannot start/resume after a kill.
Closing a FrTime animation/graphics window will *not*
kill a running program, you must kill it by hand in the
interaction pane.
> (kill-all) > (kill-all)
kill-all kills all the processes currently running kill-all kills all the processes currently running
@ -406,7 +410,7 @@ Tips and Tricks
* FrTime has two methods for drawing graphics. One runs in * FrTime has two methods for drawing graphics. One runs in
constant time, and is fast, because it simply accumulates constant time, and is fast, because it simply accumulates
pixels on the screen and doesn't redraw a list of objects. pixels on the screen and doesn't redraw a list of objects.
See the random-xs demo for this in action. See the Monte Carlo, or random-xs demo for this in action.
The other method is primarily for animations which need The other method is primarily for animations which need
redrawing because things move. It slows down pretty quickly redrawing because things move. It slows down pretty quickly