Transcript Slide 1

259201
Computer Programming
for Engineer
Week 11
Function และ File
1
function คืออะไร?
 function เป็ น m-file(โปรแกรม) ที่สามารถเรี ยกใช้เพื่อทางาน
ซ้ าๆ
 การใช้งานมีการ ‘ส่ งค่ า’ ไปยัง function และ ‘รั บค่ า’ จาก
function
function เหมือนหรือต่างจาก script
อย่างไร
เหมือน
 function และ script เป็ น m-file(โปรแกรม) ที่สามารถเรี ยกใช้งานซ้ าๆได้
ต่าง
 function มีการรับส่ งค่าตัวแปรได้ script รับส่ งตัวค่าตัวแปรไม่ได้
 script ใช้ตวั แปรร่ วมกับ command window (workspace) หรื อฟั งก์ชนั ที่
เรี ยกใช้ script นั้นๆ
 function ใช้ตวั แปรของตัวเองไม่รวมกับ command window หรื อ
function อื่นๆ (ตัวแปรจะถูกสร้างใหม่ทุกครั้งที่มีการใช้ function)
การสร้าง function
function [output argument] = <name> (input argument)
ตัวแปรส่งออก
ตัวแปรนาเข้า
ชื่อของฟังก์ชนั
ค่าจะถูกส่งกลับ
ชื่อเดียวกับ m-file ค่าจะส่งมาเมือ่ ฟงั ก์ชนั ถูกเรียก
หลังจากเสร็จสิน้ การทางาน
% comment
โปรแกรมทีต่ อ้ งการใช้งาน….
 ต้องประกาศตัวแปรต่างๆดังข้างต้นพร้อมทัง้ คาสัง่ function ในบรรทัดแรกของ m-file
 ตัวแปรทีป่ ระกาศในฟงั ก์ชนั จะมองเห็นได้ภายในฟงั ก์ชนั เท่านัน้ โดยจะถูกสร้างขึน้ ก็
ต่อเมือ่ ฟงั ก์ชนั ถูกเรียกใช้งาน
 เมือ่ ฟงั ก์ชนั ถูกเรียกใช้ MATLAB จะทาการหา m-file ชือ่ name.m
ตัวอย่างง่ายๆ: คานวณปริมาตร
ทรงกระบอก
 กาหนดให้คานวณหาปริมาตรทรงกระบอก
r
L
 เขียนฟงั ก์ชนั ชื่อ cylinder.m ทีจ่ ะทารับค่า Input arguments เป็ น ค่ารัศมี
