Aiuto su un problema


#1

Salve a tutti … premetto che ho imparato ruby da poco e ho bisogno del
vostro aiuto allora io ho creato questo programma che è un archivio di
merci in magazzino.
immettendo per esempio il prodotto ‘cemento’
il programma restituisce il prezzo di un singolo sacco ’ 4.00 $’.
Dopo ti avvisa della quantita disponibile di cemento che hai in
magazzino restituendo (esempio: ‘Quantità in magazzino: 100’)
poi chiede la quantità che vuoi richiedere (per esempio
facciamo 50) quindi il programma restituisce il totale della
moltiplicazione tra (‘4.00$’ il prezzo di un sacco per ‘50’ la quantita
richiesta quindi restituisce ‘totale 200 $’)
chiudendo il programma xò se io immetto nuovamente nella ricerca il
prodotto ‘cemento’ la quantita disponibile in magazzino rimane
invariata cioè il programma non salva l’operazione che ho
precedentemente fatto,restituendo sempre (quantita in magazzino :100) e
non (quantita in magazzino: 50) .
Allora a me serve un metodo con il quale io conservo i dati per
farsi che il programma tenga traccia delle operazioni precedentemente
svolte .

Vi allego un esempio di questo programma, ha in magazzino soltanto il
prodotto cemento… Apprezzo tanto qualsiasi vostro consiglio un saluto a
tutti


#2

Ciao Francesco,

innanzitutto complimenti per aver dimostrato di aver sbattuto un po’ la
testa con il problema, al posto di aver richiesto da subito la pappa
pronta
:slight_smile:

Ci sono davvero tante cose da affrontare, ma per partire ti consiglio di
vedere questo gist (è un tipo particolare di repository git):

https://gist.github.com/olistik/a9c4f56986be9f6675ef

Prima ancora della necessità di persistere (da qualche parte, in questo
caso su file) la quantità rimasta nel magazzino, ho modificato i nomi
delle
variabili e la gestione logica del ciclo.
In seguito ho aggiunto una semplice logica di persistenza su file.

Spero che il codice sia sufficientemente auto esplicativo, diversamente
chiedi pure lumi :slight_smile:

2015-03-18 13:31 GMT+01:00 Francesco V. removed_email_address@domain.invalid:


#3

Ti ringrazio tantissimo non sai qnt ore sono stato su qst problema !!!
per prima cosa devo cominciare ha riscrivere la parte logica e quindi mi
vado a studiare il tuo codice perchè alcune cose per esempio non le ho
capite bene ma spero si tratta solo di approfondire cmq ti ringrazio
ancora davvero tanto ti faro sapere grazie ancora a presto


#4

Ciao Maurizio innanzitutto ancora una volta GRAZIE per avermi illustrato
la strada da seguire, grazie al tuo aiuto sono riuscito a dimezzare il
mio lavoro,non finirei mai di dirtelo GRAZIE !! Allora per qnt riguarda
la parte logica è tutto chiaro semplice … ma ho qualche lacuna di
sintassi nella prima parte vorrei approfondire ancora meglio perche a me
piace avere TUTTO Molto chiaro quindi se potresti spiegarmi meglio come
si traduce la prima parte cioè :

if File.exists?(nome_file)
quantita_rimasta = File.read(‘quantita_rimasta.txt’).to_i
else
quantita_rimasta = 100
File.write(nome_file, quantita_rimasta)
end

per il resto è tutto molto chiaro infatti ho cominciato a riscrivere il
programma …ti allego il file, ho fatto il primo reparto e sto
cominciando tutto il resto.

Non so cosa altro dirti davvero grazie grazie di cuore


#5

ancora una cosa , ho aggiunto l’elenco dei reparti ma devo fare in modo
che lo visualizzi soltanto all’avvio e non ad ogni ciclo ,ci lavorero su


#6

bastava soltanto uscirlo fuori dal ciclo cmq preso dalla foga ti ho
allegato il programma con qualche elementare errore… lo allego di
nuovo


#7

Refactoring a prima vista: sostituisci gli if scelta == … elsif scelta

