Julia. Pembuat Laporan dan Dokumen


Salah satu masalah mendesak setiap saat adalah masalah menyiapkan laporan. Karena Julia adalah bahasa yang penggunanya terhubung langsung dengan tugas-tugas analisis data, menyiapkan artikel dan presentasi yang indah dengan hasil perhitungan dan laporan, topik ini tidak dapat diabaikan begitu saja.


Awalnya, artikel ini merencanakan serangkaian resep untuk menghasilkan laporan, tetapi di samping laporan adalah topik dokumentasi, dengan mana generator laporan memiliki banyak persimpangan. Oleh karena itu, ini termasuk alat untuk kriteria kemungkinan menanamkan kode executable Julia dalam templat dengan beberapa markup. Akhirnya, kami mencatat bahwa tinjauan termasuk generator laporan, keduanya diimplementasikan pada Julia itu sendiri, dan alat yang ditulis dalam bahasa pemrograman lain. Yah, tentu saja, beberapa poin kunci dari bahasa Julia sendiri tidak diabaikan, tanpanya mungkin tidak jelas dalam kasus apa dan cara apa yang harus digunakan.


Notebook Jupyter


Alat ini, mungkin, harus dikaitkan dengan yang paling populer di antara mereka yang terlibat dalam analisis data. Karena kemampuan untuk menghubungkan berbagai core komputasi, sangat populer dengan para peneliti dan ahli matematika yang terbiasa dengan bahasa pemrograman spesifik mereka, salah satunya adalah Julia. Modul yang sesuai untuk bahasa Julia sepenuhnya diterapkan untuk Jupyter Notebook. Dan itulah mengapa Notebook disebutkan di sini.
Proses pemasangan Notebook Jupyter tidak rumit. Untuk pemesanan, lihat https://github.com/JuliaLang/IJulia.jl Jika Jupyter Notebook sudah diinstal, Anda hanya perlu menginstal paket Ijulia dan mendaftarkan inti komputasi yang sesuai.


Karena produk Notebook Jupyter cukup dikenal untuk tidak menuliskannya secara rinci, kami hanya akan menyebutkan beberapa poin. Notepad (kami akan menggunakan terminologi notepad) di Jupyter Notebook terdiri dari blok, yang masing-masing dapat berisi kode atau markup dalam berbagai bentuknya (misalnya, Penurunan harga). Hasil pemrosesan adalah visualisasi markup (teks, rumus, dll.), Atau hasil dari operasi terakhir. Jika titik koma ditempatkan di akhir baris dengan kode, hasilnya tidak akan ditampilkan.


Contohnya. Notebook sebelum eksekusi ditunjukkan pada gambar berikut:



Hasil implementasinya ditunjukkan pada gambar berikut.



Notepad berisi gambar dan beberapa teks. Perhatikan bahwa untuk menampilkan matriks, dimungkinkan untuk menggunakan tipe DataFrame , yang hasilnya ditampilkan dalam bentuk tabel html dengan batas eksplisit dan penggulung, jika perlu.


Notebook Jupyter dapat mengekspor notebook saat ini ke file html. Jika ada alat konversi yang diinstal, itu dapat dikonversi ke pdf.


Untuk membuat laporan berdasarkan beberapa peraturan, Anda dapat menggunakan modul nbconvert dan perintah berikut, yang dipanggil di latar belakang sesuai dengan jadwal:
jupyter nbconvert --to html --execute julia_filename.ipynb


Saat melakukan perhitungan panjang, disarankan untuk menambahkan opsi yang menunjukkan batas waktu - --ExecutePreprocessor.timeout=180


Laporan html yang dihasilkan dari file ini akan muncul di direktori saat ini. Opsi --execute sini berarti memaksa penghitungan ulang dimulai.


Untuk satu set lengkap nbconvert modul nbconvert lihat
https://nbconvert.readthedocs.io/en/latest/usage.html


Hasil konversi ke html hampir sepenuhnya konsisten dengan gambar sebelumnya, kecuali bahwa ia tidak memiliki bilah menu atau tombol.


Jupytext


Utilitas yang agak menarik yang memungkinkan Anda untuk mengubah catatan ipynb yang dibuat sebelumnya menjadi teks Markdown atau kode Julia.


