Disegna un grafico di chiamata

10

Sto mantenendo una vecchia base di codice scritta in python. In particolare c'è una parte di codice complessa che da un modulo chiama altre funzioni da altri moduli che chiamano altre funzioni e così via. Non è OOP, solo funzioni e moduli.
Ho cercato di tenere traccia di dove inizia e termina il flusso ogni volta che chiamo la funzione principale, ma sento che ho bisogno di disegnare questo perché mi sto perdendo nelle sub-chiamate.

Ciò che mi preoccupa è che ogni funzione chiama più funzioni esterne all'interno del proprio corpo per completare il proprio compito e restituire il valore al chiamante.

Come posso disegnare questo? Che tipo di grafico / grafico sarebbe appropriato per documentare questo tipo di comportamento / codice?

Quindi, non penso sarebbe utile disegnare un diagramma UML, né un diagramma di flusso. Un grafico di chiamata, forse?

    
posta Leonardo 21.04.2015 - 12:29
fonte

2 risposte

9

Penso che quello che stai cercando sia un diagramma di sequenza . Questi ti permettono di visualizzare l'ordine in cui i vari moduli si chiamano tramite l'uso delle frecce.

Costruire uno è semplice:

  1. Disegna la tua classe di partenza con una linea tratteggiata sotto di essa.
  2. Disegna la prossima classe / metodo nella traccia chiamata con una linea tratteggiata sotto quella
  3. Collega le linee con una freccia, posizionata verticalmente sotto l'ultima freccia disegnata
  4. Ripeti i passaggi 2-3 per tutte le chiamate nella traccia

Esempio

Supponiamo di avere il seguente codice che vogliamo creare un diagramma di sequenza per:

def long_division(quotient, divisor):
    solution = ""
    remainder = quotient
    working = ""
    while len(remainder) > 0:
        working += remainder[0]
        remainder = remainder[1:]
        multiplier = find_largest_fit(working, divisor)
        solution += multiplier
        working = calculate_remainder(working, multiplier, divisor)
    print solution


def calculate_remainder(working, multiplier, divisor):
    cur_len = len(working)
    int_rem = int(working) - (int(multiplier) * int (divisor))
    return "%*d" % (cur_len, int_rem)


def find_largest_fit(quotient, divisor):
    if int(divisor) == 0:
        return "0"
    i = 0
    while i <= 10:
        if (int(divisor) * i) > int(quotient):
            return str(i - 1)
        else:
            i += 1


if __name__ == "__main__":
    long_division("645", "5")

La prima cosa che disegneremo è il punto di ingresso ( main ) che si collega al metodo long_division . Si noti che questo crea una casella in long_division, che indica l'ambito della chiamata al metodo. Per questo semplice esempio, la casella sarà l'intera altezza del nostro diagramma di sequenza a causa del fatto che questa è l'unica cosa da eseguire.

Orachiamiamofind_largest_fitpertrovareilmultiplopiùgrandecherientranelnostronumerodilavoroecelorestituisce.Disegniamounalineadalong_divisionafind_largest_fitconun'altracasellaperindicarel'ambitodellachiamatadifunzione.Notacomefiniscelascatolaquandovienerestituitoilmoltiplicatore;questaèlafinediquestoambitodifunzioni!

Ripetialcunevolteperunnumeromaggioreeiltuograficodovrebbeavereunaspettosimileaquesto:

Note

Puoi scegliere se etichettare le chiamate con i nomi delle variabili passati, o i loro valori se vuoi solo documentare un caso specifico. Puoi anche mostrare la ricorsione con una funzione che chiama se stessa.

Inoltre, puoi mostrare gli utenti qui e richiamarli e mostrare il loro input nel sistema abbastanza facilmente. È un sistema abbastanza flessibile che penso che troverai piuttosto utile!

    
risposta data 19.01.2016 - 00:14
fonte
3

Penso che un grafico di chiamata sarebbe la visualizzazione più appropriata. Se decidi di non farlo a mano, c'è un piccolo strumento chiamato pyan che esegue l'analisi statica su un file python e può generare un grafico di chiamata visualizzato tramite un file di punti graphviz (che può essere reso a un'immagine) . Ci sono state un paio di fork, ma il più completo sembra essere link .

Devi solo specificare tutti i file che vuoi vengano elaborati quando esegui il comando:

python ~/bin/pyan.py --dot a.py b.py c.py -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

o

python ~/bin/pyan.py --dot $(find . -name '*.py') -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

Puoi rendere il pulitore dei grafici con '-n' che rimuove le linee che mostrano dove è stata definita una funzione.

    
risposta data 23.06.2017 - 18:00
fonte

Leggi altre domande sui tag