Stream Three Project: การพัฒนาข้อมูลเป็นศูนย์กลาง - Code Institute
โปรเจ็กต์นี้สร้างขึ้นโดยใช้ Flask Microframework และสามารถใช้เป็นนาฬิกาจับเวลาแบบแมนนวลเพื่อจับเวลานักกีฬาหลายคนในการว่ายน้ำและลู่วิ่ง เป้าหมายของแอปพลิเคชันนี้คือการปรับปรุงประสิทธิภาพในการจับเวลากีฬาโดยการลดจำนวนคนในการจับเวลาแยกกันและจัดเก็บเวลาโดยตรง แทนที่จะเก็บเอกสารเป็นลายลักษณ์อักษร
แอปพลิเคชันนี้ใช้เพื่อการศึกษาเท่านั้น แอปพลิเคชันนี้ไม่ได้มีไว้สำหรับการใช้งานเชิงพาณิชย์
สามารถดูการสาธิตสดของโครงการนี้ได้ที่นี่ แอพนี้โฮสต์บน Heroku เวลาถูกเก็บไว้ใน MongoDB
แนวคิดสำหรับแอป Timing Assistant นี้มาจากการได้ว่ายน้ำตลอดช่วงวัยเด็ก ฉันสังเกตเห็นว่าจำเป็นต้องมีคนจำนวนหนึ่งที่เกี่ยวข้องกับกระบวนการจับเวลา เนื่องจากทัชแพดในพูลไม่ได้แสดงเวลาที่แม่นยำหรืออ่านง่ายเสมอไปเนื่องด้วยเหตุผลหลายประการ นอกจากนี้ โค้ชและนักกีฬาจะไม่เห็นเวลาสุดท้ายหรือการแบ่งแยกจนกว่าการพบกันจะสิ้นสุดลง เว้นแต่คุณจะมีคนหลายคนที่จับเวลาบนดาดฟ้าสำหรับแต่ละเลนเพื่อจดเวลาลงในคลิปบอร์ด
ฉันเห็นโอกาสนี้ในการสร้างแอปพลิเคชันที่จะลดจำนวนคนที่เกี่ยวข้องกับกระบวนการจับเวลา โดยหวังว่าจะปรับปรุงประสิทธิภาพของการพบปะและข้อเสนอแนะต่อนักกีฬาและโค้ช แอปพลิเคชันนี้สามารถปรับให้เหมาะกับกีฬาแบบกำหนดเวลาได้ และเวอร์ชันนี้ใช้ได้กับทั้งว่ายน้ำและลู่วิ่ง
โค้ชและผู้จับเวลาสามารถเลือกกีฬา พบปะ กิจกรรม ความร้อน และหมายเลขเลน ซึ่งทั้งหมดนี้ช่วยให้พวกเขาติดตามสิ่งที่เกิดขึ้นในการมีตได้ นอกจากนี้ยังช่วยให้พวกเขาสามารถให้ข้อเสนอแนะแก่นักกีฬาได้ทันทีหลังการแข่งขัน เนื่องจากเวลาจะปรากฏขึ้นหลังจากที่คุณบันทึกพวกเขาแล้วกด 'เวลาดู' ฉันยังต้องการให้แน่ใจว่าพวกเขาสามารถเห็นผลลัพธ์สะสมของการประชุม แทนที่จะเห็นเพียงกิจกรรมเดียวในแต่ละครั้ง
ไม่มีการใช้ธีมสำหรับการออกแบบนี้ แต่เลือกใช้การออกแบบที่ทันสมัยเนื่องจากมีตัวจับเวลาและข้อมูลจำนวนมากบนหน้าเว็บ จึงอาจดูยุ่งเหยิงและไม่มีการรวบรวมกัน ฉันไม่ต้องการสิ่งนี้ ดังนั้นในขณะที่ฉันต้องการตัวเลือกตัวจับเวลา เวลา และเหตุการณ์ในหน้าเดียว ฉันคิดว่าการแบ่งหน้าออกเป็นสามส่วนในแนวตั้งจะเป็นวิธีที่ดีที่สุดในการทำสิ่งนี้ โดยสร้างความแตกต่างที่เห็นได้ชัดเจนระหว่างแต่ละหน้า
Timing Assistant สร้างขึ้นโดยใช้ Flask Microframework ใน Python พร้อมฐานข้อมูล NoSQL (MongoDB) บนแบ็กเอนด์ พร้อมด้วย HTML, CSS, Javascript และ jQuery บนฟรอนต์เอนด์ และสำหรับฟังก์ชันนาฬิกาจับเวลาที่เชื่อมต่อกับแบ็กเอนด์ด้วย AJAX
ในหน้าแรกของแอป ผู้ใช้ป้อนกีฬาที่ต้องการจับเวลา ชื่อทีม ชื่อผู้ใช้ และชื่อพบปะ การดำเนินการนี้จะนำพวกเขาไปยังหน้านาฬิกาจับเวลา ซึ่งพวกเขาจะสามารถเลือกกิจกรรมและความร้อนที่ต้องการจับเวลาได้ ผู้ใช้สามารถจับเวลาได้สูงสุดสามเลนและแยกเลนทั้งสามเลน ผู้ใช้จะต้องหยุดตัวจับเวลาหลักด้วยตนเองหลังจากหยุดตัวจับเวลาขนาดเล็กทั้งสามตัวแล้ว เนื่องจากถูกตั้งค่าแยกกัน อย่างไรก็ตาม สิ่งนี้อาจมีประโยชน์อย่างยิ่ง หากโค้ชต้องการทราบว่าการแข่งขันดำเนินไปนานแค่ไหน และเปรียบเทียบเวลาของนักว่ายน้ำกับเวลาของผู้เข้าเส้นชัยคนสุดท้าย เวลาของตัวจับเวลาหลักจะไม่บันทึกลงฐานข้อมูล
เมื่อพวกเขาคลิก "ส่ง" กิจกรรมและความร้อนจะปรากฏขึ้น จากนั้นพวกเขาสามารถเริ่มจับเวลาได้สูงสุดสามเลนโดยการกด 'START' บนนาฬิกาจับเวลาหลัก การดำเนินการนี้จะเริ่มนาฬิกาจับเวลาทั้ง 4 เรือน แต่มีเพียง 3 เรือนสุดท้ายเท่านั้นที่จะถูกบันทึกไว้ในฐานข้อมูล มีตัวเลือกในการรวบรวมเวลาแยกสำหรับแต่ละเลนแยกกันด้วยปุ่ม 'SPLIT' ตัวจับเวลาแต่ละตัวสามารถหยุดและเริ่มทีละตัวได้ โดยตัวจับเวลาหลักจะควบคุมนาฬิกาจับเวลาทั้งหมด (เริ่ม หยุด และรีเซ็ต)
เมื่อคลิก 'ประหยัดเวลา' เวลาจะถูกบันทึกโดยใช้การโทร AJAX ในไฟล์ Javascript เพื่อส่งเวลาไปที่ Flask โดยที่ Flask เชื่อมต่อกับ MongoDB เมื่อบันทึกเวลาแล้ว เมื่อคลิก 'ดูเวลา' เวลาจะปรากฏใต้นาฬิกาจับเวลา
ข้อมูลจะถูกบันทึกโดยไม่ต้องระบุเหตุการณ์หรือความร้อน (ฟิลด์เหล่านี้จะว่างเปล่าเมื่อมีการดูเวลา) วิธีนี้อาจมีประโยชน์หากโค้ชต้องการใช้นาฬิกาจับเวลาในทางปฏิบัติ ไม่ใช่ในการประชุม
ฉันอยากให้โค้ชมีโอกาสดาวน์โหลดข้อมูลในรูปแบบ PDF หรือไฟล์รูปแบบอื่นๆ ในระยะยาว จะช่วยให้พวกเขาสามารถเก็บบันทึกเวลาด้วยตนเองทั้งหมดโดยไม่ต้องอาศัยข้อมูลที่เขียนด้วยลายมือหรือพึ่งพาไซต์นี้ทุกครั้งที่ต้องการกลับไปดูการประชุมเก่าๆ
ฉันอยากให้โค้ชเลือกจำนวนนาฬิกาจับเวลาที่ต้องการดูตามจำนวนนักกีฬาในแต่ละฮีต ขณะนี้คุณสามารถจับเวลาได้ครั้งละ 3 คนเท่านั้น และคุณไม่สามารถเลือกจับเวลาให้น้อยกว่า 3 คนได้
ฉันยังต้องการใช้ 'โหมดฝึกซ้อม' และ 'โหมดพบปะ' ซึ่งจะทำให้การกำหนดเวลาในการพบปะและการฝึกซ้อมมีความซับซ้อนมากขึ้น โหมด Meet จะสร้างข้อจำกัดมากขึ้นในการเลือกกิจกรรมหรือฮีต และช่วยให้โค้ชเลือกได้ว่าต้องการจับเวลากี่เลน โหมดฝึกซ้อมจะช่วยให้โค้ชจดบันทึกเวลาที่พวกเขาประหยัดได้ (สำหรับการฝึกซ้อมเฉพาะ ฯลฯ) โดยที่ไม่ต้องระบุเหตุการณ์หรือฮีต
การทดสอบทั้งหมดสำหรับโปรเจ็กต์นี้ดำเนินการด้วยตนเอง แบบฟอร์มบนหน้า Landing Page จำเป็นต้องมีแอตทริบิวต์ในแท็กอินพุตเพื่อป้องกันไม่ให้ผู้ใช้กรอกข้อมูลในฟิลด์ในแบบฟอร์ม เนื่องจากจะส่งผลให้เกิดข้อผิดพลาด 400 เนื่องจากเส้นทางแอป Flask ขึ้นอยู่กับอินพุตเหล่านี้
ฟังก์ชัน Ajax และปุ่มประหยัดเวลาได้รับการทดสอบผ่านคอนโซลและตรวจสอบว่าข้อมูลมีรูปแบบที่ถูกต้องใน MongoDB ข้อมูลที่รวบรวมจากตัวจับเวลาและโครงสร้างข้อมูลที่ต้องการก็ได้รับการทดสอบเช่นกัน
ประหยัดเวลาเป็นรายบุคคลด้วยเอกสารหนึ่งฉบับต่อช่องทาง:
เวลาสำหรับเลนที่แสดงในเอกสารเดียวกัน (หมายเหตุ: เพื่อวัตถุประสงค์ในการทดสอบ จะมีการบันทึกเพียงสองเลนที่นี่เพื่อให้แน่ใจว่าสองเลนจะปรากฏในเอกสารเดียวกัน):
โครงสร้างข้อมูลที่ถูกต้อง:
การทดสอบนาฬิกาจับเวลาทำได้ด้วยตนเองเช่นกัน เพื่อให้แน่ใจว่าปุ่มรีเซ็ตหลักจะรีเซ็ตนาฬิกาจับเวลาและล้างการแบ่งเวลาออกจากตัวจับเวลาทั้งหมด ในขณะที่นาฬิกาจับเวลาแต่ละตัวจะล้างเฉพาะเวลาและการแยกของตัวเองเท่านั้น นอกจากนี้ คุณสมบัตินี้ยังได้รับการทดสอบสำหรับฟังก์ชันเริ่ม/หยุด เนื่องจากนาฬิกาจับเวลาหลักจะควบคุมนาฬิกาจับเวลาทั้งหมด ในขณะที่นาฬิกาจับเวลาแต่ละตัวควรควบคุมเฉพาะฟังก์ชันเริ่ม/หยุดของตนเองเท่านั้น
นอกจากนี้ เส้นทางของ Flask ทั้งหมดยังได้รับการทดสอบเพื่อให้แน่ใจว่าลิงก์ทั้งหมดใช้งานได้และสามารถจัดการกับค่าที่ไม่ปกติในอินพุตได้ และจะแสดงอินพุตอย่างถูกต้องผ่าน Jinja ในไฟล์ HTML
ในระหว่างขั้นตอนการทดสอบ ฉันตระหนักว่าเป็นไปได้ที่ผู้ใช้สองคนจะมีชื่อพบปะหรือชื่อคลับเดียวกัน ดังนั้นจึงทำให้ผู้ใช้สามารถบังเอิญไปเจอข้อมูลของคนอื่นได้ ดังนั้น หากต้องการดูเวลาในเทมเพลต ฉันได้รวมข้อมูลต่อไปนี้เพื่อให้แน่ใจว่าช่องป้อนข้อมูลสามช่องบนหน้า Landing Page จะต้องตรงกันเพื่อแสดงเวลาที่สอดคล้องกัน ซึ่งจำเป็นต้องมีชื่อทีม ชื่อผู้ใช้ และชื่อการประชุมที่ถูกต้องจึงจะตรงกัน เพื่อป้องกันการประหยัดเวลาหรือการดูเวลาข้าม
{% if time.team == team %}
{% if time.username == username %}
{% if time.meet == meets %}
การแยกสำหรับแต่ละเลนเดิมแสดงในรูปแบบต่อไปนี้:
split: ["00:02.2300:01.45"]
อย่างไรก็ตาม ฉันอยากให้พวกเขาปรากฏในรายการดังนี้:
split: ["00:02.23", "00:01.45"]
ดังนั้นฉันจึงต้องใช้ความเข้าใจรายการเพื่อแยกสตริงนี้ออกเป็นหลายสตริงในรายการ (หากมีการแยกมากกว่าหนึ่งรายการสำหรับเลน) ทุกๆ 9 อักขระ
ใน HTML timer_page.html แบบฟอร์มที่ส่งข้อมูลสำหรับฟังก์ชัน AJAX ดูเหมือนว่าจะมีแท็กปิดท้ายที่หลงทาง แต่จำเป็นต้องรวมข้อมูลเวลาสุดท้าย การแยก และเลนทั้งหมดเพื่อประหยัดเวลาไปยัง MongoDB . เนื่องจากจำเป็นต้องแสดงสไตล์และองค์ประกอบอื่นๆ ดูเหมือนว่าแบบฟอร์มจะไม่สอดคล้องกับองค์ประกอบอื่นๆ นอกจากนี้ เมื่อดูที่ HTML จะมีแท็กว่างอยู่ อย่างไรก็ตาม นี่คือจุดที่เวลาแยกถูกแทรกลงใน HTML โดยใช้ jQuery
เมื่อประหยัดเวลา หากคุณเลือกเลนเดียวกันสำหรับแต่ละจับเวลา (เช่น เลน 1) จะมีเพียงเลนเดียวใน 1 ครั้งเท่านั้นที่จะปรากฏในเวลาในการรับชม แต่คุณต้องเลือกเลน เนื่องจากคุณไม่สามารถดูเวลาที่บันทึกไว้ได้หากไม่มีเลน เนื่องจากลักษณะของโครงสร้างข้อมูล รายการแบบเลื่อนลงของเลนถูกตั้งค่าให้บันทึกที่เลน 1, ลงจอด 2 และลงที่ 3 ตามค่าเริ่มต้น ในกรณีที่ผู้ใช้ไม่ได้ระบุเลน ฉันหวังว่าจะใช้การตรวจสอบความถูกต้องที่จะห้ามไม่ให้ประหยัดเวลาหากผู้ใช้เลือกหมายเลขเลนเดียวกันสำหรับสองเลนในช่วงที่ร้อน
ฟังก์ชัน Javascript ที่ใช้งานนาฬิกาจับเวลาได้รับการแก้ไขจากบทแนะนำการเขียนโค้ดด้วยนาฬิกาจับเวลาของ Sara สำหรับแอปพลิเคชันนี้ HTML บางส่วนก็สร้างแบบจำลองตามตัวอย่างของเธอเช่นกัน แต่มีการปรับเปลี่ยนให้เหมาะกับสไตล์ ปุ่มหลายปุ่ม การแยก และเลน
สำหรับ JavaScript ฟังก์ชันการรีเซ็ตได้รับการแก้ไขสำหรับปุ่มรีเซ็ตเพื่อรีเซ็ตนาฬิกาจับเวลาทั้งหมดแทนที่จะรีเฟรชหน้า และปุ่มรีเซ็ตแต่ละปุ่มสำหรับนาฬิกาจับเวลาขนาดเล็กแต่ละตัวจะถูกลบออก เนื่องจากเป็นคุณสมบัติที่ไม่จำเป็นสำหรับ UX ของโปรเจ็กต์นี้ เพิ่มฟังก์ชันแยกส่วนด้วย ฟังก์ชั่น Start/Stop ได้รับการแก้ไขสำหรับการเปลี่ยนสไตล์ในปุ่มโดยใช้ jQuery มีการเพิ่มนาฬิกาจับเวลาหลักสำหรับ UX เพื่อให้โค้ชสามารถดูเวลาทั้งหมดที่ผ่านไปพร้อมกับเวลาของแต่ละบุคคลได้ คล้ายกับกระดานคะแนนว่ายน้ำ ปุ่มบันทึกเพื่อส่งค่าไปยัง Flask และ MongoDB ถูกเพิ่มโดยใช้ Ajax
ฟังก์ชัน Ajax ได้รับการจำลองตามโพสต์นี้จาก Stack Overflow และแก้ไขให้เหมาะกับโปรเจ็กต์นี้โดยดูที่รูปแบบของการใช้ Ajax และไวยากรณ์อื่นๆ มีการเพิ่ม PreventDefault เพื่อป้องกันไม่ให้เพจโหลดซ้ำเมื่อมีการเรียก AJAX
การเรียกซ้ำใน Jinja ใช้เพื่อวนซ้ำพจนานุกรมที่ซ้อนกันใน Python เพื่อเรนเดอร์เวลาและตอบสนองข้อมูลอย่างเหมาะสมโดยทำให้แน่ใจว่าเลนทั้งหมดถูกวนซ้ำและแสดง วิธีการนี้จาก Stack Overflow ใช้เป็นแนวทางและแก้ไขตามลักษณะของโครงสร้างข้อมูลของฉัน
มีการพยายามปรับโครงสร้างฟังก์ชันจาวาสคริปต์สำหรับนาฬิกาจับเวลาเพื่อให้ผู้ใช้สามารถตัดสินใจได้ว่าต้องการให้แสดงนาฬิกาจับเวลาจำนวนเท่าใดบนหน้าจอตามจำนวนเลนที่เลือก
var stopwatches = [ ] ;
var i ;
for ( i = 0 ; i <= 1 ; i ++ ) {
var stopwatch = new timing ( "timerLabel" + i , "start" + i , "splitLabel" + i ) ;
stopwatches . push ( stopwatch ) ;
console . log ( i ) ;
document . getElementById ( "start" + i ) . onclick = function ( ) {
stopwatches [ i ] . start ( ) ;
}
document . getElementById ( "reset" + i ) . onclick = function ( ) {
stopwatches [ i ] . reset ( ) ;
}
document . getElementById ( "split" + i ) . onclick = function ( ) {
stopwatches [ i ] . split ( ) ;
}
console . log ( stopwatches ) ;
}
เมื่อพยายามเขียนสิ่งเหล่านี้ใน for loop เช่นนี้ stopwatches[i].start() จะไม่อ่าน i
เป็นตัวแปรที่สามารถเปลี่ยนแปลงได้ แต่เมื่อมันถูกฮาร์ดโค้ด ก็ไม่มีปัญหา:
document . getElementById ( "reset" + i ) . onclick = function ( ) {
stopwatches [ 0 ] . reset ( ) ;
}
document . getElementById ( "split" + i ) . onclick = function ( ) {
stopwatches [ 0 ] . split ( ) ;
}
ฉันพยายามใช้วิธีอื่น ซึ่งเกี่ยวข้องกับคำสั่ง if เพื่อให้นาฬิกาจับเวลาที่เกี่ยวข้องปรากฏขึ้น
พยายามส่ง i
ผ่านฟังก์ชันแทนเป็นอาร์กิวเมนต์ที่นำมาจาก for loop ด้านบน แต่ไม่สำเร็จ:
function chooseNumberOfStopwatches ( i ) {
if ( i == 1 ) {
stopwatches_one . start ( ) ;
}
else if ( i == 2 ) {
stopwatches_one . start ( ) ;
stopwatches_two . start ( ) ;
} else {
console . log ( 'else' ) ;
}
}
หากคุณสนใจที่จะโคลนพื้นที่เก็บข้อมูลนี้ เพื่อตั้งค่าและติดตั้งทุกอย่างใน Requirements.txt ให้รันคำสั่งต่อไปนี้ในเทอร์มินัล:
$ sudo pip3 -r install requirements.txt
โปรดทราบว่าฉันใช้ Cloud9 สำหรับโปรเจ็กต์นี้ ดังนั้นหากคุณใช้โปรแกรมแก้ไขอื่น คำสั่งเทอร์มินัลอาจแตกต่างกัน โปรดดูเอกสารของโปรแกรมแก้ไขที่คุณใช้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับคำสั่งเทอร์มินัลเฉพาะของโปรแกรมแก้ไข จะต้องได้รับคีย์ลับทั้งหมดสำหรับ MongoDB ทีละรายการ เนื่องจากคีย์เหล่านั้นถูกซ่อนไว้สำหรับฉันโดยเฉพาะ