(radius) และ ความสูง (length) ของทรงกระบอก แล้วจะทาการส่งตัวแปร
ออกเป็ นปริมาตร (volume) โดยตัวแปรเหล่านี้จะเป็ นตัวแปรทีใ่ ช้ภายใน
ฟงั ก์ชนั เท่านัน้
radius
length
cylinder
volume
ฟังก์ชนั cylinder
Command window
>> r=2;
>> v=cylinder(r,6)
function volume=cylinder(r, L)
% compute volume
%of circular cylinder
volume=pi.*r^2.*L;
ตัวแปรใน Workspace
ตัวแปรของฟังก์ชนั cylinder
r=2
ส่งค่าตัวแปรไปยังตัวแปรนาเข้า
Command window
function volume=cylinder(r, L)
% compute volume
%of circular cylinder
ส่ งค่าของ r ของ workspace ไปยัง r ของ cylinder.m volume=pi.*r^2.*L;
>> r=2;
>> v=cylinder(r,6)
ส่ ง 6 ไปยัง L ของ cylinder.m
ตัวแปรใน Workspace
r=2
ตัวแปรของฟังก์ชนั cylinder
r=2
L=6
ตัวแปร r สองตัวนี้เป็ นคน
ละตัวและไม่มีความ
เกี่ยวข้องกัน
ทางานตามโปรแกรมในฟังก์ชนั
Command window
>> r=2;
>> v=cylinder(r,6)
function volume=cylinder(r, L)
% compute volume
%of circular cylinder
volume=pi.*r^2.*L;
ตัวแปรใน Workspace
ตัวแปรของฟังก์ชนั cylinder
r=2
r=2
L=6
volume=75.3982
ส่งค่าตัวแปรไปยังตัวแปรนาเข้า
ส่ งค่าของตัวแปรส่ งกลับเก็บไว้
Command window
ในแปร v ของ workspace
>> r=2;
>> v=cylinder(r,6)
function volume=cylinder(r, L)
% compute volume
%of circular cylinder
volume=pi.*r^2.*L;
ตัวแปรใน Workspace
ตัวแปรของฟังก์ชนั cylinder
r=2
r=2
L=6
volume=75.3982
v=75.3982
ลบตัวแปรของฟังก์ชนั cylinder
Command window
>> r=2;
>> v=cylinder(r,6)
function volume=cylinder(r, L)
% compute volume
%of circular cylinder
volume=pi.*r^2.*L;
ตัวแปรใน Workspace
ตัวแปรของฟังก์ชนั cylinder
r=2
v=75.3982
r=2
L=6
volume=75.3982
ทดลองเรียกใช้ฟังก์ชนั cylinder
% CYLINDER test script:
% use a for loop to iterate N times of the test
% which computes volume of circular cylinder
% given radius and length
% Use:vol=cylinder(radius, length)
clear
clc
N = input('input total # tests \n')
for i = 1:N
rad = input('input radius = \n');
len = input('input length = \n');
if rad ~= 0 & len ~= 0
vol=cylinder(rad, len);
fprintf('volume = %f', vol);
else
N =
22
input radius =
33
input length =
44
volume = 150532.553589
this is the iteration 1
input radius =
44
input length =
66
volume = 401420.142905
this is the iteration 2
input radius =
0
input length =
4
error: input argument is zero, loop breaks
>>
disp('error: input argument is zero, loop breaks');
break;
end
fprintf('\r this is the iteration %g\n', i);
end
แบบฝึ กหัด: เขียนฟังก์ชนั ให้ BMI
Problem
 จากไฟล์เดิม io_script.m file ทา
 รับข้อมูลจากคียบ
์ อร์ด ได้แก่




name: String
weight: integer (in kilogram)
height: integer (in centimeter)
คานวณ Body Mass Index จากสูตร
BMI 

Weight(kg )
Height2 (m 2 )
แสดงข้อความด้วยฟงั ก์ชนั disp() โดยมีตวั อย่างหน้าตาผลลัพธ์ เป็น
Normal BMI value are 18.5-24.9 kg/m2

แสดงข้อความด้วยฟงั ก์ชนั fprintf() โดยมีตวั อย่างหน้าตาผลลัพธ์ เป็น
Hi! ………………. your BMI value is …………… kg/m2
name
BMI value
12
แบบฝึ กหัด: เขียนฟังก์ชนั ให้ BMI
Problem
 จงสร้าง function m-file ชื่อ bmi.m ทีร่ บั ข้อมูลเข้า 2 ค่า ได้แก่
weight และ height แล้วทาการคานวณและส่งค่า BMI กลับ ด้วย
สูตรเดิม
 จงทาการแก้ไขไฟล์ io_script.m โดยให้สว่ นทีท่ าการคานวณ BMI
แทนทีจ่ ะคานวณค่า BMI เอง ให้เรียกฟงั ก์ชนั bmi.m โดยการส่ง
ค่าตัวแปรทีฟ่ งั ก์ชนั ต้องการ แล้วรอรับผลทีส่ ง่ ออกมาจากฟงั ก์ชนั
แทน
13
สรุปการส่งค่าตัวแปรระหว่างฟังก์ชนั
กับ workspace/script m-file
 script m-file ไม่ม ี (space) ตัวแปรของตัวเอง จะใช้ spaceร่วมกับ
command window หรือฟงั ก์ชนั ทีเ่ รียก
 ฟงั ก์ชนั และ command window จะไม่ใช้พน้ื ที่ (space) ตัวแปรร่วมกัน
 ตัวแปรทีป่ ระกาศที่ command window และตัวแปรทีป่ ระกาศภายใน