Kita dapat mengubah contoh yang sebelumnya dipertimbangkan menggunakan perintah
jupytext --to julia julia_filename.ipynb


Hasilnya, kami mendapatkan file julia_filename.jl dengan kode Julia dan markup khusus dalam bentuk komentar.


 # --- # jupyter: # jupytext: # text_representation: # extension: .jl # format_name: light # format_version: '1.3' # jupytext_version: 0.8.6 # kernelspec: # display_name: Julia 1.0.3 # language: julia # name: julia-1.0 # --- # # Report example using Plots, DataFrames # ### Drawing # Good time to show some plot plot(rand(5,5), linewidth=2, title="My Plot", size = (500, 200)) # ## Some computational results rand(2, 3) DataFrame(rand(2, 3)) 

Catatan pemisah blok hanyalah umpan garis ganda.


Kita dapat melakukan transformasi terbalik menggunakan perintah:
jupytext --to notebook julia_filename.jl


Akibatnya, file ipynb akan dihasilkan, yang, pada gilirannya, dapat diproses dan dikonversi ke pdf atau html.


Lihat detail https://github.com/mwouts/jupytext


Kelemahan umum jupytext dan jupyter notebook adalah bahwa "keindahan" laporan dibatasi oleh kemampuan alat-alat ini.


HTML yang dihasilkan sendiri


Jika karena alasan tertentu kami percaya bahwa Notebook Jupyter adalah produk yang terlalu berat, membutuhkan instalasi berbagai paket pihak ketiga yang tidak diperlukan Julia untuk bekerja, atau tidak cukup fleksibel untuk membuat formulir laporan yang kami butuhkan, maka cara alternatif adalah membuat halaman html secara manual. Namun, di sini Anda harus menyelami sedikit ke dalam fitur pencitraan.


Untuk Julia, cara khas untuk mengeluarkan sesuatu ke aliran keluaran adalah dengan menggunakan fungsi Base.write , dan untuk dekorasi, Base.show(io, mime, x) . Selain itu, untuk berbagai metode output mime yang diminta, mungkin ada berbagai opsi tampilan. Misalnya, DataFrame saat ditampilkan sebagai teks ditampilkan oleh tabel pseudo-grafik.


 julia> show(stdout, MIME"text/plain"(), DataFrame(rand(3, 2))) 3×2 DataFrame │ Row │ x1 │ x2 │ │ │ Float64 │ Float64 │ ├─────┼──────────┼───────────┤ │ 1 │ 0.321698 │ 0.939474 │ │ 2 │ 0.933878 │ 0.0745969 │ │ 3 │ 0.497315 │ 0.0167594 │ 

Jika, mime ditentukan sebagai text/html , maka hasilnya adalah markup HTML.


 julia> show(stdout, MIME"text/html"(), DataFrame(rand(3, 2))) <table class="data-frame"> <thead> <tr><th></th><th>x1</th><th>x2</th></tr> <tr><th></th><th>Float64</th><th>Float64</th></tr> </thead> <tbody><p>3 rows × 2 columns</p> <tr><th>1</th><td>0.640151</td><td>0.219299</td></tr> <tr><th>2</th><td>0.463402</td><td>0.764952</td></tr> <tr><th>3</th><td>0.806543</td><td>0.300902</td></tr> </tbody> </table> 

Artinya, dengan menggunakan metode fungsi show ditentukan untuk tipe data yang sesuai (argumen ketiga) dan format output yang sesuai, adalah mungkin untuk memastikan pembentukan file dalam format data yang diinginkan.


Situasi dengan gambar lebih rumit. Jika kita perlu membuat satu file html tunggal, maka gambar tersebut harus tertanam dalam kode halaman.


