Display elements in list with for-each - scheme

I have 1 big list of smaller 3-element-lists that look like:
( ("001" "Bob" 80) ("002" "Sam" 85) ("003" "Aaron" 94) etc . . .)
I'm trying to create something like:
No.1: ID=001, Name=’’Bob’’, Grade=80
No.2: ID=002, Name=’’Sam’’, Grade=85
No.3: ID=003, Name=’’Aaron’’, Grade=94
I only have access to display and for-each (no "for" or "printf" functions)
I've been trying to create a for-each function that takes the list and:
pseudo-code:
for-each list in list
display "ID=(car list)"
display "Name ="(cadr list)" "
etc
Any help would be greatly appreciated!

So, your interpreter doesn't have printf after all? that's a shame. We can get the desired output by hand, it's a bit cumbersome but this should work on most Scheme interpreters, notice that an extra procedure is required for keeping track of the index:
(define lst
'(("001" "Bob" 80) ("002" "Sam" 85) ("003" "Aaron" 94)))
(define (add-index lst)
(let loop ((lst lst) (idx 1))
(if (null? lst)
'()
(cons (cons idx (car lst))
(loop (cdr lst) (+ idx 1))))))
(for-each (lambda (e)
(display "No.")
(display (car e))
(display ": ID=")
(display (cadr e))
(display ", Name=’’")
(display (caddr e))
(display "’’, Grade=")
(display (cadddr e))
(newline))
(add-index lst))
It prints the desired result:
No.1: ID=001, Name=’’Bob’’, Grade=80
No.2: ID=002, Name=’’Sam’’, Grade=85
No.3: ID=003, Name=’’Aaron’’, Grade=94

Here's another version. It avoids construction of a temporary list.
(define lst
'(("001" "Bob" 80) ("002" "Sam" 85) ("003" "Aaron" 94)))
(define (print-list lst)
(define (display-one-item item index)
(display "No.")
(display index)
(display ": ID=")
(display (car item))
(display ", Name=’’")
(display (cadr item))
(display "’’, Grade=")
(display (caddr item))
(newline))
(define (helper in index)
(if (not (null? in))
(begin
(display-one-item (car in) index)
(helper (cdr in) (+ index 1))
)))
(helper lst 0))
(print-list lst)

Related

Why do I get "application: not a procedure" with this for loop in Racket?

The following code reads a csv file and based on its content generates a Prolog program:
#!/usr/bin/env racket
#lang racket/base
(define (overwrite-s-to-f fname s); Will create fname and write overwriting the previous content.
(with-output-to-file #:exists 'truncate fname (lambda () (displayln s))))
(define (c-o-a-line-to-f fname s); Will append a string to fname or create it if does not exist. Appends a new line.
(with-output-to-file #:exists 'append fname (lambda () (displayln s))));
(define fname "women.csv")
(define pl-fname "females-by-Racket.pl")
(require racket/file)
(define content (file->lines fname))
(define disc-line (string-append ":-discontiguous(" (string-replace (car content) "Name," "") ").\n"))
(overwrite-s-to-f pl-fname disc-line)
(define list-of-verbs (string-split (string-replace (car content) "Name," "") ","))
(require racket/string racket/system)
(for ((row content));content is a list of strings
(let ((list-of-cs (string-split row ",")))
(when (equal? (car (cdr list-of-cs)) "+")
(displayln row)(let ((cmd (string-append "awesome("(car list-of-cs)").")))(c-o-a-line-to-f pl-fname cmd)(displayln cmd)))
(when (equal? (car (cdr (cdr list-of-cs))) "+")(displayln row)(let ((cmd (string-append "and_intelligent("(car list-of-cs)").")))
(c-o-a-line-to-f pl-fname cmd)(displayln cmd))))); TODO: when for each columns 2-last of women.csv
The content of women.csv:
Name,awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts
adriana_chechik,+,,,+,?,+,+,,-,,,,,
alysa_gap,+,,,,?,+,+,,-,,,,,
anna_de_ville,+,,,,,+,+,,+,-,+,-,-,
aurora_jolie,+,+,,,,,,,+,+,+,,+,
autumn_falls,,,,,,,,,+,+,-,+,+,
casey_calvert,+,,,,,,,,+,+,+,,,
dahlia_sky,+,,,,,,+,,,,,,,
dominica_lito,+,,,,,,+,,,,,,,
ella_knox,,,,,,,,,+,+,+,,+,
isabella_clark,+,,,,,,+,,,,,,,
jade_kush,,,,,,,,,+,+,,,+,
juelz_ventura,+,,,,,+,,,-,-,,,-,+
kapri_styles,,,,,,,,,+,,+,,,
kristina_milan,,,,,,,,,+,+,,,+,
kylie_sinner,+,+,,,,,,,+,,,,-,
leigh_raven,+,,,,,+,,,+,+,,,,
maserati,,,,,,,,,+,+,,,+,
miosotis,,,,,,,,,+,+,,,+,
scarlett_bloom,,,,,,,,,+,+,+,,-,
sheena_shaw,,,,,,,,,-,,+,,-,
sofia_rose,,,,,,,,,+,,,,+,
teanna_trump,+,,,,,,,,+,,+,,,
veronica_avluv,+,,,,,,+,,,,,,,
yudi_pineda,+,,,,,,,,+,+,,,,
females-by-Racket.pl is to look like so:
:-discontiguous(awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts).
awesome(adriana_chechik).
awesome(alysa_gap).
awesome(anna_de_ville).
awesome(aurora_jolie).
and_intelligent(aurora_jolie).
awesome(casey_calvert).
awesome(dahlia_sky).
awesome(dominica_lito).
awesome(isabella_clark).
awesome(juelz_ventura).
awesome(kylie_sinner).
and_intelligent(kylie_sinner).
awesome(leigh_raven).
awesome(teanna_trump).
awesome(veronica_avluv).
awesome(yudi_pineda).
but with more predicates (up to n-1 for each woman where n is the number of columns in women.csv)
The names of the columns or the numbers thereof in women.csv are likely to be frequently changed.
That is partly why I wish to avoid manually coding for every when. The other concerns are the sheer amount of the lines to code (15 whens for each column) and the risk of error/typo.
Is it doable to loop through every cell in list-of-cs in such way that it is taken from list-of-verbs?
I've tried this but to no avail (the comment show the error message that I got):
(for ((row content))
(let ((list-of-cs (cdr (string-split row ","))))
(for ((cell list-of-cs))
; application: not a procedure; expected a procedure
; that can be applied to arguments
(set! list-of-verbs (cdr (list-of-verbs)))
(let ((verb (car list-of-verbs)))
(when (equal? cell "+")
(displayln row)
(let ((cmd (string-append verb "(" (car row) ").")))
(c-o-a-line-to-f pl-fname cmd)))
))))
named let is a useful form to be familiar with:
#lang scheme
(define (csv->attributes rows) ;; ListOfString -> ListOfString
;; produce "column-header(row-name)" for "+" entries in csv (see example)
(let ([fields (string-split (car rows) ",")])
(let next-row ([rows (cdr rows)] [result (list)])
(cond
[(null? rows) (reverse result) ]
[else
(let* ([cells (string-split (car rows) ",")]
[name (car cells)])
(let next-cell ([cells (cdr cells)] [fields (cdr fields)] [result result])
(cond
[(null? cells) (next-row (cdr rows) result) ]
[else (next-cell
(cdr cells) (cdr fields)
(if (string=? (car cells) "+")
(cons (string-append (car fields) "(" name ")") result)
result)) ]))) ]))))
(define trio '("Name,fast,slow,sidles"
"Achilles,+,,"
"Tortoise,,+,"
"Crab,,+,+"))
Welcome to DrRacket, version 8.5 [cs].
Language: scheme, with debugging.
> (csv->attributes trio)
("fast(Achilles)" "slow(Tortoise)" "slow(Crab)" "sidles(Crab)")
>

scheme - display won't print on screen in a recursive function

I have the function getBoundedVars which uses the function boundsInLambda. In the end of it all the box bBox should contain all bounded variables in the expression exp.
I'm trying to debug this function and in order to do so I want to print the parameters of boundsInLambda every time the function is being activated but for some reason the values won't show up on the screen.
If I put the display operation in getBoundedVars it will print it but those are just the values in the first iteration.
If I run the following :
(getBoundedVars (lambda-simple (x) (lambda-simple (y) (const x))) bx)
when bx is an empty box,
'1 will be printed but the print commands in boundsInLambda will not
here's the code:
(define getBoundedVars
(lambda (exp bBox)
(if (atom? exp)
0 ;; don't put in box
(if (lambda? (car exp))
(begin
(display 1)
(newline)
(let ((pBox (make-pBox exp))
(lBox (box '()))
(bodyExp (make-body exp))
)
(boundsInLambda bodyExp lBox pBox bBox)))
(begin
(getBoundedVars (car exp) bBox)
(getBoundedVars (cdr exp) bBox))))))
(define boundsInLambda
(lambda (bodyExp lastBox paramBox boundsBox)
(newline)
(display `(bodyExp: ,bodyExp))
(newline)
(display `(lastBox: ,lastBox))
(newline)
(display `(paramBox: ,paramBox))
(newline)
(display `(boundsBox: ,boundsBox))
(newline)
(if (and (not (null? bodyExp))
(list bodyExp)
(equal? (car bodyExp) 'seq)
)
(map boundsInLambda (cadr bodyExp))
(let* ( (lists* (filter (lambda (el) (and (not (null? el)) (list? el) (not (equal? (car el) 'const)))) bodyExp))
(lists (map (lambda (el) (if (equal? (car el) 'set) (cddr el) el)) lists*))
(bounds (filter (lambda (el) (and (member el (unbox lastBox)) (not (member el (unbox paramBox))))) bodyExp))
(listsLeft? (> (length lists) 0))
(anyBounds? (> (length bounds) 0))
)
(if anyBounds?
(begin
(set-box! boundsBox (append (unbox boundsBox) bounds))))
(if listsLeft?
(map
(lambda (lst)
(if (lambda? (car lst))
(let* ((newBodyExp (make-body lst))
(newParamBox (make-pBox exp))
(newLastBox (box (append (unbox lastBox) (unbox paramBox))))
)
(boundsInLambda newBodyExp newLastBox newParamBox boundsBox))
(boundsInLambda lst lastBox paramBox boundsBox)))
lists)
0))
)))
(define make-pBox
(lambda (lamExp)
(if (equal? (car lamExp) 'lambda-simple)
(box (cadr lamExp))
(if (equal? (car lamExp) 'lambda-opt)
(box (cadr lamExp))
(box '())))))
(define make-body
(lambda (lamExp)
(if (equal? (car lamExp) 'lambda-opt)
(cdddr lamExp)
(cddr lamExp))))
any help would be very much appreciated.

Scheme programming I/O and remove

I am doing a scheme project and having some issues with the coding.
For my project we have to keep a class roster(implemented as a list) and be able to perform different operations. I have two questions:
My write roster function opens up the file name passed through but does NOT write the list to the file and Im not sure why? you can find this function in the perform task function , when n = 2.
And my remove function... when I go to test it, I get the error:
;The procedure #[compiled-procedure 13 ("list" #x3) #x14 #x11a2714] has been called with 4 arguments; it requires exactly 2 arguments.
My remove function is called removestu
here is my code:
(define performtask
(lambda (n roster)
(cond ((= n 0) (begin
(display "\n\tResetting roster...\n\n")
(menu '())
))
((= n 1) (begin
(display "\n\tLoad roster from file: ")
(read (open-input-file (read-line)))
(menu roster)
))
((= n 2) (begin
(display "\n\tStore roster to file: ")
(write roster (open-output-file (read-line)))
(menu roster)
))
((= n 3) (begin
(display "\n\tDisplaying roster, sorted by ID:\n")
(printroster (select-sort roster))
(menu roster)
))
((= n 4) (begin
(display "\n\tDisplaying roster, sorted by ID:\n")
(printroster (select-sort-name roster))
(menu roster)
))
((= n 5) (begin
(display "\n\tDisplaying roster, sorted by ID:\n")
(printroster (select-sort-grade roster))
(menu roster)
))
((= n 6) (begin
(display "\n\tEnter student name or ID: ")
(studentinfo roster (read-line))
(menu roster)
))
((= n 7) (begin
(display "\n\tAdd a student to the class roster:\n\n")
(cond ((null? roster) (menu (read-3-items 0 '())))
(else (menu (list (read-3-items 0 '()) roster))))
))
((= n 8) (begin
(display "\n\tEnter student name or ID: ")
(removestu roster (read-line))
(menu roster)
))
((= n 9) (begin
(display "\n\tExiting program...\n\n")
#t
))
(else (begin
(display "\n\tTask no. ")
(display n)
(display " does not exist.\n\n")
(menu roster)
)
)
)
)
)
(define studentinfo
(lambda (lst value)
(cond ((null? lst) (display "\n\tStudent is not found in roster.\n"))
((equal? (car (car lst)) value) (printrecord (car lst)))
((equal? (car (cdr (car lst))) value) (printrecord (car lst)))
(else (studentinfo (cdr lst) value))
)
)
)
(define printroster
(lambda (billy)
(cond ((null? billy) (newline))
(else (begin
(printrecord (car billy))
(printroster (cdr billy))
)
)
)
)
)
(define printrecord
(lambda (lst)
(begin
(display "\tID=")
(display (car lst))
(display ", Name=")
(display (car (cdr lst)))
(display ", Grade=")
(display (car (cdr (cdr lst))))
(newline)
)
)
)
(define select-sort
(lambda (roster)
(cond ((null? roster) '())
(else (cons (smallest roster (car roster)) (select-sort (remove roster (smallest roster (car roster))))))
)
)
)
(define select-sort-name
(lambda (roster)
(cond ((null? roster) '())
(else (cons (smallest-name roster (car roster)) (select-sort (remove roster (smallest-name roster (car ro\
ster))))))
)
)
)
(define select-sort-grade
(lambda (roster)
(cond ((null? roster) '())
(else (cons (smallest-grade roster (car roster)) (select-sort (remove roster (smallest-grade roster (\
car roster))))))
)
)
)
(define smallest
(lambda (roster record)
(cond ((null? roster) record)
((< (car (car roster)) (car record)) (smallest (cdr roster) (car roster)))
(else (smallest (cdr roster) record))
)
)
)
(define smallest-name
(lambda (roster record)
(cond ((null? roster) record)
((< (car (cdr (car roster))) (car (cdr record))) (smallest-name (cdr roster) (car roster)))
(else (smallest-name (cdr roster) record))
)
)
)
(define smallest-grade
(lambda (roster record)
(cond ((null? roster) record)
((< (cdr (cdr (car roster))) (cdr (cdr record))) (smallest-grade (cdr roster) (car roster)))
(else (smallest-grade (cdr roster) record))
)
)
)
(define removestu
(lambda (roster item)
(cond ((null? roster) '())
((equal? item (car roster)) (cdr roster))
(else (cons (car roster) removestu (cdr roster) item))
)
)
)
(define read-3-items
(lambda (n l)
(cond ((= n 0) (begin
(display "\tStudent ID: ")
(read-3-items 1 (list (read)))
))
((= n 1) (begin
(display "\n\tStudent name: ")
(read-3-items 2 (list (car l) (read-line)))
))
((= n 2) (begin
(display "\n\tGrade: ")
(list (car l) (car (cdr l)) (read))
))
)
)
)
(define menu
(lambda (roster)
(begin
(display "\n\tClass roster management system\n")
(display "\t============================\n")
(display "\t MENU\n")
(display "\t============================\n")
(display "\t0. Reset roster\n")
(display "\t1. Load roster from file\n")
(display "\t2. Store roster to file\n")
(display "\t3. Display roster sorted by ID\n")
(display "\t4. Display roster sorted by name\n")
(display "\t5. Display roster sorted by grade\n")
(display "\t6. Display student info\n")
(display "\t7. Add a student to roster\n")
(display "\t8. Remove a student from roster\n")
(display "\t9. Exit\n\n")
(display "\tEnter your choice: ")
(performtask (read) roster)
)
)
)
(write roster (open-output-file (read-line))) seems ok. but you don't close the port you get from open-output-file. Perhaps you should use with-output-to-file instead.
cons is called with 4 arguments (cons (car roster) removestu (cdr roster) item). It takes only two to make a pair!
I noticed that when reading a file you don't use it. The tail call is (menu roster) and the result from (read (open-input-file (read-line))) is read and returned and, since it's not used, deleted.

Scheme define a constructor and selectors for a matrix object

I'm trying to develop a constructor and selectors for a simple 2x2 matrix but I'm unsure if what I've made is correct. This takes a list with 4 elements and makes a 2x2:
(define matrix2x2
(lambda (list)
(define to-list list) ;returns the list form of this matrix
(define get-place ;returns a place based on input row col
(lambda (row col)
(cond ((and (equal? row 1) (equal? col 1)) (car list))
((and (equal? row 1) (equal? col 2)) (car (cdr list)))
((and (equal? row 2) (equal? col 1)) (car (cdr (cdr list))))
((and (equal? row 2) (equal? col 2)) (car (cdr (cdr (cdr list)))))
(else (display "no such place")))))
(lambda (ret)
(cond ((eq? ret 'get-place) get-place)
((eq? ret 'to-list) to-list)
(else (error "Unknown request" ret))))))
;tests
(define my-matrix (m2x2 '(8 1 2 7)))
((my-matrix 'get-place) 2 2)
(my-matrix 'to-list)
This works... but I'm not sure I'm using selectors properly.
What you've done is the "usual" Scheme way of implementing objects via closures. You could of course go on to define some convenience functions for the selectors:
(define (get-place matrix ix) ((matrix 'get-place) ix)
(define (matrix->list matrix) ...)
I'm not sure I understand what you're asking about the "proper" use of selectors. After all, you already know that it works ...

Scheme Formatting Help

I've been working on a project for school that takes functions from a class file and turns them into object/classes. The assignment is all about object oriented programming in scheme.
My problem however is that my code doesn't format right.
The output it gives me whenever I give it a file to pass in wraps the methods of the class in a list, making it so that the class never really gets declared. I can't for the life of me figure out how to get the parenthesis wrapping the method list to remove.
I would really appreciate any help.
Below is the output, the class file and the code,.
(define pointInstance
(let ((myx 1) (myy 2))
(lambda msg
(cond
(((eq? (car msg) getx) myx)
((eq? (car msg) gety) myy)
((eq? (car msg) setx) (set! myx x))
((eq? (car msg) show) (begin (display "[") (display myx) (display ",") (display myy) (display "]"))))))))
If you look at just after the cond you'll see how all those eq statements are contained in a list. I can't get this to work right unless they're not wrapped by that top level list.
;;;; PART1 --- A super-easy set of classes. Just models points and lines. Tests all of >the
;; basics of class behavior without touching on anything particularly complex.
(class pointInstance (parent:) (constructor_args:)
(ivars: (myx 1) (myy 2))
(methods:
(getx () myx)
(gety () myy)
(setx (x) (set! myx x))
(show () (begin (display "[") (display myx) (display ",") (display myy) (display "]")))
))
(require (lib "trace.ss"))
;; Continue reading until you hit the end of the file, all the while
;; building a list with the contents
(define load-file
(lambda (port)
(let ((rec (read port)))
(if (eof-object? rec)
'()
(cons rec (load-file port))))))
;; Open a port based on a file name using open-input-file
(define (load fname)
(let ((fport (open-input-file fname)))
(load-file fport)))
;(define lis (load "C:\\Users\\Logan\\Desktop\\simpletest.txt"))
;(define lis (load "C:\\Users\\Logan\\Desktop\\complextest.txt"))
(define lis (load "C:\\Users\\Logan\\Desktop\\pointinstance.txt"))
;(display (cdaddr (cdddar lis)))
(define makeMethodList
(lambda (listToMake retList)
;(display listToMake)
(cond
[(null? listToMake)
retList
;(display "The list passed in to parse was null")
]
[else
(makeMethodList (cdr listToMake) (append retList (list (getMethodLine listToMake))))
]
)
))
;(trace makeMethodList)
;this works provided you just pass in the function line
(define getMethodLine
(lambda (functionList)
`((eq? (car msg) ,(caar functionList)) ,(caddar functionList))))
(define load-classes
(lambda paramList
(cond
[(null? paramList) (display "Your parameters are null, man.")]
[(null? (car paramList))(display "Done creating class definitions.")]
[(not (null? (car paramList)))
(begin
(let* ((className (cadaar paramList))
(classInstanceVars (cdaddr (cddaar paramList)))
(classMethodList (cdr (cadddr (cddaar paramList))))
(desiredMethodList (makeMethodList classMethodList '()))
)
;(display "Classname: ")
;(display className)
;(newline)(newline)
;(display "Class Instance Vars: ")
;(display classInstanceVars)
;(newline)(newline)
;(display "Class Method List: ")
;(display classMethodList)
;(newline)
;(display "Desired Method List: ")
;(display desiredMethodList))
;(newline)(newline)
;----------------------------------------------------
;do not delete the below code!`
`(define ,className
(let ,classInstanceVars
(lambda msg
;return the function list here
(cond ,(makeMethodList classMethodList '())))
))
;---------------------------------------------------
))]
)
))
(load-classes lis)
;(load-classes lis)
;(load-classes-helper lis)
;(load-classes "simpletest.txt")
;(load-classes "complextest.txt")
;method list
;(display (cdr (cadddr (cddaar <class>))))
You have too many opening parenthesis in the 1st clause of the cond.
IE:
(((eq? (car msg) getx) myx)
^
Updated:
Are you looking for this?
(cond ,#(makeMethodList classMethodList '())
^^
Or you can do:
(cond . ,(makeMethodList classMethodList '())

Resources