check if a char is a vowel or constant in scheme - scheme

I am trying to check for a char is that char is vowel or constant
I don't know what is the problem with my code
(display "Please enter a character: ")
(define a (read-line))
(display " ")
(display a)
(newline)
(char? a)
(if (char=? a #\a)
(display " is a vowel"))
Can you help me with it please?

Related

How to read a string to get user input in GNU Guile?

I'm trying to make a Rock Paper Scissors game to help myself lean GNU Guile. I've hit a snag where I get user input, the player's choice in the game. If I set it to a string, then the game works correctly. If I use (read) I get back #f as the type from the look up. I've tried formatting read to try to make it a string, which didn't work.
(define (print a)
(display a)
(newline))
(define choices (make-hash-table 3))
(hashq-set! choices "r" "s")
(hashq-set! choices "s" "p")
(hashq-set! choices "p" "r")
(define (cpu-choice) (list-ref (list "r" "p" "s") (random 3)))
(print "You are playing rock paper scissors.")
(print "Type r for rock, p for paper, and s for scissors.")
(define draw
;; "s" ; This works as a test.
(read (open-input-string (read))) ; Can't get user in as string, so the hashq-ref will work.
)
(define cpu-draw (cpu-choice))
;; debug
(print (format #f "Player enterd ~a" draw))
(print (format #f "Player needs to with ~a" (hashq-ref choices draw))) ; Keeps coming back as #f
(print (format #f "CPU has entered ~a" cpu-draw))
;; norm
(newline)
(when (eq? draw cpu-draw)
(print "There was a tie")
(exit))
(when (eq? (hashq-ref choices draw) cpu-draw)
(print "You have won.")
(exit))
(print "You have failed. The computer won.")
How do I get a string from the user? Maybe something like (str (read)) or (read-string) (reading as a string).
$ guile --version
guile (GNU Guile) 2.0.13
Update
I'd just like to mention that while the answer approved is correct, I didn't understand how Guile/Scheme does strings and symbols when writing this. The only way I got the program to work was to change all the strings in choices and in the cpu-choice list into symbols. Ex:
(hashq-set! choices 'r 's)
(list 'r 'p 's)
Thank you Óscar López for your help.
Unless you surround the input with double quotes, the value that you type will be interpreted as a symbol. Either try this:
(define str (read))
> "hello"
Or this:
(define str (symbol->string (read)))
> hello
Either way, str will now hold an actual string:
str
=> "hello"

how to handle this error generated in doing sicp exercise 4.9?

I am doing the exercise.4.9 of the sicp and I am trying to implement a syntax of the "for statement" which looks like the others would see in the c++:
(for (((i 0) (j 1))
(< (+ i j) 10)
((i (+ i 1))))
(display "i:")
(display i)
(display "\n")
(display "j:")
(display j)
(display "\n"))
the syntax looks like:
(for ((initial-statement) (predicate-statement) (updating-statement)) (for-body))
and what I have generated is like:
((lambda ()
(define j 1)
(define i 0)
(define inner-loop
(if (< (+ i j) 10)
(begin (display "i:")
(display i)
(display "\n")
(display "j:")
(display j)
(display "\n")
(set! i (+ i 1))
(inner-loop))))
(inner-loop)))
And I got an error saying that the first inner-loop invocation was trying to approach an unbound variable,
I am wondering what does the correct code I should generate look like?
As #Rainer mentioned in the comments, your definition of inner-loop is incorrect.
A function in scheme is defined as: (define (name ...args) body)
Or if there are no arguments: (define (name) body)
The following works:
((lambda ()
(define j 1)
(define i 0)
(define (inner-loop)
(if (< (+ i j) 10)
(begin (display "i:")
(display i)
(display "\n")
(display "j:")
(display j)
(display "\n")
(set! i (+ i 1))
(inner-loop))))
(inner-loop)))

Scheme: What type is read?

When I read from user input from the console in scheme, what is the type that I need to use if i'm converting from that type into something I want?
For example
(string->number "20") converts the string into a number, what is the syntax for this regarding a read?
FOR EXAMPLE
(define input(read)
(let ((r read))
(????->number r)))
If we look at the Racket documentation for read we see as signature : (read [in]) → any.
So in your case if the user inputs a number it will return a number.
But explicitly check that it is a number because you can't be sure the user won't input something else!
An example :
(define (read-number)
(let ((inpt (read)))
(if (number? inpt)
inpt
(begin (display "Please input a number!")
(newline)
(read-number)))))
EDIT : If you want to test if the inputted number was zero, you should replace the if-statement by a conditional.
(cond ((and (number? inpt)
(= inpt 0)) ; Works because of lazy evalutation
; User inputted 0
...)
((number? inpt)
; User inputted a number other then zero
...)
(else
; User did not entered a number!
(display "Please input a number!")
(newline)
(read-number)))
read doesn't return anything of a specific type – it reads the textual representation of a Scheme object and returns such an object.
Example (input indicated with <-) :
> (read)
<- 23
23
> (read)
<- "hello"
"hello"
> (read)
<- (1 2 3)
'(1 2 3)
> (number? (read))
<- 23
#t
> (number? (read))
<- "hello"
#f
> (define x (read))
<- 4
> x
4
> (number? x)
#t
> (eqv? x 4)
#t
> (+ x 1)
5
> (let ((y (read))) (* y 2))
<- 4
8
So if you want a number, and the user inputs a number, you don't need to do anything.
You may want to check that the input actually is a number and ask for a new value in that case, though.

Scheme - Convert boolean to string?

I am having a tough time trying to find an example of converting a boolean to a string in Scheme.
My problem is that I use string-append to add a few strings together as part of a debugger.
My fix was to check if equal to #t, then append "#t", and like-wise with #f.
My question- is there a method in Scheme to convert bools to strings? Something like bool->string?
My Code:
(if (equal? val #t)
(string-append (number->string count) ":" "#t")
(string-append (number->string count) ":" "#f") )
Use format:
> (format "~a" #t)
"#t"
> (format "~a" #f)
"#f"
This might help you:
(define (->string x)
(call-with-output-string
(lambda (out)
(display x out))))
This writes out any object to a string port and returns its string value.
> (->string #t)
"#t"
> (->string #f)
"#f"
(define (boolean-to-string val) (if val "#t" "#f"))
(string-append (number->string count) ":" (boolean-to-string val))

Scheme case error

I'm trying to create a word count program in Scheme. I think I've worked out an algorithm that'll count my lines, words, and chars, but when I start to run the program, it tells me "The object #\1 is not applicable." "1" is the first character in the file I'm reading, and it should fall under "else". Everything I look at matches my case statement, so I think I'm doing it right, but clearly something's messed up somewhere. Thank you for your help!
(define files
(lambda (reading n)
(begin
(define in (open-input-file reading))
(let loop ((lines 0)
(words 0)
(chars 0)
(port (read-char in)))
(case (port)
((#\newline)
(loop (+ lines 1) words (+ chars 1) (read-char in)))
((#\space #\tab)
(loop lines (+ words 1) (+ chars 1) (read-char in)))
(else (loop lines words (+ chars 1) (read-char in)))))
(close-input-port in)
(display lines)
(display " ")
(display words)
(display " ")
(display chars)
(newline)
(display "Top ")
(display n)
(display " word(s):")
(newline)
'())))
Your problem is fortunately easy to fix. You've written:
(case (port) ...)
but that does a case on the result of calling the function port. Of course, port isn't a function, it's a character, so you just want:
(case port ...)
How does the "let loop" know when you've reached the end of the file? What does read-char return when it hits the end? Hint: read about the eof-object? predicate. A predicate is a function that returns #t or #f. You may need to use a cond rather than a case to use this predicate
Also, the lines, chars and words variables are local to the named let, so you can't print then out "outside". (Hint: print them inside the loop when (eof-object? port) returns #t.
Style quibble: don't use the name "port" for the char that read-char returns. "in" is the port (file handle), Maybe you can use "ch" instead of "port".

Resources