Pertimbangkan contoh penerapannya. Output ke file akan dilakukan oleh fungsi Base.write , untuk itu kami mendefinisikan metode yang sesuai. Jadi kodenya:


 #!/usr/bin/env julia using Plots using Base64 using DataFrames #        p = plot(rand(5,5), linewidth=2, title="My Plot", size = (500, 200)) #  ,  ,    @show typeof(p) # => typeof(p) = Plots.Plot{Plots.GRBackend} #    ,   3  #     abstract type Png end abstract type Svg end abstract type Svg2 end #  Base.write      #         #   —   ,  #   Base64-. #  HTML  img src="data:image/png;base64,..." function Base.write(file::IO, ::Type{Png}, p::Plots.Plot) local io = IOBuffer() local iob64_encode = Base64EncodePipe(io); show(iob64_encode, MIME"image/png"(), p) close(iob64_encode); write(file, string("<img src=\"data:image/png;base64, ", String(take!(io)), "\" alt=\"fig.png\"/>\n")) end #     Svg function Base.write(file::IO, ::Type{Svg}, p::Plots.Plot) local io = IOBuffer() show(io, MIME"image/svg+xml"(), p) write(file, replace(String(take!(io)), r"<\?xml.*\?>" => "" )) end #    XML-  ,  SVG Base.write(file::IO, ::Type{Svg2}, p::Plots.Plot) = show(file, MIME"image/svg+xml"(), p) #     DataFrame Base.write(file::IO, df::DataFrame) = show(file, MIME"text/html"(), df) #   out.html   HTML open("out.html", "w") do file write(file, """ <!DOCTYPE html> <html> <head><title>Test report</title></head> <body> <h1>Test html</h1> """) write(file, Png, p) write(file, "<br/>") write(file, Svg, p) write(file, "<br/>") write(file, Svg2, p) write(file, DataFrame(rand(2, 3))) write(file, """ </body> </html> """) end 

Untuk membuat gambar, mesin Plots.GRBackend digunakan secara default, yang dapat melakukan output gambar raster atau vektor. Bergantung pada jenis apa yang ditentukan dalam argumen mime dari fungsi show , hasil yang sesuai dihasilkan. MIME"image/png"() membentuk gambar dalam format png . MIME"image/svg+xml"() menghasilkan gambar svg. Namun, dalam kasus kedua, Anda harus memperhatikan fakta bahwa dokumen xml yang sepenuhnya independen terbentuk, yang dapat ditulis sebagai file terpisah. Pada saat yang sama, tujuan kami adalah untuk menanamkan gambar di halaman HTML, yang dalam HTML5 dapat dilakukan dengan hanya memasukkan markup SVG. Itulah sebabnya metode Base.write(file::IO, ::Type{Svg}, p::Plots.Plot) memotong header xml, yang, jika tidak, akan melanggar struktur dokumen HTML. Meskipun, sebagian besar browser dapat menampilkan gambar dengan benar bahkan dalam kasus ini.


Mengenai metode untuk Base.write(file::IO, ::Type{Png}, p::Plots.Plot) , fitur implementasi di sini adalah bahwa kita hanya dapat memasukkan data biner ke dalam HTML dalam format Base64. Kami melakukan ini menggunakan konstruksi <img src="data:image/png;base64,"/> . Dan untuk transcoding kami menggunakan Base64EncodePipe .


Metode Base.write(file::IO, df::DataFrame) memberikan output dalam format tabel-html objek DataFrame .


Halaman yang dihasilkan adalah sebagai berikut:



Pada gambar, ketiga gambar terlihat kurang lebih sama, namun, ingat bahwa salah satunya dimasukkan secara salah dari sudut pandang HTML (header xml ekstra). Salah satunya adalah raster, yang berarti tidak dapat ditingkatkan tanpa kehilangan detail. Dan hanya satu yang dimasukkan sebagai fragmen svg yang benar di dalam markup HTML. Dan itu dapat dengan mudah diskalakan tanpa kehilangan detail.


Secara alami, halaman tersebut ternyata sangat sederhana. Tetapi peningkatan visual apa pun dimungkinkan dengan CSS.


Metode menghasilkan laporan ini berguna, misalnya, ketika jumlah tabel yang ditampilkan ditentukan oleh data nyata, dan bukan oleh templat. Misalnya, Anda perlu mengelompokkan data menurut beberapa bidang. Dan untuk setiap kelompok membentuk blok terpisah. Karena ketika membuat halaman, hasilnya ditentukan oleh jumlah panggilan ke Base.write , jelas bahwa tidak ada masalah membungkus blok yang diinginkan dalam satu lingkaran, membuat output tergantung pada data, dll.


