เคยมั้ยครับที่เราเองก็ไม่รู้ว่าตอนจบ ไม่สิ ตอนต่อไปของเรื่องจะเป็นยังไง เราจะเจออะไรบ้าง เราจะมีความสุข จะทุกข์ จะอะไรก็ตามที่เราจินตนาการไม่ถูก ถ้าเรายังไม่เห็นมัน
ผมเองก็เป็นเหมือนกัน และเป็นบ่อยด้วยในช่วงที่เราต้องเจออะไรใหม่ ๆ ทั้งตอนไปฝึกงาน ที่ตอนนั้นเขียน Postcard ไปที่บ้านของตัวเองเพื่อจะอ่านตอนฝึกงานเสร็จ เพราะคือไม่รู้เลยว่าเราจะเจออะไรบ้าง และอีกอย่างนึงก็คือ โปรเจกต์ผมเนี่ยแหละ โอเคก่อนแหละเรารู้ว่าเราจะได้อะไรมา เพราะมันคือผลลัพธ์ของโปรเจกต์ แต่เราไม่รู้เลยว่า เราต้องเขียนโค้ดยังไง ทำอะไรบ้าง จนกว่าเราจะได้มันมา แน่นอนนะครับในการเขียนบทความนี้ผมจะไม่ให้กระทบใครอยู่แล้ว อ่านแล้วก็อาจจะมึน ๆ หน่อยนะครับ เพราะคนเขียนตอนเขียนก็มึน
E-health for Personal Sensor Application
นี่คือชื่อโปรเจกต์ของผมครับ หลายคนอาจจะไม่ทราบว่ามันคืออะไร ซึ่งผมเองก็อยากบอกว่า เออ มันก็งงจริง ๆ นั่นแหละ อ่าว แต่แปลง่าย ๆ เลยครับจากหลังมาหน้า คือ แอพพลิเคชั่น ที่ใช้ในการรวบรวมสุขภาพส่วนบุคคล จากตัวรับรู้ (เซนเซอร์) ต่าง ๆ ซึ่งในรายงานเอง ผมเองยังมองว่าคำว่าเซนเซอร์ อาจไม่เข้าใจมากนัก บางจุด ผมเลยเขียนว่าอุปกรณ์ดูแลสุขภาพมากกว่า มันคือการรับค่าจากอุปกรณ์ดูแลสุขภาพต่าง ๆ เข้ามาแสดงผลที่แอพพลิเคชั่น โดยไม่จำกัดบริษัท (จริง ๆ ก็จำกัดแหละ แต่ไม่ได้หมายความว่าทำให้ทำงานกับอุปกรณ์บริษัทใดบริษัทหนึ่ง) จริง ๆ มันก็คือจำกัดอยู่ดี อ่าว งงตัวเอง
แต่ทั้งหมดนี้ทำได้หมดแล้ว อ้าวแล้วอะไรเนี่ย มันคือมวยล้มต้มคนดูหรือเปล่าเนี่ย ผมก็ถามตัวเองเหมือนกัน เนื่องจากมันเป็นโปรเจกต์ต่อยอด แล้วให้ผมทำอะไร ผมถามไป แล้วคุณจะทำอะไร ผมได้รับคำถามกลับมา
เออนั่นแหละ แล้วอยากจะทำอะไรหละ
แชะภาพเพื่อนรักของผม น้องคอมเราเอง
ใช่ครับ เพราะนี่คือโปรเจกต์ของผม ผมอยากจะทำอะไรก็ได้ อาจารย์บอกว่าอาจารย์เป็นที่ปรึกษา และ กรรมการ ที่จะให้คะแนนตามสิ่งที่คุณทำ คุณคิดว่ามันมีปัญหาอะไรบ้าง อยากจะทำอะไรกับมันบ้าง ทำอะไรแล้วคิดว่ามันมีประโยชน์บ้าง เขาอนุญาติให้ใช้ Library ใดก็ได้ หรือ ใช้ Source Code ของโปรแกรมที่มีอยู่ได้ ใช่ส่วนของโปรแกรมได้ แต่สุดท้ายคุณต้องรายงานออกมาว่าสิ่งที่คุณทำคืออะไร งานของคุณอยู่ที่ไหน
เออ พูดไปพูดมา ย่อหน้าที่ผ่านมา เอามาประยุกต์เป็นคำคมได้เลยนะเนี่ย
อยากจะบอกตรง ๆ ว่าเราใช้เวลาหลายเดือนมากทั้งใน Prepare Project และใน Project 1 ในการเคลียร์เรื่องดังกล่าวข้างบนนี้ เนื่องจากผมเองก็ยังไม่คิดเป็นระบบเท่าไหร่ ดังนั้นการเข้าใจให้ได้ข้อความในย่อหน้านี้ แม้ตอนพิมพ์จะใช้เวลาเพียง 3-4 นาที แต่ในการทำ กระบวนการ คลุ่มเวลากว่า 6 - 7 เดือน
การทำโจทย์ที่ (ยัง) ไม่มี Solution
หลังจากนั้น ซึ่งจริง ๆ มันก็คือ ระหว่างนั้นนั่นแหละ ถึงแม้โปรเจกต์ยังไม่มี Scope ทั้งหมด แต่มันก็มีอะไรให้ทำ และเยอะด้วย นั้นก็คือส่วนการแก้ข้อผิดพลาด ของอุปกรณ์ 1 ใน 4 อุปกรณ์ ที่มีการทำงานพลาดอยู่ จากการทดสอบของผม และ เพื่อนผมด้วย ว่ามันไม่ได้จริง ๆ ถึงแม้อาจารย์จะยืนยันว่าได้ จนถึงวันนี้ที่ผมจะซ่อมได้แล้ว ผมก็ยังหาเหตุผลอยู่ว่า เพราะอะไรกันแน่ ที่ทำให้ตัวนี้ผิดพลาดไป เหตุผลที่ผมคิดว่าน่าจะใช่ที่สุดก็คือ การเปลี่ยนชนิดของ Database แต่โอเคแหละ เมื่อไม่รู้ ผมก็ต้องพยายามหา และ พยายามแก้
การแก้งานตรงนี้ แม้จะมีพื้นที่ประมาณ 1 ใน 4 ของรายงานและการนำเสนอ เทียบกับฟีเจอร์อื่น ๆ แต่กินเวลา 3 ใน 4 ของทั้งหมด ผมเองก็เริ่มเรียนรู้วิธีที่จะแก้ปัญหาตรงนี้ เอ้ ผมจะทำยังไงดี เพราะมันเป็น Stack ที่ค่อนข้างจะยาก มีทั้ง Android with Kotlin, ReactiveX, Dagger2 และ อื่น ๆ
ส่วนนี้ผมยกให้ ReactiveX (RxJava2) เป็นพระเอกเลยเอา ส่วน Dagger ผมเองพยายามเลี่ยง เท่าที่เลี่ยงได้ เพราะสำหรับผมรู้สึกว่า เห้ย ทำไมมันยากจังวะ เทียบกับส่วนอื่น ๆ ที่ทำด้วย Rx และทำด้วยไลบารี่อื่น ๆ ที่มันเห็นภาพ และมี Document ค่อนข้างดี แน่นอนเป็นโชคดีที่ผมไม่ต้องไปเกาะกับตัว Dagger มากนัก เพราะสิ่งที่ผมทำมันอยู่ใน Class ซึ่งมันก็มีการ Dependencies Injector นั่นแหละ แต่เราไม่ต้องไปแตะมันมาก แค่รู้ว่า เออ มันทำงานยังไง และมันทำให้เกิดอะไรขึ้น ส่วนที่ผมเขียนเองนี่ ผมยอมรับว่าผมไม่แตะ Dagger2 เลย ใครสนใจ Rx ลองไปดูได้ ReactiveX
เพราะมันไม่ใช่การบ้านทั่วไปที่เราทำ
อย่าว่าเฉลยตายตัวเลย เฉลยอ้อม ๆ ยังไม่มีเลย เสร็จแล้วยัง ทำไมไม่ทำให้เสร็จ ๆ ไป ก็มันคิดไม่ออกอ่ะปัดโถ่ หลังจากทำงานนี้ไปซักพัก คุณจะพบว่างานเอย การบ้านเอย โค้ดเล็ก ๆ เอย มันง่ายไปเลย เพราะว่ามันมี start และ end ของมัน มันมีขอบเขต มี Milestone มีจุดที่รู้ว่ามันคือ Solution ของมัน แต่ตอนนี้เราต้อง define Start,End,Milestone และ Solution ต่าง ๆ เองทั้งหมด
เอ้าไล่โค้ดไป
ตอนแรกก็มีการมานั่งวาดผังงานอยู่เหมือนกันนะ ใช้ Visio เลย แต่ตอนหลัง ก็ไม่รู้ว่าเรามานั่งวาดไปทำไมว้าา เขียนธรรมดาก็ได้ สุดท้ายทั้งหมดนี้ไม่ได้ใช้ครับ เอาไว้โชว์อาจารย์เฉย ๆ 555
ผมใช้วิธีการไล่โค้ดใน Android Studio ไปเรื่อย ๆ ครับ ตอนนั้นผมยังใช้เครื่องมือ Debug ไม่เป็น เหมือนตอนนี้ ผมใช้วิธีการคลาสสิกก็คือ พ่น Log ออกมาเรื่อย ๆ ให้รู้ว่าปัญหามันอยู่ครงไหน และอีกอย่างคือ โปรแกรมมันเดินทางยังไง ซึ่งพูดดูมันเหมือนง่าย แต่จริง ๆ มันไม่ง่ายเลยเพราะว่าคนเริ่มต้นเขียน Android อย่างผม มาเจอกับโครงสร้างโค้ดที่ซับซ้อน แต่โคตร Clean เลย (ซึ่งนี่คือโชคดีของผม)
ถ้าจะเล่าประสบการณ์ที่ผ่านมาทั้งหมดคงไม่ได้หรอก ไม่ใช่อะไร เดี๋ยวมันจะยาวเกิน หรือ ไม่ก็พิมพ์ไม่ไหว แต่อยากจะบอกว่ารู้มั้ยตอนที่ผมแก้มาจนได้เห็นระบบมันรับข้อมูลครั้งแรกได้ โอ้ย ผมแทบอยากจะกระโดดให้ลั่นห้อง
โต๊ะที่ผมทำงานและสไลด์วิธีการฟิลเตอร์ข้อมูลที่ผมคิดว่า เออ ใช้วิธีนี้แหละ
ผมเองพบว่าปัญหามันเกิดจาก 2 ส่วน ข้อมูลที่มันเป็นสตรีมของอุปกรณ์ตัวนี้ แต่ตัวอื่น ๆ ข้อมูลมันเป็นดิสครีต แน่นอนเราจะเก็บสตรีมที่มาเรื่อย ๆ ในรูปของดิสครีตก็คงไม่ได้ ทำได้เพียง เลือกจุดที่เหมาะสมที่สุดในสตรีม เป็นตัวแทนของข้อมูลสตรีมนั้น อีกส่วนคือ ระบบยังไม่สามารถ detect ได้เนี่ยเองว่า อุปกรณ์นี้นะ มันให้ค่าที่ระบบต้องการได้นะ You ไปเก็บข้อมูลสิ
นั่นคือ Part แรกของโปรเจกต์ครับ พาร์ทที่ใหญ่ที่สุด แต่งานที่ออกมาอาจจะดูเล็ก ๆ
แล้วเราจะ Report อะไร
ต่อให้ Backend ดีแค่ไหน ถ้าเข้าใช้ไม่ได้ ถ้าได้แค่ดูค่า มันก็ไม่รู้ว่าจะเอาไว้ใช้ทำอะไรสินะครับ แล้วกับระบบที่ผมทำไม่ค่อยดีเท่าไหร่แล้วด้วย ดังนั้นงานผมจึง… เดี๋ยว ยังไม่เสร็จ
ในส่วนต่อไปคือการทำ Frontend หรือ ส่วนของ Report ต่าง ๆ เป็นความไม่ถูกต้องของการเขียนโปรแกรมคอมพิวเตอร์ของผมอีกอันหนึ่งแหละครับ ก็คือการทำ UI เสมือน แอพใหม่ครอบลงแอพเก่า เนื่องจากผมเองบอกตั้งแต่ต้นว่าไม่อยากจะจับ Dagger หรือ ReactiveX ถ้าไม่จำเป็นอีก โถ.. โชคดีที่การวางแอพพลิเคชั่นเดิมของพี่เขาดีมาก คือการตัดขาดกันเลยสำหรับส่วนที่รับข้อมูล กับ ส่วนแสดงผลข้อมูล ซึ่งมีตัวที่แยกจากกันก็คือ ฐานข้อมูล (Database) ด้านบนผมได้บอกมาแล้วว่ามันคือ Cloud Firestore ใช่มั้ยครับ แต่นั่นคือสิ่งที่ผมรู้ หลังจากผ่านอะไรมาเยอะแล้ว
โอ้ข้อมูล เจ้าอยู่ที่ไหน
แชะรูปกับโต๊ะโปรเจกต์หน่อย
มันเป็นความผิดพลาด และความบ้าบอของเราเองด้วยส่วนหนึ่ง ฮา.. ที่ทำไมไม่ถาม แต่จริง ๆ น่าจะเป็นเพราะมั่นใจมาตลอดมากกว่าว่าข้อมูลเนี้ยเก็บอยู่ในตัวเครื่อง ที่เรียกว่า Room Database จะเห็นได้ว่าผมเองได้เขียนบทความเกี่ยวกับ Room Database เอาไว้ด้วย เพราะว่าตอนนั้นเรากำลังโฟกัสตรงนี้มาก ๆ ผมทั้งทำ Demo Fragment ที่ดึงข้อมูลออกมาจาก DB ดึงหมดบ้าง Specific บ้าง โดยใช้หลักการเข้าถึงของ Kotlin Coroutines & Live Data นะครับ (ตอนแรกว่าจะทำแบบดึงจาก RxJava แบบที่พี่เขาทำ สุดท้าย เออวิธีนี้แล้วกัน) ผมค้นยังไง เอ้ มันก็ไม่เจอ เอ้ ผิดตรงไหนป่าวว่ะ
เออ นอกจากนี้แล้ว เรายังทำ Note การทำ Android ผ่าน Coroutines, LiveData ลงในบล็อกด้วยนะ ดูที่นี่เลย Tin Android Doc
ผมเองก็จำไม่ได้เหมือนกันว่าผมคิดได้ตอนไหน หรืออะไรมันมาดลใจให้ผมเปลี่ยนใจไปที่ Firebase คือ ผมไม่ทราบว่าผมไปเจอโค้ดส่วนไหนเข้า จึงรู้ว่า เห้ยหรือว่าข้อมูลมันเก็บบน Firebase ว่ะ ผมเลยลองดึงข้อมูลจาก Firebase เอ้าเห้ย ปรากฏการณ์มหัสจรรย์ ได้เฉย
คืออยากบอกก่อนนะว่า ตอนนั้นผมยังไม่ได้มีสิทธิในการเข้าถึง Firebase Console ในเว็บ หรือ ในที่ใดก็แล้วแต่ ผมเองเลยไม่ทราบตรงนี้ ตอนนั้นผมใช้ Credential ที่มันฝังอยู่ในแอพอยู่แล้วในการเชื่อมต่อไป แต่ตอนนี้ผมขอเข้าถึงแล้วนะ
Firebase ให้หมด ?
บอกก่อนนะครับ ว่ามันไม่ใช่หนทางที่ดีเท่าไหร่ (หรืออาจจะไม่ดีเลย) ที่ผมเห็นว่าในเมื่อข้อมูลทั้งหมดอยู่บน Cloud Firestore แล้ว ก็เก็บข้อมูลอื่น ๆ ลงใน Firestore ด้วยสิ ในความคิดของผมตอนนั้นก็คือ เราจะได้ให้ข้อมูลที่เป็น Application Logic มันเปลี่ยนได้ง่าย ซึ่งตอนนี้ผมพิสูจน์แล้วว่า เออ ผมคิดผิด แต่ตอนนี้ตัวแอพก็ยังทำงานโดยใช้หลักการนี้อยู่นะครับ
ตอนนั้นติดป้ายหนีโควิดเอาไว้ บอกว่าจะลาแค่อาทิตย์เดียว จนถึงบัดนี้ ยังไม่ได้กลับไปถอดป้ายเลยจ้า
ในการ Indicate ข้อมูลสุขภาพว่าอยู่ในระดับปลอดภัย เสี่ยง อันตราย และ Fetch คำแนะนำให้กับผู้ใช้ อย่างแรกเลยใช่ไหมครับมันต้องมีเกณฑ์ ซึ่งผมเองเลือกเก็บเกณฑ์ไว้ใน Online เกือบทั้งหมด (ซึ่งจริง ๆ ส่วนนี้มันควรจะเก็บบนเครื่องอาจจะดีกว่า ) ถ้าไม่นับ Cache ที่ Cloud Firestore เก็บไว้ในโทรศัพท์อัตโนมัติให้ผมแล้ว (ซึ่งมันน้อยนะ มันเก็บนั่นแหละ แต่มันไม่ได้สามารถไว้ใจได้ขนาดนั้น ผมไว้ใจมันเกินไป) เราจะต้องดึง Logic พวกเกณฑ์การจำแนกทั้งหมด จาก Internet ทุก ๆ ครั้ง ที่จะมีการวิเคราะห์ หรือ ทุก ๆ ครั้งที่เราจะแสดง Data แสดงกราฟ ที่มีเส้นขีดอันตราย ขีดเสี่ยงด้วยเนี่ย เราจะต้องใช้เวลาที่นาน และอาจจะบอกว่า เราใช้ Bandwidth ในการลิงค์กับ Server โดยป่าวประโยชน์ไปรึเปล่านะ ด้วยซ้ำ และแน่นอนถึงมันจะช้าเพียงแค่ไม่กี่วินาที แต่มันก็เพียงพอที่จะทำให้ Logic ใน App ของผม คาดเคลื่อนได้ และ มันก็เกิด Deadlock ขึ้นมาด้วย
การทำตรงนี้ คงต้องประเมินให้ดี ๆ นะครับ ว่าส่วนไหนควรเก็บเป็น Application Logic Hard Code ไปเลย ควรเก็บใน Internal Database หรือควรเก็บใน External Database มันต้องแบ่งกันให้ดีกว่านี้อ่ะครับ
แล้วต้องเพิ่มฟีเจอร์อะไรอีก
ถามว่าแค่นี้พอหรือไม่ คงไม่ต้องถามหรอกครับ มันยังคงดูน้อยไปไงครับในรูปของ Senior Project โชคดีครับที่ผมได้ไปเจอข้อมูลของ NHES (National Health Examination Survey) ครั้งล่าสุดของไทย จากกรมควบคุมโรค ในเว็บของกองโรคไม่ติดต่อ ซึ่งทำไว้ในปี 2557 มันจะมีข้อมูลเปิดเผยที่เป็นสถิติประชากร เกินความชุคโรค ค่าเฉลี่ยของตัวชี้วัดทางสุขภาพต่าง ๆ พอให้ผมได้เอามาใช้บ้างกับแอพพลิเคชั่น โครงงานของผม เลยดูพอมีประโชยน์บ้าง
นี่เป็นวีดีโอพรีเซนต์นะครับ ในโพสที่เขียนมานี้อาจจะไม่ค่อยมีสาระอะไรเท่าไหร่ เล่าความรู้สึกเสียมากกว่า ในรายละเอียด ดูที่วีดีโอได้เลยครับ
รายงานเสร็จแล้วยัง
เสียงของพ่อผมเรียกมา ในหลาย ๆ ครั้ง หลังจากเห็นผมบ่นเรื่องนี้เป็นปี 5555 จริง ๆ มันไม่ใช่รายงานนะ มันคือโครงงาน แต่ก็ช่างเถอะ พ่อผมเรียกแบบนี้ไปแล้ว ผมเองก็อยากให้มันเสร็จนะ แต่โดยสภาพของเทคโนโลยี โอเค เราส่ง แต่งานเราก็ยังไม่เสร็จอยู่ดี ถึงแม้ไม่มีสัญญา Maintenance อะไร แต่มันก็เป็นสัญญาที่ให้ไว้แล้วท่ามกลางการสอบ เอ้า ไปสัญญาอะไรไว้หละ โอเค โปรเจกต์อ่ะส่งได้ แต่ท้ายที่สุด งานที่มันจะใช้ได้จริง ๆ ไม่ใข่ผลจากโครงงานหรอก เพราะ งานเราอาจถูกจำกัดด้วยเวลา และความสามารถอันเล็กน้อยของเราในตอนนั้น แต่เวลาใช้งานจริง ๆ ของแอพพลิเคชั่น หรือ ผลผลิตของ Developer ทั้งหลาย มันก็เหมือนกับลูกที่เราต้องไปคอยแก้บั๊ก ขจัดตัดแต่ง ให้มันใช้งานกับผู้ใช้งานได้ แล้วผมก็หวังว่า ผมจะทำ Production Version ออกมาได้ เร็ว ๆ นี้
เอ้าเพลงมา เราจะทำตามสัญญา….. (เออ ผมว่าเราจบบทความนี้แค่นี้ดีกว่านะครับ)
ไอดุกครับ แมวที่ภาควิชา ชอบมานอนหน้าห้องบ่อย ๆ
และต่อให้ออก Production และ Maintenance ก็คงต้องตามเก็บไปเรื่อย ๆ หากมีใครใช้แล้ว ประสบปัญหา หรือ Complaint มา แต่อย่างไรก็ดี ถ้ามันมีประโยชน์กับใครซักคน ผมว่า ผมก็คงภูมิใจนะ
ใช้กับใครดีหละ อะไรนะ ใช้กับเรานี่แหละ ได้ข่าวว่าอ้วนจังแล้ว