การเขียนโปรแกรมอย่างหมดจดเมื่อเขียนโค้ดทางวิทยาศาสตร์


169

ฉันไม่ได้เขียนโครงการขนาดใหญ่จริงๆ ฉันไม่ได้บำรุงรักษาฐานข้อมูลขนาดใหญ่หรือจัดการกับโค้ดหลายล้านบรรทัด

รหัสของฉันคือ "สคริปต์" สิ่งที่พิมพ์ - สิ่งที่จะทดสอบฟังก์ชั่นทางคณิตศาสตร์หรือเพื่อจำลองบางอย่าง - "การเขียนโปรแกรมทางวิทยาศาสตร์" โปรแกรมที่ยาวที่สุดที่ฉันทำงานจนถึงจุดนี้คือโค้ดสองร้อยบรรทัดและโปรแกรมส่วนใหญ่ที่ฉันใช้อยู่นั้นมีประมาณ 150 รายการ

รหัสของฉันยังอึ ฉันรู้เรื่องนี้เมื่อวันก่อนขณะที่ฉันพยายามค้นหาไฟล์ที่ฉันเขียนสักครู่แล้ว แต่ฉันอาจจะเขียนทับและฉันไม่ได้ใช้การควบคุมเวอร์ชันซึ่งอาจทำให้คุณรู้สึกปวดร้าวใจเป็นจำนวนมาก

รูปแบบของรหัสของฉันมีความซับซ้อนและเต็มไปด้วยความคิดเห็นที่ล้าสมัยซึ่งระบุวิธีอื่นในการทำบางสิ่งหรือคัดลอกบรรทัดของรหัสไป ในขณะที่ชื่อตัวแปรเริ่มต้นที่ดีมากและเป็นคำอธิบายในขณะที่ฉันเพิ่มหรือเปลี่ยนแปลงสิ่งต่าง ๆ ตามเช่นสิ่งใหม่ที่ใครบางคนต้องการทดสอบรหัสได้รับการซ้อนทับด้านบนและเขียนทับและเพราะฉันรู้สึกว่าสิ่งนี้ควรทดสอบอย่างรวดเร็วตอนนี้ มีกรอบฉันเริ่มใช้ชื่อตัวแปรเส็งเคร็งและไฟล์ไปที่หม้อ

ในโครงการที่ฉันกำลังทำอยู่ตอนนี้ฉันอยู่ในช่วงที่สิ่งเหล่านี้กลับมากัดฉันอย่างมาก แต่ปัญหาคือ (นอกเหนือจากการใช้การควบคุมเวอร์ชันและการสร้างไฟล์ใหม่สำหรับการทำซ้ำแต่ละครั้งและบันทึกทั้งหมดในไฟล์ข้อความที่ไหนสักแห่งซึ่งอาจจะช่วยสถานการณ์ได้อย่างมาก) ฉันไม่รู้จริง ๆ ว่าจะดำเนินการปรับปรุงอย่างไร สไตล์การเข้ารหัสที่แท้จริงของฉัน

การทดสอบหน่วยจำเป็นสำหรับการเขียนโค้ดขนาดเล็กลงหรือไม่? แล้ว OOP ล่ะ วิธีใดบ้างที่ดีสำหรับการเขียนโค้ดที่ดีและสะอาดได้อย่างรวดเร็วเมื่อทำการ "การเขียนโปรแกรมเชิงวิทยาศาสตร์" ซึ่งต่างจากการทำงานในโครงการขนาดใหญ่

ฉันถามคำถามเหล่านี้เพราะบ่อยครั้งการเขียนโปรแกรมเองนั้นไม่ซับซ้อน มันเกี่ยวกับคณิตศาสตร์หรือวิทยาศาสตร์ที่ฉันกำลังทดสอบหรือค้นคว้าด้วยการเขียนโปรแกรม เช่นคลาสจำเป็นหรือไม่เมื่อมีตัวแปรสองตัวและฟังก์ชั่นอาจดูแลได้ (พิจารณาสิ่งเหล่านี้โดยทั่วไปเป็นสถานการณ์ที่ความเร็วของโปรแกรมเป็นที่ต้องการในตอนท้ายที่เร็วกว่า - เมื่อคุณรันขั้นตอนการจำลองมากกว่า 25,000,000+ ครั้งคุณต้องการให้มันเป็นแบบนั้น)

บางทีนี่อาจจะกว้างเกินไปและถ้าเป็นเช่นนั้นฉันขอโทษ แต่เมื่อดูหนังสือโปรแกรมพวกเขามักจะพูดถึงโครงการขนาดใหญ่ รหัสของฉันไม่จำเป็นต้องมี OOP และมันก็ค่อนข้างสั้นอยู่แล้วดังนั้นจึงไม่เหมือน "โอ้ แต่ไฟล์จะลดลงหนึ่งพันบรรทัดถ้าเราทำอย่างนั้น!" ฉันต้องการทราบวิธี "เริ่มต้นใหม่" และเขียนโปรแกรมอย่างละเอียดเกี่ยวกับโครงการขนาดเล็กลงและเร็วขึ้น

ฉันยินดีที่จะให้รายละเอียดที่เฉพาะเจาะจงยิ่งขึ้น แต่ยิ่งคำแนะนำที่มีประโยชน์มากกว่านี้ฉันคิดว่า ฉันกำลังเขียนโปรแกรมใน Python 3


มีคนแนะนำสำเนาที่ซ้ำกัน ให้ฉันชัดเจนฉันไม่ได้พูดเกี่ยวกับการละเว้นมาตรฐานการเขียนโปรแกรมมาตรฐานทันที เห็นได้ชัดว่ามีเหตุผลมาตรฐานเหล่านั้นอยู่ แต่ในทางกลับกันมันเป็นเรื่องที่สมเหตุสมผลหรือไม่ที่จะเขียนโค้ดที่พูดว่า OOP เมื่อสิ่งมาตรฐานสามารถทำได้สำเร็จจะเร็วกว่ามากในการเขียนและจะอ่านได้ในระดับใกล้เคียงกันเนื่องจากความสั้น โปรแกรม?

มีข้อยกเว้น นอกจากนี้อาจมีมาตรฐานสำหรับการเขียนโปรแกรมทางวิทยาศาสตร์เกินกว่ามาตรฐานธรรมดา ฉันถามเกี่ยวกับสิ่งเหล่านั้นเช่นกัน นี่ไม่เกี่ยวกับว่ามาตรฐานการเข้ารหัสปกติควรถูกละเว้นเมื่อเขียนรหัสทางวิทยาศาสตร์มันเกี่ยวกับการเขียนรหัสทางวิทยาศาสตร์ที่สะอาด!


ปรับปรุง

แค่คิดว่าฉันจะเพิ่มการอัปเดตประเภท "ไม่ค่อนข้างหนึ่งสัปดาห์ - ต่อมา" คำแนะนำทั้งหมดของคุณมีประโยชน์อย่างยิ่ง ตอนนี้ฉันกำลังใช้การควบคุมเวอร์ชัน - git ด้วย git kraken สำหรับส่วนต่อประสานกราฟิก มันใช้งานง่ายมากและทำความสะอาดไฟล์ของฉันอย่างมาก - ไม่จำเป็นต้องใช้ไฟล์เก่า ๆ อีกต่อไปหรือโค้ดเก่า ๆ แสดงความคิดเห็นว่า "ในกรณี"

ฉันยังติดตั้ง pylint และรันบนโค้ดทั้งหมดของฉัน เริ่มต้นหนึ่งไฟล์มีคะแนนลบ ฉันไม่แน่ใจด้วยซ้ำว่ามันเป็นไปได้อย่างไร ไฟล์หลักของฉันเริ่มต้นที่คะแนน ~ 1.83 / 10 และตอนนี้อยู่ที่ ~ 9.1 / 10 รหัสทั้งหมดตอนนี้สอดคล้องกับมาตรฐานค่อนข้างดี ฉันวิ่งไปหามันด้วยสายตาของฉันเองในการอัพเดตชื่อตัวแปรที่หายไป ... เอ่อ ... เหรอ ... และมองหาส่วนต่างๆ

โดยเฉพาะอย่างยิ่งฉันถามคำถามเมื่อเร็ว ๆ นี้ในไซต์นี้เกี่ยวกับการรีแฟคเตอร์หนึ่งในฟังก์ชั่นหลักของฉันและตอนนี้มันสะอาดกว่าและสั้นกว่ามาก: แทนที่ฟังก์ชั่นที่เต็มไปด้วยความยาว ขนาดและง่ายต่อการหาว่าเกิดอะไรขึ้น

ขั้นตอนต่อไปของฉันคือการใช้ "การทดสอบหน่วย" แปลก ๆ โดยที่ฉันหมายถึงไฟล์ที่ฉันสามารถเรียกใช้ในไฟล์หลักของฉันซึ่งดูฟังก์ชั่นทั้งหมดที่อยู่ในนั้นด้วยคำสั่ง assert และลอง / ยกเว้นซึ่งอาจไม่ใช่วิธีที่ดีที่สุดในการทำมันและผลลัพธ์ในรหัสที่ซ้ำกันจำนวนมาก แต่ฉันจะอ่านต่อไปและพยายามหาวิธีที่จะทำให้ดีขึ้น

ฉันได้อัปเดตเอกสารที่ฉันเขียนไปแล้วและเพิ่มไฟล์เสริมเช่นสเปรดชีต excel เอกสารและเอกสารที่เกี่ยวข้องไปยังที่เก็บ github มันดูเหมือนโครงการเขียนโปรแกรมจริงตอนนี้

ดังนั้น ... ผมคิดว่านี่เป็นสิ่งที่จะพูดว่า: ขอขอบคุณ




8
หากคุณแข็งขันต้องการที่จะปรับปรุงรหัสของคุณคุณอาจพิจารณาการโพสต์บางอย่างเกี่ยวกับรหัสตรวจสอบ ชุมชนที่นั่นยินดีช่วยเหลือคุณ
hoffmale

7
เมื่อคุณพูดว่า "นอกเหนือจากการใช้การควบคุมเวอร์ชันและสร้างไฟล์ใหม่สำหรับการวนซ้ำใหม่และการบันทึกทั้งหมดในไฟล์ข้อความ" และ "คุณหมายถึง" หรือ "เพราะถ้าคุณใช้การควบคุมเวอร์ชันคุณไม่ควรทำ ไม่ต้องคัดลอกเวอร์ชันที่วาง ประเด็นก็คือการควบคุมเวอร์ชันจะช่วยให้คุณมีเวอร์ชั่นเก่าทั้งหมด
Richard Tingle

2
@ โปรแกรมอ่านเมลฉันไม่คิดว่าคุณจะค่อนข้างเข้าใจ ใช่มีเพียงฉันเท่านั้นที่ทุกคนจะอ่านและยุ่งเกี่ยวกับรหัส (แม้ว่าคุณจะไม่เคยรู้และฉันมีใครบางคนที่ฉันทำงานด้วยที่สามารถเขียนโปรแกรมในภาษาอื่น) ... แต่รหัสยังคงอยู่ อึ. ฉันจะต้องอ่านในภายหลังและคิดออกใหม่ว่าฉันกำลังทำอะไรอยู่ มันเป็นปัญหาและฉันสามารถเป็นพยานได้เพราะฉันได้รับผลกระทบในขณะนี้และสิ่งต่าง ๆ ได้ง่ายขึ้นเมื่อฉันใช้การควบคุมเวอร์ชันและเทคนิคอื่น ๆ ที่แนะนำที่นี่
ทุ่งหญ้า

คำตอบ:


163

นี่เป็นปัญหาที่พบได้บ่อยสำหรับนักวิทยาศาสตร์ ฉันเคยเห็นมันมากและมันก็มักจะเกิดขึ้นจากความจริงที่ว่าการเขียนโปรแกรมเป็นสิ่งที่คุณเลือกที่ด้านข้างเป็นเครื่องมือในการทำงานของคุณ

ดังนั้นสคริปต์ของคุณเป็นระเบียบ ฉันจะไปกับสามัญสำนึกและบอกว่าสมมติว่าคุณกำลังเขียนโปรแกรมอยู่คนเดียวมันก็ไม่เลวเลย! คุณจะไม่มีวันได้สัมผัสกับสิ่งที่คุณเขียนอีกเลยดังนั้นใช้เวลามากเกินไปในการเขียนโค้ดสวย ๆ แทนที่จะสร้าง "คุณค่า" (ดังนั้นผลลัพธ์ของสคริปต์ของคุณ) จะไม่ทำอะไรให้คุณมากนัก

อย่างไรก็ตามจะมีเวลาที่คุณต้องกลับไปที่สิ่งที่คุณทำและดูว่าสิ่งที่ทำงาน นอกจากนี้หากนักวิทยาศาสตร์คนอื่นจะต้องทบทวนโค้ดของคุณมันสำคัญมากที่จะต้องชัดเจนและรัดกุมที่สุดเท่าที่จะเป็นไปได้เพื่อให้ทุกคนสามารถเข้าใจได้

ปัญหาหลักของคุณกำลังอ่านง่ายดังนั้นนี่คือเคล็ดลับในการปรับปรุง:

ชื่อตัวแปร:

นักวิทยาศาสตร์ชอบใช้สัญลักษณ์สั้น ๆ สมการทางคณิตศาสตร์ทั้งหมดมักจะใช้ตัวอักษรเดียวเป็นตัวแปรและฉันไม่แปลกใจเลยที่จะเห็นตัวแปรสั้น ๆ มากมายในรหัสของคุณ สิ่งนี้สร้างความเจ็บปวดให้กับการอ่านได้มาก เมื่อคุณกลับไปที่รหัสของคุณคุณจะไม่จำสิ่งที่ y, ฉันและ x2 เหล่านั้นแสดงถึงและคุณจะใช้เวลามากในการพยายามคิดออก ลองใช้การตั้งชื่อตัวแปรของคุณแทนอย่างชัดเจนโดยใช้ชื่อที่แสดงถึงสิ่งที่พวกเขาเป็น

แบ่งรหัสของคุณเป็นฟังก์ชั่น:

ตอนนี้คุณเปลี่ยนชื่อตัวแปรทั้งหมดสมการของคุณดูแย่มากและมีความยาวหลายบรรทัด

แทนที่จะทิ้งไว้ในโปรแกรมหลักของคุณให้ย้ายสมการนั้นไปยังฟังก์ชั่นอื่นแล้วตั้งชื่อตามนั้น ตอนนี้แทนที่จะมีโค้ดขนาดใหญ่และสับสนคุณจะมีคำแนะนำสั้น ๆ ที่บอกคุณได้อย่างชัดเจนว่าเกิดอะไรขึ้นและคุณใช้สมการอะไร สิ่งนี้จะปรับปรุงทั้งโปรแกรมหลักของคุณเนื่องจากคุณไม่จำเป็นต้องดูสมการที่แท้จริงเพื่อรู้ว่าคุณทำอะไรและรหัสสมการเองในฟังก์ชันแยกต่างหากคุณสามารถตั้งชื่อตัวแปรตามที่คุณต้องการและกลับไปที่ ตัวอักษรเดียวที่คุ้นเคยมากขึ้น

ในแนวความคิดนี้ลองค้นหารหัสทั้งหมดที่เป็นตัวแทนของสิ่งต่าง ๆ โดยเฉพาะอย่างยิ่งถ้าสิ่งนั้นเป็นสิ่งที่คุณต้องทำหลาย ๆ ครั้งในรหัสของคุณและแยกออกเป็นฟังก์ชั่น คุณจะพบว่ารหัสของคุณจะอ่านง่ายขึ้นอย่างรวดเร็วและคุณจะสามารถใช้ฟังก์ชั่นเดียวกันโดยไม่ต้องเขียนโค้ดเพิ่มเติม

ถ้าหากฟังก์ชั่นเหล่านั้นมีความจำเป็นในโปรแกรมของคุณคุณสามารถสร้างห้องสมุดให้กับพวกมันได้และคุณจะสามารถใช้งานมันได้ตลอดเวลา

ตัวแปรทั่วโลก:

ย้อนกลับไปเมื่อฉันเป็นผู้เริ่มต้นฉันคิดว่านี่เป็นวิธีที่ยอดเยี่ยมในการส่งผ่านข้อมูลที่ฉันต้องการในหลาย ๆ จุดของโปรแกรม ปรากฎว่ามีหลายวิธีในการผ่านสิ่งต่าง ๆ และสิ่งเดียวที่ตัวแปรระดับโลกทำคือทำให้ผู้คนปวดหัวเพราะถ้าคุณไปที่จุดสุ่มของโปรแกรมคุณจะไม่มีทางรู้ว่าค่านั้นถูกใช้หรือแก้ไขครั้งสุดท้ายเมื่อใดและ การติดตามมันจะเป็นความเจ็บปวด พยายามหลีกเลี่ยงพวกเขาทุกครั้งที่ทำได้

