สร้างสรรค์ผลงานด้วยภาษาไพทอน (วิทยาการคำนวณ ม.3)

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

หนังสือเรียนเทคโนโลยี (วิทยาการคำนวณ) ม.3

การประมวลผลสารสนเทศ

ภาษาไพทอน (Python) มีโมดูลสำหรับจัดการข้อมูลจำนวนมาก โดยโมดูลจะใช้งานที่นี้ คือโมดูล Pandas

การใช้งานโมดูล Pandas ใน Repl.it

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

ในการใช้งานโมดูล Pandas จะต้องมีการนำเข้าโมดูล โดยใช้คำสั่งนี้

import pandas as pd

โครงสร้างข้อมูลของ Pandas

  • ข้อมูลที่เก็บเป็น Series – มีลักษณะคล้ายลิสต์ของข้อมูลหนึ่งมิติ หากผู้ใช้ไม่กำหนดดัชนี Pandas จะกำหนดดัชนีเริ่มต้นตั้งแต่ 0 ถึง จำนวนข้อมูลใน Series – 1
import pandas as pd
s = pd.Series([2,3,5,7,11,13,17,19,23,29])
print(s)
ผลลัพธ์จากการแสดงผล Series ชื่อ s ที่เก็บข้อมูลจำนวนเฉพาะที่มีค่าไม่เกิน 30
  • ข้อมูลที่เก็บเป็น DataFrame – มีลักษณะคล้ายตาราง (สองมิติขึ้นไป) หากผู้ใช้ไม่กำหนดดัชนี Pandas จะกำหนดดัชนีเริ่มต้นตั้งแต่ 0 ถึง จำนวนข้อมูลใน Series – 1
import pandas as pd
df = pd.DataFrame([["Tom",180],["Paul",183],["Jane",170],["Lisa",153]])
df.columns=["Name","Height"]
print(df)
ผลลัพธ์จากการแสดงผล DataFrame ชื่อ df ที่เก็บข้อมูลชื่อและส่วนสูง

ไฟล์ข้อมูลในรูปแบบซีเอสวี

ไฟล์รุปแบบซีเอสวี หรือ CSV (comma separated values: CSV) เป็นไฟล์ข้อมูลที่ข้อมูลแต่ละตัวในแถวเดียวกัน (บรรทัดเดียวกัน) ถูกคั่นด้วยเครื่องหมาย , (comma) โดยอาจมีแถวแรกสุดเป็นชื่อของแต่ละคอลัมน์หรือหัวตาราง ตัวอย่างเช่น ข้อมูลนักเรียน 20 คน ประกอบด้วยเลขประจำตัวนักเรียน เพศ (1 แทนเพศชาย 2 แทนเพศหญิง) คะแนนสอบวิชาวิทยาการคำนวณ และส่วนสูง มีรูปแบบข้อมูลดังนี้

เลขประจำตัว,เพศ,Cs,height
5884,2,18,158
5885,2,20,164
5887,1,15,150
5889,1,6,168
5890,2,9,153
5893,1,10,172
5895,1,20,162
5896,1,19,157
5897,2,17,169
5900,2,13,174
5903,1,16,150
5905,2,7,150
5906,1,14,169
5908,1,15,175
5910,1,20,173
5912,1,4,173
5915,1,12,175
5916,2,17,154
5919,1,19,174
5921,2,18,158

ดาวน์โหลดไฟล์ข้อมูลที่มีหัวตารางได้ที่นี่ (studentData.csv)

Pandas มีฟังก์ชัน read_csv() เพื่อใช้ในการนำเข้าข้อมูลจากไฟล์ CSV เข้ามาเก็บใน DataFrame ดังนี้

stdData=pd.read_csv('studentData.csv',delimiter=',')
print(stdData)
ผลลัพธ์จากการนำเข้าไฟล์ข้อมูล CSV ตัวอย่างรายชื่อนักเรียน 20 คน

กรณีไฟล์ CSV ไม่มีแถวแรกสุดเพื่อบอกชื่อคอลัมน์หรือหัวตาราง สามารถระบุหัวตารางในการแสดงผลได้ เช่น ถ้ามีข้อมูลลักษณะนี้

