林 娟,周飛亞,周發(fā)剛,陽鎮(zhèn)濤,唐鑄文
(1.荊楚理工學(xué)院第一臨床學(xué)院暨荊門市第一人民醫(yī)院,中國荊門 448000;2.溫州醫(yī)科大學(xué)附屬第二醫(yī)院,中國溫州 325027;3.荊楚理工學(xué)院,中國荊門 448000)
在教務(wù)系統(tǒng)[1]中有多處用到開課日期.計算課程進(jìn)度表、查詢課表時,需要指定一個本學(xué)期的開課日期,作為計算課表的日期起點,否則計算機不知道從何時開始計算.
開課日期可以用很多方法實現(xiàn).如用數(shù)據(jù)庫技術(shù),由管理員將實際的每一學(xué)期開課日期保存在數(shù)據(jù)庫中,使用時,直接從數(shù)據(jù)庫中取出,呈現(xiàn)在用戶面前.此法不僅需要每學(xué)期要輸入一次,而且占用系統(tǒng)資源,還有一個原因是管理人員也要知道開課的日期.本文的目的旨在從算法的角度來自動實現(xiàn)開課日期.
經(jīng)過觀察及多年的開學(xué)日期的回顧,學(xué)校開學(xué)后的開課日期一般是在9月1日或元宵節(jié)前后三天左右的星期一.將9月1日與元宵節(jié)作為“基點”,列出基點左右4 天的日期與星期,開課日期基本上集中在此范圍,見表1.雖然,開課日期受行政因素[2-4]等有關(guān)情況的制約,但是,大多數(shù)情況下如此.
表1 開課日期與星期可能分布的范圍Tab.1 The range of possible distribution about course start date and week
如果將開課日期制作成一個類,用戶使用時,系統(tǒng)會顯示默認(rèn)的開課日期.如果確有不符的日期,有關(guān)教務(wù)人員是會發(fā)出通知的,在使用中,由用戶修改開課日期.
作者用VFP 的類,設(shè)計成一個日期控件對象,在需要時,將其選放到表單界面中.程序運行時,系統(tǒng)自動顯示出當(dāng)前學(xué)期的開課日期[5-6],經(jīng)多年應(yīng)用,效果較好.現(xiàn)將作者開發(fā)的開課日期類介紹如下.
每年有二個學(xué)期.下半年(秋季)開學(xué)的是第一學(xué)期,學(xué)期期段為當(dāng)年的8月到次年的1月,上半年(春季)開學(xué)的為第二學(xué)期,學(xué)期期段設(shè)為2月到7月.開課日期主要用來計算這二個學(xué)期的開始上課的日期,使日期、周次能與現(xiàn)實一致.
用Microsoft Visual FoxProo 類設(shè)計器設(shè)計開課日期類.基類選用“textbox”文本框,將這個日期類命名為datemonday,對datemonday 的屬性value 設(shè)為“date()”,使datemonday 成為日期類型.在datemonday 的init 方法中編寫代碼,在程序啟動時,算出開課的陽歷日期.
VFP 中有一個日期星期轉(zhuǎn)換函數(shù)dow()[7]和一個某月中的幾號day()函數(shù),可以幫助實現(xiàn)轉(zhuǎn)換.用dow()函數(shù)得到星期幾,用day()函數(shù)取得日期號,合成到年月中,這樣,即可得到開課日期.見式(1),(2).
式中W 表示星期幾;D 代表開課日期;y=設(shè)定的陽歷日期;參數(shù)2 表示模式;使星期一等于1;星期二等于2,…n,1 是減去本身的修正值.
因春節(jié)的習(xí)俗,春季開學(xué)日期存在很大的變數(shù),陰歷日期計算也復(fù)雜得多.但是,有一個規(guī)律,開學(xué)日期常在元宵節(jié)左右,因此,將元宵節(jié)的陽歷日期計算出來,再用上述陽歷日期算法即得出春季開學(xué)日期.
可以將中華農(nóng)歷網(wǎng)1900—2100 的春節(jié)日期取出[8],用數(shù)組的方法,編入程序中應(yīng)用.Rucypli 提供了二進(jìn)制算法程序nltoyl(nlYear,nlMonth,nlDay),實現(xiàn)1900—2049年的任何一天的農(nóng)歷到陽歷的轉(zhuǎn)換,代碼請參考Rucypli 的算法程序[9].其方法是先計算出當(dāng)年之前的所有農(nóng)歷年總天數(shù),再計算出當(dāng)年之前的月天數(shù),再加上開始年日期,即得出元宵節(jié)的陽歷日期.
陰歷日期計算的結(jié)果,如果開課日期不是在星期一的,用式(2);是在星期一的,用式(3).
y 為陰歷計算成陽歷后的日期;7 為下一周的修正值.
在init 方法中,調(diào)用日期星期一函數(shù),有3 個參數(shù).第一個是年份,第二個是學(xué)期,第三個是模式值.順序不能顛倒.年與模式值是數(shù)值型,學(xué)期是字符型.如果是自動獲取開課日期的,模式值用0;如果用戶在使用中改變了學(xué)期,重新獲取開課日期的,模式值用1.Init 自動獲取開課日期程序如下:
nYear=year(date())
cXueqi=″
nModelValue=0
this.value=daymondy(nYear,cXueqi,nModelValue)
將daymondy()函數(shù)保存在daymondy.prg 文件中或者在datemonday 的方法中新建一個daymondy 方法文件.在本程序中,首先獲取計算機的當(dāng)前日期,然后取出年、月、日的值,判斷是在某一學(xué)期.如果是在第一學(xué)期,則月、日分別賦以9、1,年用當(dāng)前的年號,合成年月日,用dow()函數(shù)找到當(dāng)前的星期一那一天日期,即為開學(xué)日期.
假設(shè)是在第二學(xué)期的時間范圍,需要考慮陰歷(農(nóng)歷)的因素.第一步計算出當(dāng)年正月十五的日期.第二步再用上述的方法,將計算出的日期轉(zhuǎn)換成星期一的日期.
以上程序是自動獲取計算機的當(dāng)前日期,在實際操作中,用戶有可能改變當(dāng)前的年號,來查某一年、某一學(xué)期的課表,在程序中采用參數(shù)傳遞的方法來解決.
當(dāng)用戶在操作界面中修改了年號,先要判斷是在某一學(xué)期,將選擇的年號、學(xué)期傳給實際參數(shù)處理.如果是在第二學(xué)期,則對年+1,是在第一學(xué)期,年用原值,最后合成年月日,即是開學(xué)的星期一日期.
對天、月的處理程序代碼保存在Getmonday.prg 文件中,供daymondy()程序調(diào)用.Getmonday()程序有4個參數(shù),分別表示星期幾、日期、陰陽歷值、日月值.返回值是數(shù)值型.
星期幾用來判斷是不是星期一,用第二個參數(shù)、第一個參數(shù)計算出星期一的這一天日期、月份;第三個參數(shù)用來判斷是陽歷還是陰歷.如果元宵節(jié)這一天是星期一,按節(jié)日休假處理,即推遲一周上課,反之,將9月1日或元宵節(jié)前后三天左右的星期一作為開課(學(xué))日期.第四個參數(shù)用來判斷日、月值的返回,例如,9月1日是星期二,經(jīng)過計算后,可能是在8月31日就開課了,要將月份改為8月份.
如果日期與實際不符,用戶可能要修改日期.但是改的日期不一定是星期一,就需要提醒用戶注意.解決的辦法是在datemonday 類的InteractiveChange 中編寫程序,用_xq=DOW(_DateValue,2)進(jìn)行判斷,當(dāng)_xq≠1 時,顯示報警信息,提醒用戶注意.
將主要常量集中存入到CONSTEXT.H 文件中.本文中用到的常量如下:
**CONSTEXT.H
#DEFINE MSGTEXT1_LOC“參數(shù)設(shè)置不對!獲取的是當(dāng)前日期.請重新設(shè)置.”
#DEFINE MSGTEXT2_LOC“錯誤!請重新指定日期.您改的開課日期不是星期一,是”
#DEFINE DATEERROR_LOC“日期出錯,本系統(tǒng)陰歷日期只計算1900—2049年!”
#DEFINE MSGCAPTION_LOC“開課日期”
#DEFINE FIRSTXUEQI_LOC“第一學(xué)期”
#DEFINE XINQI1_LOC“星期一”
#DEFINE XINQI2_LOC“星期二”
#DEFINE XINQI3_LOC“星期三”
#DEFINE XINQI4_LOC“星期四”
#DEFINE XINQI5_LOC“星期五”
#DEFINE XINQI6_LOC“星期六”
#DEFINE XINQI7_LOC“星期日”
日期變換與修改日期不同,前者是操作環(huán)境條件發(fā)生改變,后者是用戶修改日期.開課日期常與學(xué)期聯(lián)合應(yīng)用.用戶在操作中,有可能不是選擇當(dāng)前的學(xué)期或當(dāng)年的內(nèi)容.如果選擇了某學(xué)期,開課日期就要隨之變化,使開課日期與學(xué)期相應(yīng)保持一致.學(xué)期控件也是一種類生成的,其中的值通常有一定的備選項.學(xué)期的組成是由當(dāng)年年份與次年年份加學(xué)期名構(gòu)成的,如“2013—2014 第一學(xué)期或2012—2013 第二學(xué)期”.當(dāng)用戶選擇“2013—2014 第一學(xué)期”時,開課日期顯示的是“09/02/2013”,當(dāng)選擇的是“2012—2013 第二學(xué)期”時,顯示的是“02/25/2013”日期.要使開課日期與學(xué)期發(fā)生變化能保持一至,在學(xué)期控件中的click 方法中,用以下代碼:
**o.exchangedate
_xueqi=alltr(this.displayvalue)
nYear=val(substr(_xueqi,1,4))&&取出年份
cXueqi=alltr((substr(_xueqi,10))&&取出學(xué)期
nModelValue=1
thisform.datemonday1.value=daymondy(nYear,cXueqi,nModelValue)
將設(shè)計好的開課日期類保存到某一個類中,供開發(fā)程序用.當(dāng)需要時,將其選放到表單的某一個位置,并在前面加上標(biāo)簽.當(dāng)程序啟動時,會自動將開課日期計算出來,呈現(xiàn)在用戶面前.開課日期返回的值是日期型的陽歷,格式用的是American(月/日/年)型.
開課日期界面如圖1.
圖1 開課日期界面(2013年下半年的開課日期)Fig.1 The interface course start date(the date of second half in 2013)
用開課日期類計算的近幾年開課日期見表2.
表2 開課日期類計算的近幾年開課日期Tab.2 The calculated course start date with date class in recent years
從2008年到2013年有12 個學(xué)期,實際的開課日期與表2 中的開課日期是一致的.準(zhǔn)確率達(dá)100%.
有了計算機以后,課表就有了靜態(tài)與動態(tài)之分.周課表就是一種半靜態(tài)半動態(tài)的形式,它是按星期排的課程內(nèi)容,每周重復(fù),直至學(xué)期結(jié)束.第一周的第一次上課日期不確定,需要指定一個開始的日期,將日期與課表的內(nèi)容固定下來,供教師或?qū)W生使用.課程進(jìn)度表要么是靜態(tài)的,要么是動態(tài)的,它是依靠周課表的星期所對應(yīng)的日期生成的每個課時單位.開課日期類就是將周課表或課程進(jìn)度表等做成動態(tài)的,進(jìn)一步提高教務(wù)系統(tǒng)的自動化程度.
本文中的一周概念是指周一到周日.開課日期是指學(xué)生每一學(xué)期第一次上課的星期一日期,用它來作為計算本學(xué)期課表的起點.不是開始上課的日期,不在此內(nèi)容之列.
寒暑假不屬于國家法定節(jié)假日,國家沒有明確規(guī)定假日有多少天.教育部的規(guī)定寒假一般是二十天,暑假一般是兩個月,大部分是由各省教育廳根據(jù)當(dāng)?shù)氐臍夂蚧蛱鞖馇闆r而定的.學(xué)校的寒假期間一般與春節(jié)重迭,與元宵節(jié)鄰近.在國務(wù)院的《全國年節(jié)及紀(jì)念日放假辦法》中,沒有元宵節(jié),元宵節(jié)不納入到節(jié)日內(nèi),也是人民的困惑.官方通用陽歷與國際接軌,民間使用陰歷傳遞傳統(tǒng)習(xí)俗.開課日期兼顧了陽歷、陰歷的算法.
通過表2 發(fā)現(xiàn),近幾年元宵節(jié)有二個星期一,二個星期四.凡是元宵節(jié)在周四以前的,本周都要開學(xué)上課,凡是元宵節(jié)在周一的推遲一周開學(xué),可能是因為開學(xué)第一天是節(jié)日,又要開學(xué),又要過節(jié),不如推遲一周開學(xué).元宵節(jié)在星期四的,開學(xué)準(zhǔn)備工作基本完成,不推遲.凡是“基點”在星期五的,不在本周內(nèi)開學(xué),推遲到下周一開學(xué).這是因為距本周星期一有4 天時間,而距下周一只有3 天時間,符合基點左右三天的計算法則.另一方面,星期五是節(jié)日,與雙休日相連,讓教師、學(xué)生充分享受集中使用節(jié)假日的歡樂,不如就到下周開課,見表1.如2014年元宵節(jié)在2月14日,是星期五,系統(tǒng)計算的結(jié)果是2月17日開課;陽歷如2000,2006,2017年的9月1日是星期五,推遲到下周一(9月4日)上課.
開課日期的控件屬性設(shè)計為可修改,當(dāng)與現(xiàn)實確有不符的情況下,用戶按照“月/日/年”的格式可以修改.修改開課日期的值只能是某一個星期一日期,如果不是星期一日期,系統(tǒng)會報警,提醒用戶注意.
查閱萬年歷,在1990—2049年間,元宵節(jié)沒有在1月份的,大多數(shù)是在陽歷2、3月份中,故在程序中沒有考慮1月份會有元宵節(jié).
開課日期除了用作課表起點計算外,在計算機排課算法中,將開課日期與教師等數(shù)據(jù)一起用函數(shù)遞增的方法處理,也許能幫助解決排課時期的沖突問題[9-14],有待進(jìn)一步研究.
本文用VFP 的類,將實際的開課日期上升為理論認(rèn)識,開發(fā)出日期控件,將極有可能的開課日期呈現(xiàn)在用戶面前.解決了過去由人們告訴計算機何時開課,而現(xiàn)在,是由計算機告訴我們何時開課.
凡是基點在星期四以前的,取本周的星期一為開課日期,其中,如果陰歷基點是星期一的,推遲到下周一開課;凡是基點是在星期五以后的,取下一周星期一開課.從計算的結(jié)果可以看出,理論與實際實現(xiàn)了統(tǒng)一,從而證明這種算法是有效的,能將復(fù)雜的問題變得簡單.本算法在教務(wù)軟件開發(fā)領(lǐng)域具有廣闊的應(yīng)用前景,反過來說,也可以作為學(xué)校開課的參考依據(jù).
[1]周發(fā)剛,陽鎮(zhèn)濤.臨床學(xué)院教務(wù)管理系統(tǒng)的開發(fā)與應(yīng)用[J].中華醫(yī)學(xué)教育雜志,2012,32(1):13-17.
[2]盧驍鵬,張 弦,周發(fā)剛.臨床學(xué)院學(xué)時課表的開發(fā)與實踐[J].中國醫(yī)學(xué)教育技術(shù),2012,26(3):311-315.
[3]黎 瓊,周飛亞,陽鎮(zhèn)濤,等.臨床學(xué)院課程進(jìn)度表的編排研究[J].中國醫(yī)學(xué)教育技術(shù),2013,27(5):553-557.
[4]MICROSOFT C.Visual Forpro 6.0 中文版語言參考手冊[M].北京:希望電子出版社,1999:493-494.
[5]中華農(nóng)歷網(wǎng).萬年歷[EB/OL].[2013-10-12].http://www.nongli.net/.
[6]Rucypli.CSDN 論壇[EB/OL].[2011-7-13].CSDN 論壇.http://topic.csdn.net/u/20110713/15/8d0010ac-e78f-41b5-89b5-f82073fa968b.html.
[7]黃 錕,陳志剛.混合算法在大學(xué)課程表問題中的應(yīng)用研究[J].電腦與信息技術(shù),2008,16(2):25-27.
[8]黃 輝,李虎雄,厲旭杰,等.基于Web 的高校辦公自動化系統(tǒng)的研究與設(shè)計[J].現(xiàn)代計算機,2009,29(1):182-184.
[9]陶 滔,謝衛(wèi)星.課表模型及排課算法應(yīng)用[J].計算機系統(tǒng)應(yīng)用,2011,20(2):198-201.
[10]丁德路,姜云飛.基于智能規(guī)劃的時間表問題研究[J].小型微型計算機系統(tǒng),2003(2):246-250.
[11]王幫海,李振柛.基于貪婪算法的自動排課表系統(tǒng)的研究與實現(xiàn)[J].計算機工程與設(shè)計,2012,29(18):4843-4846.
[12]吳金榮.關(guān)于大學(xué)課程表問題的研究[J].運籌與管理,2002,11(6):66-70.
[13]王秋芬,袁東鋒.課程表編排問題的算法研究[J].計算機與現(xiàn)代化,2012,19(3):19-22.
[14]嚴(yán)李強,付建平,郭 鑫,等.基于數(shù)據(jù)庫關(guān)系運算的排課算法設(shè)計[J].電腦知識與技術(shù),2013,9(25):5665-5672.