หากฟังก์ชั่นของคุณต้องการส่งคืนหรือแก้ไขค่าหลายค่าให้สร้างคลาสที่มีค่าเหล่านั้นและส่งค่าเหล่านั้นเป็นพารามิเตอร์หรือทำให้ฟังก์ชันส่งคืนค่าหลายค่า (ที่มีชื่อ tuples) และกำหนดค่าเหล่านั้นในรหัสผู้โทร

การควบคุมเวอร์ชัน

สิ่งนี้ไม่ได้ปรับปรุงการอ่านโดยตรง แต่ช่วยให้คุณทำตามข้างต้นทั้งหมด เมื่อใดก็ตามที่คุณทำการเปลี่ยนแปลงให้คอมมิทเข้าควบคุมเวอร์ชัน (ที่เก็บ Git ในท้องถิ่นจะใช้ได้ดี) และถ้ามีอะไรบางอย่างไม่ทำงานให้ดูที่สิ่งที่คุณเปลี่ยนแปลงหรือย้อนกลับไป! วิธีนี้จะทำให้การปรับโครงสร้างโค้ดของคุณง่ายขึ้นและจะเป็นเครือข่ายความปลอดภัยหากคุณเผลอทำสิ่งต่าง ๆ โดยไม่ตั้งใจ

การคำนึงทั้งหมดนี้ไว้ในใจจะช่วยให้คุณเขียนโค้ดที่ชัดเจนและมีประสิทธิภาพมากขึ้นและจะช่วยให้คุณค้นพบข้อผิดพลาดที่อาจเกิดขึ้นได้เร็วขึ้นเนื่องจากคุณไม่ต้องลุยฟังก์ชั่นขนาดใหญ่และตัวแปรยุ่ง


56
คำแนะนำที่ยอดเยี่ยม อย่างไรก็ตามฉันไม่สามารถลงคะแนนสำหรับความคิดเห็น "ที่ไม่เลว" มันแย่มาก สคริปต์วิทยาศาสตร์คุณภาพต่ำเป็นปัญหาใหญ่สำหรับการทำซ้ำในการวิเคราะห์ข้อมูลและแหล่งที่มาของข้อผิดพลาดบ่อยครั้งในการวิเคราะห์ การเขียนโค้ดที่ดีนั้นมีค่าไม่เพียงเพื่อให้คุณสามารถเข้าใจได้ในภายหลัง แต่ยังเพื่อให้คุณสามารถหลีกเลี่ยงข้อผิดพลาดได้ตั้งแต่แรก
Jack Aidley

22
หากรหัสเป็นการใช้งานสูตรที่รู้จักกันดีชื่อตัวแปรตัวอักษรตัวเดียวและอาจเป็นสิ่งที่ถูกต้อง ขึ้นอยู่กับผู้ชม ... และอีกหลายประเด็นไม่ว่าผู้อ่านจะได้รู้ว่าชื่อนั้นมีความหมายหรือไม่
cHao

11
@ cao ปัญหาไม่ได้เมื่อเสียบตัวแปรเหล่านั้นในสูตร (ดังนั้นคำแนะนำ "เปลี่ยนชื่อพวกเขาในฟังก์ชั่น") แต่เมื่อพวกเขาอ่านและจัดการนอกมันและเมื่อพวกเขาเริ่มขัดแย้งกับตัวแปรอื่น ๆ ลงในบรรทัด (ตัวอย่างเช่นฉันเคยเห็นคนที่ต้องการตัวแปร "x" สามตัวตั้งชื่อพวกเขา x1, x2, x3)
BgrWorker

4
"ฉันจะไปกับสามัญสำนึก ... " ไม่คุณไม่ได้ คุณกำลังต่อต้านหลักการที่มีอยู่จริงซึ่งขัดแย้งกับสามัญสำนึก ;) นี่คือคำแนะนำเสียงที่สมบูรณ์แบบ
jpmc26

3
ในฐานะโปรแกรมเมอร์ทางวิทยาศาสตร์ (อดีต) ฉันมักจะใช้กฎสามข้อ ถ้าฉันจบการเขียนโค้ดที่คล้ายกันสามครั้งการทำงานจะถูกทำให้เป็นเนื้อและเขียนขึ้นในโมดูลแยกต่างหากพร้อมด้วยเอกสารประกอบ (มักจะเป็นแค่ความคิดเห็น แต่ก็เพียงพอแล้ว) สิ่งนี้จำกัดความวุ่นวายของการเขียนโปรแกรมแบบเฉพาะกิจและทำให้ฉันสามารถสร้างห้องสมุดที่ฉันสามารถขยายได้ในอนาคต
rcollyer

141

นักฟิสิกส์ที่นี่ เคยไปที่นั่น.

ฉันจะยืนยันว่าปัญหาของคุณไม่ได้เกี่ยวกับการเลือกใช้เครื่องมือหรือกระบวนทัศน์การเขียนโปรแกรม (การทดสอบหน่วย, OOP, อะไรก็ตาม) มันเกี่ยวกับ ทัศนคติความคิด ความจริงที่ว่าชื่อตัวแปรของคุณได้รับการคัดเลือกอย่างดีในตอนแรกและท้ายที่สุดกลายเป็นเรื่องไร้สาระก็เพียงพอแล้ว หากคุณคิดว่ารหัสของคุณเป็น "เรียกใช้ครั้งเดียวแล้วละทิ้ง" ก็จะเป็นสิ่งที่หลีกเลี่ยงไม่ได้ หากคุณคิดว่ามันเป็นผลิตภัณฑ์ของงานฝีมือและความรักมันจะสวยงาม

ฉันเชื่อว่ามีเพียงสูตรอาหารเดียวสำหรับการเขียนโค้ดที่สะอาด: เขียนเพื่อมนุษย์ที่กำลังจะอ่านไม่ใช่สำหรับล่ามที่จะเรียกใช้ ล่ามไม่ดูแลถ้ารหัสของคุณเป็นระเบียบ แต่ผู้อ่านของมนุษย์ไม่ดูแล

คุณเป็นนักวิทยาศาสตร์ คุณอาจใช้เวลาขัดบทความทางวิทยาศาสตร์เป็นจำนวนมาก หากร่างแรกของคุณดูซับซ้อนคุณจะต้องปรับโครงสร้างใหม่จนกว่าตรรกะจะไหลอย่างเป็นธรรมชาติมากที่สุด คุณต้องการให้เพื่อนร่วมงานอ่านและหาข้อโต้แย้งที่ชัดเจน คุณต้องการให้นักเรียนของคุณสามารถเรียนรู้จากมัน

การเขียนโค้ดที่สะอาดเหมือนกันทุกประการ คิดว่ารหัสของคุณเป็นคำอธิบายโดยละเอียดของอัลกอริทึมที่บังเอิญสามารถอ่านได้ด้วยเครื่องเท่านั้น ลองนึกภาพคุณกำลังจะเผยแพร่มันเป็นบทความที่ผู้คนจะอ่าน คุณกำลังจะแสดงในการประชุมและนำผู้ชมผ่านมันทีละบรรทัด ตอนนี้ซ้อมการนำเสนอของคุณ ใช่ทีละบรรทัด ! น่าอายใช่มั้ย ดังนั้นล้างสไลด์ของคุณ (เอ่อ ... ฉันหมายถึงรหัสของคุณ) แล้วซ้อมอีกครั้ง ทำซ้ำจนกว่าคุณจะพอใจกับผลลัพธ์

จะดีกว่าถ้าหลังจากการฝึกซ้อมคุณสามารถแสดงรหัสของคุณให้กับคนจริงมากกว่าแค่คนในจินตนาการและตัวตนในอนาคตของคุณ การผ่านทีละบรรทัดเรียกว่า "การเดินรหัส" และไม่ใช่การปฏิบัติที่โง่เขลา

แน่นอนว่าทั้งหมดนี้มีค่าใช้จ่าย เขียนรหัสสะอาดจะใช้เวลามาก เวลามากขึ้นกว่าการเขียนรหัสใบปลิว มีเพียงคุณเท่านั้นที่สามารถประเมินได้ว่าผลประโยชน์นั้นมีมากกว่าค่าใช้จ่ายสำหรับกรณีการใช้งานเฉพาะของคุณหรือไม่

ในฐานะที่เป็นเครื่องมือที่ผมบอกว่าก่อนที่พวกเขาไม่ได้ที่สำคัญ อย่างไรก็ตามถ้าฉันต้องเลือกอย่างใดอย่างหนึ่งฉันจะบอกว่าการควบคุมเวอร์ชันมีประโยชน์มากที่สุด


32
«การเขียนโค้ดที่สะอาดเหมือนกันกับ [การเขียนบทความที่ชัดเจน] »ฉันรับรองอย่างเต็มที่แล้วเอาล่ะ!
juandesant

43
นี่คือสิ่งที่โปรแกรมเมอร์มืออาชีพส่วนใหญ่ลืมพูดเพราะเห็นได้ชัด รหัสของคุณเสร็จสมบูรณ์เมื่อโปรแกรมเมอร์อื่นสามารถอ่านและแก้ไขได้ ไม่ใช่เมื่อรันและสร้างเอาต์พุตที่ถูกต้อง OP ต้องการใช้จ่ายและชั่วโมงเพิ่มเติมต่อการสร้างสคริปต์ใหม่และแสดงความคิดเห็นรหัสของเขาเพื่อให้สามารถอ่านได้โดยมนุษย์
UEFI

31
ถึงแม้ว่าการเขียนโค้ดแบบคลีนจะใช้เวลานานกว่าการเขียนโค้ดแบบอะเวย์ แต่สิ่งที่สำคัญกว่าก็คือการอ่านโค้ดแบบอะเวย์นั้นใช้เวลามากกว่าการอ่านโค้ดแบบคลีน
user949300

3
@UEFI ไม่มันเป็นสิ่งที่โปรแกรมเมอร์มืออาชีพส่วนใหญ่ไม่ได้ตระหนักถึง หรือไม่สนใจ
jpmc26

2
ยอมรับ 100% นักสถิติหันมาเขียนโปรแกรมดังนั้นฉันจึงทำการเขียนโปรแกรม 'วิทยาศาสตร์' ในปริมาณที่พอใช้ รหัสที่ชัดเจนพร้อมความคิดเห็นที่มีความหมายคือผู้ช่วยชีวิตเมื่อคุณต้องกลับไปที่รหัส 1, 4 หรือ 12 เดือนต่อมา การอ่านรหัสจะบอกคุณถึงสิ่งที่รหัสกำลังทำอยู่ การอ่านความคิดเห็นจะบอกคุณว่าควรจะใช้รหัสอย่างไร
railsdog

82

การควบคุมเวอร์ชันน่าจะทำให้คุณได้เงินมากที่สุด มันไม่ได้มีไว้สำหรับการจัดเก็บข้อมูลระยะยาวเท่านั้นมันเหมาะสำหรับการติดตามการทดลองระยะสั้นของคุณและกลับไปใช้เวอร์ชันล่าสุดที่ใช้งานได้

สิ่งที่มีประโยชน์ที่สุดคือการทดสอบหน่วย สิ่งที่เกี่ยวกับการทดสอบหน่วยคือแม้แต่รหัสฐานที่มีรหัสเป็นล้าน ๆ บรรทัดนั้นเป็นการทดสอบหน่วยครั้งละหนึ่งฟังก์ชั่น การทดสอบหน่วยจะทำในขนาดเล็กที่ระดับต่ำสุดของสิ่งที่เป็นนามธรรม นั่นหมายความว่าไม่มีความแตกต่างระหว่างการทดสอบหน่วยที่เขียนขึ้นสำหรับฐานรหัสขนาดเล็กและที่ใช้สำหรับการทดสอบขนาดใหญ่ มีพวกเขามากขึ้น

การทดสอบหน่วยเป็นวิธีที่ดีที่สุดในการป้องกันไม่ให้สิ่งที่เคยทำมาแล้วเมื่อคุณแก้ไขสิ่งอื่นหรืออย่างน้อยก็จะบอกคุณอย่างรวดเร็วเมื่อคุณทำ จริงๆแล้วมันมีประโยชน์มากกว่าเมื่อคุณไม่ชำนาญโปรแกรมเมอร์หรือไม่ทราบว่าจะเขียนโค้ด verbose เพิ่มเติมที่มีโครงสร้างเพื่อให้เกิดข้อผิดพลาดได้น้อยลงหรือชัดเจนขึ้น

ระหว่างการควบคุมเวอร์ชันและการเขียนการทดสอบหน่วยในขณะที่คุณไปคุณจะกลายเป็นรหัสที่สะอาดมากขึ้น เทคนิคอื่น ๆ สำหรับการเขียนโค้ดสะอาดสามารถเรียนรู้ได้เมื่อคุณกดปุ่มที่ราบสูง


78
ฉันเคร่งครัดทดสอบหน่วยมากที่สุดของรหัสของฉัน แต่ฉันได้พบหน่วยสอบสวนทดสอบรหัสวิทยาศาสตร์น้อยกว่าที่ไร้ประโยชน์ วิธีการพื้นฐานดูเหมือนจะไม่ทำงานที่นี่ ฉันไม่รู้นักวิทยาศาสตร์การคำนวณใด ๆ ในสาขาของฉันที่ทำการทดสอบโค้ดการวิเคราะห์ของพวกเขา ฉันไม่แน่ใจว่าสาเหตุของการจับคู่นี้ไม่ตรงกัน แต่หนึ่งในเหตุผลนั้นแน่นอนว่ายกเว้นหน่วยเล็กน้อยมันเป็นเรื่องยากหรือเป็นไปไม่ได้ที่จะสร้างกรณีทดสอบที่ดี
Konrad Rudolph

22
@KonradRudolph เคล็ดลับในกรณีเหล่านั้นน่าจะเป็นการแยกความกังวลระหว่างส่วนต่าง ๆ ของรหัสของคุณที่มีพฤติกรรมที่ชัดเจน (อ่านอินพุตนี้คำนวณค่านี้) จากส่วนของรหัสของคุณที่มีการสำรวจอย่างแท้จริงหรือปรับตัวเช่น เอาท์พุทหรือการสร้างภาพบางส่วนที่มนุษย์สามารถอ่านได้ ปัญหาที่นี่มีแนวโน้มว่าการแยกความกังวลที่ไม่ดีทำให้เกิดการเบลอของเส้นเหล่านั้นซึ่งนำไปสู่การรับรู้ว่าการทดสอบหน่วยในบริบทนี้เป็นไปไม่ได้ซึ่งนำคุณกลับไปสู่จุดเริ่มต้นในรอบการทำซ้ำ
Ant P

18
ในหมายเหตุด้านการควบคุมเวอร์ชันยังทำงานได้ค่อนข้างดีสำหรับเอกสาร LaTeX เนื่องจากรูปแบบสามารถตอบสนองต่อการกระจายข้อความได้ ด้วยวิธีนี้คุณสามารถมีพื้นที่เก็บข้อมูลสำหรับทั้งเอกสารของคุณและรหัสที่สนับสนุนพวกเขา ฉันแนะนำให้ดูที่การควบคุมเวอร์ชันแบบกระจายเช่น Git มีบิตของเส้นโค้งการเรียนรู้ แต่เมื่อคุณเข้าใจว่าคุณมีวิธีทำความสะอาดที่ดีที่จะย้ำในการพัฒนาของคุณและคุณมีตัวเลือกที่น่าสนใจที่จะใช้แพลตฟอร์มเช่น Github ซึ่งมีบัญชีทีมฟรีสำหรับนักวิชาการ
Dan Bryant

12
@AntP เป็นไปได้ว่ามีเพียงไม่มากรหัสที่สามารถ refactored ออกความหมายในหน่วยทดสอบที่กำหนดไว้อย่างดี รหัสทางวิทยาศาสตร์จำนวนมากกำลังอัดไลบรารีเป็นกลุ่มเข้าด้วยกัน ห้องสมุดเหล่านี้จะได้รับการทดสอบอย่างดีและมีโครงสร้างที่ดีซึ่งหมายความว่าผู้เขียนเพียงแค่ต้องเขียน "กาว" และจากประสบการณ์ของฉันมันเป็นไปไม่ได้เลยที่จะเขียนการทดสอบหน่วยสำหรับกาวที่ไม่ได้ใช้ภาษา
James_pic

7
"ระหว่างการควบคุมเวอร์ชันและการเขียนการทดสอบหน่วยในขณะที่คุณใช้รหัสคุณจะกลายเป็นคนที่สะอาดกว่ามาก" สิ่งนี้ไม่เป็นความจริง ฉันสามารถยืนยันได้เป็นการส่วนตัว ไม่มีเครื่องมือเหล่านี้ที่จะหยุดคุณจากการเขียนรหัสเส็งเคร็งและโดยเฉพาะอย่างยิ่งการเขียนการทดสอบเส็งเคร็งด้านบนของรหัสเส็งเคร็งเพียงทำให้ยากต่อการล้าง การทดสอบไม่ใช่กระสุนเงินเวทย์มนตร์และการพูดถึงสิ่งเหล่านี้เป็นสิ่งที่น่ากลัวสำหรับนักพัฒนาที่ยังคงเรียนรู้ (ซึ่งก็คือทุกคน) โดยทั่วไปการควบคุมเวอร์ชันจะไม่ทำให้รหัสเสียหายเช่นเดียวกับการทดสอบที่ไม่ดี
jpmc26