5884,2,18,158
5885,2,20,164
5887,1,15,150
5889,1,6,168
5890,2,9,153
5893,1,10,172
5895,1,20,162
5896,1,19,157
5897,2,17,169
5900,2,13,174
5903,1,16,150
5905,2,7,150
5906,1,14,169
5908,1,15,175
5910,1,20,173
5912,1,4,173
5915,1,12,175
5916,2,17,154
5919,1,19,174
5921,2,18,158

ดาวน์โหลดไฟล์ข้อมูลที่ไม่มีหัวตารางได้ที่นี่ (studentData-noHeader.csv)

stdData=pd.read_csv('studentData-noHeader.csv',delimiter=',',names=['ID','Gender','CsScore','Height'])
print(stdData)
ผลลัพธ์จากการนำเข้าไฟล์ข้อมูล CSV ตัวอย่างรายชื่อนักเรียน 20 คน (กำหนดหัวตารางเอง)

ในการแสดงข้อมูลใน DataFrame ออกทางจอภาพ สามารถใช้ฟังก์ชัน print() แสดงผลลัพธ์ในรูปแบบต่างๆ ได้ โดยสามารถทดลอง run คำสั่งต่างๆ ตามตัวอย่าง แล้วทำความเข้าใจ พร้อมอธิบายการทำงานของการใช้คำสั่งแต่ละแบบได้

import pandas as pd
stdData = pd.read_csv('studentData-noHeader.csv',delimiter=',',names=['ID','Gender','CsScore','Height'])
print(stdData)     #แสดงข้อมูลทั้งหมดใน DataFrame
print(stdData.head(2))     #แสดงข้อมูล 2 แถวแรก (2 บรรทัดบนสุด)
print(stdData.tail(2))     #แสดงข้อมูล 2 แถวสุดท้าย (2 บรรทัดล่างสุด)
print(stdData['CsScore'])     #แสดงข้อมูลเฉพาะคอลัมน์เดียวที่เลือก (ดูเฉพาะประเภทเดียวที่สนใจ)
print(stdData[['ID','CsScore']])     #แสดงข้อมูลเฉพาะหลายคอลัมน์ที่เลือก (ดูเฉพาะกลุ่มประเภทที่สนใจ)
print(stdData[['ID','CsScore']].head(2))     #แสดงข้อมูลเฉพาะคอลัมน์ที่เลือก และ 2 แถวแรก (ดูเฉพาะประเภท, บรรทัดที่สนใจ)
print(stdData[stdData.Gender==2])     #แสดงเฉพาะแถวที่มีข้อมูลตามเงื่อนไขที่กำหนด (ดูเฉพาะข้อมูลของเพศหญิง ที่เป็นค่าเลข 2)
print(stdData[stdData.CsScore>=16])     #แสดงเฉพาะแถวที่มีข้อมูลตามเงื่อนไขที่กำหนด (ดูเฉพาะข้อมูลของผู้ที่ได้คะแนนมากกว่าหรือเท่ากับ 16)
ผลลัพธ์ของคำสั่ง print(stdData.head(2))
ผลลัพธ์ของคำสั่ง print(stdData.tail(2))
ผลลัพธ์ของคำสั่ง print(stdData[‘CsScore’])
ผลลัพธ์ของคำสั่ง print(stdData[[‘ID’,’CsScore’]])
ผลลัพธ์ของคำสั่ง print(stdData[[‘ID’,’CsScore’]].head(2))
ผลลัพธ์ของคำสั่ง print(stdData[stdData.Gender==2])
ผลลัพธ์ของคำสั่ง print(stdData[stdData.CsScore>=16])

การประมวลผลข้อมูลใน DataFrame

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

การนับจำนวนข้อมูลแต่ละคอลัมน์ใน DataFrame ทำได้โดยใช้ฟังก์ชัน count() เช่น

print(stdData.count())

