code ข้างล่างนี้มีคลาส Point
ที่แทนจุดในระนาบสองมิติ มีบริการ clone
เพื่อทำสำเนาจุด และ move_to
เพื่อตั้งพิกัดใหม่ให้กับจุด จงเขียนสามคำสั่งตามลำดับดังนี้ (ไม่ต้องแก้ไขคำสั่งใด ๆ ในคลาส Point
)
a
a
แล้วไปเก็บในตัวแปร b
a
ไปที่พิกัด (3,10)
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def clone(self):
return Point(self.x, self.y)
def move_to(self, x, y):
self.x = x
self.y = y
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def clone(self):
return Point(self.x, self.y)
def move_to(self, x, y):
self.x = x
self.y = y
a = Point(2,5)
b = a.clone()
a.move_to(3,10)
Ex().check_function('Point', missing_msg = "ไม่มีคำสั่งสร้างจุดด้วย Point(...)").multi(
check_args('x').has_equal_value(incorrect_msg = "ค่า x ที่ให้ตอนสร้างจุด a ไม่ถูกต้อง"),
check_args('y').has_equal_value(incorrect_msg = "ค่า y ที่ให้ตอนสร้างจุด a ไม่ถูกต้อง")
)
Ex().has_equal_ast(code = "b = a.clone()", incorrect_msg = "ไม่มีคำสั่งทำสำเนาจุด a ด้วย clone แล้วไปเก็บที่ b")
Ex().check_not(has_code(r"=\s*a\s*\.\s*move_to"), msg = "ไม่มีคำสั่งย้ายจุด a ด้วย move_to")
Ex().check_function('a.move_to', missing_msg = "ไม่มีคำสั่งย้ายจุด a ด้วย move_to").multi(
check_args('x').has_equal_value(incorrect_msg = "ค่า x ที่ให้ตอนย้ายจุด a ไม่ถูกต้อง"),
check_args('y').has_equal_value(incorrect_msg = "ค่า y ที่ให้ตอนย้ายจุด a ไม่ถูกต้อง")
)
for var in "ab":
obj = Ex().check_object(var, missing_msg = "ไม่พบตัวแปร " + var)
obj.multi(
has_equal_value(expr_code="str(type("+var+"))", incorrect_msg = var + " ต้องเป็นอ็อบเจกต์ของ Point"),
has_equal_value(expr_code = var + ".x", incorrect_msg = "พิกัด x ของ " + var + " ไม่ถูกต้อง"),
has_equal_value(expr_code = var + ".y", incorrect_msg = "พิกัด y ของ " + var + " ไม่ถูกต้อง")
)
code ข้างล่างนี้มีคลาส Point
ที่แทนจุดในระนาบสองมิติ และฟังก์ชัน shift(dx, dy, p)
ที่ปรับพิกัด (x,y)
ของจุด p
ไปเป็น (x+dx, y+dy)
หน้าที่ของฟังก์ชันนี้น่าจะเป็นส่วนหนึ่งของคลาส Point
จะเหมาะสมกว่า (ทำให้แทนที่เขียน shift(2,4,p)
ก็เขียนเป็น p.shift(2,4)
) จงย้ายฟังก์ชัน shift
ให้กลายเป็นเมท็อด shift
ของคลาส Point
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def shift(dx, dy, p):
p.x += dx
p.y += dy
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def shift(self, dx, dy):
self.x += dx
self.y += dy
import types
obj = types.SimpleNamespace
q = "`"
clsname = "Point"
qclsname = q+clsname+q
mname = "shift"
qmname = q+mname+q
point = obj(x=57, y=29)
Ex().check_class_def(clsname, missing_msg="ไม่พบคลาส " + qclsname).\
check_body().check_function_def(mname, missing_msg="ไม่พบเมท็อด " + qmname).multi(
has_equal_part_len('args', qmname + " รับพารามิเตอร์สามตัว"),
check_args('self', missing_msg = "ช่วยเขียนพารามิเตอร์ตัวแรกของ "+ qmname + " ให้เป็น `self`"),
check_body().set_context(point, 2, -3).multi(
has_equal_value(name = 'self.x', incorrect_msg = "shift ปรับค่า x ไม่ถูกต้อง"),
has_equal_value(name = 'self.y', incorrect_msg = "shift ปรับค่า y ไม่ถูกต้อง")
)
)
code ข้างล่างนี้มีคลาส BankAccount
ภายในอ็อบเจกต์ของคลาสนี้เก็บเลขบัญชี ชื่อบัญชี ยอดคงเหลือ และยอดขั้นต่ำที่ต้องมี (คือจะไม่ให้ถอน ถ้าถอนแล้วยอดคงเหลือน้อยกว่ายอดขั้นต่ำ) และมีเมท็อด set_minimum
ให้บริการตั้งยอดขั้นต่ำใหม่ได้ จงเขียนเมท็อด
deposit
รับจำนวนเงิน เพื่อฝากเพิ่มให้บัญชี (ถ้าจำนวนเงินติดลบ จะไม่เปลี่ยนค่าใด ๆ) withdraw
ลองคิดดูเองว่า ข้อกำหนดของการถอนจะต้องมีอะไรบ้าง
class BankAccount:
def __init__ (self, acc_no, acc_name, balance):
self.acc_no = acc_no
self.acc_name = acc_name
self.balance = balance
self.minimum = 0
def set_minimum(self, minimum):
self.minimum = minimum
class BankAccount:
def __init__ (self, acc_no, acc_name, balance):
self.acc_no = acc_no
self.acc_name = acc_name
self.balance = balance
self.minimum = 0
def set_minimum(self, minimum):
self.minimum = minimum
def deposit(self, amount):
if amount > 0:
self.balance += amount
def withdraw(self, amount):
if 0 < amount <= self.balance - self.minimum:
self.balance -= amount
import types
obj = types.SimpleNamespace
q = "`"
clsname = "BankAccount"
qclsname = q+clsname+q
m_deposit = "deposit"
qm_deposit = q + m_deposit + q
m_withdraw = "withdraw"
qm_withdraw = q + m_withdraw + q
bacc1 = obj(acc_no='01', acc_name='A', balance=1000, minimum=400)
bacc2 = obj(acc_no='01', acc_name='A', balance=1000, minimum=400)
def check_id_name_min(stu, sol):
return (stu.acc_no, stu.acc_name, stu.minimum) == \
(sol.acc_no, sol.acc_name, sol.minimum)
msg1 = ": ต้องไม่เปลี่ยนเลข ชื่อ หรือยอดขั้นต้ำ"
Ex().check_class_def(clsname, missing_msg="ไม่พบคลาส " + qclsname).\
check_body().multi(
check_function_def(m_deposit, missing_msg="ไม่พบเมท็อด " + qm_deposit).multi(
has_equal_part_len('args', qm_deposit + " รับพารามิเตอร์สองตัว"),
check_args('self', missing_msg = "ช่วยเขียนพารามิเตอร์ตัวแรกของ "+ qm_deposit + " ให้เป็น `self`"),
check_body().multi(
set_context(bacc1, -300).multi(
has_equal_value(name = 'self.balance', incorrect_msg = qm_deposit + ": ไม่ให้ฝาก ถ้าจำนวนเงินเป็นลบ"),
has_equal_value(name = "self", func=check_id_name_min, incorrect_msg = qm_deposit + msg1)
),
set_context(bacc1, 300).multi(
has_equal_value(name = 'self.balance', incorrect_msg = qm_deposit + ": ปรับค่า balance ไม่ถูกต้อง"),
has_equal_value(name = "self", func=check_id_name_min, incorrect_msg = qm_deposit + msg1)
)
)
),
check_function_def(m_withdraw, missing_msg="ไม่พบเมท็อด " + qm_withdraw).multi(
has_equal_part_len('args', qm_withdraw + " รับพารามิเตอร์สองตัว"),
check_args('self', missing_msg = "ช่วยเขียนพารามิเตอร์ตัวแรกของ "+ qm_withdraw + " ให้เป็น `self`"),
check_body().multi(
set_context(bacc2, -100).multi(
has_equal_value(name = 'self.balance', incorrect_msg = qm_withdraw + ": ไม่ให้ถอน ถ้าจำนวนเงินเป็นลบ"),
has_equal_value(name = "self", func=check_id_name_min, incorrect_msg = qm_withdraw + msg1)
),
set_context(bacc2, 601).multi(
has_equal_value(name = 'self.balance', incorrect_msg = qm_withdraw + ": ไม่ให้ถอน ถ้าถอนแล้วยอดต้ำกว่าขั้นต่ำ"),
has_equal_value(name = "self", func=check_id_name_min, incorrect_msg = qm_withdraw + msg1)
),
set_context(bacc2, 600).multi(
has_equal_value(name = 'self.balance', incorrect_msg = qm_withdraw + ": ปรับค่า balance ไม่ถูกต้อง"),
has_equal_value(name = "self", func=check_id_name_min, incorrect_msg = qm_withdraw + msg1)
)
)
)
)
code ข้างล่างนี้มีคลาส Rational
เพื่อผลิตจำนวนตรรกยะ คือ จำนวนที่เขียนในรูปของ เศษ/ส่วน โดยที่เศษ (numerator) และส่วน (denominator) เป็นจำนวนเต็ม ภายในมีเมท็อด __init__
และ add
ให้แล้ว โดยถ้า a
และ b
เป็น Rational
คำสั่ง a.add(b)
จะคืนอ็อบเจกต์ที่เป็นผลบวกของ a
กับ b
จงเขียนเมท็อด neg
ที่คืนอ็อบเจกต์ที่มีค่าติดลบของอ็อบเจกต์ที่ได้รับ และเมท็อด sub
ที่คืนอ็อบเจกต์ที่เป็นผลลบของอ็อบเจกต์ที่ได้รับ การเขียนคำสั่งในเมท็อด sub
ให้เรียกใช้ neg
กับ add
ให้เป็นประโยชน์
___inp___ = ["7 9 -1 9"]
def input():
t = ___inp___.pop(0)
___inp___.append(t)
return t
class Rational:
def __init__(self, n, d):
a, b = n, d
# หา หรม. ก่อนเพื่อไปหารเศษกับส่วน
# ถ้ารับ 20/40 จะได้เก็บ 1/2
while b != 0:
a,b = b,a%b
self.n = n//a # numerator เศษ
self.d = d//a # denominator ส่วน
def add(self, x):
d = self.d * x.d
n = self.n * x.d + x.n * self.d
return Rational(n, d)
def neg(self):
def sub(self, x):
#--------------------------
# ไม่ต้องแก้ไขคำสั่งใด ๆ ข้างล่างนี้
n1, d1, n2, d2 = [int(e) for e in input().split()]
r1 = Rational(n1, d1)
r2 = r1.neg()
r3 = Rational(n2, d2)
r4 = r3.neg()
r5 = r1.sub(r4)
class Rational:
def __init__(self, n, d):
a, b = n, d
while b != 0:
a,b = b,a%b
self.n = n//a # numerator เศษ
self.d = d//a # denominator ส่วน
def add(self, x):
d = self.d * x.d
n = self.n * x.d + x.n * self.d
return Rational(n, d)
def neg(self):
return Rational(-self.n, self.d)
def sub(self, x):
return self.add(x.neg())
n1, d1, n2, d2 = [int(e) for e in input().split()]
r1 = Rational(n1, d1)
r2 = r1.neg()
r3 = Rational(n2, d2)
r4 = r3.neg()
r5 = r1.sub(r4)
def check_nd(stu, sol):
return round(stu.n/stu.d, 10) == round(sol.n/sol.d, 10)
vars = ["r1", "r2", "r3", "r4", "r5"]
msgs = ["ต้องไม่เปลี่ยนแปลง", "ไม่ถูกต้อง", "ต้องไม่เปลี่ยนแปลง", "ไม่ถูกต้อง", "ไม่ถูกต้อง"]
for v,msg in zip(vars, msgs):
Ex().check_object(v, missing_msg = "ไม่มีตัวแปร " + v). \
has_equal_value(func=check_nd, incorrect_msg = "ค่าของ "+ v + " " + msg)
q = "`"
clsname = "Rational"; qclsname = q+clsname+q
mname_sub = "sub"; mname_neg = q+clsname+q
Ex().check_class_def(clsname, missing_msg="ไม่พบคลาส " + qclsname).check_body().\
check_function_def(mname_sub, missing_msg="ไม่พบเมท็อด " + mname_sub).check_body().\
has_code(r"^[^#|\"]+\.\s*add\s*\(", not_typed_msg="โจทย์ให้เมท็อด sub ใช้เมท็อด add")