Due domande: una sul ciclo if ed una sul while

Salve.
Sono uno studente universitario che si affaccia per la prima volta al
mondo Ruby.
Mi sono imbattuto pertanto in due quesiti :

il primo riguarda l’iterazione del ciclo if

-> Scrivere l’istruzione if che denisce i numeri x compresi tra 10 e 20
(estremi inclusi)

In questo caso come faccio ad iterare il ciclo if (si può iterare senza
usare nessuno tra for,while ed each?) per far stampare tutti i numeri
richiesti?

il secondo riguarda il riscrivere un codice ruby dall’each al while, che
non riesco a fare

-> Si consideri il seguente programma:

def f(a,x)
ris=0
a.each do |el|
ris = ris +x*el
end
return ris
end

Scrivere la definizione equivalente usando il while

Grazie in anticipo per l’aiuto :slight_smile:

Ciao, che problematiche hai incontrato? La cosa piu’ sensata e’
aiutarti a capire come risolvere i quesiti, non darti la soluzione
pronta :wink:

Qualora avessi bisogno di qualche risorsa per cominciare:
http://tryruby.org/

Maurizio

Il 23 maggio 2010 18.33, Daniele Ca [email protected] ha scritto:

→ Scrivere l’istruzione if che denisce i numeri x compresi tra 10 e 20
(estremi inclusi)

In questo caso come faccio ad iterare il ciclo if (si può iterare senza
usare nessuno tra for,while ed each?) per far stampare tutti i numeri
richiesti?

non credo che sia richiesto di iterare, ma di “riconoscere” se un numero
ricade nell’intervallo richiesto; quindi è un if con 2 due condizioni in
and
gli esempi che trovi qui
Ruby - if...else, case, unless dovrebbero essere
sufficienti

def f(a,x)
ris=0
a.each do |el|
ris = ris +x*el
end
return ris
end

Scrivere la definizione equivalente usando il while
a è un array; alla fine restituisce la somma di tutti gli elementi
moltiplicati per x; per documentazione su while vedi ad esempio
Ruby While and Until Loops - Techotopia

Innanzitutto vi ringrazio per le rapide e cordiali risposte :wink:

Poi avete ragione voi, è meglio ragionarci insieme che avere subito la
soluzione, così vi dico quello che ho pensato io così magari potrete
dirmi se ho preso la direzione giusta o quella sbagliata…

Per quanto riguarda il primo quesito,anche io, riflettendo, ho pensato
che non fosse richiesta l’iterazione così ho provato a buttare giù una
cosa del tipo:

x=0
if x<10 or x<20
x=x+1
puts x
else
x=x+1
end

Solo che un ciclo del genere, senza while,each o for, non può essere
iterato quindi stampa un solo numero ovvero 1. Che ne pensate?

Per quanto riguarda il secondo quesito, non so esattamente come
scriverlo, ma ho pensato a due soluzioni:

  1. avendo l’array di tre elementi, posso “dire” al codice di sommare gli
    elementi dell’array e passare al successivo fin quando non arrivo
    all’ultimo elemento

ad esempio, chiamando “i” l’indice di array, potrei scrivere

while i<=2 “sommami l’elemento e passa al successivo”

ma non so di preciso come scriverne il codice, la cosa che mi mette in
difficoltà è come indicare l’elemento “indice di array”

  1. la seconda soluzione a cui ho pensate è usare il metodo pop di
    estrazione dell’ultimo elemento dell’array fin quando l’array non è
    vuoto, ed intanto sommare gli elementi estratti, del tipo

while a!=nil oppure while a!=[] (non so come va scritto)

Cosa ne pensate? :smiley:

Se ho scritto cose per voi fuori dal mondo scusatemi, ma sono un niubbo
di Ruby :wink:

a leggere bene il primo quesito, non mi sembra che vengano richiesti
cicli, bensì solo di esprimere una condizione, o sbaglio?

in tal caso sarebbe solo:

if x >= 10 and x =< 20 # maggiore-uguale e minore-uguale vanno
specificati per includere gli estremi.

inoltre devi usare un AND perchè devi soddisfare entrambe le condizioni,
non una sola :wink:

per il secondo quesito, la seconda ipotesi è sicuramente migliore,
considerato che non è dato sapere quanti elementi sono contenuti in un
array. un esempio potrebbe essere questo:

a = [1,2,3,4,5]

while a.size > 0
puts a.shift
end

tuttavia tieni presente che:

  • pop() preleva l’ultimo elemento, mentre shift() prende il primo :wink:
  • pop() e shift() non si limitano a restituire l’elemento, ma lo
    eliminano dall’array

una versione meno distruttiva è questa:

i = 0
while i < a.size
puts a[i]
i += 1
end

ciao,
A.

Il 24/05/2010 12:25, Daniele Ca ha scritto:

grazie Luca, perfettamente daccordo con te :wink:

il codice che ho messo, è in realtà un esempio di codice che non-usa
deliberatamente Enumerable#each :stuck_out_tongue:

leggi la mail di Daniele :wink:

ciao,
A.

