# How can i create function that takes an instance and updates it?

i am trying to complete a homework task based on structure,but when i came to the third bullet point where it asked me to create a function for a customer instance,i got confused how am i supposed to do that,because i don't know which arguments to take.Here is the assignment brief.

``````A chain of supermarkets has decided to offer a loyalty card to its regular customers. Customers
can collect points to get exclusive discounts on several products.
1. Define a struct type to represent a customer. The structure should contain fields
allowing to store the name of a customer, the number of points collected by a
customer, the number of points already spent by a customer (i.e., point used to obtain
special discount) and the current number of points owned by a customer, initialized to 0
(i.e., points collected - points spent).
2. Define five named instances, e.g., â€śJames Anitaâ€ť, 3200, 1200, 0. (Note: the number of
points collected by a customer should always be greater or equal to the number of
3. Write a function that takes as input an instance of a customer struct and updates the
field corresponding to the current number of points owned by a customer. The current
number of points is computed by subtracting the points spent from the points collected.
E.g., given the struct â€śJames Anitaâ€ť, 3200, 1200, 0, it should update the last field with
2000.
4. Before proceeding to the payment of his purchase, a customer can choose to use his
points. Write a function that will take as input an instance of a customer struct, the
number of points which would be collected by the customer by proceeding to the
payment of his purchase, and the number of points the customer intends to use.
a. If the number of points which would be collected by a customer by proceeding
to the payment of his purchase and his current number of points are greater
than the number of points he intends to spend, his loyalty card account will
automatically be updated after payment (number of points collected, number of
points spent, current number of points).
b. If not, the message "Unfortunately, you need XXX extra customer points!!",
where XXX corresponds to the number of points missing, will be displayed on the
screen.
``````

and here is my code so far

``````(define-struct customer  [name nopcbc nofpasbac cnopobac])
;; A custmoer  is a structure:
;;   (make-custmoer  string number number number )

;(make-custmomer  a  b c d) represents a custmoers details
;; with a name
;; and a nopcbc b
; nofpasbac c
;cnopobac d

;; Interpretation:
;; name is the name of the customer
;; nopcbc is he number of points collected by a customer
; nofpasbac is  the number of points already spent by a customer
;cnopobac is current number of points owned by a customer, initialized to 0

(define new-customer1 (make-customer â€śJames Anitaâ€ť 3200 1200 0))
(define new-customer2 (make-customer â€śJohn woodâ€ť 4200 1800 0))
(define new-customer3 (make-customer â€śTom Smithâ€ť 3600 1500 0))
(define new-customer4 (make-customer â€śBrooke eveâ€ť 3100 1000 0))
(define new-customer5 (make-customer â€śOsman Hassanâ€ť 3900 1400 0))
``````

The current number of points is computed by subtracting the points spent from the points collected.

You need to compute this value, and update the field of the struct
(there are many ways to do so, some of which differ based on whether
or not the struct-field is mutable).

N.B. in modern Racket you would not use `define-struct`.

The names `nopcbc`, `nofpasbac`, and `cnopobca` are hard to work with;
may I suggest `total-points-collected`, `points-spent`, and
`current-points`? (Of course, the design is awkward, since it must
ensure manually that `total-points-collected` is always the sum of
`points-spent` and `current-points, but it is homeworkâ€¦)

Since this is likely a student language, continue to use `define-struct`.

For 3, determine the signature of your function. What is the problem asking for you to take in and produce? What fields do you have access to from `customer`?

1 Like

First off, welcome! Nice to have a new person on the list, and I'm glad you're interested in learning Racket.

The key thing to know about Racket is that it's a functional language. As a general rule, you don't change the value something in place, you create a new instance of it with the new value. You can test this using various forms of equality:

``````;  eq?  asks "do these two identifiers refer to the same memory address?"
;  equal? asks "are these two things sufficiently similar that a human would call them the same in most circumstances?"

; Notice that I've added the keyword "#:transparent", which makes the internals of the struct visible to Racket's various printers and inspectors
(define-struct customer  [name points-collected points-spent points-remaining] #:transparent)

; Create some instances
(define bob (customer 'bob 1700 100 1600))        ; a thing
(define bob-alias bob)                            ; different name for the same thing
(define bob-clone (customer 'bob 1700 100 1600))  ; another thing, has the same values

(equal? bob bob-clone)  ; returns #t because they are both visible,  have the same type, and have the same values [*]
(eq? bob bob-clone)     ; returns #f because they are not the same object in memory
(eq? bob bob)           ; returns #t because they are the same object in memory
(eq? bob bob-alias)     ; returns #t because they are different names for the same object in memory

; Important caveat:  Different struct definition.  I've removed the keyword #:transparent, so now Racket is restricted in how it can look inside the object
(define-struct not-transparent-cust  [name points-collected points-spent points-remaining])

(define alice       (not-transparent-cust 'alice 3 2 1))  ; a thing
(define alice-alias (not-transparent-cust 'alice 3 2 1))  ; same thing, different name
(define alice-clone (not-transparent-cust 'alice 3 2 1))  ; different thing, same values, same type

(eq? alice alice)          ; #t, same object in memory
(eq? alice alice-alias)    ; #t, same object in memory
(eq? alice alice-clone)    ; #f, not the same object in memory
(equal? alice alice-clone) ; #f whaaat???  We can see that the structs have the same values, but the type is not transparent and therefore Racket cannot introspect it sufficiently to verify all values are the same
``````

Given all of the above, how would you write a function that:

• Accepts a `customer` struct as its argument
• Extracts its field values
• Performs the necessary calculations to determine how things should change
• Returns a `customer` struct that has the correct values

Furthermore, how would you write tests that verify it works correctly? (Hint: Look at the various equality tests above.)

1 Like