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))
Related
I am trying to replace a string in the list with another given string, using abstract list functions and lambda only.
The function consumes lst, a list of strings, str, the string you are replacing, and rep, the string you are replacing str with.
Here is an example:
(replace (list "hi" "how" "are" "you") "hi" "bye") -> (list "bye" "how" "are" "you")
Written below is the code that I wrote in recursion and it works.
(define (replace lst str rep)
(cond [(empty? lst) empty]
[(equal? match (first lst))
(cons rep (replace-all (rest lst) match rep))]
[else (cons (first lst) (replace-all (rest lst) match rep))]))
Below that code is what I have tried but I'm not sure how to fix it to make it produce what I want.
(define (replace lst str rep)
(map (lambda (x) (string=? x str)) lst))
Any and all help is appreciated, thanks!
Almost there! you just have to ask, for each string: is this the one I want to replace? then replace it - otherwise leave it untouched:
(define (replace lst str rep)
(map (lambda (x) (if (string=? x str) rep x))
lst))
I am attempting to read and write a matrix from file "data.txt".
The matrix is lists with strings inside of them.
When I am writing I want to write from the begining an override the data. Basically I delete the file every time. I need bether solusion for this.
May main problem is that after a couple readings and writhings of the file corrupts.
system error: Access is denied.; errno=5
My code:
;reading file returning matix of strings
(define (file-reader file-name)
(define pointer (open-input-file file-name))
(define (helper line)
(cond
((equal? line eof) '())
((cons (list line) (helper (read-line pointer))))))
(list-matr (helper (read-line pointer)))
)
;converting matrix of string to matrix of lists with strings inside
(define (list-matr str-matr)
(define (helper str-matr line-num)
(cond
((null? str-matr) '())
((= line-num 1) (cons (map (lambda (x) (string-append x "?")) (string-split (caar str-matr) "? ")) (helper (cdr str-matr) (+ line-num 1))))
((cons (string-split (caar str-matr) " ") (helper (cdr str-matr) (+ line-num 1))))))
(helper str-matr 1))
;saving in file
(define (writer file-name questions answers)
(cond
((file-exists? file-name) (delete-file file-name)))
(write-to-file file-name (string-append (string-join questions) "\n"))
(define (helper cur-l ans)
(cond
((null? ans))
((helper (write-to-file file-name (string-append (string-join (car ans)) "\n")) (cdr ans)))))
(helper '() answers)
)
(define (write-to-file path string)
(call-with-output-file path #:exists 'append
(lambda (newline)
(display string newline))))
Commands for calling the functions.
(file-reader "data.txt")
(writer "data.txt" questions answers)
I think the problem coming from that I don't close the files, but I can't figure out where to put the command for that.
If my code is very bad you can give me other examples for reading and writing matrix from file.
Thank you.
You are correct that the file will corrupt - it's never properly closed.
Without overwriting the file each time, you will need something outside of the normal R5RS/R7RS-small specification, and I'm not aware off the top of my head of any (final) SRFI that allows random file access. That said, many/most Scheme implementations provide some form of low-level I/O interface. The disadvantage of such is that you will have to track the structure very carefully so as to overwrite or add only the correct amount, which will probably be more work than rewriting the entire file.
I would recommend restructuring this completely. First, the call-with-output-file/with-output-to-file procedures will automatically overwrite the output file unless flagged otherwise (in most implementations - though the specifications state that the behaviour is undefined). They will also automatically close the file upon completion. Similar behaviour for the call-with-input-file/with-input-from-file procedures.
You can probably simplify everything by something like the following:
; reader
; this could be further simplified by replacing the cons call with
; (cons (<parse-procedure> l) r), to parse the input at the same time
(define (matrix-read filename)
(with-input-from-file filename (lambda ()
(let loop ((l (read-line))
(r '()))
(if (eof-object? l)
(reverse r)
(loop (read-line) (cons l r))))))
; I don't understand the input/output format...
; writer
(define (matrix-write filename data)
(with-output-to-file filename (lambda ()
(for-each
(lambda (l)
; again, I don't know the actual structure outside of a list
(display l)
(newline))
data))))
If you explain the input format, I can modify the answer.
I am a beginner to functional programming and I want to be able to read values from a console into a list, pass that list as a parameter, and then return the sum of the list in Scheme.
I want to get this result: (display (sum-list-members '(1 2 3 4 5))) but the user must enter these values at the console.
This is what I am working on:
(begin
(define count 0)
(define sum-list-members
(lambda (lst)
(if (null? lst)
0
(+ (car lst) (sum-list-members (cdr lst))))))
(display "Enter a integer [press -1 to quit]: ")
(newline)
(let loop ((i 0))
(define n(read))
(sum-list-members (list n))
(set! count i)
(if (not(= n -1))
(loop (+ i 1)))
)
(newline)
)
Using chicken-scheme, I'd do it like this:
(define (read-number-list)
(map string->number (string-tokenize (read-line))))
Define your sum-list-members as such:
(define (sum-list-members lst)
(fold + 0 lst))
To get string-tokenize to work, you might have to use a certain srfi. Fold is pretty much the same thing as you wrote, except that it's a function that takes a function and initial value as parameters.
The function has to receive 2 parameters, the first parameter is the current value and the second parameter is the value returned by the previous call or the initial value.
(do ((mlist () (cons n mlist))(n (read)(read)))
((= n -1) (display (apply + mlist))))
(define str '("3" "+" "3"))
(define list '(3 + 4))
(define (tokes str)
(case (car str)
((or "+" "-" "*" "/")(write "operand")
(tokes (cdr str)))
(else (write "other"))
))
(define (tokelist)
(case (car list)
((or "+" "-" "*" "/")(write "operand"))
(else (write "other"))))
You are trying to compare a String "+" with the procedure + when you're working with the list. These are different types, and they are not equal.
Try this:
> (string? "+")
#t
> (procedure? +)
#t
> (string? +)
#f
This should give you a good idea of how to solve the problem, but note:
> (= + +)
=: expects type <number> as 1st argument, given: #<procedure:+>;
other arguments were: #<procedure:+>
You need:
> (equal? + +)
#t
> (equal? + "+")
#f
> (equal? "+" "+")
#t
Using these ideas, this should get your code working:
(define (plus? s)
(if (procedure? s) (equal? + s) (equal? "+" s)))
I am trying to make little human like text searching program in scheme
but this program doesn't work properly time to time
and I can't catch the bug for many hours
could somebody tell me what's wrong with my code?
and is it not that good idea for searching text?
when I search the string "exp"
in the text file which contain nothing but just string "explorer"
error arise
and it tells Found 0
(define (search str)
(set! count 0)
(define len (length str))
;null character calculating
(define data-len (- (length data) 1))
;when string length is less than or equal to data-length
(when (and (not (= 0 len)) (>= data-len len))
(define first-char (first str))
(define last-char (last str))
;is it correct?
(define (exact? str len index)
(if (equal? str (drop (take data (+ index len)) index))
#t
#f))
;check first and last character of string if correct, check whether this string is correct completely, if so, skip to next index
(define (loop [index 0])
(when (> data-len index)
(if (and (equal? first-char (list-ref data index))
(equal? last-char (list-ref data (+ index len -1))))
(when (exact? str len index)
(set! count (+ count 1))
(loop (+ index len)))
(loop (+ index 1)))))
(loop))
(send msg set-label (format "Found : ~a" count)))
I know it's been four years, but I'm nostalgic for my SCHEME class, so I made a thing. (I'd comment instead of answering, but I don't have enough reputation yet. ... And I'm probably about to have less.)
(define (find-pattern pat str); Returns a list of locations of PATturn in STRing.
(define (pattern-found? pat-list str-list); Is the pattern (pat-list) at the beginning of this string (str-list)? Also, they're lists, now.
(cond ((null? pat-list) #t); The base case for the recursion.
((null? str-list) #f); Obvious
((eq? (car pat-list) (car str-list)); First letter matches
(pattern-found? (cdr pat-list) (cdr str-list))); Recurse
(else #f)))
(define (look-for-pattern pat-list str-list counter results-list)
(cond ((null? str-list) results-list); Base case
((pattern-found? pat-list str-list)
(look-for-pattern pat-list
(cdr str-list)
(+ counter 1)
(cons counter results-list)))
(else (look-for-pattern pat-list
(cdr str-list)
(+ counter 1)
results-list))))
(look-for-pattern (string->list pat)
(string->list str)
0
'()))
EDIT: I mean it's been four years since the question, not since SCHEME class. That'd be a little creepy, but then again, who knows how I'll feel in three years?