Weather Forecast
November 5, 2010
The purpose of this exercise is two-fold: First, to get you into a corner of your language which might not be familiar to you. Second, to make you think about the vast amount of data that is available. If you’re not interested in American weather forecasts, pick a different data set that does interest you.
Many languages provide a built-in mechanism for retrieving files from the internet, but Scheme does not. We will use wget
to connect to the internet and retrieve files, relying on the underlying Scheme interpreter to provide the non-standard (but widely available) functions file-exists?
, delete-file
, and system
. First we write a function to find an unused filename to hold the file downloaded from the internet; it just loops until it finds a suitable candidate:
(define (tempname)
(let loop ((i 0))
(let ((f (string-append "temp" (number->string i))))
(if (file-exists? f) (loop (+ i 1)) f))))
With-input-from-url
uses wget
to retrieve the file from the internet and save it in a temporary file, and with-input-from-file
to make its contents available to Scheme:
(define (with-input-from-url url thunk)
(let ((f (tempname)))
(if (zero? (system (string-append wget " " f " " url)))
(begin (with-input-from-file f thunk) (delete-file f #t))
(error 'with-input-from-url "system error in wget"))))
How you run wget
depends on your system. Here are three definitions that work on the systems available to me; yours may differ:
(define wget "c:\cygwin\bin\wget -qO") ; windows/cygwin
(define wget "/usr/local/bin/wget -qO") ; unix/hp
(define wget "/usr/bin/wget -q0") ; linux/ubuntu
The list of cities and states for which NOAA provides forecasts is available at http://weather.noaa.gov/pub/data/forecasts/city/. Here we provide a function that builds an appropriate url for the desired city and state:
(define (weather-url state city)
(string-append
"http://weather.noaa.gov/pub/data/forecasts/city/"
state "/" city ".txt"))
All that’s left is to retrieve the url and output the file:
(define (display-weather state city)
(with-input-from-url (weather-url state city)
(lambda ()
(do ((c (read-char) (read-char)))
((eof-object? c))
(display c)))))
It’s a brisk autumn where I live:
> (display-weather "mo" "st_louis")
FPUS43 KLSX 030842
City Forecast for St Louis, MO
Issued Wednesday morning - Nov 3, 2010
.Wednesday... Sunny, high 64, 10% chance of precipitation.
.Wednesday night... Low 41, 5% chance of precipitation.
.Thursday... Partly cloudy, high 54, 10% chance of precipitation.
.Thursday night... Low 33.
.Friday... High 48.
You can see the code at http://programmingpraxis.codepad.org/0ppN34nS.
My Haskell solution (see http://bonsaicode.wordpress.com/2010/11/05/programming-praxis-weather-forecast/ for a version with comments):
function weather() { curl http://weather.noaa.gov/pub/data/forecasts/city/$1/$2.txt; }
weather $1 $2
This definitely made me think. At first I was tempted to just open the webpage itself.
This is basically a less pretty knock-off of Remco’s Haskell.
A ruby version
Actually, `file-exists?` and `delete-file` are standard if you include R6RS, and it is my understanding that they will be included in the R7RS too.
Anyway, I’m lazy so I used an existing http library for R6RS
A couple of lines for powershell
tag
My C implementation
Click here
Sorry for previous comment! it is on wrong post!
That is for “subset sums “!