29

(นอกเหนือจากการใช้การควบคุมเวอร์ชันและการสร้างไฟล์ใหม่สำหรับการวนซ้ำใหม่แต่ละครั้งและการบันทึกทั้งหมดในไฟล์ข้อความที่อื่นซึ่งอาจจะช่วยสถานการณ์ได้อย่างมาก)

คุณอาจจะคิดออกเอง แต่ถ้าคุณต้อง " บันทึกทั้งหมดไว้ในแฟ้มข้อความที่ไหนสักแห่ง " คุณไม่ได้ใช้ระบบควบคุมเวอร์ชันให้เต็มศักยภาพ ใช้บางอย่างเช่นการโค่นล้ม git หรือ Mercurial และเขียนข้อความคอมมิชชันที่ดีกับคอมมิชชันทุกอันและคุณจะมีบันทึกที่ใช้สำหรับวัตถุประสงค์ของไฟล์ข้อความ แต่ไม่สามารถแยกออกจากที่เก็บได้

ว่ากันโดยใช้การควบคุมเวอร์ชันเป็นสิ่งที่สำคัญที่สุดที่คุณสามารถทำได้ด้วยเหตุผลที่ไม่มีคำตอบที่มีอยู่กล่าวถึง: การทำสำเนาของผลลัพธ์ หากคุณสามารถใช้ข้อความบันทึกของคุณหรือเพิ่มบันทึกในผลลัพธ์ด้วยหมายเลขการแก้ไขคุณสามารถมั่นใจได้ว่าจะสามารถสร้างผลลัพธ์ใหม่ได้และคุณจะสามารถวางโค้ดได้ดีขึ้น

การทดสอบหน่วยจำเป็นสำหรับการเขียนโค้ดขนาดเล็กลงหรือไม่? แล้ว OOP ล่ะ วิธีใดบ้างที่ดีสำหรับการเขียนโค้ดที่ดีและสะอาดได้อย่างรวดเร็วเมื่อทำการ "การเขียนโปรแกรมเชิงวิทยาศาสตร์" ซึ่งต่างจากการทำงานในโครงการขนาดใหญ่

การทดสอบหน่วยไม่จำเป็น แต่ก็มีประโยชน์ถ้า (a) รหัสนั้นเป็นโมดูลที่เพียงพอที่คุณสามารถทดสอบหน่วยแทนที่จะเป็นแบบทั้งหมด (b) คุณสามารถสร้างแบบทดสอบ เป็นการดีที่คุณจะสามารถเขียนผลลัพธ์ที่คาดหวังได้ด้วยตัวเองแทนที่จะสร้างด้วยรหัสแม้ว่าอย่างน้อยการสร้างด้วยรหัสสามารถให้การทดสอบการถดถอยซึ่งบอกคุณว่ามีบางอย่างเปลี่ยนพฤติกรรมของมันหรือไม่ เพียงแค่พิจารณาว่าการทดสอบนั้นมีแนวโน้มว่าจะบั๊กกี้มากกว่ารหัสที่พวกเขากำลังทดสอบอยู่หรือไม่

OOP เป็นเครื่องมือ ใช้มันหากมันช่วยได้ แต่มันไม่ใช่กระบวนทัศน์เดียว ฉันสมมติว่าคุณรู้จักการเขียนโปรแกรมแบบขั้นตอนจริงเท่านั้น: ถ้าเป็นเช่นนั้นในบริบทที่อธิบายไว้ฉันคิดว่าคุณจะได้รับประโยชน์จากการเรียนรู้การเขียนโปรแกรมเชิงปฏิบัติการมากกว่า OOP และโดยเฉพาะอย่างยิ่งระเบียบวินัยในการหลีกเลี่ยงผลข้างเคียง Python สามารถเขียนในรูปแบบที่ใช้งานได้ดีมาก


4
+1 สำหรับการส่งข้อความ; พวกเขาเป็นเหมือนความคิดเห็นที่ไม่สามารถล้าสมัยได้เพราะมันเชื่อมโยงกับเวอร์ชันของรหัสเมื่อใช้งานได้จริง เพื่อให้เข้าใจรหัสเก่าของคุณได้ง่ายขึ้นที่จะดูประวัติของโครงการ (ถ้าการเปลี่ยนแปลงมีความละเอียดพอสมควร) แทนที่จะอ่านความคิดเห็นที่ล้าสมัย
Silly Freak

การโค่นล้มคอมไพล์และ Mercurial นั้นไม่สามารถทำได้ ฉันขอแนะนำอย่างยิ่งให้ใช้ Git (หรือ Mercurial) กับที่เก็บข้อมูลในพื้นที่เหนือการโค่นล้ม ด้วยโคเดอร์เดี่ยวข้อบกพร่องของการโค่นล้มเป็นปัญหาน้อยลง แต่มันไม่ใช่เครื่องมือที่ยอดเยี่ยมสำหรับการพัฒนาความร่วมมือและที่อาจเกิดขึ้นในการวิจัย
mcottle

2
@mcottle ฉันชอบคอมไพล์ส่วนตัว แต่ฉันไม่คิดว่านี่เป็นสถานที่ที่เหมาะสมที่จะพูดถึงรายละเอียดเกี่ยวกับความแตกต่างโดยเฉพาะอย่างยิ่งเนื่องจากตัวเลือกเป็นหนึ่งในสงครามศาสนาที่คึกคัก ดีกว่าที่จะกระตุ้นให้ OP ใช้บางอย่างมากกว่าทำให้ตกใจพวกเขาออกไปจากพื้นที่และการตัดสินใจไม่ได้ถาวรในทุกกรณี
Peter Taylor

21

ในบัณฑิตวิทยาลัยฉันเขียนโค้ดอัลกอริทึมบางตัวเอง มันเป็นเรื่องยากที่จะแตก โดยทั่วไปแล้วการประชุมการเขียนโปรแกรมจำนวนมากถูกสร้างขึ้นมาจากแนวคิดของการใส่ข้อมูลลงในฐานข้อมูลการดึงข้อมูลในเวลาที่เหมาะสมจากนั้นทำการนวดข้อมูลเพื่อนำเสนอให้ผู้ใช้โดยทั่วไปจะใช้ห้องสมุดสำหรับคณิตศาสตร์หรือ ส่วนอัลกอริทึมของกระบวนการนั้น สำหรับโปรแกรมเหล่านี้ทุกสิ่งที่คุณเคยได้ยินเกี่ยวกับ OOP การแบ่งรหัสเป็นฟังก์ชั่นสั้น ๆ และทำให้ทุกอย่างเข้าใจได้ง่ายในทันทีที่เป็นไปได้คือคำแนะนำที่ยอดเยี่ยม แต่มันก็ไม่ได้ผลสำหรับรหัสหนัก ๆ ของอัลกอริทึมหรือรหัสที่ใช้การคำนวณทางคณิตศาสตร์ที่ซับซ้อนและอย่างอื่น

หากคุณกำลังเขียนสคริปต์เพื่อทำการคำนวณทางวิทยาศาสตร์คุณอาจมีเอกสารที่มีสมการหรืออัลกอริทึมที่คุณใช้เขียนขึ้นมา หากคุณกำลังใช้แนวคิดใหม่ที่คุณค้นพบด้วยตัวคุณเองคุณหวังว่าจะเผยแพร่แนวคิดเหล่านั้นในเอกสารของคุณเอง ในกรณีนี้กฎคือ: คุณต้องการให้โค้ดของคุณอ่านเหมือนกับสมการที่เผยแพร่มากที่สุด นี่คือคำตอบของ Software Engineering.SE ที่มีผู้โหวตมากกว่า 200 คนที่สนับสนุนแนวทางนี้และอธิบายสิ่งที่ดูเหมือน: มีข้อแก้ตัวสำหรับชื่อตัวแปรแบบสั้นหรือไม่?

อีกตัวอย่างหนึ่งมีตัวอย่างโค้ดที่ยอดเยี่ยมในSimbodyซึ่งเป็นเครื่องมือจำลองฟิสิกส์ที่ใช้สำหรับการวิจัยทางฟิสิกส์และวิศวกรรม ตัวอย่างเหล่านี้มีความคิดเห็นที่แสดงสมการที่ใช้สำหรับการคำนวณตามด้วยรหัสที่อ่านได้ใกล้เคียงกับสมการที่นำไปใช้มากที่สุด

ContactGeometry.cpp:

// t = (-b +/- sqrt(b^2-4ac)) / 2a
// Discriminant must be nonnegative for real surfaces
// but could be slightly negative due to numerical noise.
Real sqrtd = std::sqrt(std::max(B*B - 4*A*C, Real(0)));
Vec2 t = Vec2(sqrtd - B, -sqrtd - B) / (2*A);

ContactGeometry_Sphere.cpp:

// Solve the scalar Jacobi equation
//
//        j''(s) + K(s)*j(s) = 0 ,                                     (1)
//
// where K is the Gaussian curvature and (.)' := d(.)/ds denotes differentiation
// with respect to the arc length s. Then, j is the directional sensitivity and
// we obtain the corresponding variational vector field by multiplying b*j. For
// a sphere, K = R^(-2) and the solution of equation (1) becomes
//
//        j  = R * sin(1/R * s)                                        (2)
//          j' =     cos(1/R * s) ,                                      (3)
//
// where equation (2) is the standard solution of a non-damped oscillator. Its
// period is 2*pi*R and its amplitude is R.

// Forward directional sensitivity from P to Q
Vec2 jPQ(R*sin(k * s), cos(k * s));
geod.addDirectionalSensitivityPtoQ(jPQ);

// Backwards directional sensitivity from Q to P
Vec2 jQP(R*sin(k * (L-s)), cos(k * (L-s)));
geod.addDirectionalSensitivityQtoP(jQP);

9
อีกอย่างหนึ่งสำหรับการสร้าง "รหัสให้อ่านมากเหมือนกับสมการที่ตีพิมพ์มากที่สุด" ขออภัยผู้สนับสนุนชื่อตัวแปรที่ยาวและมีความหมาย ชื่อที่มีความหมายมากที่สุดในรหัสทางวิทยาศาสตร์ของการเกิดครั้งนี้น่ารังเกียจสั้นและโหดเหี้ยมอย่างแม่นยำเพราะนั่นเป็นแบบแผนที่ใช้ในวารสารทางวิทยาศาสตร์ที่รหัสพยายามใช้ สำหรับโค้ดที่มีสมการหนักที่ใช้สมการที่พบในกระดาษวารสารมันมักจะดีที่สุดที่จะอยู่ใกล้ที่สุดเท่าที่จะเป็นไปได้กับการตั้งชื่อในกระดาษและถ้ามันขัดกับมาตรฐานการเข้ารหัสที่ดี
David Hammen

@DavidHammen: ในฐานะนักเรียนระดับบัณฑิตศึกษาฉันเคารพในสิ่งนั้น ในฐานะโปรแกรมเมอร์ฉันจะยืนยันว่าคุณมีบล็อกความคิดเห็นขนาดยักษ์ที่ด้านบนของแต่ละฟังก์ชั่นที่อธิบายด้วยภาษาอังกฤษแบบธรรมดา (หรือภาษาที่คุณเลือก) สิ่งที่ตัวแปรแต่ละตัวยืนอยู่แม้ว่าจะเป็นเพียงตัวยึดตำแหน่งชั่วคราว อย่างน้อยฉันก็มีการอ้างอิงที่จะมองย้อนกลับไป
tonysdg

1
@DavidHammen นอกจากนี้ Python ยังรองรับ UTF-8 ในไฟล์ต้นฉบับและกฎง่าย ๆ สำหรับชื่อตัวแปรทำให้ง่ายต่อการประกาศλหรือφแทนชื่อน่าเกลียดlambda_หรือphy...
Mathias Ettinger

1
@tonysdg คุณมีข้อมูลอ้างอิงอยู่แล้ว มันเรียกว่า "Hammen, et al. (2018)" (หรืออะไรก็ตาม) มันจะอธิบายความหมายของตัวแปรโดยละเอียดยิ่งกว่าความคิดเห็นใด ๆ ที่เคยทำได้ เหตุผลที่ทำให้ชื่อตัวแปรใกล้เคียงกับสัญกรณ์ในกระดาษนั้นมีความแม่นยำเพื่อให้ง่ายต่อการเชื่อมต่อสิ่งที่อยู่ในกระดาษกับสิ่งที่อยู่ในรหัส
ไม่มีใคร

17

ดังนั้นงานประจำวันของฉันจึงอยู่ในการตีพิมพ์และเก็บรักษาข้อมูลการวิจัยสำหรับระบบ University of California สองสามคนพูดถึงความสามารถในการทำซ้ำและฉันคิดว่านั่นเป็นประเด็นหลักจริงๆที่นี่: การจัดทำรหัสของคุณในแบบที่คุณต้องการบันทึกสิ่งอื่นที่มีคนต้องการทำซ้ำการทดสอบของคุณและการเขียนโค้ดที่ตรงไปตรง เพื่อทำซ้ำการทดสอบของคุณและตรวจสอบผลลัพธ์ของคุณเพื่อหาแหล่งที่มาของข้อผิดพลาด

แต่สิ่งที่ฉันไม่เคยเห็นมาก่อนกล่าวว่าฉันคิดว่าสำคัญคือหน่วยงานด้านเงินทุนกำลังพิจารณาการตีพิมพ์ซอฟต์แวร์มากขึ้นโดยเป็นส่วนหนึ่งของการเผยแพร่ข้อมูลและการทำให้การตีพิมพ์ซอฟต์แวร์เป็นข้อกำหนดสำหรับวิทยาศาสตร์แบบเปิด

ด้วยเหตุนี้หากคุณต้องการบางสิ่งบางอย่างที่เฉพาะเจาะจงมุ่งเป้าไปที่นักวิจัยมากกว่านักพัฒนาซอฟต์แวร์ทั่วไปฉันไม่สามารถแนะนำองค์กรSoftware Carpentry ได้สูงพอ หากคุณสามารถเข้าร่วมเป็นหนึ่งของการประชุมเชิงปฏิบัติการที่ดี; หากสิ่งที่คุณมีเวลา / การเข้าถึงทำคืออ่านเอกสารของพวกเขาเกี่ยวกับวิธีปฏิบัติที่ดีที่สุดในการคำนวณทางวิทยาศาสตร์นั่นก็ดีเช่นกัน จากหลัง:

นักวิทยาศาสตร์มักจะพัฒนาซอฟต์แวร์ของตัวเองเพื่อวัตถุประสงค์เหล่านี้เพราะการทำเช่นนั้นต้องใช้ความรู้เฉพาะโดเมนที่สำคัญ จากผลการศึกษาล่าสุดพบว่านักวิทยาศาสตร์มักใช้เวลา 30% หรือมากกว่าในการพัฒนาซอฟต์แวร์ อย่างไรก็ตาม 90% หรือมากกว่านั้นส่วนใหญ่มีการเรียนรู้ด้วยตนเองเป็นหลักดังนั้นจึงไม่มีการสัมผัสกับวิธีการพัฒนาซอฟต์แวร์ขั้นพื้นฐานเช่นการเขียนรหัสที่สามารถบำรุงรักษาได้โดยใช้การควบคุมเวอร์ชันและตัวติดตามปัญหาการตรวจสอบรหัสการทดสอบหน่วย

เราเชื่อว่าซอฟต์แวร์เป็นเพียงเครื่องมือทดลองอีกประเภทหนึ่งเท่านั้นและควรสร้างตรวจสอบและใช้อย่างระมัดระวังเหมือนกับเครื่องมือทางกายภาพใด ๆ อย่างไรก็ตามในขณะที่นักวิทยาศาสตร์ส่วนใหญ่ระมัดระวังในการตรวจสอบอุปกรณ์ในห้องปฏิบัติการและภาคสนาม แต่ส่วนใหญ่ไม่ทราบว่าซอฟต์แวร์ของตนน่าเชื่อถือแค่ไหน สิ่งนี้สามารถนำไปสู่ข้อผิดพลาดร้ายแรงที่ส่งผลต่อข้อสรุปสำคัญของการวิจัยที่เผยแพร่ ...

นอกจากนี้เนื่องจากซอฟต์แวร์มักใช้มากกว่าโครงการเดียวและมักถูกนำมาใช้ซ้ำโดยนักวิทยาศาสตร์คนอื่น ๆ ข้อผิดพลาดในการคำนวณอาจส่งผลกระทบที่ไม่สมส่วนต่อกระบวนการทางวิทยาศาสตร์ ผลกระทบแบบเรียงซ้อนประเภทนี้ทำให้เกิดการหดตัวอย่างเด่นหลายครั้งเมื่อไม่พบข้อผิดพลาดจากรหัสของกลุ่มอื่นจนกว่าจะเผยแพร่