Il 24/05/2010 14:21, Luca De Marinis ha scritto:

2010/5/24 Andrea P. [email protected]:

una versione meno distruttiva è questa:

i = 0
while i < a.size
puts a[i]
i += 1
end

Una delle cose piu’ gustose di ruby e’ il fatto che eredita dai
linguaggi funzionali alcuni costrutti standard per fare cose su
collezioni di elementi. in questo caso Enumerable#each farebbe davvero
al caso tuo. Il problema e’ solo che i linguaggi che derivano dal C ti
storcono la mente cosi’ tanto che ci vuole un po’ ad abituarsi
all’idea, e quindi all’inizio sembra piu’ ‘naturale’ scrivere cose
come queste (magari corrette, ma scomode, ovvero preoccuparsi di
indici, verifiche sugli stessi, condizioni, etc) invece di

a.each {|item| puts item}

Che non e’ semplicemente “piu’ corto” :wink:

ad occhio, sembra un corso di programmazione (basato su Ruby). le
parentesi non sono casuali :smiley:

da un punto di vista didattico, se parti da zero-assoluto, è
comprensibile che si preferisca usare una sintassi classica per
esprimere alcuni algoritmi.

del resto, imho, ruby può essere davvero apprezzato/sfruttato nel
momento in cui conosci già la programmazione ed hai usato almeno un
linguaggio tra quelli diffusi :stuck_out_tongue:

ciao,
A.

Il 24/05/2010 14:53, Luca De Marinis ha scritto:

2010/5/24 Andrea P. [email protected]:

grazie Luca, perfettamente daccordo con te :wink:

il codice che ho messo, è in realtà un esempio di codice che non-usa
deliberatamente Enumerable#each :stuck_out_tongue:

leggi la mail di Daniele :wink:

Ops, hai ragione! pero’ che esercizi strani che danno all’universita’!

Il 24/05/2010 17:33, Luca De Marinis ha scritto:

Tanto per filosofare :wink: …penso che sia una questione piuttosto
sottile.
si, stiamo andando OT, ma l’argomento può valere la pena :wink:

Da una parte sono d’accordo sul fatto che un linguaggio
potente ed elegante possa essere apprezzato fino in fondo solo da chi
si e’ fatto un po’ di ossa su linguaggi meno potenti ed eleganti (devi
avere un peggio da comparare al meglio!). Dall’altra, anche come
esperienza personale, ricordo che quando iniziai a studiare un
linguaggio ‘strutturato’ (il pascal…argh!) venire dal basic fosse
piu’ un impedimento che un vantaggio, cosi’ come provenire dai
linguaggi ‘strutturati’ ha richiesto molto ‘unlearning’ per afferrare
davvero gli oggetti.

capisco le tue disavventure, trattandosi di Pascal e Basic in ogni caso
le sintassi erano abbastanza diverse tra loro. quanto all’approccio
strutturato/OOP si tratta di due visioni diverse, quindi è un problema
che prima o poi affronti quando provi altri linguaggi, anche solo
passando da C a C++ :stuck_out_tongue:
io sono partito dal C, che reputo tuttora un ottimo linguaggio.
certamente ho incontrato difficoltà quando ho dovuto affrontare la OOP
con altri linguaggi, più che unlearning mi sono sforzato a pensare in
modo diverso :stuck_out_tongue:

Insomma, se da una parte e’ buono conoscere la sintassi C-like per
gli array e le sue trappole se poi avrai la sfortuna di programmare in
C o Java, dall’altra e’ una completa perdita di tempo dal punto di
vista di ‘imparare a risolvere problemi’ o nella accezione moderna
“imparare a risolvere i problemi con gli oggetti”…
non sono d’accordo: dal punto di vista didattico, se vuoi davvero
imparare a risolvere problemi, gli algoritmi di base dovresti
conoscerli a prescindere dallo zucchero sintattico :wink: per dire, se
vuoi studiare il sorting con Java, non vai a cercarti il metodo di
libreria, ma dovresti essere in grado di implementartelo per conto tuo.
poi quando programmerai per lavoro sarà un altro discorso :wink:
stesso ragionamento vale per capire cosa avviene nel sistema: con il C
devi sapere come sono immagazzinati i dati, come gestirli, e quanto
occupano. sarà anche noioso nell’uso quotidiano, ma (imho) un buon
programmatore dovrebbe conoscere questi concetti.

e credo che anche
il fatto che esistano corsi introduttivi di programmazione basati su
ML piuttosto che sul C o lo smalltalk dimostri come la questione sia
piuttosto aperta.
potrebbe anche dimostrare che spesso la preparazione di alcuni docenti è
un optional :wink:

Fra queste possibilita’, far usare ruby come un
linguaggio c-like e’ una scelta da parte dei docenti del corso che
personalmente non condivido affatto, ovvero, direi en passant agli
studenti “in una famiglia di linguaggi meno potenti ma molto popolari
si faceva cosi’, ma lasciate perdere perche’ la vita e’ troppo breve
per indexare gli array a mano”… anche se mi rendo conto che il mio
e’ un punto di vista minoritario se non proprio eretico :wink:

