Python论坛  - 讨论区

标题:程序问题,请大家帮忙看看。

2012年03月11日 星期日 02:29

本人是一个医生,为了进行排班,写了一个python程序,但遇到了一个问题,请大家帮忙看看。

排班的基本思路是,每个循环周期有一个人轮休,其余的人依次排班,每人一天。排班表生成一个二维数组,然后将这个二维数组写入一个csv文件中,代码如下:

#!bash/bin/python
#-*-coding:utf-8-*-

import string
import calendar

RDlist=['a','b','c','d','e','f','g']
#值班医生列表
RDfirst='d'
#RDfirst代表本月第一个值班
RDrest='b'
#RDrest代表本周期内轮休的医生

Year=2012
Month=4
#值班表的年月

separator=','
#设置分隔符

#函数Date()按年月生成的日期列表
def Date(Year,Month):
    day=1
    daynum=calendar.monthrange(Year,Month)[1]
    Date=[1]
    #monthrange(year,month)用于产生一个元组,元组的第一个数字为1号的星期数,元组的第二个数字表示本月的总天数。python的记数都是由“0”开始。
    while day<daynum:
        day=day+1
        Date.append(day)
    return Date

#函数WeekDay()按Date生成的星期列表
def WeekDay(Year,Month):
    Week=['一','二','三','四','五','六','日']
    WeekDay=[]
    for day in Date(Year,Month):
        weekday=Week[calendar.weekday(Year,Month,day)]
        WeekDay.append(weekday)
    return WeekDay


#带轮休的函数DutyRestQuery(),其中rest参数表示一个值班周期内轮休的那个医生。一个值班周期是指从值班列表第一人轮至最后一人的期间。
def DutyRestQuery(dlist,first,rest,Year,Month):
    OnDuty=first
    OnRest=rest
    clist=[i+',' for i in dlist]
    MemDutyList=[clist]
    for Day in Date(Year,Month):
        DayDuty=[]
        for member in dlist:
            if member==OnRest and member==OnDuty:
                DayDuty.append('休,')
                i=string.index(dlist,member)
                if i+1>len(dlist)-1:
                    OnDuty=dlist[0]
                else:
                    OnDuty=dlist[i+1]
            elif member==OnDuty:
                DayDuty.append('值,')
            else:
                DayDuty.append(separator)
        MemDutyList.append(DayDuty)
        n=string.index(dlist,OnDuty)
        m=string.index(dlist,OnRest)
        n=n+1
        if n>len(dlist)-1:
            OnDuty=dlist[0]
            if m>len(dlist)-1:
                OnRest=dlist[0]
            else:
                OnRest=dlist[m+1]
        else:
            OnDuty=dlist[n]
    reverse=[[r[col] for r in MemDutyList] for col in range(len(MemDutyList[0]))]
    return reverse
 
D=DutyRestQuery(RDlist,RDfirst,RDrest,Year,Month)
print '\n'.join(''.join(c for c in row) for row in D)

生成的结果如下:

a,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,
b,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,
c,,,,,,,休,,,,,,值,,,,,,值,,,,,,值,,,,,,
d,值,,,,,,值,,,,,,,休,,,,,,值,,,,,,值,,,,,
e,,值,,,,,,值,,,,,,值,,,,,,,休,,,,,,值,,,,
f,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,,休,,,
g,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,

把这个结果用表格软件打开,可以看到如果c轮休,则在轮到他值班那天会显示‘休’,而d则显示‘值’。但如果轮休的是g,即RDrest='g',问题就来了:

a,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
b,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,
c,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,
d,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,
e,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,
f,,,值,,,,,,值,,,,,,值,,,,,,值,,,,,,值,,,,
g,,,,休,,,,,,休,,,,,,休,,,,,,休,,,,,,休,,,

请大家帮忙看看,有什么解决方法没有?

 

2012年03月11日 星期日 20:52

#使用队列的思路来解决问题,供参考。

 

from collections import deque

duration = 7
person_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

# init queue
rest_queue = deque()
for person in person_list:
    rest_queue.append(person)

column_header = '\t'
for i in range(duration):
    column_header += str( i + 1) + '\t'
print column_header

row = ''
for person in person_list:
    row = person + '\t'
    for i in range(duration):
        other_person = rest_queue.popleft()
        rest_queue.append(other_person)
        if person == other_person:
            row += '休\t'
        else:
            row += '值\t'
    print row

 

2012年03月27日 星期二 17:53

谢谢您的回答,我最近也找了一本数据结构的书在看。循环队列的确是解决这一问题的好方法,但我目前还遇到一些问题,比如在您给的示例中,当duration不等于7的倍数时,就会出现排列混乱,这是因为在开始下一个member循环时,rest_queue的顺序已经和前一次不一样了。

第二,我面临的问题可能要复杂一些,就是每个月要进行一次排班,由于每个月长短不同,以及值班人员的变动,每次首个值班的人都会不一样,轮休的人也不一样,所以涉及到的变量多一些。

我自己有时间的时候再想想,不懂再问,再次谢谢!

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号