… else … end con un case:

scelta = gets.chomp

case scelta
when ‘totale’
continua_ciclo = false
when prod0

else
puts ‘Prodotto non presente.’
puts ’ ’
end

Poi ti consiglio di indentare meglio e in generale di seguire la Ruby
coding style guide https://github.com/bbatsov/ruby-style-guide ,
altrimenti
guardando il tuo codice non si capisce niente :slight_smile:

Maurizio De Santis

Il giorno 18 marzo 2015 18:50, Francesco V.
removed_email_address@domain.invalid
ha scritto:


#8

C’ effettivamente una quantit significativa di elementi su cui dovrebbe
porre l’attenzione.
Suppongo che nel suo caso, sia utile un percorso graduale che possa
fargli
capire i singoli elementi di refactoring, a partire dal suo approccio
iniziale.
On Mar 18, 2015 7:21 PM, “Maurizio De Santis”
removed_email_address@domain.invalid


#9

S ci sarebbe tanto da dire :slight_smile: intanto riguardo la questione coding style
(du cui ne hai bisogno soprattutto per interagire con gli altri
programmatori… Calcola che su stack overflow con quel codice ti
prenderebbero a pesci in faccia) consiglio una gemma molto utile che fa
da
“correttore automatico”, rubocop https://github.com/bbatsov/rubocop

Il giorno mer 18 mar 2015 20:00 maurizio de magnis <
removed_email_address@domain.invalid> ha scritto:


#10

Si scusate devo smettere di usare diminuitivi, li uso ovunque anche per
scrivere ‘prezzo1’ uso ‘prez1’ e ovviamente questo non aiuta una facile
comprensione del codice… a parte questo c’è una guida che posso
consultare per comprendere il concetto di refactoring e tanti altri
concetti importanti? sono davvero interessato a proseguire i miei studi
potreste darmi qualche dritta su cosa studiare?


#11

Prima di tutto devo sostituire tutte le abbreviazioni con le parole
intere, spero sia questo il principale problema di comprensibilità del
codice vi postero il codice a breve


#12

Un altro favore che ti chiedo Francesco di essere un po’ pi conciso e
preciso quando possibile: sia per te, cos ricevi risposte pi esatte, sia
per noi, cos non siamo costretti a fare grandi sforzi per capire cosa
vuoi; per esempio, riguardo questo pezzo di codice del buon De Magnis
che
ti aveva lasciato qualche dubbio:

if File.exists?(nome_file)
quantita_rimasta = File.read(‘quantita_rimasta.txt’).to_i
else
quantita_rimasta = 100
File.write(nome_file, quantita_rimasta)
end

Cosa non ti chiaro di preciso? La logica che ti dietro? O ci sono
parti
della sintassi del linguaggio che non comprendi?

Maurizio De Santis

Il giorno 18 marzo 2015 22:19, Enrico R. removed_email_address@domain.invalid ha
scritto:


#13

@Francesco, lungi me dallo scoraggiarti (anzi, spacca tutto! :-D)
ammetto
che quando ti ho scritto: “Ci sono davvero tante cose da affrontare”
intendevo più o meno ciò che il mio omonimo (ciao Maurì) ed Enrico hanno
detto.
Dal codice che hai prodotto, si vede che stai iniziando a “masticare”
Ruby,
ma ci sono ancora tantissimi concetti che devi conoscere prima.
Ci siamo passati tutti, secondo differenti strade, e l’aspetto positivo
è
che hai un enorme margine di miglioramento :slight_smile:
Oltre ai concetti specifici di Ruby, vedo che ti mancano anche dei
concetti
più basilari della programmazione (ma non demordere :-)).
Prima ancora di scrivere in Ruby, dovresti avere uno schema mentale
rigoroso di come il programma si deve comportare.
Hai mai sentito parlare di diagrammi di flusso?

http://it.wikipedia.org/wiki/Diagramma_di_flusso

