Buat Grafik Panggilan

11

Saya memelihara basis kode lama yang ditulis dengan python. Khususnya ada potongan kode kompleks yang dari modul memanggil fungsi lain dari modul lain yang memanggil fungsi lain dan seterusnya. Ini bukan OOP, hanya fungsi dan modul.
Saya sudah mencoba untuk melacak di mana aliran dimulai dan berakhir kapan saja saya memanggil fungsi utama tetapi saya merasa saya harus menggambar ini karena saya tersesat di sub-panggilan.

Yang menjadi perhatian saya adalah bahwa setiap fungsi memanggil beberapa fungsi eksternal di dalam tubuh mereka untuk menyelesaikan tugas mereka dan mengembalikan nilai ke pemanggil.

Bagaimana saya bisa menggambar ini? Berarti bagan / grafik seperti apa yang sesuai untuk mendokumentasikan perilaku / kode semacam ini?

Jadi, saya pikir tidak akan berguna untuk menggambar diagram UML, tidak juga diagram alur. Grafik panggilan, mungkin?

Leonardo
sumber
doxygen - akan menghasilkan grafik panggilan / pemanggil, saya tidak yakin berapa banyak dukungan yang dimilikinya untuk python. Saya tahu Anda dapat mendokumentasikan kode python untuk itu.
gbjbaanb
Saya sudah mencoba pycallgraph tetapi terlalu rumit / terlalu dalam untuk menggunakannya. Ini karena kompleksitas kode saya karena mencampur python polos dengan Django dan panggilan eksternal ke url API. Itu sebabnya saya ingin menggambar dengan tangan hanya dengan mempertimbangkan bagian yang relevan yang saya butuhkan. Masalahnya adalah saya tidak tahu grafik seperti apa yang harus digunakan untuk memiliki pemahaman penuh tentang sistem
Leonardo
5
Jika ini hanya untuk membantu Anda memahaminya, cukup gambar apa pun yang muncul secara alami. Anda selalu dapat merapikannya nanti jika masuk ke dokumentasi formal.
jonrsharpe

Jawaban:

9

Saya pikir apa yang Anda cari di sini adalah Diagram Urutan . Ini memungkinkan Anda untuk memvisualisasikan urutan berbagai modul memanggil satu sama lain melalui penggunaan panah.

Membangunnya sederhana:

  1. Gambarlah kelas awal Anda dengan garis putus-putus di bawahnya.
  2. Gambarlah kelas / metode berikutnya dalam jejak panggilan dengan garis putus-putus di bawahnya
  3. Hubungkan garis dengan panah, diposisikan secara vertikal di bawah panah terakhir yang Anda gambar
  4. Ulangi langkah 2-3 untuk semua panggilan dalam penelusuran Anda

Contoh

Mari kita asumsikan kita memiliki kode berikut yang ingin kita buat diagram urutan:

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")

Hal pertama yang akan kita gambar adalah titik masuk ( main) yang terhubung ke metode long_division. Perhatikan bahwa ini membuat kotak di long_division, menandakan ruang lingkup metode panggilan. Untuk contoh sederhana ini, kotak akan menjadi seluruh ketinggian diagram urutan kami karena fakta bahwa ini adalah satu-satunya yang berjalan.

masukkan deskripsi gambar di sini

Sekarang kami menelepon find_largest_fituntuk menemukan kelipatan terbesar yang sesuai dengan nomor kerja kami, dan mengembalikannya kepada kami. Kami menarik garis dari long_divisionke find_largest_fitdengan kotak lain untuk menandakan ruang lingkup untuk panggilan fungsi. Perhatikan bagaimana kotak berakhir ketika pengganda dikembalikan; ini adalah akhir dari lingkup fungsi!

masukkan deskripsi gambar di sini

Ulangi beberapa kali untuk jumlah yang lebih besar dan bagan Anda akan terlihat seperti ini:

masukkan deskripsi gambar di sini

Catatan

Anda dapat memilih apakah Anda ingin memberi label panggilan dengan nama variabel yang disahkan, atau nilainya jika Anda hanya ingin mendokumentasikan satu kasus tertentu. Anda juga dapat menampilkan rekursi dengan fungsi yang memanggil dirinya sendiri.

Selain itu, Anda dapat menampilkan pengguna di sini dan meminta mereka dan menunjukkan input mereka ke dalam sistem dengan cukup mudah. Ini adalah sistem yang cukup fleksibel yang saya pikir Anda akan menemukan sedikit berguna!

Ampt
sumber
Terima kasih, saya tahu diagram urutan, tetapi saya merasa lebih cocok untuk oop. Dalam kasus saya, masalahnya sedikit lebih berantakan, artinya misalnya saya memiliki sekitar 20 fungsi / pembantu yang tersebar di beberapa modul. Bagaimana saya menentukan modul yang memiliki fungsi? Mempertimbangkan bahwa beberapa fungsi juga diganti namanya selama impor ..
Leonardo
1
Saya akan mengatakan bahwa tidak masalah berapa banyak modul yang Anda miliki - contoh di atas tidak sama sekali. Cukup beri nama sehingga Anda dapat menemukannya nanti, ModuleA / function1, ModuleB / Function2 dll. Untuk 20 fungsi ini akan menjadi lebih besar, tapi jelas bukan tidak mungkin untuk dipahami. Pemikiran lain yang dapat Anda lakukan adalah mengakhiri garis untuk fungsi setelah penggunaan terakhir dan meletakkan garis fungsi lain di bawahnya untuk menghemat ruang horisontal dalam diagram Anda.
Ampt
5

Saya pikir grafik panggilan akan menjadi visualisasi yang paling tepat. Jika Anda memutuskan untuk tidak melakukannya dengan tangan, ada alat kecil yang bagus pyanyang melakukan analisis statis pada file python dan dapat menghasilkan grafik panggilan yang divisualisasikan melalui file graphviz dot (yang dapat dirender menjadi gambar). Ada beberapa garpu, tetapi yang berfitur lengkap tampaknya https://github.com/davidfraser/pyan .

Anda hanya perlu menentukan semua file yang ingin Anda proses ketika Anda menjalankan perintah:

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

atau

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

Anda dapat membuat grafik lebih bersih dengan '-n' yang menghilangkan garis yang menunjukkan di mana fungsi didefinisikan.

seren
sumber