ฟงั ก์ชนั ทีม่ ชี อ่ื ตัวแปรเหมือนกัน จะเป็ นตัวแปรคนละตัวกัน
 การเปลีย่ นแปลงค่าของตัวแปรที่ space ใดจะไม่มผี ลต่ออีก space หนึ่ง
 การส่งค่าระหว่างฟงั ก์ชนั กับฟงั ก์ชนั และ ฟงั ก์ชนั กับ command
window เป็ นเพียงการคัดลอกค่าจะตัวแปรใน space หนึ่งไปให้กบั ตัว
แปรทีป่ ระกาศไว้รอรับค่าของอีก space หนึ่งเท่านัน้ เราเรียกว่าเป็ นการ
pass by value
การส่งค่าตัวแปรระหว่างฟังก์ชนั กับ
workspace/script m-file
function testScope(x)
fprintf('Inside testScope function');
fprintf('you just pass in x = %.2f\n',x);
x = 0;
fprintf('Then this function changes it''s x to %.2f\n',x);
%scope.m
x = 5.5;
testScope(x);
fprintf('After calling testScope function x is still %.2f\n',x);
>> scope
Inside testScope functionyou just pass in x = 5.50
Then this function changes it's x to 0.00
After calling testScope function x is still 5.50
การส่งค่ากลับมากกว่า 1 ค่าจาก Mfunctions
 M-functions สามารถส่งค่ากลับได้มากกว่าหนึ่งค่าหรือไม่สง่ ค่ากลับ
 ค่าทีส่ ง่ กลับอาจเป็ น scalar หรือ array (รวมทัง้ string) หรือ structure
 ถ้าฟงั ก์ชน
ั ส่งกลับมากกว่า 1 ค่า เราจะต้องใช้เครือ่ งหมาย [ ] เพือ่ ครอบ
ตัวแปรทัง้ หมดทีต่ อ้ งการส่งค่าออก ค่าทีส่ ง่ ออกจากฟงั ก์ชนั จะอยูใ่ น
รูปแบบ array ของตัวแปรเหล่านัน้

หากเป็ นเช่นนี้ การรอรับค่าทีส่ ง่ ออกมาจากฟงั ก์ชนั ก็จาเป็ นต้องสร้างอา
เรย์ของตัวแปร จานวนเท่ากับทีส่ ง่ ออกมา เช่นกัน หากตัวแปรรอรับมีเพียง
1 ตัวแปรก็จะรับค่าเฉพาะตัวแปรตัวแรกทีฟ่ งั ก์ชนั ส่งออกมาเท่านัน้ ทีเ่ หลือ
จะไม่สามารถอ้างถึงได้
ตัวอย่างฟังก์ชนั ที่ส่งค่ากลับมากกว่า 1
ค่าในรูปแบบอาเรย์ของตัวแปร
function [area volume] =cylinder(radius, length)
% CYLINDER computes volume of circular cylinder
% given radius and length
% Use: [ar, vol] =cylinder(radius, length)
volume=pi.*radius^2.*length;
area = 2 .* pi .* length + 2.* pi .*r .*r;
>> [ar, vol]=cylinderAV(1,10)
ar =
69.1150
vol =
31.4159
>> result=cylinderAV(1,10)
result =
69.1150
>> whos
Name
Size
Bytes Class
ans
1x1
8 double array
Grand total is 1 elements using 8 bytes
ตัวอย่าง: Quadratic Roots
 จงเขียน function m-file ชือ่ roots.m ทีใ่ ช้ในการคานวณ
ค่ารากทีส่ องของฟงั ก์ชนั Quadratic
a x2 + b x + c = 0
 roots.m จะต้องรับค่าสัมประสิทธิของ
์ Quadratic 3 ค่า
(a,b,c) และส่งค่าราก 2 ค่า (x1 และ x2) ออก ค่าราก
คานวณได้จาก
 b  b  4ac
x1 
2a
2
 b  b 2  4ac
