2013年12月1日 星期日

University: Course work

問題 -- University 2:Acme大學提供許多課程(course)讓學生選修。每一個課程有它的名稱(name)、代碼(code)、學分(credit)及描述(description)。每個學期,學系開設若干課程(course offerings)。開課相關資訊有:課程代碼、學系代碼、年度(year)及學期(semester)。一門課在開課後,將擁有其開課代碼(course offering code)-由年、學期、系代碼、與課程代碼組成,例如2013 Fall semester Computer Science 開的課程comp_100,其開課代碼為 2013F_CS_comp_100並非每一個課程在每一學期都會被開設;同時,有些課程會有一個學系以上開設。在University 1程式的基礎上,為程式增加載入課程及開課的資料自檔案載入、顯示的功能。輸入檔案格式如下:

課程 courses.txt
Introduction to Computing;comp_100;3;Fundamentals of computing…
Computer Programming;comp_101;3;Programming using an imperative language such as C...
Object-oriented programming;comp_201;3;Programming using an OO language such as C++ or Java...

開課 courseofferings.txt
comp_100;CS;2013;Fall
comp_100;MU;2013;Fall
comp_100;CH;2013;Fall
comp_101;CS;2013;Fall
comp_201;CS;2014;Spring

載入資料後,行政人員可以選擇顯示特定學系指定學期的所有開課資訊,其順序按課程代碼遞增排序。隨後,行政人員可以選擇新增或刪除開課,例如:選CS系2013年 Fall學期後增加開課,


Select department: CS
Select year semester: 2013 Fall


Fall 2013 Course offerings:

Computer Science (CS): 2 courses, 6 credits
=================================

2013F_CS_comp_100; Introduction to Computing; 3 credits
2013F_CS_comp_101; Computer Programming; 3 credits

Add (+)/delete(-) course offering or anything else to go back:+
You selected adding a new course offering.
Input course id:comp_201

程式輸出:

Name: Object-oriented programming
ID: comp_201
Credits: 3 
Description: Programming using an OO language such as C++ or Java...
Is this correct Y/N: Y
Done adding course offering.

Fall 2013 Course offerings:
Computer Science (CS): 3 courses, 9 credits
=================================
2013F_CS_comp_100; Introduction to Computing; 3 credits
2013F_CS_comp_101; Computer Programming; 3 credits
2013F_CS_comp_201; Object-oriented programming; 3 credits

Add (+)/delete(-) course offering or anything else to go back:x
Select department:

如果新增的開課已有同一開課代號的課程存在,則通知使用者並忽略該項作業。

離開程式時,提示行政人員是否將開課資料寫回courseofferings.txt






University: sorting students a responsibility for Department?

Task 4 的 sorting 該交給哪個物件負責?明顯的選項是Department,因為它認得所有學生。但是,如Matrix例子,我們選擇以其他C function處理linear transformation,目的在讓Matrix維持簡單、易懂。

所以,按照同一個想法,我將先以一個C函數處理這件工作。
先寫測試:

TEST (NameDec, sort){
Department cs("Computer Science","CS");
Student mary("Alan","U20130003", &cs);
Student john("Betty","U20130002", &cs);
Student paul("Carol","U20130001", &cs);

vector<Student *> stus(cs.students());
sort (stus.begin(),stus.end(),nameDec);
CHECK(string("Carol")==stus[0]->name());
CHECK(string("Betty")==stus[1]->name());
CHECK(string("Alan")==stus[2]->name());
}

需要寫Department::students、Student::name、nameDec等函數,其中:

bool nameDec(Student *s1, Student * s2){
return s1->name() > s2->name();
}

為了強調這個函數用於依姓名排序Student,可將它定義為Student的member function。如宣告成一般 method,則需透過
Student物件才能找到這個函數:

Student s(...);

sort (stus.begin(),stus.end(), s.nameDec);

邏輯上有些怪。解決的作法是將它定義成static member function:

class Student {
public:
...
static bool nameDec(Student *s1, Student * s2){...}
};

static 的意義是宣告nameDec為Student class共用。static函數無法取用 instance variable或呼叫非static 之 member function(原因與 this 有關)。

如此,可直接使用該函數

sort (stus.begin(),stus.end(),Student::nameDec);

接著,完成依ID排序。

學習議題: static member function。


L步驟:請試著以user與programmer的角度回顧,增加必要的improvement round。