โครงร่างระดับสูงของแนวทางปฏิบัติที่พวกเขาแนะนำ:

  1. เขียนโปรแกรมสำหรับคนไม่ใช่คอมพิวเตอร์
  2. ปล่อยให้คอมพิวเตอร์ทำงาน
  3. ทำการเปลี่ยนแปลงที่เพิ่มขึ้น
  4. อย่าทำซ้ำตัวเอง (หรือคนอื่น ๆ )
  5. วางแผนสำหรับข้อผิดพลาด
  6. ปรับซอฟต์แวร์ให้เหมาะสมหลังจากทำงานอย่างถูกต้องเท่านั้น
  7. การออกแบบและวัตถุประสงค์ของเอกสารไม่ใช่กลไก
  8. ร่วมมือ

กระดาษจะมีรายละเอียดมากในแต่ละจุดเหล่านี้


16

มันสมเหตุสมผลหรือไม่ที่จะเขียนโค้ดที่พูดว่า OOP เมื่อบางสิ่งมาตรฐานสามารถทำได้สำเร็จจะเร็วกว่ามากในการเขียนและจะมีระดับการอ่านที่คล้ายกันเนื่องจากความสั้นของโปรแกรม

คำตอบส่วนบุคคล:
ฉันทำสคริปต์มากสำหรับวัตถุประสงค์ทางวิทยาศาสตร์ด้วย สำหรับสคริปต์ที่มีขนาดเล็กกว่าฉันเพียงลองทำตามวิธีการเขียนโปรแกรมที่ดีทั่วไป (เช่นใช้การควบคุมเวอร์ชันฝึกการควบคุมตนเองด้วยชื่อตัวแปร) ถ้าฉันเพิ่งเขียนบางอย่างเพื่อเปิดหรือดูชุดข้อมูลอย่างรวดเร็วฉันไม่ต้องกังวลกับ OOP

คำตอบทั่วไป:
"มันขึ้นอยู่กับ" แต่ถ้าคุณกำลังดิ้นรนที่จะคิดออกเมื่อจะใช้แนวคิดการเขียนโปรแกรมหรือกระบวนทัศน์นี่คือสองสามสิ่งที่คิดเกี่ยวกับ:

  • ความสามารถในการปรับขนาด: สคริปต์จะยืนอยู่คนเดียวหรือในที่สุดมันจะถูกใช้ในโปรแกรมขนาดใหญ่ขึ้นหรือไม่ ถ้าเป็นเช่นนั้นการเขียนโปรแกรมขนาดใหญ่โดยใช้ OOP? รหัสในสคริปต์ของคุณสามารถรวมเข้ากับโปรแกรมที่ใหญ่กว่าได้หรือไม่?
  • ความเป็นโมดูล: โดยทั่วไปรหัสของคุณควรเป็นแบบแยกส่วน อย่างไรก็ตาม OOP แบ่งรหัสเป็นส่วน ๆ ด้วยวิธีพิเศษ ประเภทของโมดูลนั้น (เช่นการแบ่งสคริปต์ของคุณออกเป็นคลาส) เหมาะสมกับสิ่งที่คุณกำลังทำอยู่หรือไม่?

ฉันต้องการทราบวิธี "เริ่มต้นใหม่" และเขียนโปรแกรมอย่างละเอียดเกี่ยวกับโครงการขนาดเล็กลงและเร็วขึ้น

# 1: ทำความคุ้นเคยกับสิ่งที่มีอยู่:
แม้ว่าคุณจะ "แค่" การเขียนสคริปต์ (และคุณแค่ใส่ใจเกี่ยวกับองค์ประกอบทางวิทยาศาสตร์) คุณควรใช้เวลาสักครู่เพื่อเรียนรู้เกี่ยวกับแนวคิดการเขียนโปรแกรมและกระบวนทัศน์ที่แตกต่างกัน ด้วยวิธีนี้คุณสามารถมีความคิดที่ดีขึ้นเกี่ยวกับสิ่งที่คุณควร / ไม่ควรใช้และเมื่อใด นั่นอาจฟังดูน่ากลัวเล็กน้อย และคุณอาจยังมีคำถามว่า "ฉันจะเริ่มต้นที่ไหน / ฉันจะเริ่มมองหาอะไร" ฉันพยายามอธิบายจุดเริ่มต้นที่ดีในสองจุดต่อไป

# 2: เริ่มแก้ไขสิ่งที่คุณรู้ว่าผิด: โดย
ส่วนตัวแล้วฉันจะเริ่มจากสิ่งที่ฉันรู้ว่าผิด รับการควบคุมเวอร์ชันบางอย่างและเริ่มฝึกฝนตัวเองให้ดีขึ้นด้วยชื่อตัวแปรเหล่านั้น (เป็นการดิ้นรนอย่างจริงจัง) การแก้ไขสิ่งที่คุณรู้ว่าผิดอาจฟังดูชัดเจน อย่างไรก็ตามจากประสบการณ์ของฉันฉันพบว่าการแก้ไขสิ่งหนึ่งนำฉันไปสู่สิ่งอื่นและอื่น ๆ ก่อนที่ฉันจะรู้ฉันได้เปิดเผยสิ่งต่าง ๆ 10 อย่างที่ฉันทำผิดและคิดหาวิธีแก้ไขพวกเขาหรือวิธีการนำไปใช้อย่างสะอาด

# 3: รับพันธมิตรการเขียนโปรแกรม:
หาก "เริ่มต้นใหม่" สำหรับคุณไม่ได้เกี่ยวข้องกับการเรียนอย่างเป็นทางการพิจารณาร่วมกับนักพัฒนาและขอให้พวกเขาตรวจสอบรหัสของคุณ แม้ว่าพวกเขาจะไม่เข้าใจวิทยาศาสตร์เป็นส่วนหนึ่งของสิ่งที่คุณทำ แต่พวกเขาอาจบอกคุณได้ว่าคุณควรทำอะไรเพื่อทำให้โค้ดของคุณดูดีขึ้น

# 4: มองหากลุ่ม:
ฉันไม่ทราบว่าคุณอยู่ในพื้นที่วิทยาศาสตร์ แต่ขึ้นอยู่กับสิ่งที่คุณทำในโลกวิทยาศาสตร์ลองค้นหากลุ่ม Consortiums กลุ่มทำงานหรือผู้เข้าร่วมประชุม จากนั้นดูว่ามีมาตรฐานใด ๆ ที่พวกเขากำลังทำงานอยู่หรือไม่ ที่อาจนำคุณไปสู่มาตรฐานการเข้ารหัส ตัวอย่างเช่นฉันทำงานเกี่ยวกับพื้นที่เชิงภูมิศาสตร์หลายอย่าง มองไปที่เอกสารการประชุมและคณะทำงานนำฉันไปเปิด Geospatial Consortium หนึ่งในสิ่งที่พวกเขาทำคือทำงานบนมาตรฐานสำหรับการพัฒนาเชิงพื้นที่

ฉันหวังว่าจะช่วย!


หมายเหตุด้านข้าง: ฉันรู้ว่าคุณเพิ่งใช้ OOP เป็นตัวอย่าง ฉันไม่ต้องการให้คุณคิดว่าฉันติดอยู่กับวิธีจัดการกับการเขียนโค้ดโดยใช้ OOP มันง่ายกว่าที่จะเขียนคำตอบต่อจากตัวอย่างนั้น


ฉันคิดว่า # 3 เป็นปัญหาที่สำคัญที่สุด - โปรแกรมเมอร์ที่มีประสบการณ์สามารถบอกแนวคิดที่ต้องการ (# 1) OP วิธีการจัดระเบียบสคริปต์ในทางที่ดีขึ้นและวิธีใช้การควบคุมเวอร์ชัน (# 2)
Doc Brown

16

ฉันอยากจะแนะนำให้ยึดมั่นในหลักการ Unix: Keep It Simple, Stupid! (จูบ)

หรือใส่อีกวิธี: ทำสิ่งหนึ่งในเวลาและทำได้ดี

นั่นหมายความว่าอย่างไร? ก่อนอื่นก็หมายความว่าหน้าที่ของคุณควรสั้น ฟังก์ชั่นใด ๆ ที่ไม่สามารถเข้าใจได้อย่างสมบูรณ์ในวัตถุประสงค์การใช้งานและการใช้งานภายในไม่กี่วินาทีนั้นยาวเกินไป มีแนวโน้มที่จะทำหลายสิ่งพร้อมกันซึ่งแต่ละอย่างควรเป็นหน้าที่ของตนเอง ดังนั้นแยกมัน

ในแง่ของโค้ดบรรทัดฮิวริสติกของฉันก็คือ 10 บรรทัดนั้นเป็นฟังก์ชั่นที่ดี คนอื่นมีการวิเคราะห์พฤติกรรมอื่น ๆ ส่วนที่สำคัญคือการทำให้ความยาวของสิ่งที่คุณสามารถเข้าใจได้ในทันที

คุณแยกฟังก์ชั่นยาว ๆ ได้อย่างไร? ก่อนอื่นคุณต้องมองหารูปแบบการทำซ้ำของรหัส แล้วคุณปัจจัยจากรูปแบบรหัสเหล่านี้ให้พวกเขามีชื่อที่อธิบายและดูรหัสของคุณหด จริง ๆ แล้วการ refactoring ที่ดีที่สุดคือ refactoring ที่ลดขนาดรหัส

นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งเมื่อฟังก์ชันที่เป็นปัญหาได้รับการโปรแกรมด้วยการคัดลอกวาง เมื่อใดก็ตามที่คุณเห็นรูปแบบซ้ำ ๆ คุณจะรู้ทันทีว่าสิ่งนี้น่าจะกลายเป็นหน้าที่ของมันเอง นี่คือหลักการของการไม่ทำซ้ำตัวเอง (แห้ง) เมื่อใดก็ตามที่คุณกดปุ่มคัดลอกคุณกำลังทำอะไรผิดพลาด! สร้างฟังก์ชั่นแทน

เรื่องเล็ก ๆ น้อย
ฉันเคยใช้รหัส refactoring หลายเดือนซึ่งมีฟังก์ชั่นประมาณ 500 บรรทัดในแต่ละครั้ง หลังจากที่ฉันทำเสร็จแล้วรหัสทั้งหมดสั้นกว่าหนึ่งพันบรรทัด ฉันได้สร้างเอาต์พุตเชิงลบในรูปของบรรทัดของโค้ด ฉันเป็นหนี้ บริษัท ( http://www.geekherocomic.com/2008/10/09/programmers-salary-policy/index.html ) ถึงกระนั้นฉันก็เชื่อมั่นว่านี่เป็นหนึ่งในผลงานที่มีค่าที่สุดของฉันที่ฉันเคยทำ ...

ฟังก์ชั่นบางอย่างอาจใช้เวลานานเพราะพวกเขากำลังทำสิ่งต่าง ๆ ที่แตกต่างกันไป สิ่งเหล่านี้ไม่ใช่การละเมิดแบบแห้ง แต่สามารถแยกออกได้ ผลลัพธ์มักจะเป็นฟังก์ชั่นระดับสูงที่เรียกฟังก์ชั่นที่เต็มไปด้วยมือซึ่งใช้แต่ละขั้นตอนของฟังก์ชั่นดั้งเดิม โดยทั่วไปจะเพิ่มขนาดรหัส แต่ชื่อฟังก์ชั่นที่เพิ่มเข้ามาทำสิ่งมหัศจรรย์ในการทำให้โค้ดอ่านง่ายขึ้น เพราะตอนนี้คุณมีฟังก์ชั่นระดับบนสุดที่มีชื่อทุกขั้นตอนอย่างชัดเจน นอกจากนี้หลังจากการแยกนี้ชัดเจนขั้นตอนใดที่ทำงานกับข้อมูลใด (อาร์กิวเมนต์ของฟังก์ชันคุณไม่ได้ใช้ตัวแปรโกลบอลใช่ไหม?)

ฮิวริสติกที่ดีสำหรับฟังก์ชั่นการแบ่งส่วนประเภทนี้คือเมื่อใดก็ตามที่คุณถูกล่อลวงให้เขียนความคิดเห็นในส่วนหรือเมื่อคุณพบความคิดเห็นของส่วนในโค้ดของคุณ นี่เป็นจุดหนึ่งที่ควรแยกฟังก์ชั่นของคุณ ความคิดเห็นในส่วนยังสามารถให้บริการเพื่อสร้างแรงบันดาลใจชื่อสำหรับฟังก์ชั่นใหม่

หลักการ KISS และ DRY สามารถนำคุณไปได้ไกล คุณไม่จำเป็นต้องเริ่มต้นด้วย OOP เป็นต้นโดยทันทีคุณสามารถทำได้ง่าย ๆ เพียงแค่ใช้สองสิ่งนี้ อย่างไรก็ตามมันจะจ่ายเงินในระยะยาวเพื่อทราบเกี่ยวกับ OOP และกระบวนทัศน์อื่น ๆ เพราะพวกเขาให้เครื่องมือเพิ่มเติมที่คุณสามารถใช้เพื่อทำให้รหัสโปรแกรมของคุณชัดเจนยิ่งขึ้น

ในที่สุดบันทึกทุกการกระทำด้วยการกระทำ คุณปัจจัยบางสิ่งบางอย่างออกไปในฟังก์ชั่นใหม่ที่กระทำ คุณหลอมรวมสองฟังก์ชั่นเป็นหนึ่งเพราะพวกเขาทำจริงๆสิ่งเดียวกันที่กระทำ ถ้าคุณเปลี่ยนชื่อตัวแปรที่กระทำ กระทำบ่อยๆ หากหนึ่งวันผ่านไปและคุณไม่ได้กระทำคุณอาจจะทำผิดพลาด


2
จุดที่ดีเกี่ยวกับวิธีการแยกยาว ฮิวริสติกที่ดีอีกข้อหนึ่งเกี่ยวกับย่อหน้าหลังเกร็ดเล็กเกร็ดน้อย: หากวิธีการของคุณสามารถแบ่งออกเป็นส่วน ๆ อย่างมีเหตุมีผลและคุณถูกล่อลวงให้เขียนความคิดเห็นอธิบายสิ่งที่แต่ละส่วนทำ ข่าวดีความคิดเห็นเหล่านั้นอาจช่วยให้คุณมีความคิดที่ดีว่าจะเรียกใช้วิธีการใหม่อย่างไร
Jaquez

@Jaquez Ah ลืมไปเลยอย่างสิ้นเชิง ขอบคุณที่เตือนฉัน. ฉันได้อัปเดตคำตอบของฉันเพื่อรวม :-) นี้แล้ว
cmaster

1
จุดที่ดีฉันต้องการทำให้เรื่องนี้ง่ายขึ้นเพื่อบอกว่า "DRY" เป็นปัจจัยเดียวที่สำคัญที่สุด การระบุ "การทำซ้ำ" และการลบออกเป็นรากฐานที่สำคัญของโครงสร้างการเขียนโปรแกรมอื่นเกือบทั้งหมด เพื่อให้เป็นอีกวิธีหนึ่งการสร้างโปรแกรมทั้งหมดจะมีอย่างน้อยก็บางส่วนเพื่อช่วยคุณสร้างรหัส DRY เริ่มต้นด้วยการพูดว่า "ไม่ต้องทำซ้ำเลยทีเดียว" จากนั้นฝึกฝนการระบุและกำจัดมัน เปิดกว้างมากกับสิ่งที่อาจซ้ำซ้อน - แม้ว่ามันจะไม่ใช่รหัสที่คล้ายกัน แต่มันอาจเป็นการทำงานซ้ำซ้อน ...
Bill K

11

ฉันเห็นด้วยกับคนอื่น ๆ ว่าการควบคุมเวอร์ชันจะแก้ไขปัญหาของคุณได้ทันที โดยเฉพาะ:

  • ไม่จำเป็นต้องเก็บรักษารายการที่มีการเปลี่ยนแปลงหรือมีสำเนาไฟล์จำนวนมาก ฯลฯ เนื่องจากเป็นสิ่งที่การควบคุมเวอร์ชันดูแล
  • ไม่มีไฟล์ที่สูญหายเนื่องจากการเขียนทับ ฯลฯ (ตราบใดที่คุณยังยึดติดกับพื้นฐานเช่นหลีกเลี่ยง "ประวัติการเขียนใหม่")
  • ไม่จำเป็นต้องมีความคิดเห็นที่ล้าสมัย, รหัสตาย, ฯลฯ ถูกเก็บไว้รอบ "ในกรณี"; เมื่อพวกเขามุ่งมั่นที่จะควบคุมเวอร์ชันรู้สึกฟรีเพื่อกำจัดพวกเขา นี้สามารถรู้สึกปลดปล่อยมาก!

ฉันจะบอกว่าอย่าคิดมาก: แค่ใช้คอมไพล์ ยึดคำสั่งง่ายๆ (เช่นเพียงmasterสาขาเดียว) บางทีอาจใช้ GUI และคุณควรจะปรับ เป็นโบนัสคุณสามารถใช้ gitlab, github และอื่น ๆ สำหรับการเผยแพร่และสำรองข้อมูลฟรี)