Ogni sviluppatore (Ruby, Python, C, Pascal, etc) li conosce e li usa per
definire il comportamento dell’algoritmo che deve implementare.
Mano a mano che diventi più esperto, l’uso dei diagrammi di flusso
diventa
più inconscio perché con l’esperienza assimili automaticamente questo
tipo
di rappresentazione formale degli algoritmi.

Praticamente: prova a rivedere la tua prima versione del ciclo while e
confrontala con quella che ti ho fornito io.
Prova a capire come mai la mia contiene meno istruzioni.

Secondariamente, la ripetizione del codice è male praticamente in ogni
caso
in cui un insieme di operazioni viene ripetuto tante volte, variando
solo
alcuni elementi.

Per esempio, la procedura che carica la quantità rimasta in magazzino:

if File.exists?(qnt0)
qnt_rim0 = File.read(‘qnt_rim0.txt’).to_i
else
qnt_rim0 = 100
File.write(qnt0, qnt_rim0)
end

Se ci pensi, è codice ripetuto tantissime volte che varia solo per
alcuni
parametri.
Hai agito così probabilmente per due motivi:

  1. non sai come si scrive una funzione in Ruby

  2. non hai maturato ancora abbastanza esperienza da sentire “dolore”
    dovuto
    a questo tipo di ripetizione

  3. si risolve abbastanza facilmente, mentre 2) dipende quasi
    completamente
    dall’esperienza (diretta, tramite letture di articoli/codice altrui o
    tramite il confronto con altri sviluppatori).

Prova a pensare a quanto tedioso e a rischio di errore sia dover
modificare
la procedura di caricamento, per tutti i materiali di ogni reparto.

Un primissimo metodo per migliorare questa situazione è proprio l’uso
delle
funzioni:

def nomefunzione(parametro_1, parametro_2)

fai cose con parametro_1 e parametro_2

eventualmente restituisci un valore a chi ha chiamato questa

funzione
end

def somma(a, b)
a + b
end

x = somma(1, 3)
puts "x = " + x.to_s

Nel tuo caso:

def carica_quantita_rimasta(indice_reparto, indice_prodotto)
nome_file = ‘qnt_rim_’ + indice_reparto.to_s + ‘_’ +
indice_prodotto.to_s

  • ‘.txt’
    if File.exists?(nome_file)
    quantita = File.read(nome_file).to_i
    else
    quantita = 100
    File.write(nome_file, quantita_rimasta)
    end
    quantita
    end

qnt_rim0 = carica_quantita_rimasta(0, 1)
qnt_rim0_1 = carica_quantita_rimasta(0, 2)

qnt_rim21_15 = carica_quantita_rimasta(21, 15)

In questo caso, quando avrai necessità di modificare la procedura di
caricamento delle quantità rimaste a magazzino, dovrai modificare solo
un
punto del tuo sorgente.

Ti anticipo anche altre migliorie, lasciando a te l’onere di sbatterci
di
nuovo un po’ la testa :wink:

https://gist.github.com/olistik/cd3673ee0901593f1d96

Tieni bene a mente che ci sono vari modi per risolvere il tuo problema,
il
sorgente che ti ho passato deve solo servire per darti un’idea degli
strumenti e approcci che potresti usare.
Non è sicuramente il metodo migliore, quello lo devi trovare te che
conosci
il dominio applicativo di riferimento :slight_smile:

Al prossimo round :wink:

2015-03-18 23:23 GMT+01:00 Maurizio De Santis
removed_email_address@domain.invalid:


#14

Francesco, non e’ solo questione di abbreviazioni, una cosa
fondamentale che devi imparare a fare e’ riconoscere le ripetizioni
nel tuo codice ed evitarle.

Come primo passo ti consiglio di imparare ad usare metodi*, array e
iteratori. Non ho idea di una buona guida in italiano … prova a
googlare queste cose e cerca di capire da solo come sfruttarle per
ridurre il numero di righe del tuo codice.

E

  • metodi sono (per dirla grezza) funzioni di oggetti ma non ti
    preoccupare di tutto cio ancora.

2015-03-18 21:57 GMT+01:00 Francesco V. removed_email_address@domain.invalid:


#15