Contoh kode:


 using DataFrames #       ptable = DataFrame( Symbol = ["H", "He", "C", "O", "Fe" ], Room = [:Gas, :Gas, :Solid, :Gas, :Solid] ) res = groupby(ptable, [:Room]) #      open("out2.html", "w") do f for df in (groupby(ptable, [:Room])) write(f, "<h2>$(df[1, :Room])</h2>\n") show(f, MIME"text/html"(), DataFrame(df)) write(f, "\n") end end 

Hasil skrip ini adalah sebuah fragmen dari halaman HTML.



Harap dicatat bahwa segala sesuatu yang tidak memerlukan konversi dekorasi / format ditampilkan langsung melalui fungsi Base.write . Pada saat yang sama, semua yang membutuhkan konversi adalah output melalui Base.show .


Weave.jl


Weave adalah pembuat laporan ilmiah yang dilaksanakan oleh Julia. Menggunakan ide-ide generator Pweave, Knitr, rmarkdown, Sweave. Tugas utamanya adalah untuk mengekspor markup sumber dalam salah satu bahasa yang diusulkan (Noweb, Markdown, format skrip) ke LaTex, Pandoc, penurunan harga Github, MultiMarkdown, Asciidoc, format reStructuredText. Dan, bahkan di IJulia Notebooks dan sebaliknya. Pada bagian terakhir, mirip dengan Jupytext.


Yaitu, Weave adalah alat yang memungkinkan Anda untuk menulis template yang berisi kode Julia dalam berbagai bahasa markup, dan pada output memiliki markup dalam bahasa lain (tetapi dengan hasil eksekusi kode Julia). Dan ini adalah alat yang sangat berguna khusus untuk para peneliti. Misalnya, Anda dapat menyiapkan artikel tentang Lateks, yang akan menyisipkan Julia dengan perhitungan otomatis hasil dan substitusi. Weave akan menghasilkan file untuk artikel terakhir.


Ada dukungan untuk editor Atom menggunakan plugin yang sesuai https://atom.io/packages/language-weave . Ini memungkinkan Anda untuk mengembangkan dan men-debug skrip Julia yang tertanam di markup, dan kemudian menghasilkan file target.


Prinsip dasar dalam Weave, seperti yang telah disebutkan, adalah mengurai templat yang berisi markup dengan teks (rumus, dll.) Dan menempelkan kode pada Julia. Hasil eksekusi kode dapat ditampilkan dalam laporan akhir. Output teks, kode, output hasil, output grafik - semua ini dapat dikonfigurasikan secara individual.


Untuk memproses template, Anda perlu menjalankan skrip eksternal yang akan mengumpulkan semuanya menjadi satu dokumen dan mengonversinya menjadi format output yang diinginkan. Yaitu, templat secara terpisah, penangan secara terpisah.


Contoh dari skrip pemrosesan seperti itu:


 #     : # Markdown weave("w_example.jmd", doctype="pandoc" out_path=:pwd) # HTML weave("w_example.jmd", out_path=:pwd, doctype = "md2html") # pdf weave("w_example.jmd", out_path=:pwd, doctype = "md2pdf") 

jmd dalam nama file adalah Julia Markdown.


Ambil contoh yang sama yang kami gunakan di alat sebelumnya. Namun, kami akan memasukkan judul dengan informasi tentang penulis yang dipahami Weave.


 --- title : Intro to Weave.jl with Plots author : Anonymous date : 06th Feb 2019 --- # Intro ## Plot ` ``{julia;} using Plots, DataFrames plot(rand(5,5), linewidth=2, title="My Plot", size = (500, 200)) ` `` ## Some computational results ` ``julia rand(2, 3) ` `` ` ``julia DataFrame(rand(2, 3)) ` `` 

Fragmen ini, yang dikonversi ke pdf, terlihat seperti ini:



Font dan tata letak dikenali dengan baik oleh pengguna Lateks.


Untuk setiap bagian dari kode yang disematkan, Anda dapat menentukan bagaimana kode ini akan diproses dan apa yang akan ditampilkan pada akhirnya.