เหตุผลที่ฉันเขียนคำตอบนี้คือเพื่อแก้ไขสองสิ่งที่คุณอาจลองโดยที่ฉันไม่ได้เห็นดังกล่าวข้างต้น ประการแรกคือการใช้การยืนยันเป็นทางเลือกที่มีน้ำหนักเบาเพื่อการทดสอบหน่วย การทดสอบหน่วยมักจะนั่ง "นอก" ฟังก์ชั่น / โมดูล / สิ่งที่ถูกทดสอบ: พวกเขามักจะส่งข้อมูลบางส่วนไปยังฟังก์ชั่นรับผลกลับมาแล้วตรวจสอบคุณสมบัติของผลลัพธ์ที่ นี่เป็นความคิดที่ดี แต่อาจไม่สะดวก (โดยเฉพาะอย่างยิ่งสำหรับรหัส "ทิ้ง") ด้วยเหตุผลบางประการ:

  • การทดสอบหน่วยจำเป็นต้องตัดสินใจว่าจะให้ข้อมูลใดแก่ฟังก์ชัน ข้อมูลนั้นจะต้องเป็นจริง (มิฉะนั้นจะมีการทดสอบจุดเล็ก ๆ ) มันจะต้องมีรูปแบบที่ถูกต้อง ฯลฯ
  • การทดสอบหน่วยต้องมี "การเข้าถึง" สำหรับสิ่งที่พวกเขาต้องการยืนยัน โดยเฉพาะการทดสอบหน่วยไม่สามารถตรวจสอบข้อมูลกลางใด ๆ ภายในฟังก์ชั่น; เราจะต้องแยกฟังก์ชั่นนั้นออกเป็นชิ้นเล็ก ๆ ทดสอบชิ้นส่วนเหล่านั้นแล้วเสียบเข้าด้วยกันที่อื่น
  • การทดสอบหน่วยจะถือว่าเกี่ยวข้องกับโปรแกรมด้วย ตัวอย่างเช่นชุดทดสอบอาจกลายเป็น "เก่า" หากมีการเปลี่ยนแปลงครั้งใหญ่ตั้งแต่ครั้งสุดท้ายและอาจมีการทดสอบหลายครั้งสำหรับรหัสที่ไม่ได้ใช้อีกต่อไป

การยืนยันไม่มีข้อบกพร่องเหล่านี้เนื่องจากจะถูกตรวจสอบในระหว่างการเรียกใช้โปรแกรมปกติ โดยเฉพาะอย่างยิ่ง:

  • เนื่องจากพวกเขาทำงานเป็นส่วนหนึ่งของการเรียกใช้โปรแกรมปกติเราจึงมีข้อมูลในโลกแห่งความเป็นจริงให้เล่นด้วย สิ่งนี้ไม่ต้องการการแยกจากกันและ (ตามคำจำกัดความ) เป็นจริงและมีรูปแบบที่ถูกต้อง
  • การยืนยันสามารถเขียนได้ทุกที่ในรหัสเพื่อให้เราสามารถวางไว้ทุกที่ที่เราเข้าถึงข้อมูลที่เราต้องการตรวจสอบ หากเราต้องการทดสอบค่ากลางในฟังก์ชั่นเราสามารถใส่คำยืนยันลงไปตรงกลางของฟังก์ชันนั้นได้!
  • เนื่องจากพวกเขาเขียนในบรรทัดการยืนยันจึงไม่สามารถ "ไม่ซิงค์" กับโครงสร้างของรหัสได้ หากเราตรวจสอบให้แน่ใจว่ามีการตรวจสอบการยืนยันตามค่าเริ่มต้นเราไม่จำเป็นต้องกังวลว่าพวกเขาจะได้รับ "ค้าง" เพราะเราจะเห็นทันทีว่าพวกเขาผ่านหรือไม่ในครั้งต่อไปที่เราเรียกใช้โปรแกรม!

คุณพูดถึงความเร็วเป็นปัจจัยซึ่งในการตรวจสอบการยืนยันกรณีอาจไม่เป็นที่พึงปรารถนาในลูปนั้น (แต่ยังมีประโยชน์สำหรับการตรวจสอบการตั้งค่าและการประมวลผลที่ตามมา) อย่างไรก็ตามการใช้งานการยืนยันเกือบทั้งหมดเป็นวิธีปิดพวกเขา ตัวอย่างเช่นใน Pythonเห็นได้ชัดว่าพวกเขาสามารถปิดการใช้งานโดยใช้-Oตัวเลือก (ฉันไม่ทราบเรื่องนี้เนื่องจากฉันไม่เคยรู้สึกว่าจำเป็นต้องปิดการใช้งานใด ๆ ยืนยันของฉันก่อน) ผมจะแนะนำให้คุณปล่อยให้พวกเขาได้ที่โดยค่าเริ่มต้น; ถ้ารอบการเข้ารหัส / การดีบัก / การทดสอบของคุณช้าลงคุณอาจจะดีกว่าการทดสอบด้วยชุดย่อยของข้อมูลที่มีขนาดเล็กลงหรือทำการวนซ้ำที่น้อยลงของการจำลองบางอย่างระหว่างการทดสอบหรืออะไรก็ตาม หากคุณปิดการใช้งานการยืนยันในการทำงานที่ไม่ใช่การทดสอบด้วยเหตุผลด้านประสิทธิภาพสิ่งแรกที่ฉันแนะนำให้คุณทำคือการวัดว่าจริงๆแล้วมันเป็นต้นเหตุของการชะลอตัวหรือไม่! (มันง่ายมากที่จะหลอกตัวเองเมื่อพูดถึงปัญหาคอขวดของการแสดง)

คำแนะนำสุดท้ายของฉันคือการใช้ระบบสร้างที่จัดการการอ้างอิงของคุณ ฉันใช้Nixเป็นการส่วนตัวแต่เคยได้ยินสิ่งที่ดีเกี่ยวกับGuixเช่นกัน นอกจากนี้ยังมีทางเลือกอื่นเช่น Docker ซึ่งมีประโยชน์น้อยกว่ามากจากมุมมองทางวิทยาศาสตร์ แต่อาจคุ้นเคยเล็กน้อย

ระบบเช่นห้ามเพิ่งจะได้รับความนิยม (เล็กน้อย) เมื่อเร็ว ๆ นี้และบางคนอาจคิดว่ามันเกินความจริงสำหรับรหัส "ทิ้ง" เช่นที่คุณอธิบาย แต่ประโยชน์ของพวกเขาสำหรับการทำซ้ำของการคำนวณทางวิทยาศาสตร์ พิจารณา shell script สำหรับทำการทดสอบเช่นนี้ (เช่นrun.sh):

#!/usr/bin/env bash
set -e
make all
./analyse < ./dataset > output.csv

เราสามารถเขียนมันลงใน "การสืบทอด" ที่ห้ามแทนเช่นนี้ (เช่นrun.nix):

with import <nixpkgs> {};
runCommand "output.csv" {} ''
  cp -a ${./.} src
  cd src
  make all
  ./analyse < ./dataset > $out
''

สิ่งที่''...''อยู่ระหว่างคือรหัสทุบตีเช่นเดียวกับที่เราเคยมีมาก่อนยกเว้นว่า${...}สามารถใช้เพื่อ "splice" ในเนื้อหาของสตริงอื่น ๆ (ในกรณีนี้./.ซึ่งจะขยายไปยังเส้นทางของไดเรกทอรีที่มีrun.nix) with import ...เส้นนำเข้าห้ามห้องสมุดมาตรฐานซึ่งมีrunCommandรหัสการทำงานทุบตี เราสามารถเรียกใช้การทดสอบของเราโดยใช้ซึ่งจะให้ออกจากเส้นทางเช่นnix-build run.nix/nix/store/1wv437qdjg6j171gjanj5fvg5kxc828p-output.csv

แล้วสิ่งนี้จะซื้อเรา ห้ามจะตั้งค่าสภาพแวดล้อม "สะอาด" โดยอัตโนมัติซึ่งมีการเข้าถึงสิ่งที่เราขออย่างชัดเจนเท่านั้น โดยเฉพาะอย่างยิ่งมันไม่สามารถเข้าถึงตัวแปรเช่นเดียว$HOMEกับซอฟต์แวร์ระบบที่เราติดตั้ง สิ่งนี้ทำให้ผลลัพธ์เป็นอิสระจากรายละเอียดของเครื่องปัจจุบันของเราเช่นเนื้อหาของ~/.configหรือรุ่นของโปรแกรมที่เราติดตั้ง AKA เป็นสิ่งที่ป้องกันไม่ให้คนอื่นเลียนแบบผลลัพธ์ของเรา! นี่คือเหตุผลที่ฉันเพิ่มที่cpคำสั่งเนื่องจากโครงการจะไม่สามารถเข้าถึงได้โดยค่าเริ่มต้น อาจเป็นเรื่องที่น่ารำคาญว่าซอฟท์แวร์ของระบบไม่สามารถใช้กับสคริปต์ Nix ได้ แต่มันก็มีวิธีอื่นเช่นกัน: เราไม่ต้องการอะไรที่ติดตั้งบนระบบของเรา (นอกเหนือจาก Nix) เพื่อใช้งานมันในสคริปต์ เราเพียงแค่ขอมันและห้ามจะออกไปและดึง / รวบรวม / สิ่งที่จำเป็น (ส่วนใหญ่จะถูกดาวน์โหลดเป็นไบนารี; ห้องสมุดมาตรฐานก็มีขนาดใหญ่มาก!) ตัวอย่างเช่นหากเราต้องการแพคเกจ Python และ Haskell จำนวนมากสำหรับภาษาเฉพาะบางเวอร์ชันรวมถึงขยะอื่น ๆ (เพราะเหตุใด)

with import <nixpkgs> {};
runCommand "output.csv"
  {
    buildInputs = [
      gcc49 libjson zlib
      haskell.packages.ghc802.pandoc
      (python34.withPackages (pyPkgs: [
        pyPkgs.beautifulsoup4 pyPkgs.numpy pyPkgs.scipy
        pyPkgs.tensorflowWithoutCuda
      ]))
    ];
  }
  ''
    cp -a ${./.} src
    cd src
    make all
    ./analyse < ./dataset > $out
  ''

สิ่งเดียวกันnix-build run.nixจะทำงานสิ่งนี้ดึงข้อมูลทุกอย่างที่เราขอก่อน (และแคชทั้งหมดในกรณีที่เราต้องการในภายหลัง) เอาต์พุต (ไฟล์ / ไดเร็กทอรีใด ๆ ที่เรียกว่า$out) จะถูกเก็บไว้โดย Nix ซึ่งเป็นพา ธ ที่แยกออกมา มันถูกระบุโดยแฮชการเข้ารหัสของอินพุตทั้งหมดที่เราขอ (เนื้อหาสคริปต์แพ็คเกจอื่นชื่อชื่อคอมไพเลอร์แฟล็ก ฯลฯ ); แพคเกจอื่น ๆ เหล่านั้นจะถูกระบุโดยการแฮชของอินพุตของพวกเขาและอื่น ๆ ที่เรามีห่วงโซ่เต็มรูปแบบของการพิสูจน์สำหรับทุกสิ่งกลับไปที่รุ่นของ GCC ที่รวบรวมรุ่นของ GCC ที่รวบรวมทุบตีเป็นต้น!

หวังว่าฉันจะแสดงให้เห็นว่าสิ่งนี้ซื้อเรามากสำหรับรหัสทางวิทยาศาสตร์และเป็นเรื่องง่ายที่จะเริ่มต้นด้วยเหตุผล นอกจากนี้ยังเริ่มได้รับความสนใจอย่างมากจากนักวิทยาศาสตร์เช่น (Google อันดับต้น ๆ ) https://dl.acm.org/citation.cfm?id=2830172ดังนั้นอาจเป็นทักษะที่มีคุณค่าในการฝึกฝน (เช่นเดียวกับการเขียนโปรแกรม)


2
คำตอบที่มีประโยชน์อย่างละเอียดมาก - ฉันชอบคำตอบอื่น ๆ แต่คำยืนยันนั้นเหมือนขั้นตอนแรกที่มีประโยชน์มาก
ทุ่งหญ้า

9

โดยไม่ต้องไปควบคุมเวอร์ชันเต็มงอกขน + บรรจุภัณฑ์ + หน่วยทดสอบชนิดของความคิด (ซึ่งมีการเขียนโปรแกรมที่ดีที่คุณควรพยายามที่จะบรรลุในบางจุด), การแก้ปัญหากลางหนึ่งที่ผมคิดว่าจะพอดีคือการใช้จูปิเตอร์โน๊ตบุ๊ค ดูเหมือนว่าจะรวมเข้ากับการคำนวณทางวิทยาศาสตร์ได้ดีขึ้น

มันมีข้อดีที่คุณสามารถผสมความคิดของคุณกับรหัส; อธิบายว่าทำไมวิธีการจึงดีกว่าวิธีอื่นและปล่อยให้รหัสเก่าตามที่เป็นอยู่ในส่วนของเฉพาะกิจ นอกจากนี้การใช้เซลล์อย่างถูกต้องตามธรรมชาติจะทำให้คุณแยกส่วนรหัสของคุณและจัดระเบียบเป็นฟังก์ชันที่สามารถช่วยให้เข้าใจได้


1
นอกจากนี้ยังช่วยในการทำซ้ำ - คุณสามารถเรียกใช้รหัสเดียวกันเพื่อสร้างรูปสิ่งพิมพ์เช่นหรือกลับไปที่สิ่งที่คุณวางไว้เดือนที่ผ่านมาอาจรวมถึงความคิดเห็นวิจารณ์
afaulconbridge

สำหรับคนที่ต้องการอ่านเพิ่มเติมนี้เป็นที่รู้จักกันในนามการเขียนโปรแกรมความรู้
llrs

6

คำตอบยอดนิยมดีอยู่แล้ว แต่ฉันต้องการตอบคำถามของคุณโดยตรง

การทดสอบหน่วยจำเป็นสำหรับการเขียนโค้ดขนาดเล็กลงหรือไม่?

ขนาดของรหัสไม่เกี่ยวข้องโดยตรงกับความต้องการสำหรับการทดสอบหน่วย มันมีความสัมพันธ์ทางอ้อม: การทดสอบหน่วยมีคุณค่ามากขึ้นในcodebases ที่ซับซ้อนและ codebases ขนาดเล็กมักจะไม่ซับซ้อนเท่าที่ใหญ่กว่า

การทดสอบหน่วยส่องแสงสำหรับรหัสที่ง่ายต่อการทำผิดพลาดหรือเมื่อคุณจะมีการใช้งานของรหัสนี้มากมาย การทดสอบหน่วยทำเพียงเล็กน้อยเพื่อช่วยคุณในการพัฒนาในปัจจุบันแต่พวกเขาทำอย่างมากเพื่อป้องกันไม่ให้คุณทำผิดพลาดในอนาคตที่ทำให้โค้ดที่มีอยู่นั้นทำงานผิดปกติในทันที (แม้ว่าคุณจะไม่ได้สัมผัสสิ่งนั้น)

สมมติว่าคุณมีแอปพลิเคชั่นที่ Library A ทำการคูณตัวเลขและ Library B ใช้ทฤษฎีบทพีทาโกรัส เห็นได้ชัดว่า B ขึ้นอยู่กับ A. คุณจำเป็นต้องแก้ไขบางสิ่งในไลบรารี A และสมมติว่าคุณแนะนำข้อบกพร่องที่เป็นตัวเลขลูกบาศก์แทนที่จะเป็นสี่เหลี่ยมจัตุรัส

Library B จะเริ่มต้นทำงานผิดปกติอาจโยนข้อยกเว้นหรือให้เอาต์พุตผิด และเมื่อคุณดูประวัติรุ่นของไลบรารี่ B คุณจะเห็นว่ามันไม่ถูกแตะต้อง ผลลัพธ์สุดท้ายที่เป็นปัญหาคือคุณไม่มีข้อบ่งชี้ว่าจะเกิดข้อผิดพลาดอะไรและคุณจะต้องแก้ไขข้อบกพร่องของพฤติกรรม B ก่อนที่คุณจะรู้ว่าปัญหาอยู่ใน A นั่นคือความพยายามที่สูญเปล่า

เข้าสู่การทดสอบหน่วย การทดสอบเหล่านี้ยืนยันว่าไลบรารี A ทำงานตามที่ตั้งใจไว้ หากคุณแนะนำบั๊กในไลบรารี A ที่ทำให้เกิดผลลัพธ์ที่ไม่ดีจากนั้นหน่วยทดสอบของคุณจะตรวจจับสิ่งนั้น ดังนั้นคุณจะไม่ติดขัดในการพยายามดีบักไลบรารี B
ซึ่งอยู่นอกเหนือขอบเขตของคุณ แต่ในการพัฒนาการรวมกลุ่มอย่างต่อเนื่องการทดสอบหน่วยจะดำเนินการเมื่อใดก็ตามที่มีคนยอมรับรหัสบางส่วนซึ่งหมายความว่าคุณจะรู้ว่า