จะแสดงผลลัพธ์ของการนับจำนวนข้อมูลแต่ละคอลัมน์ใน DataFrame ดังนี้

การนับจำนวนข้อมูลเพียงคอลัมน์เดียวจาก DataFrame สามารถใช้คำสั่งในรูปแบบต่อไปนี้

print(stdData.['ID'].count())

จะแสดงผลลัพธ์ของการนับจำนวนข้อมูลเลขประจำตัว (ID) ใน DataFrame ดังนี้

การหาค่าเฉลี่ยของข้อมูลเพียงคอลัมน์เดียว (คะแนนวิชาวิทยาการคำนวณของข้อมูล 20 รายการ) สามารถทำได้โดยใช้ฟังก์ชัน mean() ดังนี้

print(stdData['CsScore'].mean())

จะแสดงผลลัพธ์ค่าเฉลี่ยของข้อมูลคะแนนวิชาวิทยาการคำนวณ (CsScore)ใน DataFrame ดังนี้

การหาค่าผลรวม ค่ามัธยฐาน ค่ามากที่สุด ค่าน้อยที่สุด สามารถใช้ฟังก์ชัน sum() median() max() min() ตามลำดับ

print(stdData['CsScore'].sum())
print(stdData['CsScore'].median())
print(stdData['CsScore'].max())
print(stdData['CsScore'].min())

จะแสดงผลลัพธ์ดังนี้

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

print(stdData.groupby('Gender').mean())

จะแสดงผลลัพธ์ดังนี้

จะเห็นว่าผลลัพธ์แสดงค่าเฉลี่ยของข้อมูลทุกคอลัมน์ แยกตามข้อมูล Gender รวมทั้งคอลัมน์ ID และ Height ที่ไม่ต้องการหาค่าเฉลี่ย (สำหรับคอลัมน์ ID เป็นเลขประจำตัวนักเรียน ไม่ควรนำมาหาค่าเฉลี่ยเพราะไม่สื่อความหมายแต่อย่างใด)

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

print(stdData.groupby('Gender')[['CsScore']].mean())
หรือ
print(stdData.groupby('Gender').mean()[['CsScore']])

จะแสดงผลลัพธ์ดังนี้

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

print(stdData.sort_values(by=['Height']))

จะแสดงผลลัพธ์ดังนี้

การเรียงลำดับค่าของข้อมูลจากมากไปน้อย เช่น เรียงความสูงของนักเรียนจากมากไปน้อย สามารถกำหนดค่าเพิ่มเติมในฟังก์ชัน sort_values() ได้ดังนี้

print(stdData.sort_values(by=['Height'],ascending=False))

จะแสดงผลลัพธ์ดังนี้

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

เลขประจำตัว,Science1
5897,8
5919,16
5910,15
5896,7
5900,18
5893,4
5908,10
5887,9
5885,17
5921,4
5912,3
5916,4
5915,11
5905,12
5889,8
5895,16
5890,14
5906,4
5903,7
5884,14

ดาวน์โหลดไฟล์ข้อมูลคะแนนวิทยาศาสตร์ได้ที่นี่ (sciScore.csv)

ดาวน์โหลดไฟล์ข้อมูลที่มีหัวตารางได้ที่นี่ (studentData.csv)

ดาวน์โหลดไฟล์ข้อมูลที่ไม่มีหัวตารางได้ที่นี่ (studentData-noHeader.csv)

  • การเชื่อมโยงข้อมูลแบบพื้นฐาน (มีชื่อคอลัมน์ในแต่ละไฟล์ที่ตรงกัน 1 คอลัมน์) สามารถทำการเชื่อมโยงข้อมูลได้โดยอัตโนมัติ โดยการใช้ฟังก์ชัน merge() เช่น ทั้ง 2 ไฟล์ มีคอลัมน์ที่ชื่อเลขประจำตัวที่เหมือนกัน ฟังก์ชัน merge() สามารถ เชื่อมโยงข้อมูลผ่านข้อมูลเลขประจำตัวได้โดยอัตโนมัติ โดยมีคำสั่งดังนี้