x2 
2a
18
ตัวอย่าง: Quadratic Roots
function [x1 x2] =roots(a,b,c)
% ROOTS computes the roots of
% quadratic equation
% given coefficients a, b and c.
% Use: [r1, r2] =roots(a,b,c)
x1 = (-b+sqrt(b^2-4*a*c))/(2*a);
x2 = (-b-sqrt(b^2-4*a*c))/(2*a);
[x1 x2] = roots(1,-3,2)
if x1 == 2
disp(‘x1 is correct')
else
fprintf(‘x1 %.2f should have been 2\n', x1);
end
if x2 == 1
disp(‘x2 is correct')
else
fprintf(‘x2 %.2f should have been 2\n', x2);
end
19
ลาดับการค้นหา M-Functions ของ
MATLAB
 หากในเครือ่ งคอมพิวเตอร์ของคุณมีไฟล์ฟงั ก์ชนั ชื่อเดียวกันมากกว่า 1
ไฟล์ (เก็บไว้คนละที)่ หากเรียกฟงั ก์ชนั นัน้ ทางานแล้ว MATLAB จะทา
การค้นหาฟงั ก์ชนั ตามลาดับต่อไปนี้ หากเจอไฟล์ ณ ทีใ่ ดเป็ นอันแรกก็จะ
เรียกใช้ฟงั ก์ชนั นัน้ ทันที
1.
2.
3.
ฟงั ก์ชนั ทีเ่ รียกอยูใ่ น current directory หรือไม่?
ฟงั ก์ชนั ทีเ่ รียกเป็ น built-in MATLAB function หรือไม่?
ฟงั ก์ชนั ทีเ่ รียกอยูใ่ น MATLAB path หรือไม่ (ค้นหาจากบนลงล่างของรายการ)
Built-in functions
 MATLAB จะจัดเก็บ Built-in functions ประเภทเดียวกัน
ไว้ในโฟลเดอร์เดียวกัน. ใช้คาสัง่ help เพือ่ ขอดูรายชือ่
โฟลเดอร์ต่างๆ พร้อมรายละเอียดย่อยๆ
>> help
HELP topics
matlab\general
matlab\ops
matlab\lang
matlab\elmat
manipulation.
matlab\elfun
…
-
General purpose commands.
Operators and special characters.
Programming language constructs.
Elementary matrices and matrix
-
Elementary math functions.
21
เรียกดูกลุ่มฟังก์ชนั
>> help
HELP topics
matlab\general
matlab\ops
matlab\lang
matlab\elmat
manipulation.
matlab\elfun
…
-
General purpose commands.
Operators and special characters.
Programming language constructs.
Elementary matrices and matrix
-
Elementary math functions.
22
ตัวอย่าง geometric transformation
ั หา geometric transformation
 จากปญ
rotation
shearing
(x-axis)
scaling
shearing
(y-axis)
translation
 x'  x  a 
 y'   y   b 
     
= ตาแหน่งใหม่
= ตาแหน่งเดิม
23
ตัวอย่าง geometric transformation
 เราสามารถเขียนโปรแกรม rotatation เพื่อคานวณหาตาแหน่งใหม่โดย
การหมุนรอบจุดกาเนิด
x=0:.01:pi/2;
script
y=cos(x);
plot(x,y,'r')
hold on
for i=1:9
[xnew,ynew]=rotation(x,y,i*pi/5);
plot(xnew,ynew,'b')
end
hold off
function [xnew,ynew]=rotation(x,y,angle)
X=[cos(angle) -sin(angle);
sin(angle) cos(angle)] *[x;y];
xnew=X(1,:);
ynew=X(2,:);
1.5
1
0.5
0
-0.5
-1
-1.5
-2
-1.5
-1
-0.5
0
0.5
1
1.5
2
ฟังก์ชนั ที่เกี่ยวกับไฟล์
ฟงั ก์ชนั fopen  เปิ ดไฟล์ขอ้ มูล
fid คือ file identifier เป็ นตัวแปร
มารองรับผลลัพธ์ทฟ่ี งั ก์ชนั นี้ทา
การส่งออกมา
fid = fopen(‘filename’, ’permission’)
r: read w: write
Permission :
‘r’
‘w’
‘a’
‘r+’
‘w+’
‘a+’
a: append
เปิดอ่านอย่างเดียว
เปิดเพือ่ เขียน และสร้างไฟล์ถา้ ยังไม่มไี ฟล์น้อี ยูแ่ ล้ว ถ้ามีขอ้ มูล
เก่าจะเขียนทับโดยไม่สนใจว่าข้อมูลเก่าเป็ นอย่างไร
เปิดเพือ่ เพิม่ ข้อมูลต่อท้ายไฟล์ และสร้างไฟล์ถา้ ยังไม่มไี ฟล์น้ีอยูแ่ ล้ว
เปิดเพือ่ อ่านและเขียน โดยเปิดจากไฟล์เก่าและจะไม่มกี ารสร้างไฟล์ใหม่
เปิดเพือ่ อ่านและเขียน และจะสร้างไฟล์ขน้ึ ใหม่เสมอ
เปิดเพือ่ อ่านและเพิม่ ต่อท้าย และจะสร้างไฟล์ถา้ ยังไม่มไี ฟล์น้อี ยูแ่ ล้ว
25
ฟังก์ชนั ที่เกี่ยวกับไฟล์
Permission อื่นๆ
‘t’
เปิดเป็ น text mode
ตัวอย่างวิธีใช้
fid = fopen(‘c:\windows\test.dat’, ’r’);
% เปิดไฟล์ช่อื test.dat ทีอ่ ยูใ่ น c:\windows เพือ่ อ่านอย่างเดียว
fid = fopen(‘test2.dat’, ‘w’);
% สร้างหรือเปิดไฟล์ช่อื test2.dat เพือ่ เขียนทับ
fid = fopen(‘test3.txt’, ‘at+’);
% สร้างหรือเปิดไฟล์ช่อื test3.txt เพือ่ เขียนต่อท้าย แบบ text mode
26
ฟังก์ชนั ที่เกี่ยวกับไฟล์
 ฟงั ก์ชนั fclose  ปิ ดไฟล์ขอ้ มูลทีถ่ ูกชีด้ ว้ ย fid
fclose(fid)

return 0 ถ้าปิดปกติ,
return –1 ถ้ามีสงิ่ ผิดปกติ
 ฟงั ก์ชนั fprintf  เขียนข้อมูลลงในไฟล์
count = fprintf(fid,format,A,…)
count: ค่าจานวน Byte ทีถ่ ูกเขียน
fid:
file identifier แทน file ทีถ่ กู เขียน
format: รูปแบบของข้อมูลทีจ่ ะถูกเขียน
A:
ตัวแปรทีใ่ ช้เก็บข้อมูลทีจ่ ะถูกเขียน
27
ฟังก์ชนั ที่เกี่ยวกับไฟล์
Example
a=[51 71 19 32];
fid=fopen('test.txt','wt+'); %เปิดไฟล์ text.txt เพือ่ เขียนอ่าน
count=length(a);
%กรณีทไ่ี ม่มไี ฟล์น้อี ยูจ่ ะสร้างขึน้ ใหม่
%ฟงั ก์ชนั length สาหรับบอกความยาว
%ของอาเรย์
for i=1:count
fprintf(fid,'Vector A : %.2f\t',a(:,i));
fprintf(fid,'Column : %.0f\n',i);
end
fclose(fid)
28
ฟังก์ชนั ที่เกี่ยวกับไฟล์
29
ฟังก์ชนั ที่เกี่ยวกับไฟล์
 ฟงั ก์ชนั fscanf  อ่านข้อมูลจากไฟล์
A = fscanf(fid, format, size)
fid: file identifier แทนไฟล์ทจ่ี ะใช้อ่าน
A: ตัวแปรทีใ่ ช้เก็บค่า
format: รูปแบบการอ่าน
%s อ่านเป็ นอักษร แยกโดยช่องว่าง
%c อ่านทีละหนึ่งอักษร
%d อ่านตัวเลขจานวนเต็ม
size: ขนาดทีส่ ามารถกาหนดได้วา่ ต้องการอ่านกี่
ตัว
30
ฟังก์ชนั ที่เกี่ยวกับไฟล์
fid = fopen(‘test.txt’);
while 1
% 1 แทนค่าความจริงเป็ นจริง (True)
word = fscanf(fid, ‘%s’, 1);
if isempty(word), break, end
disp(word);
isempty: เช็คว่าเป็ น
end
อาเรย์วา่ งหรือไม่
fclose(fid);
31
ฟังก์ชนั ที่เกี่ยวกับไฟล์
 ฟงั ก์ชนั fgetl  อ่านข้อมูลทัง้ บรรทัดจากไฟล์
line = fgetl(fid)
line เก็บค่าทีอ่ ่านได้ เมือ่ อ่านจนจบ line=-1
32
ฟังก์ชนั ที่เกี่ยวกับไฟล์
fid = fopen(‘test.txt’);
while 1
% 1 แทนค่าความจริงเป็ นจริง (True)
line = fgetl(fid);
if ~ischar(line), break, end
disp(line);
ischar: เช็คว่าเป็ น
end
อาเรย์ของ
fclose(fid);
Character หรือไม่
33
Example
 file rain.txt เก็บค่า daily rainfall สาหรับ 1
อาทิตย์
0.100000
1.000000
0.000000
0.200000
3.560000
0.000000
0.000000
(หมายเหตุ ระวังอย่าให้มีบรรทัดว่าง ๆ อยู่ต่อท้าย โปรแกรมอาจจะทางานผิดผลาดได้)
 จงหาค่าเฉลีย่ ของฝนทีต่ กในหนึ่งสัปดาห์
34
fid = fopen('rain.txt');
default_eval_print_flag=0;
sum = 0;
count = 0;
while 1
line = fgetl(fid);
if ~ischar(line)
break;
end
sum = sum+eval(line(1:8));
count = count+1;
end
disp("Average rain fall is");
disp(sum/count);
fclose(fid);
% เปิดแฟ้ม rain.txt
% กาหนดให้คาสัง่ eval ไม่แสดงผล
% กาหนดค่าเริม่ ต้นให้กบั ตัวแปร
% วนรอบไปเรือ่ ย ๆ
% อ่านข้อมูลขึน้ มาหนึ่งบรรทัด
% ถ้าไม่ใช่ขอ้ ความให้หยุดอ่าน
% แปลงตัวอักษรลาดับที่ 1 ถึง 8 ให้
% เป็ นตัวเลข แล้ว…
% นามาบวกรวมกับ และเพิม่ ค่า counter
% แสดงค่าเฉลีย่ ทีไ่ ด้
35
การบ้าน
ให้เขียนโปรแกรมเพือ่ แยกไฟล์ ทีม่ ขี อ้ มูลดังต่อไปนี้ออกเป็ น 2 ชุดตามตัวเลขใน column สุดท้ายโดยถ้า column
สุดท้ายเป็ นเลข 1 ให้เอาข้อมูลทัง้ หมดไปเก็บไว้ในไฟล์ชอ่ื set1.txt ถ้าเป็ น 2 ให้เก็บไว้ในไฟล์ชอ่ื set 2.txt
6.02 1.87
7.10 3.49
5.67 2.99
5.65 2.89
5.90 3.27
5.70 3.34
6.76 2.75
6.61 2.60
6.23 2.90
6.16 3.41
6.21 2.26
6.57 3.49
5.81 2.94
5.88 2.49
7.61 2.75
6.77 2.92
4.91
4.52
3.93
5.16
4.18
4.10
4.32
3.74
5.52
5.04
6.06
5.68
4.96
6.09
5.45
5.59
1.52
1.47
1.45
1.49
1.61
1.59
1.50
1.68
2.12
2.35
2.15
2.10
1.87
2.05
2.24
1.96
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
***หมายเหตุ สามารถใช้ คาสัง่ load ในการอ่านค่าจากไฟล์ได้ เช่น load filename.txt
36