Profilo di andredatto

Nome andredatto
Indirizzo email n/a
Messaggi3
  • Re: Problema python in algoritmica
    Forum >> Principianti
    Eh, diciamo che non hai capito la cosa fondamentale. Mettiamola così: a ogni iterazione, quella funzione restituisce un "coso" nella forma:

    R + S

    dove "S" è una stringa, e "R" è il risultato di un'altra ricorsione. Quindi, dopo un po' di volte che ripeti la ricorsione, hai un "coso" di questo tipo:

    (((((...) + S) + S) + S) + S)

    dove "..." rappresenta il livello di ricorsione che hai raggiunto attualmente. Arrivati all'ultima ricorsione, la funzione restituisce una stringa vuota e si ferma (cioè non chiama più se stessa). Quindi, dopo l'ultima ricorsione, tu avrai un "coso" finale di questo tipo:

    (((((("") + S) + S) + S) + S) + S)

    che è ovviamente la somma di varie stringhe, ossia una stringa. In altre parole, la stringa finale è il risultato dell'accumulo progressivo delle "stringhe-resto" prodotte a ogni successiva ricorsione, più l'ultima stringa vuota di chiusura. (Le "stringhe-resto", come spero avrai capito, sono i resti convertiti in stringa: questo algoritmo mappa la procedura che faresti con carta e penna per convertire un intero decimale in binario).





    Esercizio numero 1: che cosa garantisce che a un certo punto la funzione "esca", e non continui a ricorrere all'infinito? Ovvero, che cosa garantisce che si arrivi sempre, a un certo punto, allo zero e quindi a chiamare "binario(0)"?

    Esercizio numero 2: che cosa succede se, arrivati a zero, la funzione non esce restituendo la stringa vuota, ma qualsiasi altra cosa? Cioè, per esempio, se scrivo:
    def binario(n):
        if n==0:
            return None # o "return 42", o "return False", qualunque cosa
        etc etc etc come sopra
    
    La funzione "funziona" ancora? E perché?

    Esercizio numero 3: scritta in questo modo la funzione ha un piccolo baco: se chiami "binario(0)" il risultato è una stringa vuota, cosa ovviamente sbagliata. Il binario di 0 invece è "0", ovviamente. Il problema è che quando la funzione testa "if n==0" non riesce a distinguere se sta parlando proprio del numero originale oppure del numero che riceve a una ricorsione successiva. Cioè non riesce a distinguere se in quel momento sta eseguendo la prima ricorsione, o è già arrivata a una ricorsione successiva. Bisognerebbe correggere la funzione con qualcosa del genere:
    # pseudo-codice
    def binario(n):
        if n==0 and siamo-alla-prima-ricorsione:
            return "0"
        if n==0 and siamo-oltre-la-prima-ricorsione:
            return ""
        etc etc come sopra
    
    C'è un modo per fare questo? (questo esercizio è un po' più difficile. Forse puoi usarlo per fare l'ingenuo e trollare il tuo prof. C'è una discreta possibilità che così su due piedi non lo sappia fare neanche lui).





    Detto questo, il tuo problema resta lo stesso: posso guidarti per mano, centimetro dopo centimetro; posso farti un milione di esempi e di metafore; ma se non ci ragioni sopra con la tua testa, perderndoci una giornata (ma una giornata seria, intendo: col telefonino spento, senza distrazioni, senza musica... come si faceva una volta) non ci riuscirai mai. E' proprio qualcosa che ti scatta nella testa, e deve scattarti perché riesci a visualizzarlo alla tua maniera. Poi prova con gli esercizi che ti ho proposto, poi prova altre funzioni ricorsive, eccetera.


    La ricorsione non è difficile di per sé: tuttavia è oggettivamente difficile visualizzare il flusso del programma ricorsivo nella testa. C'è solo da mettersi lì con pazienza e carta e penna.
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



    Dovresti fare il professore nella mia università, oltre ad essere molto preparato sei anche molto gentile e disponibile ti ringrazio per il tempo dedicatomi, salvo inconvenevoli.
    Ho provato a fare gli esercizi in 30 minuti sono riuscito a ponderare queste soluzioni
    1= la condizione if n==0 si verifica sempre perche u numero fratto 2 per "n" volte alla fine torna 0 e quindi essendo una ricorsione prima o poi arriva a zero e fa verificare la condizione che fa uscire dal ciclo e attiva il return

    2= inizialmente pensavo che avrebbe funzionato sia che al posto di '' ci sia stati caratteri che numeri, invece provando ho visto che i numeri a meno che non metta <code> str(numero) </code> non funziona, a livello logico però ho compreso che in effetti python non permette di addizionare numeri e stringhe quindi okei. per quanto riguarda il none essendo una key in python non penso possa farlo
    3= in 20 minuti nella pausa pranzo ho pensato che un modo sarebbe :calcolare il LEN della str e mettere che se il len della str è =0 ti return '0' elif ti return ' ' , senno avevo anche pensati di printare un count ad ogni ciclo e se il count era a 0 e n==0 allora return '0'
    <code>





    def bin (n):
    if n==0 and len(str(n))==1:
    return '0'
    elif n==0:
    return ''

    return bin(n//2)+str(n%2)
    </code>
    pero non penso vada bene dopo trovo una soluzione e modifico il post se non mi hai ancora risposto.
    ancora grazie comunque













    --- Ultima modifica di andredatto in data 2018-11-21 13:39:34 ---



    --- Ultima modifica di andredatto in data 2018-11-21 13:41:21 ---


    --- Ultima modifica di andredatto in data 2018-11-21 13:41:53 ---
  • Re: Problema python in algoritmica
    Forum >> Principianti
    Non ci sono molte soluzioni per capire la ricorsione: bisogna mettersi lì con carta e penna e fare il conto, e poi rifarlo e rifarlo ancora finché non capisci come funziona. Per prima cosa, riscriviamo la funzione formattandola con l'apposito pulsante "code" (quello con il simbolo "<>") in modo che si capisca di che cosa parliamo:

    def binario(n):
        if n==0:
            return ''
         
    
    Ora, è chiaro che se ti metti con carta e penna a calcolare "binario(353646545521)" non ne esci vivo. Però carta e penna è l'unico modo, fidati. Proviamo insieme a calcolare cosa succede quando scrivi


    binario(5)  # dà "101", ovviamente
    Allora, sei pronto? Via:


    PRIMO PASSAGGIO: "binario(5)"
    - 5 è uguale a 0? No, andiamo avanti
    - 5%2 è uguale a 1. Quindi la stringa finale terminerà per "1"
    - 5//2 è uguale a 2. Quindi dobbiamo calcolare binario(2)
    - stato attuale: la stringa è "....1", e dobbiamo calcolare binario(2)

    SECONDO PASSAGGIO: "binario(2)"
    - 2 è uguale a 0? No, andiamo avanti
    - 2%2 è uguale a 0. Quindi aggiungiamo a sinistra uno "0" alla stringa finale
    - 2//2 è uguale a 1. Quindi dobbiamo calcolare binario(1)
    - stato attuale: la stringa è "...01", e dobbiamo calcolare binario(1)

    TERZO PASSAGGIO: "binario(1)"
    - 1 è uguale a 0? No, andiamo avanti
    - 1%2 è uguale a 1. Quindi aggiungiamo a sinistra un "1" alla stringa finale
    - 1//2 è uguale a 0. Quindi dobbiamo calcolare binario(0)
    - stato attuale: la stringa è "...101", e dobbiamo calcolare binario(0)

    QUARTO PASSAGGIO: "binario(0)"
    - 0 è uguale a 0? Sì, quindi aggiungiamo una stringa vuota ("") a sinistra alla stringa finale, e usciamo
    - stato attuale: la stringa è "101", e non dobbiamo calcolare più nessuna ricorsione.

    Risultato: "101"

    Se non sei riuscito a seguire questi passaggi, ripetili con carta e penna finché non ci riesci. Se ci sei riuscito, prova almeno altre cinque volte con carta e penna a fare altri calcoli semplici (binario(3), binario(7), binario(9)...) finché non hai interiorizzato come funziona. Purtroppo la ricorsione funziona così, devi trovare il modo di immaginarti nella testa lo stack delle chiamate successive e i risultati parziali.




    --- Ultima modifica di RicPol in data 2018-11-20 21:49:07 ---
    grazie mille una risposta molto esaudiente e completa complimenti hai dato un significato ad ogni concetto espresso e mi hai "passato" un po del tuo ragionamento, in questo caso ho capito quasi tutto escluso <code> return binario(n//2) + str(n%2)
    non capisco perche invece di fare la somma fra n//2 +stri(n%2) salva str(n%2) in una stringa prima di fare n//2, piu che non ho capito diciamo che non ho ben chiaro forse riguardandolo un po' potrei trovarci una logica. Visto che sei stato molto bravo hai dei consigli o delle guide per quanto riguarda queste cose ?
  • Problema python in algoritmica
    Forum >> Principianti
    salve a tutti sto studiando algoritmica per un esame universitario e mi sono trovato un po in difficolta con questa semplice ricorsione che ora vi mostro: so che ci sono delle librerie per fare lo stesso ma non è quello il punto, mi serve riuscire a capire bene un algoritmo :question: :question:
    def binario(n):

    if n == 0 : #condizione

    return ' ' #non so cosa sia forse una sorta di pass o rende stringa il numero :question:

    return binario(n//2)+str(n%2) #richiama la funzione e quindi divide escludendo i decimali n finche non diventa = 0 salva il modulo 2 di ogni n che viene diviso come stringa. non capisco bene il +str forse perche non si sommano i valori dato che è diventato una str




    print(binario(353646545521))

    allora io interpreto questa funzione in questo modo, utilizzo if per controllare che n non sia 0 se non lo è mi divide il numero messo in in input(353646545521) escludendo i decimali e sommando il modulo dello stesso numero come stringa, essendo richiamata la funzione divide il numero n volte finche n non torna 0, a quel punto non capisco che cosa ci sta a fare il return ' ' , so cosa fa la funzione stampa il binario del numero facendo il modulo di n piu il modulo di n//2 ecc finche non viene 0 e considera il risultato come stringa ma non riesco proprio a capire bene se è essenziale return o funge come una sorta di condizione passiva che serve solo a fermare la funzione, qualcuno che mi delucidi un po?

    grazie mille in anticipo