Assessment Bank
ลองตอบทั้ง 10 ข้อก่อนเปิดเฉลย — ถ้าตอบได้ 8+ ข้อ คุณพร้อมสำหรับ capstone แล้ว
Q1: ทำไม Python ไม่มี char แต่ C กับ SQL มี?
Section titled “Q1: ทำไม Python ไม่มี char แต่ C กับ SQL มี?”ใน C มี char (1 byte), SQL มี CHAR(1) — แต่ Python ไม่มี data type char เลย ทำไม?
ดูเฉลย Q1
C ถูกออกแบบมาให้ทำงานใกล้ hardware — char คือ 1 byte ซึ่งเป็นหน่วยเล็กที่สุดของ memory ใน C ทุกอย่างเกี่ยวกับขนาด byte
SQL มี CHAR(1) เพราะ database ต้องจองพื้นที่ล่วงหน้า — ถ้ารู้ว่า column เก็บตัวอักษรตัวเดียว (เช่น เพศ M/F) ก็จอง 1 byte พอ
Python ถูกออกแบบมาให้ “ง่าย” — ไม่แยก char กับ string เพราะ programmer ไม่ต้องคิดเรื่อง byte-level 'A' ใน Python คือ str ที่มี length 1 ไม่ใช่ type แยก
type('A') # <class 'str'> — ไม่ใช่ char!len('A') # 1'A'[0] # 'A' — ยังเป็น strหลักการ: C ให้ control, SQL ให้ structure, Python ให้ convenience
Q2: sizeof("HI") ได้ 3 ใน C ทำไม?
Section titled “Q2: sizeof("HI") ได้ 3 ใน C ทำไม?”"HI" มีแค่ 2 ตัวอักษร แต่ sizeof("HI") return 3 — ทำไม?
ดูเฉลย Q2
ใน C ทุก string ลงท้ายด้วย null terminator '\0' (byte value 0):
char s[] = "HI";// Memory: ['H', 'I', '\0']// 72 73 0sizeof(s); // 3 — นับ null terminator ด้วย!strlen(s); // 2 — ไม่นับ null terminator| Function | นับอะไร | ผลลัพธ์ |
|---|---|---|
sizeof() | bytes ทั้งหมดใน memory (รวม \0) | 3 |
strlen() | ตัวอักษรจริง (ไม่รวม \0) | 2 |
ความเชื่อมโยงกับ SQL: CHAR(5) ใน SQL เก็บ 'HI' เป็น 'HI ' (pad spaces) → LENGTH = 5 เหมือนที่ C จอง memory เกินจำนวนตัวอักษรจริง
Q3: LEN vs LENB สำหรับตัวอักษรไทยใน Sheets
Section titled “Q3: LEN vs LENB สำหรับตัวอักษรไทยใน Sheets”ใน Google Sheets:
=LEN("ก") → ?=LENB("ก") → ?ได้เท่าไหร่? ทำไมต่างกัน?
ดูเฉลย Q3
=LEN("ก") → 1 // นับจำนวน characters=LENB("ก") → 3 // นับจำนวน bytesทำไมต่างกัน?
LEN()นับ characters —"ก"คือ 1 ตัวอักษรLENB()นับ bytes —"ก"ใน UTF-8 ใช้ 3 bytes
| ตัวอักษร | LEN | LENB | เหตุผล |
|---|---|---|---|
A | 1 | 1 | ASCII = 1 byte |
ก | 1 | 3 | Thai UTF-8 = 3 bytes |
日 | 1 | 3 | CJK UTF-8 = 3 bytes |
เชื่อมกับ C:
strlen("ก"); // 3 (bytes, เหมือน LENB)// C ไม่มี "character count" built-in สำหรับ UTF-8เชื่อมกับ Python:
len('ก') # 1 (characters, เหมือน LEN)len('ก'.encode('utf-8')) # 3 (bytes, เหมือน LENB)Q4: ISBLANK("") เป็น FALSE แต่ COUNTBLANK("") นับเป็น 1 ทำไม?
Section titled “Q4: ISBLANK("") เป็น FALSE แต่ COUNTBLANK("") นับเป็น 1 ทำไม?”ใน Google Sheets ถ้า cell A1 มีสูตร ="":
=ISBLANK(A1) → FALSE=COUNTBLANK(A1) → 1ขัดกันไหม? ทำไม?
ดูเฉลย Q4
ไม่ขัดกัน — เพราะ 2 functions มีนิยาม “ว่าง” ต่างกัน:
| Function | นิยาม “ว่าง” | ="" ถือว่า? |
|---|---|---|
ISBLANK() | Cell ไม่มีอะไรเลย (no value, no formula) | FALSE — มีสูตร ="" อยู่! |
COUNTBLANK() | Cell ที่ แสดงผล เป็นว่าง (display is empty) | 1 — display เป็นว่าง! |
เปรียบเทียบกับ SQL:
SELECT '' IS NULL; -- FALSE (empty string is NOT null!)SELECT NULL IS NULL; -- TRUEเปรียบเทียบกับ Python:
"" is None # False"" == "" # Truepd.isna("") # Falsepd.isna(None) # Trueบทเรียน: blank cell, empty string "", และ NULL คือ 3 สิ่งที่ต่างกัน — ทุกเครื่องมือมีวิธีแยกต่างกัน
Q5: ทำไมห้ามใช้ float เก็บราคา?
Section titled “Q5: ทำไมห้ามใช้ float เก็บราคา?”ถ้า price = 24.99 ทำไมเก็บเป็น float / REAL ไม่ได้?
ดูเฉลย Q5
เพราะ float เก็บทศนิยมแบบประมาณ — ไม่แม่นยำ 100%
# Python0.1 + 0.2 # 0.30000000000000004
# สะสม 50,000 แถวsum(24.99 for _ in range(50000))# อาจได้ 1249499.9999... แทน 1249500.00-- SQLSELECT CAST(0.1 AS REAL) + CAST(0.2 AS REAL);-- 0.30000001...
SELECT 0.1::NUMERIC + 0.2::NUMERIC;-- 0.3 (exact!)| Type | เก็บ 24.99 ได้ exact? | สะสม 50,000 แถว |
|---|---|---|
float / REAL | ไม่ exact | error เป็นหมื่นบาท |
Decimal / NUMERIC | exact | ตรง 100% |
| Integer cents (2499) | exact | ตรง 100% |
กฎ: ถ้าเป็นเงิน → NUMERIC(p,s) / Decimal / integer cents เท่านั้น
Q6: WHERE customer_id = NULL ผิดตรงไหน?
Section titled “Q6: WHERE customer_id = NULL ผิดตรงไหน?”SELECT * FROM customers WHERE customer_id = NULL;Query นี้ไม่ return อะไรเลย ทั้งที่มีแถวที่ customer_id เป็น NULL อยู่ — ทำไม?
ดูเฉลย Q6
ใน SQL, NULL ไม่เท่ากับอะไรเลย — แม้แต่ตัวมันเอง:
SELECT NULL = NULL; -- NULL (ไม่ใช่ TRUE!)SELECT NULL != NULL; -- NULL (ไม่ใช่ TRUE!)SELECT NULL IS NULL; -- TRUE ✅กฎของ SQL: การเปรียบเทียบใดๆ กับ NULL ได้ผลลัพธ์เป็น NULL (ไม่ใช่ TRUE หรือ FALSE) — ซึ่ง WHERE ไม่ยอมรับ
วิธีที่ถูก:
SELECT * FROM customers WHERE customer_id IS NULL; -- ✅SELECT * FROM customers WHERE customer_id IS NOT NULL; -- ✅เปรียบเทียบกับ Python:
None == None # True! (Python ต่างจาก SQL)x is None # วิธีที่ถูก (Pythonic)
import pandas as pdpd.isna(None) # Trueเปรียบเทียบกับ Sheets:
=A1 = "" // TRUE ถ้า A1 ว่าง — Sheets ไม่แยก NULL กับ ""!=ISBLANK(A1) // TRUE เฉพาะ truly blank cellQ7: Leading zeros หายตอนเปิด CSV ใน Sheets — ป้องกันยังไง?
Section titled “Q7: Leading zeros หายตอนเปิด CSV ใน Sheets — ป้องกันยังไง?”ไฟล์ CSV มี student_id = "001234" แต่เปิดใน Google Sheets แล้วกลายเป็น 1234 — เกิดอะไรขึ้น? ป้องกันยังไง?
ดูเฉลย Q7
ปัญหา: Google Sheets (และ Excel) เห็น 001234 แล้ว “ช่วย” แปลงเป็นตัวเลข 1234 โดยอัตโนมัติ — leading zeros หาย
ป้องกัน 3 วิธี:
-
Import แบบ manual: File > Import > ตั้ง column type เป็น Text
-
เติม prefix: ใน CSV เก็บเป็น
="001234"(prefix ด้วย=)// หรือเติม apostrophe ก่อน'001234 -
แก้หลัง import: ใช้
=TEXT(A2, "000000")เพื่อเติม leading zeros กลับ
ใน Python — ป้องกันตั้งแต่อ่าน:
df = pd.read_csv('file.csv', dtype={'student_id': 'string'})# ถ้าไม่ใส่ dtype → pandas แปลงเป็น int64 → 001234 กลายเป็น 1234ใน SQL — ป้องกันด้วย schema:
CREATE TABLE students ( student_id VARCHAR(6) NOT NULL -- VARCHAR ไม่ใช่ INTEGER!);ใน C:
char id[] = "001234"; // string → leading zeros คงอยู่int id_num = 1234; // int → leading zeros หาย!บทเรียน: ถ้า “ตัวเลข” มี leading zeros → มันไม่ใช่ตัวเลข มันคือ text
Q8: เห็นเลข 46136 ใน date cell — มันคืออะไร?
Section titled “Q8: เห็นเลข 46136 ใน date cell — มันคืออะไร?”เปิด Google Sheets แล้วเห็นเลข 46136 ในเซลล์ที่ควรเป็นวันที่ — เกิดอะไรขึ้น?
ดูเฉลย Q8
46136 คือ date serial number — Google Sheets (และ Excel) เก็บวันที่เป็นตัวเลข:
วันที่ 1 = December 30, 189946136 = วันที่ 46,136 นับจาก Dec 30, 1899=DATE(2026, 4, 24) → 46141 (ตัวอย่าง)=TEXT(46136, "YYYY-MM-DD") → แสดงวันที่จริงทำไมเห็นเป็นตัวเลข?
- Cell format ถูกตั้งเป็น “Number” แทน “Date”
- แก้: Format > Number > Date
เปรียบเทียบกับ C:
time_t t = time(NULL); // seconds since 1970-01-01 (Unix epoch)// ไม่ใช่ serial number — คือจำนวนวินาทีเปรียบเทียบกับ Python:
from datetime import dated = date(2025, 1, 15)d.toordinal() # 738,901 (days since year 1)# Python ใช้ epoch ต่างจาก Sheets!เปรียบเทียบกับ SQL:
SELECT DATE '2025-01-15';-- SQL เก็บเป็น date object ไม่ใช่ serial number-- แต่ EXTRACT(EPOCH FROM ...) แปลงเป็น Unix timestamp ได้บทเรียน: ทุกเครื่องมือเก็บ date เป็นตัวเลข “ข้างใน” — แค่ epoch (จุดเริ่มนับ) ต่างกัน
Q9: CHAR(5) เก็บ 'HI' เป็นอะไร? เชื่อมกับ C ยังไง?
Section titled “Q9: CHAR(5) เก็บ 'HI' เป็นอะไร? เชื่อมกับ C ยังไง?”ใน SQL: CHAR(5) เก็บ 'HI' จริงๆ แล้วได้อะไร? เปรียบเทียบกับ C ได้อย่างไร?
ดูเฉลย Q9
SQL:
CREATE TABLE t (c CHAR(5));INSERT INTO t VALUES ('HI');SELECT c, LENGTH(c), c || '!' FROM t;-- 'HI ', 5, 'HI !'CHAR(5) pad spaces ให้เต็ม 5 ตัวอักษร: 'HI' → 'HI ' (3 spaces)
C:
char fixed[6] = "HI"; // 6 bytes: 'H','I','\0','\0','\0','\0'// C ไม่ pad spaces — มันเติม null bytes (\0)sizeof(fixed); // 6 (รวม null terminator)strlen(fixed); // 2 (นับแค่ตัวอักษรจริง)เปรียบเทียบ:
SQL CHAR(5) | C char[6] | |
|---|---|---|
เก็บ 'HI' | 'HI ' (pad spaces) | "HI\0\0\0\0" (pad nulls) |
| ขนาด | 5 characters เสมอ | 6 bytes เสมอ |
| ส่วนเกิน | spaces | null bytes |
| LENGTH/strlen | 5 (รวม spaces) | 2 (ไม่รวม nulls) |
ทำไมใช้ VARCHAR ดีกว่า?
CREATE TABLE t2 (c VARCHAR(5));INSERT INTO t2 VALUES ('HI');SELECT c, LENGTH(c) FROM t2;-- 'HI', 2 ← ไม่ pad! ประหยัดเนื้อที่Q10: 0.1 + 0.2 problem ข้ามเครื่องมือ
Section titled “Q10: 0.1 + 0.2 problem ข้ามเครื่องมือ”เขียนผลลัพธ์ของ 0.1 + 0.2 ใน ทั้ง 4 เครื่องมือ — ที่ไหนดูถูก? ที่ไหนดูผิด? ที่ไหนถูกจริง?
ดูเฉลย Q10
| เครื่องมือ | Expression | ผลลัพธ์ที่แสดง | ค่าจริงใน memory | ถูกจริงไหม? |
|---|---|---|---|---|
| Sheets | =0.1+0.2 | 0.3 | 0.30000000000000004 | ดูถูก แต่ผิด |
| C (float) | 0.1f + 0.2f | 0.300000 | 0.30000001192... | ผิด |
| C (double) | 0.1 + 0.2 | 0.300000 | 0.30000000000000004 | ผิด (แต่ error น้อยกว่า float) |
| Python (float) | 0.1 + 0.2 | 0.30000000000000004 | เหมือน display | ผิด — แต่ Python ซื่อสัตย์ แสดงค่าจริง! |
| Python (Decimal) | Decimal('0.1') + Decimal('0.2') | 0.3 | 0.3 | ถูกจริง! |
| SQL (REAL) | 0.1::REAL + 0.2::REAL | 0.30000001 | เหมือน display | ผิด |
| SQL (NUMERIC) | 0.1::NUMERIC + 0.2::NUMERIC | 0.3 | 0.3 | ถูกจริง! |
สรุป:
| ดูถูก แต่ผิด | ดูผิดจริง | ถูกจริง | |
|---|---|---|---|
| Sheets, C (printf %.1f) | Python float, C (printf %.20f) | Python Decimal, SQL NUMERIC |
# เปิดโปง Sheets:from decimal import Decimalprint(f"{0.1 + 0.2:.20f}") # 0.30000000000000004441print(Decimal('0.1') + Decimal('0.2')) # 0.3บทเรียน: ปัญหานี้เกิดกับ ทุกเครื่องมือ ที่ใช้ IEEE 754 floating-point — วิธีแก้คือใช้ exact decimal types เมื่อต้องการความแม่นยำ
สรุปผลการทำ Quiz
Section titled “สรุปผลการทำ Quiz”| คะแนน | ระดับ | คำแนะนำ |
|---|---|---|
| 9–10 | ยอดเยี่ยม | พร้อมสำหรับ capstone! |
| 7–8 | ดี | ทบทวนข้อที่พลาดแล้วลองใหม่ |
| 5–6 | ปานกลาง | กลับไปอ่าน Module ที่เกี่ยวข้องแล้วลองทำ Try-It อีกครั้ง |
| ต่ำกว่า 5 | ต้องทบทวน | เริ่มจาก Module 0 ใหม่ ทำ Try-It ทุกข้อ |