โดยเฉพาะอย่างยิ่งสำหรับการดำเนินการทางคณิตศาสตร์ที่ซับซ้อนการทดสอบหน่วยสามารถเป็นพรได้ คุณทำการคำนวณตัวอย่างสองสามข้อจากนั้นคุณเขียนการทดสอบหน่วยซึ่งเปรียบเทียบผลลัพธ์ที่ได้จากการคำนวณของคุณกับผลลัพธ์ที่แท้จริงของคุณ (ตามพารามิเตอร์อินพุตเดียวกัน)

อย่างไรก็ตามโปรดทราบว่าการทดสอบหน่วยจะไม่ช่วยให้คุณสร้างรหัสที่ดี แต่รักษามัน หากคุณมักจะเขียนโค้ดหนึ่งครั้งและไม่เคยทบทวนมันการทดสอบหน่วยจะมีประโยชน์น้อยกว่า

แล้ว OOP ล่ะ

OOP เป็นวิธีคิดเกี่ยวกับเอนทิตีที่แตกต่างกันตัวอย่างเช่น:

เมื่อCustomerต้องการที่จะซื้อProductเขาพูดไปจะได้รับVendor แล้วจะจ่ายOrderAccountantVendor

เปรียบเทียบสิ่งนี้กับวิธีที่โปรแกรมเมอร์ทำงานคิดเกี่ยวกับสิ่งต่าง ๆ :

เมื่อลูกค้าต้องการpurchaseProduct()เขาtalktoVendor()ก็จะsendOrder()ให้เขา ผู้ชนะจะpayVendor()ได้

แอปเปิ้ลและส้ม ทั้งคู่ไม่เป็นคนดีกว่าคนอื่นอย่างเป็นกลาง สิ่งหนึ่งที่น่าสนใจที่ควรทราบก็คือสำหรับ OOP นั้นVendorมีการพูดถึงสองครั้ง แต่มันก็หมายถึงสิ่งเดียวกัน อย่างไรก็ตามสำหรับการเขียนโปรแกรมการทำงานtalktoVendor()และpayVendor()เป็นสองสิ่งที่แยกจากกัน
สิ่งนี้แสดงให้เห็นถึงความแตกต่างระหว่างแนวทาง หากมีตรรกะเฉพาะของผู้จำหน่ายที่ใช้ร่วมกันจำนวนมากระหว่างการกระทำทั้งสองนี้ OOP จะช่วยลดการทำซ้ำรหัส อย่างไรก็ตามหากไม่มีตรรกะที่ใช้ร่วมกันระหว่างทั้งสองดังนั้นการรวมพวกเขาเข้ากับงานเดี่ยวVendorนั้นเป็นงานที่ไร้ประโยชน์ (และการเขียนโปรแกรมแบบ fuctional นั้นมีประสิทธิภาพมากกว่า)

บ่อยครั้งที่การคำนวณทางคณิตศาสตร์และวิทยาศาสตร์เป็นการดำเนินการที่แตกต่างกันซึ่งไม่ต้องอาศัยตรรกะ / สูตรที่ใช้ร่วมกันโดยปริยาย เนื่องจากการเขียนโปรแกรมที่ใช้งานบ่อยกว่า OOP

วิธีใดบ้างที่ดีสำหรับการเขียนโค้ดที่ดีและสะอาดได้อย่างรวดเร็วเมื่อทำการ "การเขียนโปรแกรมเชิงวิทยาศาสตร์" ซึ่งต่างจากการทำงานในโครงการขนาดใหญ่

คำถามของคุณบอกเป็นนัยว่าคำจำกัดความของ "รหัสที่ดีและสะอาด" นั้นเปลี่ยนแปลงไม่ว่าคุณจะทำการเขียนโปรแกรมทางวิทยาศาสตร์หรือทำงานในโครงการขนาดใหญ่ (ฉันถือว่าคุณหมายถึงองค์กร)

คำจำกัดความของรหัสที่ดีไม่เปลี่ยนแปลง อย่างไรก็ตามความจำเป็นในการหลีกเลี่ยงความซับซ้อน (ซึ่งสามารถทำได้โดยการเขียนโค้ดที่สะอาด) แต่จะเปลี่ยนแปลง

อาร์กิวเมนต์เดียวกันกลับมาที่นี่

  • หากคุณไม่เคยทบทวนรหัสเดิมอีกครั้งและเข้าใจตรรกะโดยไม่จำเป็นต้องแยกออกจากกันอย่าใช้ความพยายามมากเกินไปในการทำให้สิ่งต่าง ๆ คงอยู่ได้
  • หากคุณกลับไปใช้โค้ดเก่าหรือตรรกะที่จำเป็นนั้นซับซ้อนเกินกว่าที่คุณจะจัดการทั้งหมดได้ในคราวเดียว (ดังนั้นคุณต้องแบ่งการแก้ปัญหาออกเป็นส่วน ๆ ) จากนั้นมุ่งเน้นไปที่การเขียนที่สะอาด

ฉันถามคำถามเหล่านี้เพราะบ่อยครั้งการเขียนโปรแกรมเองนั้นไม่ซับซ้อน มันเกี่ยวกับคณิตศาสตร์หรือวิทยาศาสตร์ที่ฉันกำลังทดสอบหรือค้นคว้าด้วยการเขียนโปรแกรม

ฉันได้รับความแตกต่างที่คุณทำที่นี่ แต่เมื่อคุณมองกลับไปที่รหัสที่มีอยู่คุณกำลังดูทั้งคณิตศาสตร์และการเขียนโปรแกรม หากทั้งสองเป็นที่วางแผนหรือซับซ้อนแล้วคุณจะต่อสู้เพื่ออ่านมัน

เช่นคลาสจำเป็นหรือไม่เมื่อมีตัวแปรสองตัวและฟังก์ชั่นอาจดูแลได้

นอกจากหลักการของ OOP แล้วเหตุผลหลักที่ฉันเขียนคลาสเพื่อเก็บค่าข้อมูลบางอย่างก็เพราะว่ามันช่วยให้การประกาศพารามิเตอร์ของเมธอดและค่าส่งคืนนั้นง่ายขึ้น ตัวอย่างเช่นหากฉันมีวิธีการมากมายที่ใช้ตำแหน่ง (คู่ lat / lon) จากนั้นฉันจะเบื่อที่จะพิมพ์อย่างรวดเร็วfloat latitude, float longitudeและชอบเขียนLocation locมาก

สิ่งนี้จะเพิ่มขึ้นอีกเมื่อคุณพิจารณาว่าโดยทั่วไปแล้ววิธีการหนึ่งจะคืนค่า (ยกเว้นว่ามีคุณสมบัติเฉพาะภาษาที่จะส่งกลับค่ามากขึ้น) และสิ่งต่าง ๆ เช่นสถานที่ตั้งต้องการให้คุณคืนสองค่า (lat + lon) สิ่งนี้เป็นการจูงใจให้คุณสร้างLocationคลาสเพื่อทำให้รหัสของคุณง่ายขึ้น

เช่นคลาสจำเป็นหรือไม่เมื่อมีตัวแปรสองตัวและฟังก์ชั่นอาจดูแลได้

สิ่งที่น่าสนใจอีกอย่างที่ควรทราบคือคุณสามารถใช้ OOP โดยไม่ต้องผสมค่าข้อมูลและวิธีการ ไม่ใช่นักพัฒนาทุกคนที่เห็นด้วยที่นี่ (บางคนเรียกว่า antipattern) แต่คุณสามารถมีโมเดลข้อมูลโลหิตจางที่คุณมีคลาสข้อมูลแยกต่างหาก(เก็บค่าฟิลด์) และคลาสตรรกะ (วิธีการจัดเก็บ)
แน่นอนว่านี่เป็นสเปกตรัม คุณไม่จำเป็นต้องเป็นโรคโลหิตจางอย่างสมบูรณ์คุณสามารถใช้มันได้เมื่อคุณเห็นว่าเหมาะสม

ตัวอย่างเช่นวิธีการที่ต่อท้ายชื่อและนามสกุลของบุคคลนั้นยังคงสามารถอยู่ในPersonชั้นเรียนของตัวเองเพราะมันไม่ใช่ "ตรรกะ" จริง ๆ แต่เป็นค่าที่คำนวณได้

(พิจารณาสิ่งเหล่านี้โดยทั่วไปเป็นสถานการณ์ที่ความเร็วของโปรแกรมเป็นที่ต้องการในตอนท้ายที่เร็วกว่า - เมื่อคุณรันขั้นตอนการจำลองมากกว่า 25,000,000+ ครั้งคุณต้องการให้มันเป็นแบบนั้น)

คลาสนั้นใหญ่พอ ๆ กับผลรวมของฟิลด์ ยกตัวอย่างLocationอีกครั้งซึ่งประกอบด้วยสองfloatค่าเป็นสิ่งสำคัญที่จะต้องทราบที่นี่ว่าLocationวัตถุเดียวจะใช้หน่วยความจำมากถึงสองfloatค่าแยก

ในแง่นั้นมันไม่สำคัญว่าคุณจะใช้ OOP หรือไม่ รอยเท้าหน่วยความจำเหมือนกัน

การแสดงของตัวเองนั้นไม่ได้เป็นอุปสรรค์ที่ยิ่งใหญ่สำหรับการข้าม ความแตกต่างระหว่างเช่นการใช้วิธีการทั่วโลกหรือวิธีการเรียนมีอะไรจะทำอย่างไรกับประสิทธิภาพการทำงานแบบไทม์ แต่มีทุกอย่างที่จะทำกับการสร้างเวลา bytecode

คิดแบบนี้: ไม่ว่าฉันจะเขียนสูตรเค้กเป็นภาษาอังกฤษหรือสเปนก็ไม่ได้เปลี่ยนความจริงที่ว่าเค้กจะใช้เวลา 30 นาทีในการอบ (= ประสิทธิภาพรันไทม์) สิ่งเดียวที่การเปลี่ยนแปลงภาษาของสูตรคือวิธีการปรุงอาหารผสมส่วนผสม (= การรวบรวม bytecode)

สำหรับ Python โดยเฉพาะคุณไม่จำเป็นต้องรวบรวมรหัสล่วงหน้าอย่างชัดเจนก่อนที่จะเรียกมัน อย่างไรก็ตามเมื่อคุณไม่ได้รวบรวมล่วงหน้าการรวบรวมจะเกิดขึ้นเมื่อพยายามเรียกใช้รหัส เมื่อฉันพูดว่า "runtime" ฉันหมายถึงการประมวลผลเองไม่ใช่การคอมไพล์ซึ่งสามารถนำหน้าการเรียกใช้งานได้


6

ประโยชน์ของรหัสทางวิทยาศาสตร์ที่สะอาด

  • ... ดูที่การเขียนโปรแกรมหนังสือพวกเขามักจะพูดถึงโครงการขนาดใหญ่

  • ... มันสมเหตุสมผลหรือไม่ที่จะเขียนโค้ดที่บอกว่า OOP เมื่อบางสิ่งมาตรฐานสามารถทำได้สำเร็จจะเร็วกว่ามากในการเขียนและจะมีระดับการอ่านที่คล้ายกันเนื่องจากความสั้นของโปรแกรม?

การพิจารณาโค้ดของคุณจากมุมมองของโคเดอร์ในอนาคตอาจเป็นประโยชน์

  • ทำไมพวกเขาถึงเปิดไฟล์นี้
  • พวกเขากำลังมองหาอะไร

จากประสบการณ์ของฉัน

รหัสที่สะอาดควรทำให้ง่ายต่อการตรวจสอบผลลัพธ์ของคุณ

  • ทำให้ผู้ใช้รู้ได้ง่ายว่าพวกเขาต้องทำอะไรเพื่อเรียกใช้โปรแกรมของคุณ
  • คุณอาจต้องการแบ่งโปรแกรมของคุณเพื่อให้อัลกอริทึมแต่ละตัวสามารถแยกกันได้

  • หลีกเลี่ยงการเขียนฟังก์ชั่นที่มีผลข้างเคียงแบบเคาน์เตอร์ง่ายซึ่งการดำเนินการหนึ่งที่ไม่เกี่ยวข้องทำให้การดำเนินการอื่นทำงานแตกต่างกัน หากคุณไม่สามารถหลีกเลี่ยงได้ให้บันทึกสิ่งที่รหัสของคุณต้องการและวิธีการตั้งค่า

โค้ดที่สะอาดสามารถใช้เป็นรหัสตัวอย่างสำหรับโค้ดในอนาคต

ความคิดเห็นที่ชัดเจน (รวมถึงรายการที่แสดงว่าควรเรียกใช้ฟังก์ชั่นอย่างไร) และฟังก์ชั่นที่แยกออกจากกันสามารถสร้างความแตกต่างอย่างมากในการใช้เวลานานสำหรับคนที่เพิ่งเริ่มต้น (หรืออนาคตคุณ)

นอกจากนี้การสร้าง "API" ที่แท้จริงสำหรับอัลกอริทึมของคุณสามารถทำให้คุณเตรียมพร้อมมากขึ้นถ้าคุณตัดสินใจที่จะทำให้สคริปต์ของคุณเป็นห้องสมุดจริงเพื่อให้คนอื่นใช้

ข้อเสนอแนะ

สูตรทางคณิตศาสตร์ "อ้างอิง" โดยใช้ความคิดเห็น

  • เพิ่มความคิดเห็นไปที่ "อ้างอิง" สูตรทางคณิตศาสตร์โดยเฉพาะอย่างยิ่งถ้าคุณใช้การเพิ่มประสิทธิภาพ
  • หากคุณได้รับสูตรจากหนังสือเพิ่มความคิดเห็นว่าJohn Smith Method from Some Book 1st Ed. Section 1.2.3 Pg 180ถ้าคุณพบสูตรในเว็บไซต์หรือในกระดาษก็อ้างว่าเช่นกัน
  • ผมอยากแนะนำให้หลีกเลี่ยง "การเชื่อมโยงเท่านั้น" ความเห็นให้แน่ใจว่าคุณหมายถึงวิธีการโดยใช้ชื่อที่ไหนสักแห่งเพื่อให้คน google มันฉันได้วิ่งเข้ามาในบางส่วน "การเชื่อมโยงเท่านั้น" ความคิดเห็นที่เปลี่ยนเส้นทางไปยังหน้าภายในเก่าและพวกเขาสามารถทำลายมาก .
  • คุณสามารถลองพิมพ์สูตรในความคิดเห็นของคุณได้ถ้ามันยังอ่านง่ายใน Unicode / ASCII แต่สิ่งนี้อาจจะดูงุ่มง่ามมาก (ความคิดเห็นเกี่ยวกับโค้ดไม่ใช่ LaTeX)

ใช้ความคิดเห็นอย่างชาญฉลาด

หากคุณสามารถปรับปรุงความสามารถในการอ่านรหัสของคุณโดยใช้ชื่อตัวแปร / ชื่อฟังก์ชันที่ดีให้ทำก่อน โปรดจำไว้ว่าความคิดเห็นจะติดอยู่ตลอดไปจนกว่าคุณจะลบออกดังนั้นพยายามแสดงความคิดเห็นที่จะไม่ล้าสมัย

ใช้ชื่อตัวแปรอธิบาย

  • ตัวแปรตัวอักษรเดียวอาจเป็นตัวเลือกที่ดีที่สุดหากเป็นส่วนหนึ่งของสูตร
  • อาจเป็นสิ่งสำคัญสำหรับผู้อ่านในอนาคตที่จะสามารถดูรหัสที่คุณเขียนและเปรียบเทียบกับสมการที่คุณใช้
  • เมื่อเหมาะสมให้พิจารณาเพิ่มคำต่อท้ายเพื่ออธิบายความหมายที่แท้จริงเช่น xBar_AverageVelocity
  • ตามที่กล่าวไว้ก่อนหน้านี้ฉันขอแนะนำอย่างชัดเจนให้ระบุสูตร / วิธีที่คุณใช้โดยใช้ชื่อในความคิดเห็นที่อื่น

เขียนโค้ดเพื่อเรียกใช้โปรแกรมของคุณกับข้อมูลที่ดีและเป็นที่รู้จักที่รู้จักกันดี

การทดสอบหน่วยจำเป็นสำหรับการเขียนโค้ดขนาดเล็กลงหรือไม่?

ฉันคิดว่าการทดสอบหน่วยจะมีประโยชน์ฉันคิดว่ารูปแบบที่ดีที่สุดของการทดสอบหน่วยสำหรับโค้ดทางวิทยาศาสตร์คือชุดของการทดสอบที่ทำงานบนข้อมูลที่ไม่ดีและเป็นที่รู้จัก