Si come prima cosa devo assimilare il diagramma del flusso cosi da avere
una visione chiara, nonostante conoscessi le funzioni ahimè non avevo
capito l’importanza di essi in praticamente le ho ignorate ‘perdendo’
ore e ore di lavoro soltanto per non averle prese in considerazione.
Sicuramente so che questo non è neanche l’inizio per comprendere appieno
le potenzialità di questo linguaggio ma sono deciso a continuare.
dopotutto sono passati 2 mesi da quando ho iniziato a studiare e
all’inizio ho cominciato così per ‘gioco’ dedicandomi nel tempo libero.
Adesso so quali argomenti devo affrontare seguirò le tue indicazioni
passo passo! vi ringrazio davvero tanto c sentiremo presto.


#16

Caro Francesco

if File.exists?(nome_file)
quantita_rimasta = File.read(‘quantita_rimasta.txt’).to_i
else
quantita_rimasta = 100
File.write(nome_file, quantita_rimasta)
end

A) Se il file esiste: la quantita rimasta viene letta direttamente dal
file.
B) Se il file non esiste: inizializza la quantita rimasta (100) e
scrivilo su file

alla prima esecuzione del programma viene eseguito B (il file non
esiste), pre le altre esecuzioni viene esguito A (il file esiste).

Sapresti dirmi cosa succede se eseguo il programma con un file
quantita_rimasta.txt vuoto?
Come controlleresti questa eccezione?

D


#17

scusate veramente per la domanda ma io non riesco a capire le funzioni
, in teoria è semplicissimo ma non ho chiaro come si applicano quando
devono puntare a un array o a qualsiasi variabile,
prendendo l’esempio che mi ha dato maurizio :

def nomefunzione(parametro_1, parametro_2) [Prima questione: (i
parametri perche nn possono essere anche degli Array?)

fai cose con parametro_1 e parametro_2 [seconda questione:( perchè non

riesco ad usare IL METODO .EACH DO in questo caso ? )

eventualmente restituisci un valore a chi ha chiamato questa

funzione
end

da stamattina ho cominciato a rivedere il concetto di funzione e
applicarla quando si tratta di piccole cose non è difficile, il problema
sorge non appena devo far puntare ad un oggetto ( o ad un array). sarei
grato se qualcuno potrebbe chiarirmi le idee perchè mi sento davvero
spiazzato…


#18

Eccoti un esempio di funzione con array come parametro:

https://gist.github.com/tucano/c836b4f47036f43e1553


#19

ciao davide ti ringrazio per avermi chiarito la sintassi
cmq dovrebbe essere questa la soluzione

if File.exists?(qnt0)
qnt_rim0 = File.read(‘qnt_rim0.txt’).to_i

else
qnt_rim0 = 100
File.write(qnt0, qnt_rim0)

if qnt_rim0 = 0

puts ’ Prodotto esaurito’

end
end


#20

In verita volevo farti prendere in considerazione il caso in cui hai un
file vuoto.

Su unix puoi provare con:

touch quantita_rimasta.txt

che crea un file vuoto

E poi lo passi al programma:

irb(main):001:0> File.exists? “quantita_rimasta.txt”
=> true

Il file esiste, non ce dubbio.

Cosa succede se lo converto to integer?

irb(main):002:0> File.read(‘quantita_rimasta.txt’).to_i
=> 0

Ritorna 0

Ma sei sicuro che sia quello che vuoi?

Prendi in considerazione il Caso klingon:

  1. Scrivi il tuo programma per calcolare la quantita di cememento
    rimasta e lo metti in una cartella
  2. Arriva un klingon che vuole rovinarti la vita e mette nella stessa
    cartella un file vuoto con nome quantita_rimasta.txt
  3. Ora, qualsiasi cosa farai, il programma ti dira: ‘Prodotto esaurito’

Vedi come e facile per un klingon bloccare la produzione di cemento dei
terrestri?

Ma Va bene lo stesso, sono io che sono un rompicazzo ed oggi devo
trovare qualcosa di alternativo a quello che dovrei fare.

DR