import pandas as pd
stdData=pd.read_csv('studentData.csv',delimiter=',')     #อ่านค่าข้อมูลเก็บไว้ใน stdData
sciData=pd.read_csv('sciScore.csv',delimiter=',')     #อ่านข้อข้อมูลเก็บไว้ใน sciData
newData=stdData.merge(sciData)     #เชื่อมโยงข้อมูลของ stdData กับ sciData ไปเก็บไว้ใน newData
print(newData)

จะแสดงผลลัพธ์ดังนี้

  • การเชื่อมโยงข้อมูลกรณีที่ชื่อคอลัมน์ไม่ตรงกัน เช่น หากไฟล์ทั้งสองที่ต้องการเชื่อมโยง มีข้อมูลของเลขประจำตัวคนละชื่อกัน (ไฟล์แรกเป็นชื่อ “ID” ไฟล์ที่สองเป็นชื่อ “เลขประจำตัว”) เมื่อทำการเชื่อมโยงข้อมูลด้วยฟังก์ชัน merge() ต้องมีการระบุชื่อคอลัมน์ทางซ้าย (คอลัมน์ชื่อ ID) ที่เชื่อมโยงกับคอลัมน์ทางขวา (คอลัมน์ชื่อ เลขประจำตัว) ผ่านค่า left_on กับ right_on ตามลำดับ โดยมีคำสั่งดังนี้
import pandas as pd
stdData=pd.read_csv('studentData-noHeader.csv',delimiter=',',names=['ID','Gender','CsScore','Height'])
sciData=pd.read_csv('sciScore.csv',delimiter=',')
newData=stdData.merge(sciData,left_on='ID',right_on='เลขประจำตัว')
print(newData)

จะแสดงผลลัพธ์ดังนี้


การทำข้อมูลให้เป็นภาพ

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

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

import pandas as pd
import matplotlib.pyplot as plt
stdData=pd.read_csv('studentData-noHeader.csv',delimiter=',',names=['ID','Gender','CsScore','Height'])
sciData=pd.read_csv('sciScore.csv',delimiter=',')
newData=stdData.merge(sciData,left_on='ID',right_on='เลขประจำตัว',how='inner')
print(newData)
newData.CsScore.hist(range=[0,20],bins=21)
plt.title('Computing Science Test Score Frequency')
plt.xlabel('CsScore')
plt.ylabel('Frequency')
plt.axis([0,20,0,5])
plt.xticks(range(0,21,2))
plt.show()

จะแสดงผลลัพธ์ดังนี้

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

import pandas as pd
import matplotlib.pyplot as plt
stdData=pd.read_csv('studentData-noHeader.csv',delimiter=',',names=['ID','Gender','CsScore','Height'])
sciData=pd.read_csv('sciScore.csv',delimiter=',')
newData=stdData.merge(sciData,left_on='ID',right_on='เลขประจำตัว',how='inner')
print(newData)
plt.scatter(newData.CsScore,newData.Science1)
plt.xlabel('Computing Science score')
plt.ylabel('Science score')
for i in range(0,20):
     plt.text(newData.CsScore[i],newData.Science1[i],newData.ID[i])
plt.title('Computing Science score & Science score relationship')
plt.show()

จะแสดงผลลัพธ์ดังนี้


การสร้างส่วนต่อประสานกราฟิกกับผู้ใช้

ในการเขียนโปรแกรมที่มีส่วนต่อประสานกราฟิกกับผู้ใช้ (Graphical User Interface: GUI) ช่วยให้เห็นภาพรวมของโปรแกรมได้เป็นอย่างดี ในภาษาไพทอนมีโมดูล tkinter ที่ช่วยให้การพัฒนาส่วนต่อประสานกราฟิกกับผู้ใช้ทำได้โดยง่ายและรวดเร็ว มี 4 ขั้นตอนดังนี้

  1. นำเข้าโมดูล tkinter
  2. สร้างหน้าต่างหลัก (main window)
  3. จัดวางวิดเจ็ต (widget) หรือองค์ประกอบอื่นที่เป็นส่วนต่อประสานกราฟิกกับผู้ใช้ลงในหน้าต่างหลัก เช่น ปุ่มกด กล่องข้อความ
  4. เชื่อมโยงเหตุการณ์ (event) ต่างๆ ที่เกิดขึ้นจากการทำงานกับวิดเจ็ตเข้ากับส่วนของโปรแกรมย่อย เพื่อให้แอปพลิเคชันทำงานได้ตามต้องการ

