How can I convert this list of numbers and symbols into a string? - string

is there a way too convert a list like this into a normal string?
list->string does not work because it isn't a list of chars.
It is a bit problematic because the list consists of symbols and numbers :/
(list + 4 * 5 - 3 6) //-> "+4*5-36"

Standard Scheme
For numbers:
(number->string 123 10) ; ==> "123"
For symbols:
(symbol->string 'test) ; ==> "test"
So you can check what type it is and use the correct procedure to convert to string. You can use string-append so join more strings together.
(string-append (symbol->string '+)
(number->string 4)
(symbol->string '*)
(number->string 5)
(symbol->string '-)
(number->string 3)
(number->string 6))
; ==> "+4*5-36"
If you make a procedure any->string you can make a one level list to string like this with SRFI-1:
(foldr (lambda (e a) (string-append (any->string e) a))
""
'(+ 4 * 5 - 3 6))
; ==> "+4*5-36"
Racket
Racket has format. If you do (format "~a" data) it will produce a string:
(format "~a" '(+ 4 * 5 - 3 6))
; ==> "(+ 4 * 5 - 3 6)"
Note that the first element of (list + 4 * 5 - 3 6) isn't the symbol + since the variable + gets evaluated to a procedure that adds stuff. eg. (+ 3 4) ; ==> 7 and + ; ==> #<procedure:+> (in racket; implementation specific)

I will show you in mit-scheme:
(define input '(+ 4 * 5 - 3 6))
(fold-right (lambda (x acc)
(string-append ((cond ((number? x) number->string )
((symbol? x) symbol->string ))
(else (error "unknown case" x))
x)
acc))
""
input)
Example:
1 ]=>
(define input '(+ 4 * 5 - 3 6))
;Value: input
...
;Value: "+4*5-36"
In case the list contains more kind of symbolic expressions, apart from numbers and symbols, you extend the cond-statement with other cases.
Also, do not forget to quote the input, otherwise + gets evaluated to a strange value.

Related

Print formatted string with variables [duplicate]

Python : xx = "p" + "y" + str(3) => xx == "py3"
How can I get the same result using Racket?
(string-append "racket" (number->string 5) " ")
Is there another way in Racket, similar to the Python example above, to append a number to a string?
$ racket
Welcome to Racket v5.3.5.
-> (~a "abc" "def")
"abcdef"
-> (~a "abc" 'xyz 7 )
"abcxyz7"
->
Python automatically coerces the number to a string, while Racket will not do so. Neither Racket nor Python will coerce the number into a string. That is why you must use number->string explicitly in Racket, and str() in Python ("p" + str(3)). You may also find Racket's format function to behave similarly to some uses of Python's % operator:
# Python
"py %d %f" % (3, 2.2)
;; Racket
(format "rkt ~a ~a" 3 2.2)
But there is no Racket nor Python equivalent to "foo" + 3 that I know of.
[Answer edited per my mistake. I was confusing Python behavior with JavaScript, misled by OP]

racket programming: how to add a new line after 2 white space character?

I am currently using Dr Racket to do the programming and the task that I am required to do is to give a prompt to a user for an input file. Using the integer values in the input file, the program will execute two functions (two-lhs and two-rhs) that calculates sum of N squares, and output the result to a prompted output file; having the value from two-lhs to be listed on the left side and the value from two-rhs on the right side.
For example: suppose there is a file named 'data' in the directory where line one has the integer 25 and line two has 7, and line three has 9. User that inputs 'data' as an input file and 'testing' as an output file, the output file named 'testing' will be created in the directory with following values and format:
(results from two-lhs) (results from two-rhs)
5525 5525
140 140
285 285
This is my current code with comments of my understanding:
#lang racket
(define squared ;helper function for two lhs
(lambda (x) (* x x)))
(define Two-LHS
(lambda (n)
(cond((= n 0) 0)
(else
(+ (squared n) (Two-LHS(- n 1)))))))
(define Two-RHS
(lambda (n)
(cond ((= n 0) 0)
(else
(/ (* n (+ n 1) (+ (* n 2) 1)) 6)))))
(define in ;function that reads in the input file from user
(lambda ()
(let((pin(open-input-file (symbol->string (read))))) ;prompts the user for input file. pin = the input-port
(let f ((x(read pin))) ;f is a procedure that reads the input port?
(if(eof-object? x) ; x reads the value inside pin and if x happens to be end of file object
(begin ; then closes the input-port
(close-input-port pin)
'())
(cons (Two-LHS x)(cons (Two-RHS x)(f(read pin))))) ;else using the x, executes two lhs and rhs until x reaches
)))) ; end of file to close the port
(define write-lst
(lambda (lst outp) ;lst = input file, outp = output file
(if(eq? lst '()) ; if input file contains an empty list
(close-output-port outp) ; the output-port will be closed
(begin ; else execute begin
(write (car lst) outp) ; which writes the first element of the list to the output file
(display #\space outp) ; will add whitespace after each element to the output file.
(newline outp) ; was thinking this would add newline on the output file after each iteration, but need a way to add newline after every 2 whitespace.
(write-lst (cdr lst) outp))))) ;recurses back to write-lst function with the next element in the list without
;the first element until it becomes an empty list so that output-port could close.
(define out ;will be renamed to two-sum, since this is the function that will write to the output file.
(lambda (lst) ;lst = input file
(let((pout(open-output-file (symbol->string (read))))) ; prompts the user for the output file, pout = the output-port
(write-lst lst pout); uses write-list function to write out to output file
)))
(out (in))
The output file I get running my code is:
5525
5525
140
140
285
285
How can I make the output file to be formatted correctly?
Any help in the right direction would be extremely appreciated!
Thank you.
We can levarage Racket's fprintf procedure to make things easier, and iterate over the list two elements at a time - assuming that it has an even number of elements:
(define write-lst
(lambda (lst outp)
(if (null? lst)
(close-output-port outp)
(begin
(fprintf outp "~a ~a~n" (car lst) (cadr lst))
(write-lst (cddr lst) outp)))))
The trick is here, in the format string: "~a ~a~n". It states: print an object, a whitespace, another object and a new line. And we pass the current element (car lst) and the second element (cadr lst) - in fact, we could just use the first and second procedures, which are easier to understand. Finally, in the recursion we advance two elements: (cddr lst).

How to initialize a string with a fill pointer in Common Lisp?

I want to use formatted output in a loop to generate a string. Manual says it can be easily done by giving format function a string with a fill pointer as a destination. Unfortunately, it is not transparent from the manual how to initialize this string in the first place.
I tried (string "") and (format nil "") with no luck.
(make-array 0 :element-type 'character :fill-pointer 0) did work for me, but it just doesn't feel right.
What is the proper way to initialize a string with a fill pointer?
(make-array estimated-size-of-final-string
:element-type 'character :fill-pointer 0)
(with :adjustable t too if the estimate is inaccurate) is one way; for accumulating output to produce a string it may be more idiomatic to use with-output-to-string:
(with-output-to-string (stream)
(loop repeat 8 do (format stream "~v,,,'-#A~%" (random 80) #\x)))
=>
"----------------------------------x
--------x
--------------------------------------x
----------------------------------------------------------------x
--------------x
-----------------------------------------x
---------------------------------------------------x
-----------------------------------------------------------x
"
(make-array 0 :element-type 'character :fill-pointer 0) is the canonical way (well, it's quite possible to use an initial non-zero length and use :initial-contents with a string value). It's also possible to specify the fil-pointer value as t, that will set the fill-pointer at the end of the string.
Using FORMAT to a string with a fill pointer is a very rarely used functionality.
CL-USER 125 > (let ((s (make-array 0
:element-type 'character
:adjustable t
:fill-pointer t)))
(format s "Hello, ~a!" 'bill)
s)
"Hello, BILL!"
CL-USER 126 > (describe *)
"Hello, BILL!" is an (ARRAY CHARACTER (12))
FILL-POINTER 12
0 #\H
1 #\e
2 #\l
3 #\l
4 #\o
5 #\,
6 #\Space
7 #\B
8 #\I
9 #\L
10 #\L
11 #\!

how do I properly execute a program with scheme48?

I'm learning Scheme. I want to build script-fu filters for Gimp, so I was using tinyscheme to execute the scripts I made, but it seems like tinyscheme has a very limited set of functions, functions like max, min and even?, are missing. (I'd like someone to prove me wrong here :( )
Ok, actually, I just want to execute a Scheme script with scheme48. How do I do that?
for example, how do I execute the following file with scheme48?
(define (addx inNum inX)
(if (> (* inNum inX) 999) 0
(+ (* inNum inX) (addx inNum (+ 1 inX)))))
(display
(- (+ (addx 3 1) (addx 5 1)) (addx 15 1)))
I also was not able to run a scheme-script with scheme48 successfully (and I couldn’t find a hint in the manual yet). You may alternatively use Guile (assuming, you are working on linux or something like that):
#!/usr/local/bin/guile -s
!#
(define (addx in-num in-x)
(if (> (* in-num in-x) 999)
0
(+ (* in-num in-x) (addx in-num (+ 1 in-x)))))
(display (- (+ (addx 3 1) (addx 5 1)) (addx 15 1)))
(newline)
Save it and then run:
$chmod u+x test.scm
./test.scm
233168
$
(by the way: Please don’t format Scheme like C).
EDIT
According to a post of Mike Sperber on the Scheme48 mailing list, shebanging will not work. Explicitely invoking Scheme48 is to be done this way:
#!/bin/bash
scheme48 -a batch << EOF
(letrec ((fac (lambda (n)
(if (= n 1)
1
(* n (fac (- n 1)))))))
(fac 5))
EOF
$ ./test.scm
120

How to define a string in Scheme - any string that I choose?

Given that:
(define output "")
or that
(define output "goodInput")
When I run those defines in my code, I get:
ERROR: In procedure memoization:
ERROR: Bad define placement (define output "").
Why is that ?
EDIT:
; Formal function of the code
(define (double->sum myString)
(define myVector 0)
(set! myVector (breaking myString))
(define output "")
(define returnValue (checkLegit myVector)) ; check the number of legitimate characters ,they need to be either numbers or "."
(define flag 0)
(if (not(= returnValue (vector-length myVector))) (set! output "Input error") (set! flag (+ flag 1)))
(define i 0) ; the length of the vector
(define count 0) ; the value of all the numbers in the vector
(if
(= flag 1)
(do ()
((= i (vector-length myVector))) ; run until the end of the vector
(cond
((char=? (vector-ref myVector i) #\.) ; check if we found a dot
(set! output (appending output count)) (set! output (appendingStrings output ".")) (set! count 0)
)
(else (set! count (+ count (char->integer(vector-ref myVector i)) )) (set! count (- count 48))
); end of else
) ; end of cond
(set! i (+ i 1)) ; inc "i" by 1
); end of do
) ; end do
; if flag = 1 , then the input is in a correct form
(if (= flag 1) (set! output (appending output count)))
(if (= flag 1)
output
"Input error")
) ; END
The problem is not in the string definition itself (there are no strange characters, or anything like that), it's in the place within the code where that definition is happening: you're inside a procedure, and the last line in a procedure can not be a define. Try returning something after the definition and it should work fine.
I guess that you've just started writing the procedure, just keep going after the define and write the rest of the code. For the time being, use a placeholder value at the end, so the interpreter won't complain:
(define (double->sum myString)
(define myVector 0)
(set! myVector (breaking myString))
(define output "")
'ok)
Also a matter of style - although it's ok to define-and-set a variable like that, it's more idiomatic to use a let expression for defining local variables. This is what I mean:
(define (double->sum myString)
(let ((myVector (breaking myString))
(output ""))
'ok))
In that way, you won't have to use set!, which mutates the variable and goes against the functional-programming style preferred in Scheme.

Resources