Sebagai contoh:


  • echo = true - kode akan ditampilkan
  • eval = true - hasil eksekusi kode akan ditampilkan
  • label - tambahkan label. Jika Lateks digunakan, maka itu akan digunakan sebagai label ara :.
  • fig_width, fig_height - ukuran gambar
  • dan sebagainya

Untuk format noweb dan skrip, serta lebih lanjut tentang alat ini, lihat http://weavejl.mpastell.com/stable/


Literate.jl


Penulis paket ini, ketika ditanya mengapa Literate, merujuk pada paradigma Pemrograman Literate Donald Knutt. Tugas alat ini adalah membuat dokumen berdasarkan kode Julia yang berisi komentar dalam format penurunan harga. Tidak seperti alat Weave yang diperiksa sebelumnya, ia tidak dapat membuat dokumen dengan hasil eksekusi. Namun, alat ini ringan dan terutama berfokus pada pendokumentasian kode. Misalnya, bantu dalam menulis contoh indah yang dapat ditempatkan pada platform penurunan harga apa pun. Sering digunakan dalam rangkaian alat dokumentasi lain, misalnya, bersama dengan Documenter.jl .


Ada tiga opsi yang mungkin untuk format output - penurunan harga, notebook dan skrip (kode Julia murni). Tak satu pun dari mereka akan menjalankan kode yang diterapkan.