เขียนโค้ดเพื่อเรียกใช้อัลกอริทึมของคุณและตรวจสอบว่าผลลัพธ์นั้นเบี่ยงเบนจากที่คุณคาดหวังมากแค่ไหน วิธีนี้จะช่วยคุณค้นหาปัญหา (อาจจะแย่มากและหายาก) ที่คุณเผลอใช้โค้ดบางอย่างที่ทำให้เกิดผลบวกปลอมหรือทำผิดพลาดที่ทำให้ฟังก์ชั่นคืนค่าเดิมเสมอ

โปรดทราบว่าสิ่งนี้สามารถทำได้ในระดับที่เป็นนามธรรม ตัวอย่างเช่นคุณสามารถทดสอบอัลกอริทึมการจับคู่รูปแบบทั้งหมดหรือคุณสามารถทดสอบฟังก์ชันที่เพิ่งคำนวณระยะห่างระหว่างผลลัพธ์ทั้งสองในกระบวนการปรับให้เหมาะสมของคุณ เริ่มต้นด้วยส่วนที่สำคัญที่สุดสำหรับผลลัพธ์ของคุณก่อนและ / หรือส่วนต่างๆของรหัสที่คุณเป็นกังวลมากที่สุด

ทำให้ง่ายต่อการเพิ่มกรณีทดสอบใหม่พิจารณาเพิ่มฟังก์ชัน "ตัวช่วย" และจัดโครงสร้างข้อมูลอินพุตของคุณอย่างมีประสิทธิภาพ สิ่งนี้อาจหมายถึงการบันทึกข้อมูลอินพุตลงในไฟล์เพื่อให้คุณสามารถเรียกใช้การทดสอบใหม่ได้อย่างง่ายดาย แต่ระวังให้มากเพื่อหลีกเลี่ยงผลบวกปลอมหรือกรณีทดสอบที่ถูกแก้ไข / ลำเอียงเล็กน้อย

ลองพิจารณาใช้การตรวจสอบไขว้ดูโพสต์นี้สำหรับการตรวจสอบไขว้สำหรับข้อมูลเพิ่มเติม

ใช้การควบคุมเวอร์ชัน

ฉันขอแนะนำให้ใช้การควบคุมเวอร์ชันและโฮสต์ที่เก็บของคุณบนไซต์ภายนอก มีเว็บไซต์ที่จะโฮสต์ที่เก็บฟรี

ข้อดี:

  1. มันมีการสำรองข้อมูลในกรณีที่ฮาร์ดดิสก์ของคุณล้มเหลว
  2. มันมีประวัติซึ่งช่วยให้คุณไม่ต้องกังวลหากปัญหาล่าสุดที่เกิดขึ้นนั้นเกิดจากการที่คุณเปลี่ยนไฟล์โดยไม่ได้ตั้งใจและคุณประโยชน์อื่น ๆ
  3. ช่วยให้คุณใช้การแบรนช์ซึ่งเป็นวิธีที่ดีในการทำงานกับโค้ดระยะยาว / การทดลองโดยไม่ส่งผลต่องานที่ไม่เกี่ยวข้อง

ใช้ความระมัดระวังเมื่อคัดลอก / วางรหัส

รูปแบบของรหัสของฉันมีความซับซ้อนและเต็มไปด้วยความคิดเห็นที่ล้าสมัยซึ่งระบุวิธีอื่นในการทำบางสิ่งหรือคัดลอกบรรทัดของรหัสไป

  • การคัดลอก / วางรหัสสามารถช่วยคุณประหยัดเวลา แต่เป็นหนึ่งในสิ่งที่อันตรายที่สุดที่คุณสามารถทำได้โดยเฉพาะอย่างยิ่งถ้าเป็นรหัสที่คุณไม่ได้เขียนด้วยตัวเอง (เช่นถ้าเป็นรหัสจากเพื่อนร่วมงาน)

  • ทันทีที่คุณได้รับรหัสและทดสอบฉันขอแนะนำให้ดำเนินการอย่างระมัดระวังเพื่อเปลี่ยนชื่อตัวแปรหรือแสดงความคิดเห็นในสิ่งที่คุณไม่เข้าใจ



6

เครื่องมือของการค้ามักจะคิดค้นเพื่อแก้ปัญหาความต้องการ หากคุณมีความต้องการใช้เครื่องมือหากไม่ใช่คุณก็ไม่จำเป็นต้องทำเช่นนั้น

โดยเฉพาะโปรแกรมทางวิทยาศาสตร์ไม่ใช่เป้าหมายสุดท้าย แต่เป็นโปรแกรม คุณเขียนโปรแกรมเพื่อแก้ปัญหาที่คุณมีอยู่ตอนนี้ - คุณไม่คาดหวังว่าโปรแกรมอื่น ๆ ที่จะใช้งาน (และต้องได้รับการดูแล) ในสิบปี เพียงอย่างเดียวนั่นหมายความว่าคุณไม่ต้องคิดเกี่ยวกับเครื่องมือใด ๆ ที่อนุญาตให้นักพัฒนาปัจจุบันบันทึกประวัติผู้อื่นเช่นการควบคุมเวอร์ชันหรือฟังก์ชั่นการจับภาพในโค้ดเช่นการทดสอบหน่วย

อะไรจะเป็นประโยชน์ต่อคุณ

  • การควบคุมเวอร์ชันนั้นดีเพราะช่วยให้คุณสำรองข้อมูลงานของคุณได้อย่างง่ายดาย ตั้งแต่ปี 2018 GitHub เป็นสถานที่ที่นิยมมากในการทำเช่นนั้น (และคุณสามารถย้ายได้ในภายหลังหากจำเป็น - Git นั้นยืดหยุ่นมาก) การสำรองข้อมูลทดแทนที่ง่ายและราคาถูกนั้นเป็นขั้นตอนการสำรองข้อมูลอัตโนมัติในระบบปฏิบัติการของคุณ (Time Machine สำหรับ Mac, rsync สำหรับ Linux และอื่น ๆ ) รหัสของคุณต้องอยู่ในหลาย ๆ แห่ง!
  • การทดสอบหน่วยเป็นเรื่องที่ดีเพราะถ้าคุณเขียนพวกเขาก่อนคุณจะถูกบังคับให้คิดเกี่ยวกับวิธีการตรวจสอบสิ่งที่รหัสทำจริงซึ่งช่วยให้คุณออกแบบ API ที่มีประโยชน์มากขึ้นสำหรับรหัสของคุณ สิ่งนี้มีประโยชน์หากคุณเคยเขียนโค้ดเพื่อนำกลับมาใช้ใหม่ในภายหลังและช่วยคุณในขณะที่เปลี่ยนอัลกอริทึมเพราะคุณรู้ว่ามันใช้งานได้ในกรณีเหล่านี้
  • เอกสาร เรียนรู้การเขียนเอกสารที่เหมาะสมในภาษาการเขียนโปรแกรมที่คุณใช้ (javadoc สำหรับ Java เป็นต้น) เขียนเพื่ออนาคตของคุณ ในขั้นตอนนี้คุณจะพบว่าชื่อตัวแปรที่ดีทำให้การทำเอกสารง่ายขึ้น ย้ำ. ให้ความใส่ใจกับเอกสารของคุณเช่นเดียวกับที่กวีทำกับบทกวี
  • ใช้เครื่องมือที่ดี ค้นหา IDE ที่ช่วยคุณและเรียนรู้ได้ดี การเปลี่ยนโครงสร้างเช่นการเปลี่ยนชื่อตัวแปรเป็นชื่อที่ดีกว่านั้นจะง่ายกว่ามาก
  • หากคุณมีเพื่อนลองพิจารณาใช้การตรวจสอบเพื่อน การมีคนนอกมองดูและเข้าใจรหัสของคุณเป็นอนาคตที่คุณเขียน หากเพื่อนของคุณไม่เข้าใจรหัสของคุณคุณอาจจะไม่ทราบทีหลัง

คำตอบนี้ไม่ได้รับการโหวตอย่างไร มันมีตอนนี้ กลุ่มของเราพบว่าการตรวจสอบโดยเพื่อนเป็นหนึ่งในเครื่องมือที่มีประสิทธิภาพสูงสุดของทั้งหมดสำคัญกว่าการทดสอบหน่วยเมื่อมันมาถึงรหัสทางวิทยาศาสตร์ มันง่ายที่จะทำผิดพลาดเมื่อแปลชุดสมการที่ซับซ้อนในบทความทางวิทยาศาสตร์เป็นรหัส นักวิทยาศาสตร์และวิศวกรของบ่อยครั้งทำให้โปรแกรมเมอร์ที่ไม่ดีอย่างยิ่ง; การตรวจสอบโดยเพื่อนสามารถจับความน่าเกลียดทางสถาปัตยกรรมที่ทำให้รหัสยากที่จะรักษา / เข้าใจ / ใช้
David Hammen

5

นอกเหนือจากคำแนะนำที่ดีที่นี่แล้วคุณอาจต้องการพิจารณาวัตถุประสงค์ของการเขียนโปรแกรมและสิ่งที่สำคัญสำหรับคุณ

"มันเป็นเรื่องของคณิตศาสตร์หรือวิทยาศาสตร์ที่ฉันกำลังทำการทดสอบหรือค้นคว้าด้วยการเขียนโปรแกรม"

หากจุดประสงค์คือการทดสอบและทดสอบบางอย่างเพื่อความเข้าใจของคุณเองและคุณรู้ว่าผลลัพธ์ควรเป็นอย่างไรรหัสของคุณก็คือการใช้งานอย่างรวดเร็วและวิธีการที่คุณใช้อยู่ในปัจจุบันอาจจะไม่เพียงพอ หากผลลัพธ์ไม่เป็นไปตามที่คาดไว้คุณสามารถกลับไปทบทวน

อย่างไรก็ตามหากผลลัพธ์ของการเข้ารหัสของคุณกำลังบอกทิศทางของการวิจัยและคุณไม่รู้ว่าผลลัพธ์ควรเป็นเช่นไรความถูกต้องจะมีความสำคัญเป็นพิเศษ ข้อผิดพลาดในรหัสของคุณอาจทำให้คุณได้ข้อสรุปที่ไม่ถูกต้องจากการทดสอบของคุณด้วยความหมายที่ไม่ดีหลายประการสำหรับการวิจัยโดยรวมของคุณ

ในกรณีดังกล่าวการแบ่งรหัสของคุณให้เป็นฟังก์ชั่นที่เข้าใจได้และตรวจสอบได้ง่ายด้วยการทดสอบหน่วยจะทำให้คุณมีความมั่นใจในผลลัพธ์มากขึ้นและอาจช่วยให้คุณประหยัดจากความยุ่งยากในภายหลัง


5

การควบคุมเวอร์ชันและการทดสอบหน่วยนั้นดีเยี่ยมสำหรับการรักษารหัสโดยรวมของคุณให้เป็นระเบียบและใช้งานได้จริง ๆ แล้วไม่ได้ช่วยให้คุณเขียนโค้ดที่สะอาดขึ้น

  • การควบคุมเวอร์ชันจะช่วยให้คุณเห็นว่ารหัสได้รับยุ่งและเป็นอย่างไร
  • การทดสอบหน่วยจะทำให้แน่ใจว่าแม้รหัสจะยุ่งเหยิง แต่ก็ยังใช้งานได้

ถ้าคุณต้องการที่จะหยุดตัวเองจากการเขียนรหัสยุ่งคุณต้องมีเครื่องมือที่ใช้งานได้เมื่อเกิดปัญหา: เมื่อคุณเขียนรหัส เครื่องมือชนิดที่เป็นที่นิยมที่เรียกว่า linter ฉันไม่ใช่นักพัฒนาหลาม แต่ดูเหมือนว่าPylintอาจเป็นตัวเลือกที่ดี

ส่วนท้ายมองดูโค้ดที่คุณเขียนและเปรียบเทียบกับชุดแนวทางปฏิบัติที่ดีที่สุดที่กำหนดค่าได้ หาก linter มีกฎที่ตัวแปรต้องเป็นcamelCaseและคุณเขียนลงsnake_caseไปมันจะตั้งค่าสถานะนั้นว่าเป็นความผิดพลาด linters ที่ดีมีกฎตั้งแต่ "ตัวแปรที่ประกาศจะต้องใช้" ถึง "ความซับซ้อนของฟังก์ชันต้องน้อยกว่า 3"

โปรแกรมแก้ไขรหัสส่วนใหญ่สามารถกำหนดค่าให้เรียกใช้ linter ทุกครั้งที่คุณบันทึกหรือโดยทั่วไปขณะที่คุณพิมพ์และระบุปัญหาแบบอินไลน์ ถ้าคุณพิมพ์สิ่งที่ต้องการx = 7ที่xจะมีการเน้นด้วยการเรียนการสอนที่จะใช้อีกต่อไปชื่อที่ดีกว่า (ถ้านั่นคือสิ่งที่คุณได้กำหนดค่า) วิธีนี้ทำงานเหมือนกับการตรวจการสะกดในโปรแกรมประมวลผลคำส่วนใหญ่ทำให้ยากที่จะเพิกเฉยและช่วยสร้างนิสัยที่ดีขึ้น


สิ่งนี้ควรมี upvotes มากขึ้น +1
heather

2
แต่เพื่อประโยชน์ของสวรรค์ให้แน่ใจว่าคุณรู้วิธีกำหนดค่า linter ให้เป็นสไตล์ที่คุณชอบไม่เช่นนั้นมันจะทำให้คุณโกรธด้วยความงุนงง
DrMcCleod

4

ทุกสิ่งที่คุณระบุไว้เป็นเครื่องมือในกล่องเครื่องมือเปรียบเทียบ เหมือนมีอะไรในชีวิตเครื่องมือต่าง ๆ เหมาะสมสำหรับงานต่าง ๆ

เมื่อเทียบกับสาขาวิศวกรรมอื่น ๆ ซอฟต์แวร์ทำงานกับชิ้นส่วนต่างๆที่พวกเขาทำเองนั้นค่อนข้างเรียบง่าย คำสั่งที่ได้รับมอบหมายไม่ได้ประเมินแตกต่างกันไปขึ้นอยู่กับความผันผวนของอุณหภูมิของห้อง ifคำสั่งไม่เป็นสนิมเข้าไปในสถานที่และให้กลับมาในสิ่งเดียวกันหลังจากชั่วขณะหนึ่ง แต่เนื่องจากองค์ประกอบแต่ละชิ้นนั้นง่ายมากและซอฟต์แวร์ที่มนุษย์เขียนขึ้นองค์ประกอบเหล่านั้นจึงรวมกันเป็นชิ้นใหญ่และใหญ่ขึ้นจนกระทั่งผลลัพธ์มีขนาดใหญ่และซับซ้อนจนเกินขอบเขตของสิ่งที่ผู้คนสามารถจัดการจิตใจได้

เมื่อโครงการซอฟต์แวร์เติบโตขึ้นเรื่อย ๆ ผู้คนได้ศึกษาและสร้างเครื่องมือเพื่อพยายามจัดการความซับซ้อนนั้น OOP เป็นตัวอย่างหนึ่ง ภาษาการเขียนโปรแกรมที่เป็นนามธรรมมากขึ้นเป็นวิธีการอื่น เนื่องจากเงินจำนวนมากในซอฟต์แวร์ทำมากขึ้นเครื่องมือในการบรรลุซึ่งเป็นสิ่งที่คุณจะได้เห็นและอ่าน แต่ดูเหมือนว่าสถานการณ์เหล่านั้นจะไม่มีผลกับคุณ

ดังนั้นอย่ารู้สึกว่าคุณต้องทำสิ่งนั้น ในตอนท้ายของวันรหัสเป็นเพียงวิธีการที่จะสิ้นสุด น่าเสียดายที่สิ่งที่ดีที่สุดจะช่วยให้คุณมีมุมมองที่ถูกต้องเกี่ยวกับสิ่งที่เป็นและสิ่งที่ไม่เหมาะสมคือการทำงานในโครงการขนาดใหญ่บางโครงการเนื่องจากเป็นการยากที่จะรู้ว่าสิ่งใดหายไปเมื่อกล่องเครื่องมือเป็นใจ

ไม่ว่าในกรณีใดฉันไม่ต้องกังวลว่าจะไม่ใช้ OOP หรือเทคนิคอื่น ๆ ตราบใดที่สคริปต์ของคุณมีขนาดเล็ก ปัญหาหลายอย่างที่คุณอธิบายเป็นเพียงทักษะองค์กรระดับมืออาชีพทั่วไปนั่นคือการไม่สูญเสียไฟล์เก่าเป็นสิ่งที่ทุกสาขาต้องจัดการ


4

นอกเหนือจากคำแนะนำที่ดีทั้งหมดที่ได้รับจนถึงตอนนี้หนึ่งในวิธีปฏิบัติที่ฉันได้เรียนรู้เมื่อเวลาผ่านไปและการค้นหาที่สำคัญคือการเพิ่มความเห็นอย่างละเอียดในโค้ดของคุณ มันเป็นสิ่งที่สำคัญที่สุดสำหรับฉันเมื่อฉันกลับมาที่บางอย่างหลังจากเวลาผ่านไปนาน อธิบายกับตัวเองว่าคุณกำลังคิดอะไรอยู่ มันใช้เวลาเล็กน้อยในการทำ แต่มันค่อนข้างง่ายและไม่เจ็บปวด

