Search code examples
structsetracketlocal

Racket: add a new quantity to a specific product


The goal of the code is that. after i add a new item, i need to add a new quantity to the product i want and by using set!, i need that the new quantity really change.

(define-struct articulo (nombre cantidadDisponible))

(define  listaArticulos empty)

(define (productoNuevo nom can)
  (set! listaArticulos
        (cons (make-articulo nom can) listaArticulos)))

(define (agregarValor datoABuscar datoASumar)
(local
  ( 
   (define (agregar lista buscar valorSumar)
     (cond
       [(empty? lista)empty]
       [(string=? buscar (articulo-nombre (car listaArticulos)))
        (make-articulo (+ (articulo-cantidadDisponible(car lista)) valorSumar)
              (agregar (cdr lista)buscar valorSumar))]
       [else (make-articulo (car lista) (agregar (cdr lista) buscar valorSumar))]
       )
     )
   ) 
  (begin
    (set! listaArticulos (agregar listaArticulos datoABuscar datoASumar))
    )
  )
)

Adding new items to the itemlist

(productoNuevo "tomatoes" 20)
(productoNuevo "oranges" 20)

Then i need to add a new quantity to the product i want

(agregarValor "tomatoes" 10)

Then i want to confirm that the new quantity was added

listaArticulos 

The output must be

(list (make-articulo "oranges" 20) (make-articulo "tomatoes" 30))

But is instead

(make-articulo 30 (make-articulo 30 '()))

Can you please help me with this?


Solution

  • I'm afraid the procedure's logic isn't right. These are the main issues:

    • You need to build a new list as the output, and only after that, set! the result to the external list.
    • Both the second and third conditions need to be rewritten so they construct the output list with cons.
    • The line with the string=? condition is incorrect, you're taking the car of the wrong list.
    • When calling make-articulo, you forgot to pass the the name of the item.

    This should fix the problems:

    (define (agregarValor datoABuscar datoASumar)
      (local
        ((define (agregar lista buscar valorSumar)
           (cond
             [(empty? lista) empty]
             [(string=? buscar (articulo-nombre (car lista)))
              (cons 
               (make-articulo (articulo-nombre (car lista))
                              (+ (articulo-cantidadDisponible (car lista)) valorSumar))
               (agregar (cdr lista) buscar valorSumar))]
             [else (cons (car lista) (agregar (cdr lista) buscar valorSumar))])))
        (begin 
          (set! listaArticulos (agregar listaArticulos datoABuscar datoASumar)))))
    

    Now it works as expected:

    (define (print lst)
      (for-each (λ (articulo)
                  (printf "~s: ~s ~n"
                          (articulo-nombre articulo)
                          (articulo-cantidadDisponible articulo)))
                lst))
    
    (productoNuevo "tomatoes" 20)
    (productoNuevo "oranges" 20)
    (print listaArticulos)
    => "oranges": 20 
       "tomatoes": 20
    
    (agregarValor "tomatoes" 10)
    (print listaArticulos)
    => "oranges": 20 
       "tomatoes": 30