Contoh file sumber dengan komentar penurunan harga (setelah karakter pertama #):


 #!/usr/bin/env julia using Literate Literate.markdown(@__FILE__, pwd()) # documenter=true # # Intro # ## Plot using Plots, DataFrames plot(rand(5,5), linewidth=2, title="My Plot", size = (500, 200)) # ## Some computational results rand(2, 3) DataFrame(rand(2, 3)) 

Hasil karyanya akan menjadi dokumen Markdown dan arahan untuk Documenter , jika generasinya belum dinonaktifkan secara eksplisit.


 ` ``@meta EditURL = "https://github.com/TRAVIS_REPO_SLUG/blob/master/" ` `` ` ``@example literate_example #!/usr/bin/env julia using Literate Literate.markdown(@__FILE__, pwd(), documenter=true) ` `` # Intro ## Plot ` ``@example literate_example using Plots, DataFrames plot(rand(5,5), linewidth=2, title="My Plot", size = (500, 200)) ` `` ## Some computational results ` ``@example literate_example rand(2, 3) DataFrame(rand(2, 3)) ` `` *This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* 

Sisipan kode di dalam penurunan harga di sini sengaja dimasukkan dengan jarak antara tanda kutip pertama dan berikutnya, agar tidak rusak saat menerbitkan artikel.


Lihat lebih detail https://fredrikekre.imtqy.com/Literate.jl/stable/


Documenter.jl


Generator Dokumentasi. Tujuan utamanya adalah untuk membentuk dokumentasi yang dapat dibaca untuk paket yang ditulis dalam Julia. Documenter mengonversi contoh html atau pdf dengan markup Markdown dan kode Julia yang disematkan, serta file sumber modul, mengekstraksi dokumen-dokumen Julia (komentar Julia sendiri).


Contoh dokumentasi khas:



Dalam artikel ini kita tidak akan membahas prinsip-prinsip dokumentasi, karena, dengan cara yang baik, ini harus dilakukan sebagai bagian dari artikel terpisah tentang pengembangan modul. Namun, kita akan melihat beberapa aspek Documenter di sini.


Pertama-tama, perlu memperhatikan fakta bahwa layar dibagi menjadi dua bagian - sisi kiri berisi daftar isi interaktif. Sisi kanan sebenarnya adalah teks dokumentasi.


Struktur direktori yang khas dengan contoh dan dokumentasi adalah sebagai berikut:


  docs/ src/ make.jl src/ Example.jl ... 

Direktori docs/src adalah dokumentasi penurunan harga. Dan contoh ditemukan di suatu tempat di direktori sumber shared src .


File kunci untuk Docuementer adalah docs/make.jl Isi file ini untuk Documenter itu sendiri:


 using Documenter, DocumenterTools makedocs( modules = [Documenter, DocumenterTools], format = Documenter.HTML( # Use clean URLs, unless built as a "local" build prettyurls = !("local" in ARGS), canonical = "https://juliadocs.imtqy.com/Documenter.jl/stable/", ), clean = false, assets = ["assets/favicon.ico"], sitename = "Documenter.jl", authors = "Michael Hatherly, Morten Piibeleht, and contributors.", analytics = "UA-89508993-1", linkcheck = !("skiplinks" in ARGS), pages = [ "Home" => "index.md", "Manual" => Any[ "Guide" => "man/guide.md", "man/examples.md", "man/syntax.md", "man/doctests.md", "man/latex.md", hide("man/hosting.md", [ "man/hosting/walkthrough.md" ]), "man/other-formats.md", ], "Library" => Any[ "Public" => "lib/public.md", hide("Internals" => "lib/internals.md", Any[ "lib/internals/anchors.md", "lib/internals/builder.md", "lib/internals/cross-references.md", "lib/internals/docchecks.md", "lib/internals/docsystem.md", "lib/internals/doctests.md", "lib/internals/documenter.md", "lib/internals/documentertools.md", "lib/internals/documents.md", "lib/internals/dom.md", "lib/internals/expanders.md", "lib/internals/mdflatten.md", "lib/internals/selectors.md", "lib/internals/textdiff.md", "lib/internals/utilities.md", "lib/internals/writers.md", ]) ], "contributing.md", ], ) deploydocs( repo = "github.com/JuliaDocs/Documenter.jl.git", target = "build", ) 

Seperti yang Anda lihat, metode utama di sini adalah makedocs dan deploydocs , yang menentukan struktur dokumentasi di masa depan dan tempat penempatannya. makedocs menyediakan formasi markdown markup dari semua file yang ditentukan, yang meliputi eksekusi kode tertanam dan ekstraksi komentar dokumen.


Documenter mendukung sejumlah arahan untuk memasukkan kode. Formatnya adalah `` @something


  • @docs , @autodocs - tautan ke dokumentasi dokumen diekstraksi dari file Julia.
  • @ref , @meta , @index , @contents - tautan, indikasi halaman indeks, dll.
  • @example , @repl , @eval - mode eksekusi kode Julia yang disematkan.
  • ...

Kehadiran arahan @example, @repl, @eval , pada kenyataannya, menentukan apakah akan menyertakan Documenter dalam ikhtisar ini atau tidak. Selain itu, Literate.jl disebutkan sebelumnya dapat secara otomatis menghasilkan markup tersebut, seperti yang ditunjukkan sebelumnya. Artinya, tidak ada batasan mendasar pada penggunaan generator dokumentasi sebagai generator laporan.


Untuk selengkapnya tentang Documenter.jl, lihat https://juliadocs.imtqy.com/Documenter.jl/stable/


Kesimpulan


Meskipun menggunakan bahasa Julia yang muda, paket dan alat sudah dikembangkan untuk memungkinkan kita untuk berbicara tentang penggunaan penuh dalam layanan yang sangat dimuat, dan bukan hanya tentang pelaksanaan proyek percobaan. Seperti yang Anda lihat, kemampuan untuk menghasilkan berbagai dokumen dan laporan, termasuk hasil eksekusi kode baik dalam teks dan dalam bentuk grafis, sudah disediakan. Selain itu, tergantung pada kompleksitas laporan, kita dapat memilih antara kemudahan membuat template dan fleksibilitas menghasilkan laporan.


Artikel ini tidak mempertimbangkan generator Flax dari paket Genie.jl. Genie.jl adalah upaya untuk mengimplementasikan Julia on Rails, dan Flax adalah sejenis analog dari eRubis dengan sisipan kode untuk Julia. Namun, Flax tidak disediakan sebagai paket terpisah, dan Genie tidak termasuk dalam repositori paket utama, jadi itu tidak termasuk dalam ulasan ini.


Secara terpisah, saya ingin menyebutkan paket Makie.jl dan Luxor.jl , yang menyediakan pembentukan visualisasi vektor yang kompleks. Hasil pekerjaan mereka juga dapat digunakan sebagai bagian dari laporan, tetapi artikel terpisah juga harus ditulis tentang ini.


Referensi


Source: https://habr.com/ru/post/id439442/


All Articles