การสร้างหน้าต่างหลักด้วย tkinter

import tkinter as tk
m=tk.Tk()     #m ย่อมาจาก main window คือ หน้าต่างหลัก
m.title('Main window')
m.mainloop()

จะแสดงผลลัพธ์ดังนี้

การเพิ่มปุ่มลงในหน้าต่างหลัก

import tkinter as tk
m=tk.Tk()
m.title('Main window')
button=tk.Button(m,text='Stop',width=25,command=lambda:m.destroy())
button.pack()
m.mainloop()

จะแสดงผลลัพธ์ดังนี้

การเพิ่มวิดเจ็ตลาเบลลงในหน้าต่างหลัก

import tkinter as tk
def counting():
     global count
     global label1Text
     count+=1
     label1Text.set(str(count))

m=tk.Tk()
count=0
label1Text=tk.StringVar()
label1Text.set(str(count))

m.title('Main window')
button=tk.Button(m,text='Stop',width=25,command=lambda:m.destroy())
button.pack()

button2=tk.Button(m,text='Counting',width=25,command=lambda:counting())
button2.pack()

label1=tk.Label(m,borderwidth=2,relief="ridge",textvariable=label1Text,width=30)
label1.pack()
m.mainloop()

จะแสดงผลลัพธ์ดังนี้

การเพิ่มปุ่มตัวเลขบนเครื่องคิดเลข

import tkinter as tk
     def press(n):
     global expression
     global label1Text
     expression = expression+n
     label1Text.set(expression)

m=tk.Tk()
m.title('Main window')

expression=' '
label1Text=tk.StringVar()
label1Text.set(expression)

label1=tk.Label(m,borderwidth=2,relief='ridge',textvariable=label1Text,width=30)
label1.pack()
button1=tk.Button(m,text='1',width=25,command=lambda:press('1'))
button1.pack()
button=tk.Button(m,text='Stop',width=25,command=lambda:m.destroy())
button.pack()
m.mainloop()

จะแสดงผลลัพธ์ดังนี้

การจัดวางวิดเจ็ตแบบกริด

import tkinter as tk
def press(n):
     global expression
     global label1Text
     expression = expression+n
     label1Text.set(expression)

m=tk.Tk()
m.title('Main window')

expression=' '
label1Text=tk.StringVar()
label1Text.set(expression)

label1=tk.Label(m,borderwidth=2,relief='ridge',textvariable=label1Text,width=20)
label1.grid(row=0,columnspan=2)

button1=tk.Button(m,text='1',width=6,command=lambda:press('1'))
button1.grid(row=2,column=0)
button2=tk.Button(m,text='2',width=5,command=lambda:press('2'))
button2.grid(row=2,column=1)
button3=tk.Button(m,text='3',width=6,command=lambda:press('3'))
button3.grid(row=1,column=0)
button4=tk.Button(m,text='4',width=5,command=lambda:press('4'))
button4.grid(row=1,column=1)

button=tk.Button(m,text='Stop',width=16,command=lambda:m.destroy())
button.grid(row=3,columnspan=2)
m.mainloop()

จะแสดงผลลัพธ์ดังนี้


อ้างอิง

สถาบันส่งเสริมการสอนวิทยาศาสตร์และเทคโนโลยี กระทรวงศึกษาธิการ, หนังสือเรียนรายวิชาพื้นฐานวิทยาศาสตร์และเทคโนโลยี เทคโนโลยี (วิทยาการคำนวณ) ชั้นมัธยมศึกษาปีที่ 3

One thought on “สร้างสรรค์ผลงานด้วยภาษาไพทอน (วิทยาการคำนวณ ม.3)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s