[racket] Run Code after Button Click using the racket/gui library

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Oct 27 22:05:02 EDT 2014

On Oct 27, 2014, at 7:46 PM, Derek C. wrote:

> Hello,
> 
> Thank you for the reply. It was very helpful.
> 
> The only thing that I am confused in doing now is that I have to store the value of the zip code in order to use it within the API’s url. That is the first thing I was trying to do because I need to take the zip code that is entered and be able to add it within the url before the .xml extension.
> 
> For Example: http://api.wunderground.com/api/*snip*/conditions/q/ZIPCODE.xml
> where ZIPCODE is the zip code that was entered.

See my sketch of the 'retrieve' function (not the fake one, the real one). Change the format string to something so that 

 (format underground-format zip-code)

makes the correct string. See 

 (format "hello/there/~a" "02115")


> At first, I was attempting to get this value from the zipcodelabel message% object, using (define x (send zipcodelabel get-label)) but that would only give me the initial value of the message% which is "No Zip Code Entered".


No it isn't. Add a '(displayln zip-code)' to the fake retrieve function and you'll see that it retrieves the entered code. 




> 
> Thanks again,
> Puzzledplane
> 
> From: Matthias Felleisen
> Sent: ‎Monday‎, ‎October‎ ‎27‎, ‎2014 ‎1‎:‎56‎ ‎PM
> To: Derek C.
> Cc: users at racket-lang.org
> 
> 
> On Oct 26, 2014, at 5:51 PM, Derek C. wrote:
> 
> I am trying to get the value of a label after a button is clicked. I know that I can use (send x get-label) to get the value of the label, but it only gets the initial value of the label in my case "No Zip Code Entered".
> 
> I don't know what you are asking. When I enter a zip code and click Submit, the zip code shows up in your text field. 
> 
> 
> Also, after that button is pressed I would like to run code that queries an API and parses xml information using the zip code from the label. Below is my code:
> 
> See below. I have marked some small changes and sketched a way to get this going. I also fixed some basic style issues. 
> 
> Note: if this is homework, please forward the assignment so we can help more directly. If not, I recommend developing with testing in mind (see rackunit and submodules). 
> 
> -- Matthias
> 
> 
> 
> 
> 
> #lang racket
> 
> (require racket/gui/base)
> 
> ;; -> Void 
> (define (main) ;; don't run directly, wrap in main function from the beginning; work with (module+ main ...) if you want to always run 
>   
>   ;; Creates a Frame called mainframe
>   (define mainframe 
>     (new frame%
>          [label "Forecaster - Powered by Wunderground API"]
>          [width 500]
>          [height 500]
>          [stretchable-width 500]
>          [stretchable-height 500]))
>   
>   ;; Creates a Current Conditions group-box-panel
>   (define maingroup
>     (new group-box-panel%
>          [label "Current Conditions:"]
>          [parent mainframe]
>          [min-height 450]
>          [stretchable-height 450]))
>   
>   (define cclabel-text (new text%)) ; you want a editor here, not a message 
>   [send cclabel-text insert "Insert Conditions Here from API"] ;; add your initial string, though I am not sure what for 
>   (define cclabel  ;; now put the editor into a canvas
>     (new editor-canvas%
>          [parent maingroup]
>          [label "current conditions"]
>          [editor cclabel-text]))
>   
>   ;; Creates a Zip Code group-box-panel
>   (define zipcodegroup 
>     (new group-box-panel%
>          [label "Zip Code:"]
>          [parent mainframe]
>          [min-height 100]
>          [stretchable-height 100]))
>   
>   ;; Zip Code Message Label -- Defaults to No Zip Code Entered
>   (define zipcodelabel
>     (new message%
>          [parent zipcodegroup]
>          [label "No Zip Code Entered"] ))
>   
>   ;; Zip Code Text-Field
>   (define zipInput 
>     (new text-field% 
>          [parent zipcodegroup]
>          [label ""]
>          [init-value ""]
>          [min-width 5]
>          [stretchable-width 5]
>          [callback
>           (lambda(f ev)
>             (define v (send f get-value))
>             (unless (string->number v)
>               (send f set-value (regexp-replace* #rx"[^0-9]+" v ""))))]))
>   
>   ;; Submit Button
>   (define submit-button 
>     (new button% 
>          [parent zipcodegroup]
>          [label "Submit"]
>          [callback  
>           (lambda (button event)
>             ;; use internal define over let only because it's easier
>             (define zip-code (send zipInput get-value))
>             (define weather  (retrieve zip-code))
>             (send zipcodelabel set-label zip-code)
>             ;; now insert weather into the editor, but clear it first 
>             (send cclabel-text select-all)
>             (send cclabel-text clear)
>             (send cclabel-text insert (prepare-as-text weather)))]))
>   ;; -- IN -- 
>   (send mainframe show #t))  
> 
> ;; helper but this may actually have to work on the editor directly to make it look good 
> (define (prepare-as-text list-of-pairs)
>   (string-join 
>    (map (lambda (x) (format "~a ~a" (first x) (second x))) list-of-pairs)
>    "\n"))
> 
> ;XML Parsing:
> ;
> ;#lang racket
> 
> ;; this module should presumably provide a retrieve function that does the hard work: 
> ;; (provide 
> ;;    ; ZipCode -> [Listof [List Symbol String]]
> ;;    ; retrieve the information for the given zip code and deliver the result as an association list 
> ;;    ; -- examples here -- 
> ;;    retrieve)
> (require net/url xml xml/path)
> 
> (define underground-url-format
>   "http://api.wunderground.com/api/*snip*/conditions/q/autoip.xml")
> 
> ;; I am taking a short-cut here: 
> (define (retrieve zip-code)
>   (list (list 'Location: "Boston, MA") (list 'Conditions: "typical fall day") 
>         (list 'Temperature: "57o F")   (list 'Feels-Like: "damp, humid, earthy")
>         (list 'Humidity: "67%")        (list 'Wind: "5mph, south-by-south-west")))
> 
> (define (retrieve-to-be-done zip-code)  
>   (define curent-cond-url (string->url (format underground-url-format zip-code)))
>   (define current-cond-port (get-pure-port curent-cond-url))
>   (define response (port->string current-cond-port))
>   (close-input-port current-cond-port)
>   
>   (define data (xml->xexpr
>                 ((eliminate-whitespace '(response))
>                  (read-xml/element (open-input-string response)))))
>   
>   (define curr-location (se-path*/list '(display_location full) data))
>   (define curr-weather (se-path*/list '(current_observation weather) data))
>   (define curr-temp (se-path*/list '(current_observation temp_f) data))
>   (define curr-humidity (se-path*/list '(current_observation relative_humidity) data))
>   (define curr-wind (se-path*/list '(current_observation wind_string) data))
>   (define curr-feels-like (se-path*/list '(current_observation feelslike_f) data))
>   
>   (list (list 'Location: curr-location) (list 'Conditions: curr-weather) 
>         (list 'Temperature: curr-temp)  (list 'Feels-Like: curr-feels-like)
>         (list 'Humidity: curr-humidity) (list 'Wind: curr-wind)))

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141027/7f11ee6a/attachment-0001.html>

Posted on the users mailing list.