A novice in programming here (also first time posting here), trying to solve ex.91 from the htdp book (in racket - beginner student language). There's trouble with a helper function, which I named 'render-cat'. Here it is:
; Position -> Image ; given pos, renders cat image on the canvas (check-expect (render-cat 0) (place-image cat1 0 FLOOR BACKGROUND)) (check-expect (render-cat 50) (place-image cat1 50 FLOOR BACKGROUND)) (check-expect (render-cat (cat-x (make-cat 83 100 "right"))) (place-image cat2 83 FLOOR BACKGROUND)) (define (render-cat pos) (cond [(odd? pos) (place-image cat2 pos FLOOR BACKGROUND)] [else (place-image cat1 pos FLOOR BACKGROUND)]))
So, render-cat is supposed to consume a number (named Position here). Position is also the first field of the cat struct (named x):
(define-struct cat [x h dir]) ; an example (define vcat0 (make-cat 0 100 "right")
and here's the function that calls render-cat:
; VCat -> Image ; draws cat and happiness gauge (check-expect (render-all vcat0) (overlay/align "right" "top" (show-gauge (* 2 (cat-h vcat0))) (render-cat (cat-x vcat0)))) ; merely selecting x (define (render-all vc) (overlay/align "right" "top" (show-gauge (* 2 (cat-h vc))) (render-cat (cat-x vc))))
so, when render-cat is called by render-all, only the x field is passed to render-cat, basically a number - and the tests seem to agree. However, when I run the full world application - defined as such:
; VCat -> VCat (define (happy-cat vc) (big-bang vc [on-tick update-all] [on-key pet] [to-draw render-all] ; the problem seems to be here [stop-when unhappy?])),
odd?: expects an integer, given (make-cat 3 100 "right")( (odd? pos) being the only thing highlighted, in render-cat) To my understanding this means that instead of just 3, the function somehow gets the entire struct in full, even though I'm explicitly passing only the x field value, and this happens in the next state of the world program (since the initial x of cat is 0 and the next is supposed to be 3). I have no idea how that happens, though. Cats are naughty and go where they want, even in the coding world I guess, even though they may not be more chaotic than my state of confusion right now.
I tried flooring the pos in the (odd? pos) part, just in case there was some issue there causing havoc, but the error was not about that, so, as I kind of expected, the same error occurred regardless. I considered it might have to do with the data used, so I tried to have the function take the full VCat as input and extract the position field in its body instead, also changed the function call, passing in vc instead of (cat-x vc). Maybe this way the program would be more consistent and there wouldn't be any monkey business in between.
; VCat -> Image ; draws cat and happiness gauge (check-expect (render-all vcat0) (overlay/align "right" "top" (show-gauge (* 2 (cat-h vcat0))) (render-cat vcat0))) (define (render-all vc) (overlay/align "right" "top" (show-gauge (* 2 (cat-h vc))) (render-cat vc))) ;changed this ; VCat (changed this) -> Image ; given vc, renders cat image on the canvas (check-expect (render-cat vcat0) (place-image cat1 0 FLOOR BACKGROUND)) (check-expect (render-cat vcat1) (place-image cat1 (cat-x vcat1) FLOOR BACKGROUND)) (check-expect (render-cat (make-cat 83 100 "right")) (place-image cat2 83 FLOOR BACKGROUND)) (define (render-cat vc) (cond [(odd? (cat-x vc)) (place-image cat2 (cat-x vc) FLOOR BACKGROUND)] ; changes also in the [else (place-image cat1 (cat-x vc) FLOOR BACKGROUND)])); function definition
However, the same thing happens, the exact same error (all tests still pass). There's no other place in this world program where I'm using this function and the error is rather vague as to when the problem occurs exactly, only hinting that one update is made before the program stops (using the stepper didn't help much either), so at this point I'm lost. If you could provide any insight on what the case might actually be, I'd greatly appreciate it.
As per Shawn and MartinPůda's suggestions, I looked into
update-all which was updating the VCat world state.
; VCat -> VCat ; updates x coordinate, happiness level and direction (check-expect (update-all vcat0) (make-cat (update+ vcat0) (lvl-down (cat-h vcat0)) (set-direction vcat0))) (define (update-all vc) (make-cat (update+ vc) (lvl-down (cat-h vc)) (set-direction vc)))
Turns out I was using a helper function which was returning a VCat instead of a Position (
update+), so the next VCat was something like (make-cat x h dir) where x was (make-cat ...), hence the error when render-cat had to work with x, now a cat struct rather than a simple number.
(update+ was a function I'd tweaked another one into. The previous version had been properly returning a Position, so I changed that part back and it works! The trouble was essentially with the confused signature of the helper function for the update: VCat -> VCat, where it should've remained VCat -> Pos.