Saya tidak benar-benar menulis proyek besar. Saya tidak memelihara database besar atau berurusan dengan jutaan baris kode.
Kode saya terutama "jenis scripting" jenis - hal untuk menguji fungsi matematika, atau untuk mensimulasikan sesuatu - "pemrograman ilmiah". Program terpanjang yang saya kerjakan hingga saat ini adalah beberapa ratus baris kode, dan sebagian besar program yang saya kerjakan sekitar 150.
Kode saya juga omong kosong. Saya menyadari ini beberapa hari yang lalu ketika saya mencoba untuk menemukan file yang saya tulis beberapa waktu yang lalu tetapi saya mungkin menimpa dan bahwa saya tidak menggunakan kontrol versi, yang mungkin membuat banyak dari Anda merasa ngeri kesakitan karena kebodohan saya.
Gaya kode saya berbelit-belit dan dipenuhi dengan komentar usang yang mencatat cara alternatif untuk melakukan sesuatu atau dengan baris kode yang disalin. Sementara nama variabel selalu dimulai dengan sangat bagus dan deskriptif, karena saya menambahkan atau mengubah hal-hal sesuai misalnya, sesuatu yang baru ingin diuji seseorang, kode akan ditimpa di atas dan ditimpa dan karena saya merasa hal ini harus diuji dengan cepat sekarang karena saya punya kerangka saya mulai menggunakan nama variabel jelek dan file masuk ke pot.
Dalam proyek yang sedang saya kerjakan sekarang, saya berada dalam fase di mana semua ini kembali menggigit saya secara besar-besaran. Tetapi masalahnya adalah (selain menggunakan kontrol versi, dan membuat file baru untuk setiap iterasi baru dan merekam semuanya dalam file teks di suatu tempat, yang mungkin akan membantu situasi secara dramatis) Saya tidak benar-benar tahu bagaimana cara melanjutkan peningkatan gaya coding saya yang sebenarnya.
Apakah pengujian unit diperlukan untuk menulis potongan kode yang lebih kecil? Bagaimana dengan OOP? Apa jenis pendekatan yang baik untuk menulis kode yang baik dan bersih dengan cepat ketika melakukan "pemrograman ilmiah" sebagai lawan bekerja pada proyek yang lebih besar?
Saya mengajukan pertanyaan ini karena seringkali, pemrograman itu sendiri tidak super kompleks. Ini lebih tentang matematika atau sains yang saya uji atau teliti dengan pemrograman. Misalnya, apakah kelas diperlukan ketika dua variabel dan suatu fungsi mungkin bisa mengatasinya? (Pertimbangkan ini juga umumnya situasi di mana kecepatan program lebih disukai berada di ujung yang lebih cepat - ketika Anda menjalankan 25.000.000 langkah waktu simulasi, Anda agak menginginkannya.)
Mungkin ini terlalu luas, dan jika demikian, saya minta maaf, tetapi melihat buku-buku pemrograman, mereka sering kali ditujukan pada proyek yang lebih besar. Kode saya tidak perlu OOP, dan itu sudah sangat pendek sehingga tidak seperti "oh, tapi file akan berkurang seribu baris jika kita melakukannya!" Saya ingin tahu bagaimana "memulai" dan memprogram dengan bersih pada proyek-proyek yang lebih kecil dan lebih cepat ini.
Saya akan dengan senang hati memberikan rincian yang lebih spesifik, tetapi semakin umum sarannya, semakin berguna, saya pikir. Saya pemrograman dengan Python 3.
Seseorang menyarankan duplikat. Biarkan saya jelaskan saya tidak berbicara tentang mengabaikan standar pemrograman standar. Jelas, ada alasan standar itu ada. Tetapi di sisi lain, apakah masuk akal untuk menulis kode yang mengatakan OOP ketika beberapa hal standar dapat dilakukan, akan jauh lebih cepat untuk ditulis, dan akan memiliki tingkat keterbacaan yang sama karena pendeknya standar. program?
Ada pengecualian. Lebih jauh, mungkin ada standar untuk pemrograman ilmiah di luar standar biasa. Saya bertanya tentang itu juga. Ini bukan tentang apakah standar pengkodean normal harus diabaikan ketika menulis kode ilmiah, ini tentang menulis kode ilmiah bersih!
Memperbarui
Hanya berpikir saya akan menambahkan jenis pembaruan "tidak-cukup-satu-minggu-kemudian". Semua saran Anda sangat membantu. Saya sekarang menggunakan kontrol versi - git, dengan git kraken untuk antarmuka grafis. Ini sangat mudah digunakan, dan telah membersihkan file saya secara drastis - tidak perlu lagi ada file lama, atau kode versi lama berkomentar "berjaga-jaga".
Saya juga menginstal pylint dan menjalankannya pada semua kode saya. Satu file mendapat skor negatif pada awalnya; Aku bahkan tidak yakin bagaimana itu bisa terjadi. File utama saya dimulai pada skor ~ 1,83 / 10 dan sekarang berada di ~ 9,1 / 10. Semua kode sekarang sesuai dengan standar. Saya juga menabraknya dengan mata saya sendiri memperbarui nama variabel yang telah ... uhm ... salah, dan mencari bagian untuk refactor.
Secara khusus, saya mengajukan pertanyaan baru-baru ini di situs ini tentang refactoring salah satu fungsi utama saya, dan sekarang jauh lebih bersih dan jauh lebih pendek: alih-alih fungsi yang panjang, bengkak, jika diisi / diisi, sekarang kurang dari setengah ukuran dan lebih mudah untuk mencari tahu apa yang sedang terjadi.
Langkah saya berikutnya adalah menerapkan semacam "unit test". Maksud saya file yang bisa saya jalankan di file utama saya yang melihat semua fungsi di dalamnya dengan pernyataan tegas dan coba / pengecualian, yang mungkin bukan cara terbaik untuk melakukannya, dan menghasilkan banyak kode duplikat, tetapi saya akan terus membaca dan mencoba mencari cara untuk melakukannya dengan lebih baik.
Saya juga telah memperbarui secara signifikan dokumentasi yang telah saya tulis, dan menambahkan file tambahan seperti spreadsheet excel, dokumentasi, dan makalah terkait ke repositori github. Agak terlihat seperti proyek pemrograman nyata sekarang.
Jadi ... saya kira ini semua untuk mengatakan: terima kasih .
sumber
Jawaban:
Ini adalah masalah yang cukup umum bagi para ilmuwan. Saya sudah sering melihatnya, dan selalu bermula dari kenyataan bahwa pemrograman adalah sesuatu yang Anda pilih sebagai alat untuk melakukan pekerjaan Anda.
Jadi skrip Anda berantakan. Saya akan menentang akal sehat dan mengatakan bahwa, dengan asumsi Anda pemrograman sendiri, ini tidak terlalu buruk! Anda tidak akan pernah menyentuh sebagian besar dari apa yang Anda tulis lagi, jadi menghabiskan terlalu banyak waktu untuk menulis kode cantik alih-alih menghasilkan "nilai" (jadi hasil skrip Anda) tidak akan berbuat banyak untuk Anda.
Namun, akan ada saat di mana Anda harus kembali ke sesuatu yang Anda lakukan dan melihat dengan tepat bagaimana sesuatu itu bekerja. Selain itu, jika ilmuwan lain perlu meninjau kode Anda, sangat penting baginya untuk sejelas dan sesingkat mungkin, sehingga semua orang dapat memahaminya.
Masalah utama Anda adalah keterbacaan, jadi inilah beberapa tips untuk meningkatkan:
Nama variabel:
Para ilmuwan senang menggunakan notasi singkat. Semua persamaan matematika biasanya menggunakan huruf tunggal sebagai variabel, dan saya tidak akan terkejut melihat banyak dan banyak variabel sangat pendek dalam kode Anda. Ini menyakitkan keterbacaan banyak. Ketika Anda akan kembali ke kode Anda, Anda tidak akan mengingat apa yang diwakili oleh y, i dan x2, dan Anda akan menghabiskan banyak waktu untuk mencari tahu. Coba sebutkan variabel Anda secara eksplisit, menggunakan nama yang mewakili apa sebenarnya variabel itu.
Bagi kode Anda menjadi beberapa fungsi:
Sekarang setelah Anda mengganti nama semua variabel Anda, persamaan Anda tampak mengerikan, dan panjangnya banyak baris.
Alih-alih meninggalkannya di program utama Anda, pindahkan persamaan itu ke fungsi yang berbeda, dan beri nama sesuai. Sekarang alih-alih memiliki garis kode yang besar dan kacau, Anda akan memiliki instruksi singkat yang memberi tahu Anda dengan tepat apa yang terjadi dan persamaan apa yang Anda gunakan. Ini meningkatkan kedua program utama Anda, karena Anda bahkan tidak perlu melihat persamaan aktual untuk mengetahui apa yang Anda lakukan, dan kode persamaan itu sendiri, seperti dalam fungsi terpisah Anda dapat memberi nama variabel Anda seperti yang Anda inginkan, dan kembali ke satu huruf yang lebih akrab.
Pada garis pemikiran ini, cobalah untuk mencari tahu semua bagian kode yang mewakili sesuatu, terutama jika sesuatu itu adalah sesuatu yang harus Anda lakukan berulang kali dalam kode Anda, dan membaginya menjadi beberapa fungsi. Anda akan mengetahui bahwa kode Anda akan dengan cepat menjadi lebih mudah dibaca, dan Anda akan dapat menggunakan fungsi yang sama tanpa menulis lebih banyak kode.
Menghitung kue, jika fungsi-fungsi itu diperlukan di lebih dari program Anda, Anda bisa membuat perpustakaan untuk mereka, dan Anda akan selalu memilikinya.
Variabel global:
Kembali ketika saya masih pemula, saya pikir ini adalah cara yang bagus untuk menyampaikan data yang saya butuhkan di banyak titik program saya. Ternyata ada banyak cara lain untuk menyebarkan hal-hal, dan satu-satunya hal variabel global lakukan adalah membuat orang sakit kepala, karena jika Anda pergi ke titik acak program Anda, Anda tidak akan pernah tahu kapan nilai itu terakhir digunakan atau diedit, dan melacaknya akan menyebalkan. Cobalah untuk menghindarinya sedapat mungkin.
Jika fungsi Anda perlu mengembalikan atau memodifikasi beberapa nilai, buat kelas dengan nilai-nilai itu dan turunkan sebagai parameter, atau buat fungsi mengembalikan beberapa nilai (dengan nama tupel) dan tetapkan nilai-nilai itu dalam kode pemanggil.
Kontrol Versi
Ini tidak secara langsung meningkatkan keterbacaan, tetapi membantu Anda melakukan semua hal di atas. Setiap kali Anda melakukan beberapa perubahan, komit ke kontrol versi (repositori Git lokal akan cukup baik), dan jika sesuatu tidak berfungsi, lihat apa yang Anda ubah atau putar kembali! Ini akan membuat refactoring kode Anda lebih mudah, dan akan menjadi jaring pengaman jika Anda tidak sengaja memecahkan barang.
Mempertahankan semua ini dalam pikiran akan memungkinkan Anda untuk menulis kode yang jelas dan lebih efektif, dan juga akan membantu Anda menemukan kemungkinan kesalahan lebih cepat, karena Anda tidak perlu mengarungi fungsi-fungsi raksasa dan variabel-variabel yang berantakan.
sumber
Fisikawan di sini. Pernah ke sana.
Saya berpendapat bahwa masalah Anda bukan tentang pilihan alat atau paradigma pemrograman (pengujian unit, OOP, apa pun). Ini tentang sikap , pola pikir. Fakta bahwa nama variabel Anda dipilih dengan baik pada awalnya dan akhirnya menjadi omong kosong cukup mengungkapkan. Jika Anda menganggap kode Anda sebagai "jalankan sekali, lalu buang", maka itu pasti akan berantakan. Jika Anda menganggapnya sebagai produk kerajinan dan cinta, itu akan menjadi indah.
Saya percaya hanya ada satu resep untuk menulis kode bersih: tuliskan untuk manusia yang akan membacanya, bukan untuk penerjemah yang akan menjalankannya. Penerjemah tidak peduli jika kode Anda berantakan, tetapi pembaca manusia tidak peduli.
Anda seorang ilmuwan. Anda mungkin dapat menghabiskan banyak waktu memoles artikel ilmiah. Jika draf pertama Anda terlihat berbelit-belit, Anda akan refactor sampai logika mengalir dengan cara yang paling alami. Anda ingin kolega Anda membacanya dan menemukan argumen yang jelas. Anda ingin siswa Anda dapat belajar darinya.
Menulis kode bersih sama persis . Pikirkan kode Anda sebagai penjelasan terperinci dari suatu algoritma yang kebetulan hanya bisa dibaca mesin. Bayangkan Anda akan mempublikasikannya sebagai artikel yang akan dibaca orang. Anda bahkan akan menunjukkannya di sebuah konferensi dan mengajak hadirin melewatinya baris demi baris. Sekarang, latih presentasi Anda . Ya, baris demi baris ! Memalukan, bukan? Jadi bersihkan slide Anda (err ... maksud saya, kode Anda), dan latih kembali. Ulangi sampai Anda puas dengan hasilnya.
Akan lebih baik jika, setelah latihan, Anda dapat menunjukkan kode Anda kepada orang-orang nyata daripada hanya orang-orang imajiner dan diri masa depan Anda. Melewatinya baris demi baris disebut "kode berjalan", dan itu bukan praktik konyol.
Tentu saja, semua ini harus dibayar. Menulis kode bersih membutuhkan lebih banyak waktu daripada menulis kode yang bisa dibuang. Hanya Anda yang dapat mengevaluasi apakah manfaatnya lebih besar daripada biaya untuk kasus penggunaan khusus Anda.
Adapun alat, saya katakan sebelumnya mereka tidak begitu penting. Namun, jika saya harus memilih satu, saya akan mengatakan kontrol versi adalah yang paling berguna.
sumber
Kontrol versi mungkin akan memberi Anda hasil maksimal. Ini bukan hanya untuk penyimpanan jangka panjang, ini bagus untuk melacak eksperimen jangka pendek Anda dan kembali ke versi terakhir yang berfungsi, membuat catatan sepanjang jalan.
Berikutnya yang paling berguna adalah unit test. Satu hal tentang pengujian unit adalah bahkan basis kode dengan jutaan baris kode diuji unit satu fungsi pada suatu waktu. Pengujian unit dilakukan dalam skala kecil, pada tingkat abstraksi terendah. Itu berarti secara mendasar tidak ada perbedaan antara tes unit yang ditulis untuk basis kode kecil dan yang digunakan untuk yang besar. Hanya ada lebih banyak dari mereka.
Tes unit adalah cara terbaik agar tidak merusak sesuatu yang sudah berfungsi saat Anda memperbaiki sesuatu yang lain, atau setidaknya untuk memberi tahu Anda dengan cepat ketika Anda melakukannya. Mereka sebenarnya lebih berguna ketika Anda tidak sebagai seorang programmer yang terampil, atau tidak tahu bagaimana atau tidak ingin menulis lebih banyak kode verbose yang disusun untuk membuat kesalahan lebih kecil atau lebih jelas.
Antara kontrol versi dan penulisan unit test saat Anda berjalan, kode Anda secara alami akan menjadi jauh lebih bersih. Teknik-teknik lain untuk pengkodean yang lebih bersih dapat dipelajari ketika Anda mencapai dataran tinggi.
sumber
Anda mungkin akan menemukan ini sendiri, tetapi jika Anda harus " merekam semuanya dalam file teks di suatu tempat " Anda tidak menggunakan sistem kontrol versi secara maksimal. Gunakan sesuatu seperti Subversion, git, atau Mercurial dan tulis pesan komit yang baik dengan setiap komit dan Anda akan memiliki log yang melayani tujuan file teks tetapi tidak dapat dipisahkan dari repositori.
Selain itu, menggunakan kontrol versi adalah hal paling penting yang dapat Anda lakukan untuk alasan yang tidak disebutkan oleh jawaban yang ada: reproduksibilitas hasil . Jika Anda dapat menggunakan pesan log atau menambahkan catatan ke hasil dengan nomor revisi maka Anda dapat yakin dapat membuat ulang hasil, dan Anda akan lebih baik ditempatkan untuk mempublikasikan kode dengan kertas.
Pengujian unit tidak pernah diperlukan, tetapi akan berguna jika (a) kode cukup modular sehingga Anda dapat menguji unit daripada keseluruhannya; (B) Anda dapat membuat tes. Idealnya Anda dapat menulis output yang diharapkan dengan tangan daripada menghasilkannya dengan kode, meskipun menghasilkannya dengan kode setidaknya dapat memberi Anda tes regresi yang memberi tahu Anda apakah ada sesuatu yang mengubah perilakunya. Pertimbangkan apakah tes lebih cenderung buggy daripada kode yang mereka uji.
OOP adalah alat. Gunakan jika itu membantu, tetapi itu bukan satu-satunya paradigma. Saya berasumsi bahwa Anda hanya benar-benar tahu pemrograman prosedural: jika itu masalahnya, maka dalam konteks yang dijelaskan saya pikir Anda akan mendapat manfaat lebih banyak dari mempelajari pemrograman fungsional daripada OOP, dan khususnya disiplin menghindari efek samping jika memungkinkan. Python dapat ditulis dalam gaya yang sangat fungsional.
sumber
Di sekolah pascasarjana, saya sendiri menulis beberapa kode algoritma-berat. Agak sulit untuk dipecahkan. Singkatnya, banyak konvensi pemrograman dibangun di sekitar gagasan memasukkan informasi ke dalam basis data, mengambilnya pada waktu yang tepat, dan kemudian memijat data itu untuk disajikan kepada pengguna, biasanya menggunakan perpustakaan untuk matematika apa pun- atau algoritma-bagian berat dari proses itu. Untuk program-program ini, semua yang pernah Anda dengar tentang OOP, memecah kode menjadi fungsi-fungsi pendek, dan membuat segala sesuatu mudah dimengerti sekilas di mana mungkin adalah saran yang sangat baik. Tapi itu tidak bekerja untuk kode algoritma-berat, atau kode yang mengimplementasikan perhitungan matematika yang kompleks dan sedikit lainnya.
Jika Anda menulis skrip untuk melakukan perhitungan ilmiah, Anda mungkin memiliki makalah dengan persamaan atau algoritma yang Anda gunakan tertulis di dalamnya. Jika Anda menggunakan ide-ide baru yang Anda temukan sendiri, mudah-mudahan Anda akan mempublikasikannya di karya Anda sendiri. Dalam kasus ini, aturannya adalah: Anda ingin kode Anda membaca sebanyak mungkin persamaan yang diterbitkan. Berikut ini adalah jawaban pada Rekayasa Perangkat Lunak. SE dengan lebih dari 200 upvotes mendukung pendekatan ini dan menjelaskan seperti apa: Apakah ada alasan untuk nama variabel pendek?
Sebagai contoh lain, ada beberapa cuplikan kode di Simbody , alat simulasi fisika yang digunakan untuk penelitian dan rekayasa fisika. Cuplikan ini memiliki komentar yang menunjukkan persamaan yang digunakan untuk perhitungan, diikuti oleh kode yang membaca sedekat mungkin dengan persamaan yang diterapkan.
ContactGeometry.cpp
:ContactGeometry_Sphere.cpp
:sumber
λ
atauφ
bukan yang jeleklambda_
atauphy
...Jadi, pekerjaan saya sehari-hari adalah dalam publikasi data penelitian dan pelestarian untuk sistem University of California. Beberapa orang telah menyebutkan reproduktifitas, dan saya pikir itu benar-benar masalah inti di sini: mendokumentasikan kode Anda seperti cara Anda mendokumentasikan apa pun yang dibutuhkan seseorang untuk mereproduksi percobaan Anda, dan, idealnya, menulis kode yang membuatnya mudah bagi orang lain. untuk mereproduksi percobaan Anda dan memeriksa hasil Anda untuk sumber kesalahan.
Tetapi sesuatu yang belum pernah saya lihat sebutkan, yang menurut saya penting, adalah bahwa lembaga pendanaan semakin melihat publikasi perangkat lunak sebagai bagian dari publikasi data, dan menjadikan publikasi perangkat lunak sebagai persyaratan untuk ilmu pengetahuan terbuka.
Untuk itu, jika Anda menginginkan sesuatu yang spesifik, ditargetkan pada peneliti daripada pengembang perangkat lunak umum, saya tidak bisa merekomendasikan organisasi Software Carpentry dengan cukup tinggi. Jika Anda dapat menghadiri salah satu bengkel mereka , bagus; jika semua yang Anda punya waktu / akses lakukan adalah membaca beberapa makalah mereka tentang praktik terbaik komputasi ilmiah , itu bagus juga. Dari yang terakhir:
Garis besar praktik yang mereka rekomendasikan:
Makalah ini menjelaskan secara rinci tentang masing-masing poin ini.
sumber
Jawaban pribadi:
Saya juga banyak menulis skrip untuk tujuan ilmiah. Untuk skrip yang lebih kecil, saya hanya mencoba mengikuti praktik pemrograman umum yang baik (yaitu menggunakan kontrol versi, mempraktikkan kontrol diri dengan nama variabel). Jika saya hanya menulis sesuatu untuk dengan cepat membuka atau memvisualisasikan dataset, saya tidak peduli dengan OOP.
Jawaban Umum:
"Tergantung." Tetapi jika Anda kesulitan untuk mencari tahu kapan harus menggunakan konsep atau paradigma pemrograman, berikut adalah beberapa hal untuk dipikirkan:
# 1: Biasakan diri dengan apa yang ada di luar sana:
Meskipun Anda adalah skrip "hanya" (dan Anda benar-benar hanya peduli pada komponen sains), Anda harus meluangkan waktu untuk mempelajari konsep dan paradigma pemrograman yang berbeda. Dengan begitu, Anda dapat memiliki gagasan yang lebih baik tentang apa yang harus / tidak ingin Anda gunakan dan kapan. Itu mungkin terdengar agak menakutkan. Dan Anda mungkin masih memiliki pertanyaan, "Di mana saya mulai / apa yang saya mulai cari?" Saya mencoba menjelaskan titik awal yang baik dalam dua poin berikut.
# 2: Mulailah memperbaiki apa yang Anda tahu salah:
Secara pribadi, saya akan mulai dengan hal-hal yang saya tahu salah. Dapatkan kontrol versi dan mulailah mendisiplinkan diri Anda untuk menjadi lebih baik dengan nama-nama variabel (itu adalah perjuangan yang serius). Memperbaiki apa yang Anda tahu salah mungkin terdengar jelas. Namun, dalam pengalaman saya, saya telah menemukan bahwa memperbaiki satu hal menuntun saya ke hal lain, dan seterusnya. Sebelum saya menyadarinya, saya telah mengungkap 10 hal berbeda yang saya lakukan salah dan menemukan cara untuk memperbaikinya atau bagaimana menerapkannya dengan cara yang bersih.
# 3: Dapatkan mitra pemrograman:
Jika "memulai dari awal" untuk Anda tidak melibatkan mengambil kelas formal, pertimbangkan untuk bekerja sama dengan pengembang dan meminta mereka untuk meninjau kode Anda. Bahkan jika mereka tidak memahami bagian sains dari apa yang Anda lakukan, mereka mungkin dapat memberi tahu Anda apa yang dapat Anda lakukan untuk membuat kode Anda lebih elegan.
# 4: Cari konsorsium:
Saya tidak tahu bidang ilmiah Anda. Tetapi tergantung pada apa yang Anda lakukan di dunia ilmiah, cobalah mencari konsorsium, kelompok kerja, atau peserta konferensi. Kemudian lihat apakah ada standar yang sedang mereka kerjakan. Itu dapat mengarahkan Anda ke beberapa standar pengkodean. Sebagai contoh, saya melakukan banyak pekerjaan geospasial. Melihat makalah konferensi dan kelompok kerja membawa saya ke Konsorsium Geospasial Terbuka . Salah satu yang mereka lakukan adalah mengerjakan standar untuk pengembangan geospasial.
Saya harap itu membantu!
Catatan: Saya tahu Anda baru saja menggunakan OOP sebagai contoh. Saya tidak ingin Anda berpikir bahwa saya terjebak pada bagaimana menangani penulisan kode menggunakan OOP. Lebih mudah untuk menulis jawaban yang berlanjut dengan contoh itu.
sumber
Saya akan merekomendasikan untuk tetap berpegang pada prinsip Unix: Keep It Simple, Stupid! (CIUMAN)
Atau, dengan kata lain: Lakukan satu hal pada satu waktu, dan lakukan dengan baik.
Apa artinya? Pertama-tama, itu artinya fungsi Anda harus pendek. Fungsi apa pun yang tidak dapat sepenuhnya dipahami dalam tujuan, penggunaan, dan implementasi dalam beberapa detik pasti terlalu lama. Kemungkinan melakukan beberapa hal sekaligus, masing-masing harus menjadi fungsi mereka sendiri. Jadi pisahkanlah.
Dalam hal baris kode, heuristik saya adalah bahwa 10 baris adalah fungsi yang baik, dan apa pun di atas 20 kemungkinan besar omong kosong. Orang lain punya heuristik lain. Bagian penting adalah menjaga panjang ke sesuatu yang Anda dapat benar-benar pegang dalam sekejap.
Bagaimana Anda membagi fungsi yang panjang? Nah, pertama-tama Anda mencari pola kode yang berulang. Kemudian Anda faktor keluar pola-pola kode ini, beri mereka nama deskriptif, dan saksikan kode Anda menyusut . Sungguh, refactoring terbaik adalah refactoring yang mengurangi ukuran kode.
Ini terutama benar ketika fungsi yang dimaksud telah diprogram dengan salin-tempel. Setiap kali Anda melihat pola berulang seperti itu, Anda langsung tahu bahwa ini kemungkinan akan berubah menjadi fungsi tersendiri. Ini adalah prinsip Don't Repeat Yourself (DRY) . Setiap kali Anda menekan copy-paste, Anda melakukan sesuatu yang salah! Buat fungsi sebagai gantinya.
Beberapa fungsi mungkin lama karena mereka melakukan beberapa hal berbeda satu sama lain. Ini bukan pelanggaran KERING, tetapi juga bisa dipecah. Hasilnya sering merupakan fungsi tingkat tinggi yang memanggil beberapa fungsi yang mengimplementasikan langkah-langkah individual dari fungsi aslinya. Ini umumnya akan meningkatkan ukuran kode, tetapi nama fungsi yang ditambahkan bekerja sangat baik dalam membuat kode lebih mudah dibaca. Karena sekarang Anda memiliki fungsi tingkat atas dengan semua langkahnya yang dinamai secara eksplisit. Juga, setelah pemisahan ini jelas, langkah mana yang beroperasi pada data mana. (Argumen fungsi. Anda tidak menggunakan variabel global, bukan?)
Heuristik yang baik untuk pemisahan fungsi jenis ini adalah kapan pun Anda tergoda untuk menulis komentar bagian, atau ketika Anda menemukan komentar bagian dalam kode Anda. Ini kemungkinan besar salah satu poin di mana fungsi Anda harus dipecah. Komentar bagian juga dapat berfungsi untuk menginspirasi nama untuk fungsi baru.
Prinsip KISS dan KERING dapat membawa Anda jauh. Anda tidak perlu memulai dengan OOP dll segera, seringkali Anda dapat mencapai penyederhanaan yang hebat dengan hanya menerapkan keduanya. Namun, dalam jangka panjang hasilnya akan baik untuk mengetahui tentang OOP dan paradigma lain karena mereka memberi Anda alat tambahan yang dapat Anda gunakan untuk membuat kode program Anda lebih jelas.
Akhirnya, catat setiap tindakan dengan komit. Anda memfaktorkan sesuatu ke dalam fungsi baru, itu adalah sebuah komit . Anda menggabungkan dua fungsi menjadi satu, karena mereka benar-benar melakukan hal yang sama, itu adalah sebuah komit . Jika Anda mengganti nama variabel, itu adalah sebuah komit . Berkomitmen sering. Jika satu hari berlalu, dan Anda tidak berkomitmen, Anda mungkin melakukan sesuatu yang salah.
sumber
Saya setuju dengan yang lain bahwa kontrol versi akan menyelesaikan banyak masalah Anda segera. Secara khusus:
Saya akan mengatakan jangan terlalu memikirkannya: gunakan saja git. Tetap berpegang pada perintah sederhana (misalnya hanya satu
master
cabang), mungkin menggunakan GUI, dan Anda harus baik-baik saja. Sebagai bonus, Anda dapat menggunakan gitlab, github, dll. Untuk penerbitan dan pencadangan gratis;)Alasan saya menulis jawaban ini adalah untuk membahas dua hal yang mungkin Anda coba yang belum saya lihat di atas. Yang pertama adalah menggunakan pernyataan sebagai alternatif yang ringan untuk pengujian unit. Tes unit cenderung duduk "di luar" fungsi / modul / apa pun yang sedang diuji: mereka biasanya mengirim beberapa data ke dalam suatu fungsi, menerima hasil kembali, kemudian memeriksa beberapa properti hasil itu. Ini umumnya ide yang baik, tetapi mungkin tidak nyaman (terutama untuk kode "buang") karena beberapa alasan:
Pernyataan tidak memiliki kelemahan ini, karena mereka diperiksa selama eksekusi normal suatu program. Khususnya:
Anda menyebutkan kecepatan sebagai faktor, dalam hal ini pemeriksaan pernyataan mungkin tidak diinginkan dalam loop itu (tetapi masih berguna untuk memeriksa pengaturan dan pemrosesan selanjutnya). Namun, hampir semua implementasi asersi menyediakan cara untuk mematikannya; misalnya dengan Python mereka tampaknya dapat dinonaktifkan dengan menjalankan dengan
-O
opsi (saya tidak tahu ini, karena saya tidak pernah merasa perlu untuk menonaktifkan salah satu dari pernyataan saya sebelumnya). Saya akan merekomendasikan bahwa Anda meninggalkan mereka disecara default; jika siklus pengodean / debugging / pengujian Anda melambat, Anda mungkin lebih baik melakukan pengujian dengan subset data yang lebih kecil, atau melakukan lebih sedikit iterasi dari beberapa simulasi selama pengujian, atau apa pun. Jika Anda benar-benar menonaktifkan pernyataan dalam pengujian non-berjalan karena alasan kinerja, hal pertama yang saya sarankan Anda lakukan adalah mengukur apakah mereka sebenarnya sumber perlambatan! (Sangat mudah untuk menipu diri kita sendiri ketika datang ke kemacetan kinerja)Saran terakhir saya adalah menggunakan sistem build yang mengelola dependensi Anda. Saya pribadi menggunakan Nix untuk ini, tetapi telah mendengar hal-hal baik tentang Guix juga. Ada juga alternatif seperti Docker, yang jauh kurang berguna dari perspektif ilmiah tetapi mungkin sedikit lebih akrab.
Sistem seperti Nix baru-baru ini menjadi (sedikit) populer, dan beberapa orang mungkin menganggapnya berlebihan untuk "membuang" kode seperti yang Anda jelaskan, tetapi manfaatnya untuk reproduksibilitas komputasi ilmiah sangat besar. Pertimbangkan skrip shell untuk menjalankan percobaan, seperti ini (misalnya
run.sh
):Kami dapat menulis ulangnya menjadi "derivasi" Nix, seperti ini (misalnya
run.nix
):Hal-hal di antaranya
''...''
adalah kode bash, sama seperti yang kami miliki sebelumnya, kecuali yang${...}
dapat digunakan untuk "splice" dalam konten string lain (dalam hal ini./.
, yang akan diperluas ke jalur direktori yang berisirun.nix
). Thewith import ...
garis mengimpor Nix ini perpustakaan standar , yang menyediakanrunCommand
untuk menjalankan kode bash. Kita dapat menjalankan eksperimen menggunakannix-build run.nix
, yang akan memberikan jalan seperti/nix/store/1wv437qdjg6j171gjanj5fvg5kxc828p-output.csv
.Jadi, apa ini membeli kita? Nix akan secara otomatis mengatur lingkungan "bersih", yang hanya memiliki akses ke hal-hal yang telah kami minta secara eksplisit. Secara khusus ia tidak memiliki akses ke variabel seperti
$HOME
atau perangkat lunak sistem apa pun yang telah kami instal. Ini menjadikan hasil independen dari detail mesin kami saat ini, seperti konten~/.config
atau versi program yang kami instal; AKA hal-hal yang mencegah orang lain meniru hasil kami! Ini sebabnya saya menambahkan itucp
perintah, karena proyek tidak akan dapat diakses secara default. Mungkin tampak menjengkelkan bahwa perangkat lunak sistem tidak tersedia untuk skrip Nix, tetapi sebaliknya juga: kita tidak memerlukan apa pun yang diinstal pada sistem kami (selain Nix) untuk memanfaatkannya dalam skrip; kami hanya memintanya dan Nix akan keluar dan mengambil / mengkompilasi / apa pun yang diperlukan (kebanyakan hal akan diunduh sebagai binari; perpustakaan standar juga sangat besar!). Misalnya, jika kita menginginkan banyak paket Python dan Haskell tertentu, untuk beberapa versi tertentu dari bahasa-bahasa tersebut, ditambah beberapa sampah lainnya (karena mengapa tidak?):Hal yang sama
nix-build run.nix
akan menjalankan ini, mengambil semua yang kami minta terlebih dahulu (dan menyimpannya semua kalau-kalau kami menginginkannya nanti). Output (semua file / direktori yang dipanggil$out
) akan disimpan oleh Nix, yang merupakan jalan yang diludahkan. Itu diidentifikasi oleh hash kriptografi dari semua input yang kami minta (isi skrip, paket lain, nama, flag kompiler, dll.); paket-paket lain diidentifikasi oleh hash input mereka , dan seterusnya sehingga kami memiliki rantai penuh keunggulan untuk semuanya, segera kembali ke versi GCC yang menyusun versi GCC yang menyusun bash, dan seterusnya!Mudah-mudahan saya telah menunjukkan bahwa ini banyak membeli kita untuk kode ilmiah, dan cukup mudah untuk memulai. Ini juga mulai dianggap sangat serius oleh para ilmuwan, misalnya (hit Google teratas) https://dl.acm.org/citation.cfm?id=2830172 jadi mungkin keterampilan yang berharga untuk dikembangkan (seperti pemrograman)
sumber
Tanpa pergi ke kontrol versi lengkap + pengemasan + unit tes jenis pola pikir (yang merupakan praktik pemrograman yang baik yang harus Anda coba capai di beberapa titik), salah satu solusi menengah yang saya pikir akan cocok adalah dengan menggunakan Jupiter Notebook . Ini tampaknya lebih baik diintegrasikan dengan perhitungan ilmiah.
Ini memiliki keuntungan bahwa Anda dapat mencampur pikiran Anda dengan kode; menjelaskan mengapa suatu pendekatan lebih baik daripada yang lain dan meninggalkan kode lama apa adanya di bagian ad-hoc. Selain menggunakan sel dengan benar akan secara alami membawa Anda untuk memecah kode Anda dan mengaturnya menjadi fungsi yang dapat membantu pemahamannya.
sumber
Jawaban teratas sudah baik, tetapi saya ingin menjawab beberapa pertanyaan Anda secara langsung.
Ukuran kode tidak secara langsung berkaitan dengan kebutuhan untuk tes unit. Ini terkait secara tidak langsung: tes unit lebih berharga dalam basis kode kompleks , dan basis kode kecil umumnya tidak serumit yang lebih besar.
Tes unit bersinar untuk kode di mana mudah untuk membuat kesalahan, atau ketika Anda akan memiliki banyak implementasi kode ini. Tes unit tidak banyak membantu Anda dengan perkembangan saat ini , tetapi mereka melakukan banyak hal untuk mencegah Anda membuat kesalahan di masa depan yang menyebabkan kode yang ada tiba-tiba bertingkah buruk (walaupun Anda tidak menyentuh hal itu).
Katakanlah Anda memiliki aplikasi di mana Perpustakaan A melakukan kuadrat angka, dan Perpustakaan B menerapkan teorema Pythagoras. Jelas, B tergantung pada A. Anda perlu memperbaiki sesuatu di perpustakaan A, dan katakanlah Anda memperkenalkan bug yang kubus angka daripada mengkuadratkannya.
Perpustakaan B tiba-tiba akan mulai berperilaku buruk, mungkin melemparkan pengecualian atau hanya memberikan output yang salah. Dan ketika Anda melihat sejarah versi perpustakaan B, Anda melihat bahwa itu tidak tersentuh. Hasil akhir yang bermasalah adalah bahwa Anda tidak memiliki indikasi apa yang mungkin salah, dan Anda harus men-debug perilaku B sebelum Anda menyadari masalahnya ada di A. Itu adalah usaha yang sia-sia.
Masukkan tes unit. Tes ini mengkonfirmasi bahwa perpustakaan A berfungsi sebagaimana mestinya. Jika Anda memperkenalkan bug di perpustakaan A yang menyebabkannya mengembalikan hasil yang buruk, maka pengujian unit Anda akan menangkapnya. Oleh karena itu, Anda tidak akan terjebak mencoba men-debug pustaka B.
Ini di luar jangkauan Anda, tetapi dalam pengembangan integrasi berkelanjutan, pengujian unit dijalankan setiap kali seseorang melakukan beberapa kode, yang berarti Anda akan tahu Anda telah memecahkan sesuatu ASAP.
Khusus untuk operasi matematika yang rumit, unit test dapat menjadi berkah. Anda melakukan beberapa contoh perhitungan, dan kemudian Anda menulis unit test yang membandingkan output terhitung dan output aktual Anda (berdasarkan parameter input yang sama).
Namun, perhatikan bahwa tes unit tidak akan membantu Anda membuat kode yang baik, tetapi mempertahankannya . Jika Anda biasanya menulis kode sekali dan tidak pernah mengunjungi lagi, tes unit akan kurang bermanfaat.
OOP adalah cara berpikir tentang entitas yang berbeda, misalnya:
Bandingkan ini dengan cara seorang programmer fungsional memikirkan hal-hal:
Apel dan jeruk. Tak satu pun dari mereka secara obyektif lebih baik dari yang lain. Satu hal yang menarik untuk dicatat adalah bahwa untuk OOP,
Vendor
disebutkan dua kali tetapi mengacu pada hal yang sama. Namun, untuk pemrograman fungsional,talktoVendor()
danpayVendor()
dua hal terpisah.Ini menunjukkan perbedaan antara pendekatan. Jika ada banyak logika khusus vendor bersama antara kedua tindakan ini, maka OOP membantu mengurangi duplikasi kode. Namun, jika tidak ada logika bersama antara keduanya, maka menggabungkan mereka menjadi satu
Vendor
adalah pekerjaan yang sia-sia (dan karena itu pemrograman fungsional lebih efisien).Lebih sering daripada tidak, perhitungan matematika dan ilmiah adalah operasi yang berbeda yang tidak bergantung pada logika / rumus bersama implisit. Karena itu, pemrograman fungsional lebih sering digunakan daripada OOP.
Pertanyaan Anda menyiratkan bahwa definisi "kode yang baik, bersih" berubah apakah Anda melakukan pemrograman ilmiah atau bekerja pada proyek yang lebih besar (saya asumsikan Anda maksud perusahaan).
Definisi kode yang baik tidak berubah. Namun, kebutuhan untuk menghindari kerumitan (yang bisa dilakukan dengan menulis kode bersih) memang berubah.
Argumen yang sama kembali ke sini.
Saya mendapatkan perbedaan yang Anda buat di sini, tetapi ketika Anda melihat kembali kode yang ada, Anda melihat matematika dan pemrogramannya. Jika salah dibuat atau rumit, maka Anda akan kesulitan untuk membacanya.
Selain prinsip OOP, alasan utama saya menulis kelas untuk menampung beberapa nilai data adalah karena menyederhanakan menyatakan parameter metode dan mengembalikan nilai. Sebagai contoh, jika saya memiliki banyak metode yang menggunakan lokasi (lat / lon pair), maka saya akan cepat bosan karena harus mengetik
float latitude, float longitude
dan akan lebih suka menulisLocation loc
.Ini diperparah lebih lanjut ketika Anda mempertimbangkan bahwa metode umumnya mengembalikan satu nilai (kecuali fitur spesifik bahasa ada untuk mengembalikan lebih banyak nilai), dan hal-hal seperti lokasi ingin Anda mengembalikan dua nilai (lat + lon). Ini memberi Anda insentif untuk membuat
Location
kelas untuk menyederhanakan kode Anda.Hal lain yang menarik untuk dicatat adalah Anda dapat menggunakan OOP tanpa mencampurkan nilai dan metode data. Tidak semua pengembang setuju di sini (beberapa menyebutnya sebagai antipattern), tetapi Anda dapat memiliki model data anemia di mana Anda memiliki kelas data terpisah (menyimpan bidang nilai) dan kelas logika (menyimpan metode).
Ini, tentu saja, pada spektrum. Anda tidak perlu menderita anemia sempurna, Anda dapat menggunakannya saat Anda menganggapnya tepat.
Sebagai contoh, metode yang hanya menggabungkan nama depan dan belakang seseorang masih dapat ditempatkan di
Person
kelas itu sendiri, karena itu bukan benar-benar "logika" melainkan nilai yang dihitung.Kelas selalu sebesar jumlah bidangnya. Mengambil contoh
Location
lagi, yang terdiri dari duafloat
nilai, penting untuk dicatat di sini bahwa satuLocation
objek akan mengambil memori sebanyak duafloat
nilai yang terpisah .Dalam hal itu, tidak masalah apakah Anda menggunakan OOP atau tidak. Jejak memori sama.
Performa itu sendiri juga bukan halangan besar untuk dilewati. Perbedaan antara misalnya menggunakan metode global atau metode kelas tidak ada hubungannya dengan kinerja runtime, tetapi semuanya terkait dengan pembuatan bytecode waktu kompilasi.
Pikirkan seperti ini: apakah saya menulis resep kue saya dalam bahasa Inggris atau Spanyol tidak mengubah fakta bahwa kue akan memakan waktu 30 menit untuk dipanggang (= kinerja runtime). Satu-satunya hal yang diubah bahasa resep adalah bagaimana si juru masak mencampurkan bahan-bahannya (= mengkompilasi bytecode).
Khususnya untuk Python, Anda tidak perlu mengkompilasi kode secara eksplisit sebelum memanggilnya. Namun, ketika Anda tidak melakukan pra-kompilasi, kompilasi akan terjadi ketika mencoba mengeksekusi kode. Ketika saya mengatakan "runtime", maksud saya eksekusi itu sendiri, bukan kompilasi yang bisa mendahului eksekusi.
sumber
Manfaat kode ilmiah bersih
Mungkin bermanfaat untuk mempertimbangkan kode Anda dari perspektif pembuat kode masa depan.
Dari pengalaman saya,
Kode bersih harus memudahkan verifikasi hasil Anda
Anda mungkin ingin membagi program Anda sehingga masing-masing algoritma dapat dibandingkan secara terpisah.
Hindari menulis fungsi dengan efek samping kontra-intuitif di mana satu operasi yang tidak terkait menyebabkan operasi lain berperilaku berbeda. Jika Anda tidak dapat menghindarinya, dokumentasikan apa yang dibutuhkan kode Anda dan cara mengaturnya.
Kode bersih dapat berfungsi sebagai kode contoh untuk coders masa depan
Komentar yang jelas (termasuk yang menunjukkan bagaimana fungsi harus dipanggil) dan fungsi yang terpisah dapat membuat perbedaan besar dalam berapa lama bagi seseorang yang baru memulai (atau masa depan Anda) untuk membuat sesuatu yang berguna dari pekerjaan Anda.
Selain itu, membuat "API" nyata untuk algoritme Anda dapat membuat Anda lebih siap jika Anda memutuskan untuk membuat skrip Anda menjadi perpustakaan nyata untuk digunakan orang lain.
Rekomendasi
"Kutip" rumus matematika menggunakan komentar.
John Smith Method from Some Book 1st Ed. Section 1.2.3 Pg 180
, jika Anda menemukan formula di situs web atau di kertas, kutip juga.Gunakan komentar dengan bijak
Jika Anda dapat meningkatkan keterbacaan kode Anda dengan menggunakan nama variabel / nama fungsi yang baik, lakukan itu terlebih dahulu. Ingatlah bahwa komentar akan bertahan selamanya sampai Anda menghapusnya, jadi cobalah untuk membuat komentar yang tidak akan kedaluwarsa.
Gunakan nama variabel deskriptif
xBar_AverageVelocity
Tulis kode untuk menjalankan program Anda terhadap data buruk yang diketahui baik dan buruk.
Saya pikir pengujian unit dapat membantu, saya pikir bentuk terbaik pengujian unit untuk kode ilmiah adalah serangkaian tes yang dijalankan pada data yang diketahui buruk dan baik.
Tulis beberapa kode untuk menjalankan algoritme Anda dan periksa untuk melihat seberapa jauh hasilnya menyimpang dari yang Anda harapkan. Ini akan membantu Anda menemukan masalah (berpotensi sangat buruk dan sulit ditemukan) di mana Anda secara tidak sengaja membuat kode sesuatu yang menyebabkan hasil positif palsu, atau membuat kesalahan yang menyebabkan fungsi selalu mengembalikan nilai yang sama.
Perhatikan bahwa ini dapat dilakukan pada tingkat abstraksi apa pun. Misalnya, Anda dapat menguji keseluruhan algoritma pencocokan pola, atau Anda dapat menguji fungsi yang hanya menghitung jarak antara dua hasil dalam proses optimasi Anda. Mulailah dengan bidang yang paling penting untuk hasil Anda terlebih dahulu, dan / atau bagian-bagian kode yang paling Anda khawatirkan.
Buat lebih mudah untuk menambahkan kasus uji baru, pertimbangkan untuk menambahkan fungsi "pembantu", dan susun data input Anda secara efektif. Ini mungkin berarti menyimpan data input ke file sehingga Anda dapat dengan mudah menjalankan kembali tes, meskipun sangat berhati-hati untuk menghindari positif palsu atau kasus tes yang bias / sepele diselesaikan.
Pertimbangkan untuk menggunakan sesuatu seperti validasi silang , lihat posting ini di cross divalidasi untuk informasi lebih lanjut.
Gunakan kontrol versi
Saya akan merekomendasikan menggunakan kontrol versi dan hosting repositori Anda di situs eksternal. Ada situs yang akan meng-host repositori secara gratis.
Keuntungan:
Berhati-hatilah saat menyalin / menempelkan kode
Menyalin / menempel kode dapat menghemat waktu Anda, tetapi ini adalah salah satu hal paling berbahaya yang dapat Anda lakukan, terutama jika itu kode yang tidak Anda tulis sendiri (misalnya, jika itu kode dari kolega).
Segera setelah Anda mendapatkan kode yang berfungsi dan diuji, saya akan merekomendasikan melaluinya dengan sangat hati-hati untuk mengubah nama variabel atau komentar apa pun yang Anda tidak mengerti.
sumber
Alat-alat perdagangan biasanya diciptakan untuk menyelesaikan suatu kebutuhan. Jika Anda perlu menggunakan alat ini, jika tidak, kemungkinan besar Anda tidak perlu melakukannya.
Secara khusus, program ilmiah bukanlah target akhir, mereka adalah sarana. Anda menulis program untuk menyelesaikan masalah yang Anda miliki sekarang - Anda tidak mengharapkan program itu digunakan oleh orang lain (dan harus dipelihara) dalam sepuluh tahun. Itu saja berarti Anda tidak perlu memikirkan alat apa pun yang memungkinkan pengembang saat ini untuk mencatat riwayat untuk orang lain seperti kontrol versi, atau menangkap fungsionalitas dalam kode seperti tes unit.
Apa yang akan menguntungkan Anda?
sumber
Selain saran bagus yang sudah ada di sini, Anda mungkin ingin mempertimbangkan tujuan pemrograman Anda, dan karena itu apa yang penting bagi Anda.
"Ini lebih tentang matematika atau sains yang saya uji atau teliti dengan pemrogramannya."
Jika tujuannya adalah untuk bereksperimen dan menguji sesuatu untuk pemahaman Anda sendiri dan Anda tahu apa hasilnya seharusnya maka kode Anda pada dasarnya adalah membuang-cepat dan pendekatan Anda saat ini mungkin sudah cukup, meskipun dapat ditingkatkan. Jika hasilnya tidak seperti yang diharapkan, Anda dapat kembali dan meninjau.
Namun, jika hasil coding Anda menginformasikan arah penelitian Anda dan Anda tidak tahu apa hasilnya harus menjadi, maka kebenaran menjadi sangat penting. Kesalahan dalam kode Anda dapat menyebabkan Anda menarik kesimpulan yang salah dari eksperimen Anda dengan berbagai implikasi buruk bagi keseluruhan riset Anda.
Dalam hal ini, memecah kode Anda menjadi fungsi yang mudah dimengerti dan diverifikasi dengan unit test akan memberi Anda batu bata bangunan yang lebih solid memberi Anda lebih percaya diri pada hasil Anda dan dapat menyelamatkan Anda dari banyak frustrasi nanti.
sumber
Sama bagusnya dengan kontrol versi dan pengujian unit untuk menjaga kode keseluruhan Anda terorganisir dan fungsional, tidak ada yang benar-benar membantu Anda menulis kode yang lebih bersih.
Jika Anda ingin menghentikan diri Anda dari menulis kode yang berantakan, Anda memerlukan alat yang berfungsi di mana kekacauan terjadi: ketika Anda menulis kode. Jenis alat yang populer disebut linter. Saya bukan pengembang python, tetapi sepertinya Pylint mungkin merupakan pilihan yang baik.
Linter melihat kode yang telah Anda tulis, dan membandingkannya dengan seperangkat praktik terbaik yang dapat dikonfigurasi. Jika linter memiliki aturan bahwa variabel harus
camelCase
, dan Anda menuliskannyasnake_case
, itu akan menandai itu sebagai kesalahan. Linter yang baik memiliki aturan mulai dari "variabel yang dideklarasikan harus digunakan" hingga "Kompleksitas fungsi siklomatik harus kurang dari 3".Sebagian besar editor kode dapat dikonfigurasikan untuk menjalankan linter setiap kali Anda menyimpan, atau hanya secara umum saat Anda mengetik, dan menunjukkan masalah sebaris. Jika Anda mengetikkan sesuatu seperti
x = 7
,x
akan disorot, dengan instruksi untuk menggunakan nama yang lebih panjang dan lebih baik (jika itu yang Anda konfigurasikan). Ini berfungsi seperti periksa ejaan pada sebagian besar pengolah kata, membuatnya sulit untuk diabaikan, dan membantu membangun kebiasaan yang lebih baik.sumber
Semua yang Anda daftarkan adalah alat di kotak alat metaforis. Seperti apa pun dalam hidup, alat yang berbeda sesuai untuk tugas yang berbeda.
Dibandingkan dengan bidang teknik lainnya, perangkat lunak bekerja dengan banyak potongan individual yang cukup sederhana. Pernyataan tugas tidak dievaluasi secara berbeda tergantung pada fluktuasi suhu ruangan. Sebuah
if
pernyataan tidak menimbulkan korosi dan terus mengembalikan hal yang sama setelah beberapa saat. Tetapi karena unsur-unsur individu sangat sederhana, dan perangkat lunak yang dibuat oleh manusia, unsur-unsur tersebut digabungkan menjadi potongan-potongan yang lebih besar dan lebih besar sampai hasilnya menjadi begitu besar dan kompleks sehingga mencapai batas apa yang dapat dikelola orang secara mental.Sebagai proyek perangkat lunak telah tumbuh dan berkembang, orang telah mempelajarinya dan menciptakan alat untuk mencoba mengelola kompleksitas itu. OOP adalah salah satu contohnya. Semakin banyak bahasa pemrograman abstrak adalah cara lain. Karena sebagian besar uang dalam perangkat lunak melakukan lebih banyak lagi , alat untuk mencapai itulah yang akan Anda lihat dan baca. Tapi sepertinya situasi itu tidak berlaku untuk Anda.
Jadi, jangan merasa Anda perlu melakukan semua itu. Pada akhirnya, kode itu hanyalah alat untuk mencapai tujuan. Sayangnya, apa yang terbaik memberi Anda perspektif yang tepat tentang apa yang ada dan apa yang tidak sesuai adalah bekerja pada beberapa proyek yang lebih besar, karena jauh lebih sulit untuk mengetahui apa yang hilang ketika kotak peralatan itu ada di pikiran Anda.
Bagaimanapun, saya tidak akan khawatir tentang tidak menggunakan OOP atau teknik lain selama skrip Anda kecil. Banyak masalah yang Anda uraikan hanyalah keterampilan organisasi profesional umum, yaitu tidak kehilangan file lama adalah sesuatu yang harus dihadapi semua bidang.
sumber
Selain semua saran bagus yang diberikan sejauh ini, satu praktik yang saya pelajari dari waktu ke waktu dan penting adalah dengan sangat bebas menambahkan komentar terperinci ke kode Anda. Ini adalah satu-satunya hal terpenting bagi saya ketika saya kembali ke sesuatu setelah selang waktu yang lama. Jelaskan pada diri sendiri apa yang Anda pikirkan. Dibutuhkan sedikit waktu untuk melakukannya tetapi relatif mudah dan kebanyakan tidak menyakitkan.
Saya kadang-kadang memiliki dua atau tiga kali lebih banyak baris komentar daripada kode, terutama ketika konsep atau tekniknya baru bagi saya dan saya harus menjelaskan kepada diri sendiri.
Lakukan kontrol versi, perbaiki praktik Anda, dll .... semua hal di atas. Tetapi jelaskan hal-hal untuk diri Anda saat Anda pergi. Ini bekerja dengan sangat baik.
sumber
Kualitas apa yang penting untuk program semacam ini?
Mungkin tidak masalah apakah itu mudah untuk mempertahankan atau mengembangkannya, karena kemungkinan itu tidak akan terjadi.
Mungkin tidak masalah seberapa efisien itu.
Mungkin tidak masalah apakah itu memiliki antarmuka pengguna yang hebat atau apakah itu aman terhadap penyerang jahat.
Mungkin penting bahwa itu dapat dibaca: bahwa seseorang yang membaca kode Anda dapat dengan mudah meyakinkan diri sendiri bahwa itu melakukan apa yang diklaimnya lakukan.
Itu tentu penting bahwa itu benar. Jika program memberikan hasil yang salah, itu kesimpulan ilmiah Anda di luar jendela. Tetapi hanya perlu memproses dengan benar input yang sebenarnya Anda minta untuk diproses; itu benar-benar tidak terlalu penting apakah itu jatuh jika diberi nilai data input negatif, jika semua nilai data Anda positif.
Penting juga bagi Anda untuk mempertahankan beberapa level kontrol perubahan. Hasil ilmiah Anda harus dapat direproduksi, dan itu berarti Anda perlu tahu versi program mana yang menghasilkan hasil yang ingin Anda publikasikan. Karena hanya ada satu pengembang, kontrol perubahan tidak perlu terlalu rumit, tetapi Anda perlu memastikan bahwa Anda dapat kembali ke titik waktu dan mereproduksi hasil Anda.
Jadi jangan khawatir tentang paradigma pemrograman, orientasi objek, keanggunan algoritmik. Jangan khawatir tentang kejelasan dan keterbacaan dan tentang keterlacakan perubahan Anda dari waktu ke waktu. Jangan khawatir tentang antarmuka pengguna. Jangan khawatir tentang pengujian setiap kemungkinan kombinasi parameter input, tetapi lakukan pengujian yang cukup untuk menjadi percaya diri (dan untuk membuat orang lain percaya diri) bahwa hasil dan kesimpulan Anda valid.
sumber
Saya telah bekerja di lingkungan yang sama dengan akademisi yang menulis banyak kode (matematika / sains) tetapi kemajuan mereka lambat karena alasan yang sama yang Anda gambarkan. Namun saya telah memperhatikan satu hal tertentu yang berjalan dengan baik yang saya pikir juga dapat membantu Anda: membangun dan memelihara koleksi perpustakaan khusus yang dapat digunakan di berbagai proyek. Perpustakaan ini harus menyediakan fungsi utilitas dan karenanya akan membantu menjaga proyek Anda saat ini khusus untuk domain masalah.
Misalnya, Anda mungkin harus berurusan dengan banyak transformasi koordinat di bidang Anda (ECEF, NED, lat / lon, WGS84 dll.), Jadi fungsi seperti
convert_ecef_to_ned()
harus pergi ke proyek baru yang disebutCoordinateTransformations
. Letakkan proyek di bawah kontrol versi dan simpan di server departemen Anda sehingga orang lain dapat menggunakannya (dan semoga meningkatkannya). Kemudian setelah beberapa tahun Anda harus memiliki koleksi perpustakaan yang kuat dengan proyek Anda hanya berisi kode khusus untuk domain masalah / penelitian tertentu.Beberapa saran yang lebih umum:
sumber
Berikut ini adalah pendapat saya dan sangat dipengaruhi oleh jalan saya sendiri.
Pengkodean sering menimbulkan perspektif dogmatis tentang bagaimana Anda harus melakukan sesuatu. Alih-alih teknik & alat, saya pikir Anda perlu melihat nilai & biaya kumulatif untuk memutuskan strategi yang tepat.
Menulis kode yang bagus, mudah dibaca, dapat di-debuggable, dan padat membutuhkan banyak waktu & usaha. Dalam banyak kasus, mengingat horizon perencanaan yang terbatas, tidak ada gunanya melakukan ini (analisis kelumpuhan).
Seorang kolega memiliki aturan praktis; jika pada dasarnya Anda melakukan hal yang sama untuk ketiga kalinya maka investasikan upaya, jika tidak, pekerjaan cepat & kotor pantas dilakukan.
Menguji semacam itu penting, tetapi untuk satu proyek, cukup mengamati bola mata mungkin sudah cukup. Untuk hal yang substansial, pengujian & infrastruktur pengujian sangat penting. Nilai itu membebaskan Anda saat pengkodean, biayanya adalah jika tes berfokus pada implementasi tertentu maka tes juga perlu pemeliharaan. Tes juga mengingatkan Anda tentang bagaimana hal-hal yang seharusnya beroperasi.
Untuk skrip saya sendiri (sering untuk hal-hal seperti memvalidasi perkiraan probabilitas, atau serupa), saya menemukan dua hal kecil yang sangat berguna: 1. Sertakan komentar yang menunjukkan bagaimana kode digunakan. 2. Sertakan deskripsi singkat tentang mengapa Anda menulis kode. Hal-hal ini sangat jelas ketika Anda menulis kode, tetapi kejernihannya terbuang seiring waktu :-).
OOP adalah tentang menggunakan kembali kode, abstrak, enkapsulasi, anjak piutang, dll. Sangat berguna, tetapi mudah hilang jika memproduksi kode & desain berkualitas bukanlah tujuan akhir Anda. Butuh waktu & upaya untuk menghasilkan barang berkualitas.
sumber
Sementara saya berpikir bahwa unit test memiliki kelebihannya, mereka memiliki nilai yang diragukan untuk pengembangan ilmiah - mereka seringkali terlalu kecil untuk menawarkan banyak nilai.
Tapi saya sangat suka tes integrasi untuk kode ilmiah:
Isolasikan sebagian kecil dari kode Anda yang dapat bekerja sendiri, misalnya pipa ETL. Kemudian tulis tes yang menyediakan data, jalankan pip etl (atau hanya langkah) dan kemudian uji bahwa hasilnya sesuai dengan harapan Anda. Sementara potongan yang diuji dapat berupa banyak kode, pengujian memberikan nilai tetap:
Saya sering menggunakan teknik ini, dan seringkali berakhir dengan fungsi utama yang dapat dibaca secara relatif tetapi sub-fungsi seringkali cukup panjang dan jelek, tetapi dapat dimodifikasi dan disusun kembali dengan cepat karena batas I / O yang kuat.
sumber
Saya biasanya bekerja pada basis sumber yang sangat besar. Kami menggunakan semua alat yang Anda sebutkan. Baru-baru ini, saya mulai mengerjakan beberapa skrip python untuk proyek sampingan. Mereka adalah beberapa lusin hingga beberapa ratus baris paling banyak. Karena kebiasaan, saya melakukan skrip saya ke kontrol sumber. Ini bermanfaat karena saya dapat membuat cabang untuk mencoba eksperimen yang mungkin tidak berhasil. Saya dapat melakukan fork jika saya perlu menggandakan kode dan memodifikasinya untuk tujuan lain. Ini menyisakan yang asli kalau-kalau saya perlu mengeluarkannya lagi.
Untuk "unit test", saya hanya memiliki beberapa file input yang dimaksudkan untuk menghasilkan beberapa output yang diketahui yang saya periksa dengan tangan. Saya mungkin bisa mengotomatiskannya, tetapi rasanya butuh waktu lebih banyak untuk melakukan itu daripada menghemat dengan melakukannya. Mungkin tergantung pada seberapa sering saya harus memodifikasi dan menjalankan skrip. Either way, jika berhasil, lakukanlah. Jika lebih banyak masalah daripada nilainya, jangan buang waktu Anda.
sumber
Dengan kode penulisan - seperti halnya penulisan pada umumnya - pertanyaan utamanya adalah:
Hal-hal seperti pedoman pengkodean formal tidak masuk akal ketika Anda adalah satu-satunya audiens Anda.
Yang sedang berkata, di sisi lain, akan sangat membantu untuk menulis kode dengan cara, masa depan Anda, Anda dapat memahaminya segera.
Jadi "gaya yang baik" akan menjadi satu, yang paling membantu Anda. Seperti apa gaya itu adalah jawaban yang tidak bisa saya berikan.
Saya pikir Anda tidak perlu tes OOP atau Unit untuk file 150 LOC. VCS khusus akan menarik ketika Anda memiliki beberapa kode yang berkembang. Kalau
.bak
tidak, lakukan triknya. Alat-alat ini adalah obat untuk penyakit, Anda bahkan mungkin tidak punya.Mungkin Anda harus menulis kode Anda sedemikian rupa, sehingga bahkan jika Anda membacanya saat sedang mabuk, Anda dapat membaca, memahami dan memodifikasinya.
sumber