forse non avrei scelto ruby per poi insegnarlo in quel modo, questo è
vero :wink: tuttavia, il tuo concetto di linguaggio meno potente è
abbastanza singolare :stuck_out_tongue:

ho sempre ritenuto che la potenza di un linguaggio non sia misurabile
solo in termini di espressività sintattica, anche perchè spesso va
rapportato al come/quanto ti permette di raggiungere determinati
obiettivi, e quanto controllo vuoi sul codice :wink:

ciao,
A.

2010/5/24 Andrea P. [email protected]:

ad occhio, sembra un corso di programmazione (basato su Ruby). le
parentesi non sono casuali :smiley:

da un punto di vista didattico, se parti da zero-assoluto, è
comprensibile che si preferisca usare una sintassi classica per
esprimere alcuni algoritmi.

del resto, imho, ruby può essere davvero apprezzato/sfruttato nel
momento in cui conosci già la programmazione ed hai usato almeno un
linguaggio tra quelli diffusi :stuck_out_tongue:

Tanto per filosofare :wink: …penso che sia una questione piuttosto
sottile. Da una parte sono d’accordo sul fatto che un linguaggio
potente ed elegante possa essere apprezzato fino in fondo solo da chi
si e’ fatto un po’ di ossa su linguaggi meno potenti ed eleganti (devi
avere un peggio da comparare al meglio!). Dall’altra, anche come
esperienza personale, ricordo che quando iniziai a studiare un
linguaggio ‘strutturato’ (il pascal…argh!) venire dal basic fosse
piu’ un impedimento che un vantaggio, cosi’ come provenire dai
linguaggi ‘strutturati’ ha richiesto molto ‘unlearning’ per afferrare
davvero gli oggetti.
Insomma, se da una parte e’ buono conoscere la sintassi C-like per
gli array e le sue trappole se poi avrai la sfortuna di programmare in
C o Java, dall’altra e’ una completa perdita di tempo dal punto di
vista di ‘imparare a risolvere problemi’ o nella accezione moderna
“imparare a risolvere i problemi con gli oggetti”… e credo che anche
il fatto che esistano corsi introduttivi di programmazione basati su
ML piuttosto che sul C o lo smalltalk dimostri come la questione sia
piuttosto aperta. Fra queste possibilita’, far usare ruby come un
linguaggio c-like e’ una scelta da parte dei docenti del corso che
personalmente non condivido affatto, ovvero, direi en passant agli
studenti “in una famiglia di linguaggi meno potenti ma molto popolari
si faceva cosi’, ma lasciate perdere perche’ la vita e’ troppo breve
per indexare gli array a mano”… anche se mi rendo conto che il mio
e’ un punto di vista minoritario se non proprio eretico :wink:

Ciao

def f(a,x)
i=0
ris=0
while i < a.length
ris=ris+x*a[i]
i=i+1
end
return ris
end

direi che ci siamo

alcune migliorie:
def f(a,x)
i=0
ris=0
while i < a.length
ris += x * a[i]
i += 1
end
ris
end

in questo modo risolvi l’esercizio con l’uso del while, come richiesto;
ovviamente in Ruby si sarebbe scritto, (ne faccio una funzione anche se
non necessario in modo da rendere più agevole il confronto con il tuo
codice)

def f1(a,x)
ris = a.inject(0) {|somma,num| somma += x * num }
end

a = [1,2,3]
x = 2

p f(a,x)
p f1(a,x)
restituiscono entrambi 12

come vedi è più breve e diretto

ciao e buono studio

Giampiero Z. wrote:

def f1(a,x)
ris = a.inject(0) {|somma,num| somma += x * num }
end
[…]

come vedi è più breve e diretto

E soprattutto non si perde tempo a scrivere, debuggare, leggere e cercar
di capire del codice che, come è stato abbondantemente dimostrato, non
serve a nulla. Anche il programma girerà più veloce :slight_smile:

Sull’altro piatto della bilancia c’è la necessità di dover imparare il
significato di metodi come inject, detect, collect, each, select,
reject, etc però un link a RDoc Documentation sempre pronto
in toolbar risolve tanti problemi.

Paolo

PS: concordo con chi scriveva che se i docenti volevano insegnare i
while avrebbero fatto meglio a scegliere il C o Java, mentre per i loop
veri (i LOOPNZ e i DJNZ) c’è l’assembler :wink:

Innanzitutto vi ringrazio tutti per aver partecipato in questo post: è
molto istruttivo leggervi !!! Ho trovato gente preparata su cui
riflettere della programmazione Ruby e ciò mi aiuta moltissimo!!
Comunque confermo che il corso che sto seguendo è un corso di Fondamenti
di Informatica basato sul Ruby :wink:

Per tornare IT: per quanto riguarda il primo quesito, penso che abbiate
ragione e non ci sia bisogno di iterare.
Per il secondo invece, seguendo i vostri consigli, l’ho riscritto così

def f(a,x)
i=0
ris=0
while i < a.length
ris=ris+x*a[i]
i=i+1
end
return ris
end