บางครั้งฉันมีความคิดเห็นสองถึงสามเท่าของความคิดเห็นเช่นเดียวกับฉันโดยเฉพาะอย่างยิ่งเมื่อแนวคิดหรือเทคนิคใหม่สำหรับฉันและอธิบายให้ฉันฟัง

ทำการควบคุมเวอร์ชันปรับปรุงวิธีปฏิบัติของคุณ ฯลฯ .... ทั้งหมดข้างต้น แต่อธิบายสิ่งต่าง ๆ ให้ตัวเองในขณะที่คุณไป มันใช้งานได้ดีจริงๆ


4

คุณสมบัติใดที่มีความสำคัญสำหรับโปรแกรมประเภทนี้

มันอาจไม่สำคัญว่ามันจะง่ายต่อการบำรุงรักษาหรือพัฒนาเพราะโอกาสที่จะไม่เกิดขึ้น

มันอาจไม่สำคัญว่าจะมีประสิทธิภาพแค่ไหน

มันอาจไม่สำคัญว่าจะมีส่วนต่อประสานกับผู้ใช้ที่ยอดเยี่ยมหรือว่าปลอดภัยต่อผู้โจมตีที่ประสงค์ร้าย

อาจเป็นเรื่องที่อ่านได้: บางคนที่อ่านโค้ดของคุณสามารถโน้มน้าวใจตนเองว่าทำในสิ่งที่อ้างว่าทำ

แน่นอนมันสำคัญว่ามันถูกต้อง หากโปรแกรมให้ผลลัพธ์ที่ไม่ถูกต้องนั่นเป็นข้อสรุปทางวิทยาศาสตร์ของคุณนอกหน้าต่าง แต่จะต้องดำเนินการอย่างถูกต้องข้อมูลที่คุณขอให้ดำเนินการอย่างถูกต้องเท่านั้น มันไม่สำคัญมากนักว่ามันจะตกลงมาหรือไม่หากได้รับค่าข้อมูลอินพุตเชิงลบหากค่าข้อมูลทั้งหมดของคุณเป็นค่าบวก

นอกจากนี้ยังเป็นเรื่องสำคัญที่คุณต้องควบคุมการเปลี่ยนแปลงในระดับหนึ่ง ผลลัพธ์ทางวิทยาศาสตร์ของคุณจะต้องทำซ้ำและนั่นหมายความว่าคุณต้องรู้ว่าโปรแกรมรุ่นใดที่ให้ผลลัพธ์ที่คุณต้องการเผยแพร่ เนื่องจากมีนักพัฒนาเพียงคนเดียวการควบคุมการเปลี่ยนแปลงจึงไม่จำเป็นต้องมีความประณีตมากนัก แต่คุณต้องแน่ใจว่าคุณสามารถย้อนเวลากลับไปเพื่อสร้างผลลัพธ์ใหม่ได้

ดังนั้นไม่ต้องกังวลกับกระบวนทัศน์การเขียนโปรแกรมการวางแนววัตถุความสง่างามของอัลกอริทึม กังวลเกี่ยวกับความชัดเจนและความสามารถในการอ่านและเกี่ยวกับความสามารถในการติดตามการเปลี่ยนแปลงของคุณเมื่อเวลาผ่านไป ไม่ต้องกังวลกับส่วนต่อประสานผู้ใช้ ไม่ต้องกังวลเกี่ยวกับการทดสอบการรวมกันของพารามิเตอร์อินพุตที่เป็นไปได้ แต่ทำการทดสอบให้มากพอที่จะมั่นใจ (และทำให้ผู้อื่นมั่นใจ) ว่าผลลัพธ์และข้อสรุปของคุณนั้นถูกต้อง


4

ฉันทำงานในสภาพแวดล้อมที่คล้ายกันกับนักวิชาการผู้เขียนโค้ด (คณิตศาสตร์ / วิทยาศาสตร์) จำนวนมาก แต่ความก้าวหน้าของพวกเขาช้าเนื่องจากเหตุผลเดียวกับที่คุณอธิบาย อย่างไรก็ตามฉันสังเกตเห็นสิ่งหนึ่งที่เป็นไปได้ด้วยดีซึ่งฉันคิดว่าสามารถช่วยคุณได้ด้วย: สร้างและบำรุงรักษาคอลเล็กชันของห้องสมุดเฉพาะที่สามารถใช้ได้ในหลายโครงการ ไลบรารีเหล่านี้ควรมีฟังก์ชั่นยูทิลิตี้และจะช่วยให้โครงการปัจจุบันของคุณเฉพาะโดเมนปัญหา

ตัวอย่างเช่นคุณอาจจะต้องจัดการกับจำนวนมากของการเปลี่ยนแปลงพิกัดในเขตของคุณ (ECEF, NED, lat lon / WGS84 ฯลฯ ) เพื่อฟังก์ชั่นเช่นควรจะไปเป็นโครงการใหม่ที่เรียกว่าconvert_ecef_to_ned() CoordinateTransformationsวางโครงการภายใต้การควบคุมเวอร์ชันและโฮสต์ไว้บนเซิร์ฟเวอร์ของแผนกของคุณเพื่อให้ผู้อื่นสามารถใช้ (และหวังว่าจะปรับปรุง) หลังจากนั้นไม่กี่ปีคุณควรมีการรวบรวมไลบรารีที่มีประสิทธิภาพสำหรับโครงการของคุณที่มีรหัสเฉพาะสำหรับปัญหา / โดเมนการวิจัยเฉพาะ

คำแนะนำทั่วไปเพิ่มเติมบางส่วน:

  • มุ่งมั่นที่จะสร้างแบบจำลองปัญหาเฉพาะของคุณอย่างถูกต้องที่สุดเท่าที่จะทำได้ไม่ว่าจะเป็นอะไรก็ตาม วิธีการที่คำถามออกแบบซอฟต์แวร์เช่นอะไร / ที่ / วิธีการใส่ตัวแปรควรเป็นที่ชัดเจนมากขึ้นที่จะตอบ
  • ฉันจะไม่กังวลกับการพัฒนาแบบทดสอบเนื่องจากรหัสทางวิทยาศาสตร์อธิบายความคิดและแนวคิดและมีความสร้างสรรค์และลื่นไหลมากขึ้น ไม่มี API ที่จะกำหนดบริการที่จะรักษาความเสี่ยงต่อรหัสของผู้อื่นเมื่อเปลี่ยนการทำงาน ฯลฯ

อย่าปล่อยให้คนอื่นปรับปรุง โอกาสที่พวกเขาจะไม่เข้าใจวัตถุประสงค์ของรหัสและพวกเขาก็จะทำสิ่งสกปรก
คณิตศาสตร์ที่

@ มา ธ อลเลอร์เอาละถ้าพวกมันเป็นไลบรารียูทิลิตี้ทั่วไปมันคงเป็นเรื่องยากสำหรับคนอื่น ๆ ที่จะทำให้สับสนนั่นเป็นความคิด
jigglypuff

เหตุใดจึงยากที่จะทำให้ไลบรารีวัตถุประสงค์ทั่วไปสับสน มันไม่ยากเลยถ้าคุณไม่รู้ว่าคุณกำลังทำอะไรอยู่หรือถ้าคุณพยายามอย่างหนักจริงๆ
mathreadler

@Mathreadler เนื่องจากโดยทั่วไปมีเพียงวิธีเดียวที่จะทำการแปลงพิกัดหรือแปลงหน่วยเช่น
jigglypuff

โดยทั่วไปจะมีวิธีการมากมายขึ้นอยู่กับวิธีเก็บหมายเลขของคุณในหน่วยความจำซึ่งเป็นตัวแทนที่พวกเขาใช้และอื่น ๆ อีกมากมายซึ่ง CPU ที่คุณต้องการรวบรวมไลบรารี coder หนึ่งอาจสันนิษฐานว่าทุกคนจะใช้ IEEE เป็นสองเท่า แต่อีกตัวอย่างหนึ่งมักใช้ความแม่นยำเดียวหรือรูปแบบแปลก ๆ ที่สาม coder หนึ่งจะใช้แม่แบบ polymorphism แต่อีกอันหนึ่งอาจแพ้มันบางอันที่สามถึงกับ weirder อันหนึ่งที่จะเข้ารหัสยากทุกอย่างในระดับต่ำ c หรือชุดประกอบ
mathreadler

3

ต่อไปนี้เป็นความคิดเห็นของฉันและได้รับอิทธิพลอย่างมากจากเส้นทางของฉันเอง

การเข้ารหัสมักจะทำให้มุมมองที่ถูกต้องเกี่ยวกับวิธีที่คุณควรทำสิ่งต่าง ๆ แทนที่จะใช้เทคนิค & เครื่องมือฉันคิดว่าคุณต้องดูค่าและค่าใช้จ่ายสะสมเพื่อตัดสินใจเลือกกลยุทธ์ที่เหมาะสม

การเขียนโค้ดที่ดีอ่านง่าย debuggable ใช้เวลาและความพยายามอย่างมาก ในหลายกรณีการกำหนดขอบเขตการวางแผนที่ จำกัด ไม่คุ้มกับการทำเช่นนี้ (การวิเคราะห์อัมพาต)

เพื่อนร่วมงานคนหนึ่งมีกฎง่ายๆ หากคุณกำลังทำสิ่งเดียวกันเป็นครั้งที่สามแล้วลองลงทุนมิฉะนั้นงานที่รวดเร็วและสกปรกก็เหมาะสม

การทดสอบบางประเภทนั้นเป็นสิ่งจำเป็น แต่สำหรับโครงการหนึ่งงานการมองด้วยดวงตาก็อาจเพียงพอ สำหรับสิ่งที่สำคัญการทดสอบและโครงสร้างพื้นฐานการทดสอบเป็นสิ่งจำเป็น ค่าคือมันทำให้คุณเป็นอิสระเมื่อการเขียนโปรแกรมค่าใช้จ่ายคือถ้าการทดสอบมุ่งเน้นไปที่การใช้งานเฉพาะการทดสอบนั้นจำเป็นต้องบำรุงรักษาด้วยเช่นกัน การทดสอบยังเตือนให้คุณทราบถึงสิ่งที่ควรปฏิบัติในการทำงาน

สำหรับสคริปต์ที่ไม่ใช้งานของตัวเอง (บ่อยครั้งสำหรับสิ่งต่าง ๆ เช่นการตรวจสอบความน่าจะเป็นโดยประมาณหรือคล้ายกัน) ฉันพบว่าสิ่งเล็ก ๆ สองอย่างมีประโยชน์มาก: 1. ใส่ความคิดเห็นที่แสดงวิธีใช้งานโค้ด 2. ใส่คำอธิบายสั้น ๆ ว่าทำไมคุณถึงเขียนโค้ด สิ่งเหล่านี้ชัดเจนมากเมื่อคุณเขียนโค้ด แต่ความชัดเจนจะทำให้เสียเวลา :-)

OOP นั้นเกี่ยวกับการใช้รหัสซ้ำสิ่งที่แนบมาในรูปแบบแฟ็กเตอริง ฯลฯ มีประโยชน์มาก แต่ง่ายที่จะหลงทางหากผลิตโค้ดและการออกแบบที่มีคุณภาพไม่ใช่เป้าหมายสุดท้ายของคุณ ต้องใช้เวลาและความพยายามในการผลิตสิ่งที่มีคุณภาพ


3

ในขณะที่ฉันคิดว่าการทดสอบหน่วยมีข้อดีของพวกเขาพวกเขามีค่าสงสัยสำหรับการพัฒนาทางวิทยาศาสตร์ - พวกเขามักจะมีขนาดเล็กเกินไปที่จะให้คุณค่ามากมาย

แต่ฉันชอบการทดสอบการรวมสำหรับโค้ดทางวิทยาศาสตร์:

แยกรหัสขนาดเล็กของคุณซึ่งสามารถทำงานได้ด้วยตัวเองเช่นไปป์ไลน์ ETL จากนั้นเขียนการทดสอบที่ให้ข้อมูลเรียกใช้ etl ไปป์ไลน์ (หรือเพียงแค่ขั้นตอน) แล้วทดสอบว่าผลลัพธ์ตรงกับความคาดหวังของคุณ ในขณะที่ก้อนทดสอบสามารถเป็นรหัสจำนวนมากการทดสอบยังคงให้ค่า:

  1. คุณมีตะขอที่สะดวกในการรันรหัสอีกครั้งซึ่งช่วยให้รันได้บ่อยครั้ง
  2. คุณสามารถทดสอบสมมติฐานในการทดสอบของคุณ
  3. หาก somethink แตกเป็นเรื่องง่ายที่จะเพิ่มการทดสอบที่ล้มเหลวและทำการแก้ไข
  4. คุณประมวลผลอินพุต / เอาต์พุตที่คาดหวังหลีกเลี่ยงอาการปวดหัวตามปกติซึ่งเป็นผลมาจากการพยายามเดารูปแบบข้อมูลอินพุต
  5. แม้ว่าจะไม่เป็นแบบทดสอบหน่วยก็ตามการทดสอบทางไอทียังช่วยแยกรหัสของคุณออกจากกันและบังคับให้คุณเพิ่มขอบเขตในรหัสของคุณ

ฉันใช้เทคนิคนี้บ่อยครั้งและมักจะจบลงด้วยฟังก์ชั่นหลักที่อ่านได้ง่าย แต่ฟังก์ชั่นย่อยมักจะค่อนข้างยาวและน่าเกลียด แต่สามารถแก้ไขและจัดเรียงใหม่ได้อย่างรวดเร็วเนื่องจากขอบเขต I / O ที่แข็งแกร่ง


2

ปกติแล้วฉันจะทำงานบนฐานข้อมูลขนาดใหญ่มาก เราใช้เครื่องมือทั้งหมดที่คุณพูดถึง เมื่อเร็ว ๆ นี้ฉันเริ่มทำงานกับสคริปต์ไพ ธ อนสำหรับโปรเจ็กต์ด้านข้าง พวกเขาเป็นไม่กี่โหลถึงไม่กี่ร้อยบรรทัดมากที่สุด ฉันไม่ผูกมัดกับสคริปต์เพื่อควบคุมซอร์ส สิ่งนี้มีประโยชน์เพราะฉันสามารถสร้างสาขาสำหรับทดลองการทดลองที่อาจใช้ไม่ได้ ฉันสามารถแยกได้ถ้าฉันต้องการทำซ้ำรหัสและแก้ไขเพื่อจุดประสงค์อื่น สิ่งนี้จะทิ้งต้นฉบับไว้ในชั้นเชิงในกรณีที่ฉันต้องนำมันออกมาอีกครั้ง

สำหรับ "การทดสอบหน่วย" ฉันมีไฟล์อินพุตบางไฟล์ที่มีวัตถุประสงค์เพื่อสร้างเอาต์พุตที่รู้จักซึ่งฉันตรวจสอบด้วยมือ ฉันอาจจะทำให้มันเป็นไปโดยอัตโนมัติ แต่มันรู้สึกว่ามันจะใช้เวลามากกว่านี้ในการทำเช่นนั้นมากกว่าที่ฉันจะประหยัดด้วยการทำมัน มันอาจขึ้นอยู่กับว่าฉันต้องแก้ไขและเรียกใช้สคริปต์บ่อยแค่ไหน ไม่ว่าจะด้วยวิธีใดถ้าทำได้ให้ทำ หากเป็นปัญหามากกว่าที่ควรค่าอย่าเสียเวลา


2

ด้วยการเขียนโค้ด - เช่นเดียวกับการเขียนโดยทั่วไป - คำถามหลักคือ:

คุณมีผู้อ่านคนใดในใจ? หรือใครใช้รหัสของคุณ

สิ่งต่างๆเช่นแนวทางการเข้ารหัสที่เป็นทางการไม่สมเหตุสมผลเมื่อคุณเป็นผู้ชมเพียงคนเดียว

ในทางกลับกันการเขียนโค้ดในทางใดทางหนึ่งในอนาคตคุณจะสามารถเข้าใจได้ทันที

ดังนั้น "สไตล์ที่ดี" จะเป็นหนึ่งซึ่งจะช่วยให้คุณมากที่สุด สไตล์นั้นควรเป็นคำตอบที่ฉันไม่สามารถให้ได้

ฉันคิดว่าคุณไม่จำเป็นต้องทดสอบ OOP หรือหน่วยสำหรับไฟล์ 150 LOC VCS เฉพาะจะน่าสนใจเมื่อคุณมีรหัส evoluting มิฉะนั้น.bakจะหลอกลวง เครื่องมือเหล่านี้เป็นวิธีแก้ปัญหาที่เลวร้ายคุณอาจไม่มีเลย

บางทีคุณควรเขียนโค้ดด้วยวิธีนี้ถึงแม้ว่าคุณจะอ่านในขณะที่เมา แต่คุณสามารถอ่านทำความเข้าใจและแก้ไขมันได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.