2023年7月13日木曜日

CSV file to competition format(INRC2) conversion

 sugawara-system/Schedule_Nurse3_Gallery: The State of the Art commercial solver, Schedule Nurse galleries sites. Contains samples and project files for benchmark test results such as Classical Scheduling Benchmarks, Scheduling Benchmarks, INRC1, INRC2, etc. (github.com)

The solution file can be output as a CSV file. I have written a script to convert this CSV file to the competition format. Usually, I would have used Python, but that would not have been interesting, so I implemented it here as a project for the Schedule Nurse. This project is a dummy project, and the constraints are meaningless. What is meaningful is post_main(), which is executed as a post-process.

import win32gui, win32con, os
import csv

def get_day_str(day):
    if day==0:
        return "Mon"
    elif day==1:
        return "Tue"
    elif day==2:
        return "Wed"
    elif day==3:
        return "Thu"
    elif day==4:
        return "Fri"
    elif day==5:
        return "Sat"
    elif day==6:
        return "Sun"
    else:
        raise ValueError("Unsupported Day!")

def get_shift_name(label):
    if label=='D':
        return "Day"
    elif label=='N':
        return "Night"
    elif label=='L':
        return "Late"
    elif label=='E':
        return "Early"
    else :
        raise ValueError("Unsupported Shift!")

def get_task_name(label):
    if label=='He':
        return "HeadNurse"
    elif label=='Nu':
        return "Nurse"
    elif label=='Ca':
        return "Caretaker"
    elif label=='Tr':
        return "Trainee"
    else :
        raise ValueError("Unsupported Shift!")


def make_weeks_data(lst,fname):
    persons=int((len(lst)-3)/2)
    items=len(lst[0])
    print('items=',items)
    name=""
    phases=3
    weeks=4
    
    start_row=2
    print('persons=',persons)
    if items==107:
        phases=3
        weeks=4
    elif items==254:
        phases=4
        weeks=8
    elif items==142:
        phases=4
        weeks=4
    else:
        raise ValueError("Unsupported Items!")
    
    start_day=2+phases*7

    for week in range(weeks):
        w_str=""
        file_name = "sol-week" +   str(week) + ".txt";
        assigned=0

        for person in range(persons):
            #print(person)
            #print(lst[person*2+2][0])
            name=lst[person*2+start_row][0]
            print(name)
            for day in range(7):
                shift=lst[person*2+start_row][week*7*phases+day*phases+start_day]
                if shift=='O' or shift=='':
                    continue
                for ph in range(phases):
                    task=lst[person*2+1+start_row][week*7*phases+day*phases+start_day+ph]
                    if task !='':
                        w_str+=name +' '+get_day_str(day)+' '+get_shift_name(shift) +' '+get_task_name(task)+'\n'
                        break
                assigned +=1

        Wstr="SOLUTION\n";
        Wstr+=str(week)+' '+ fname[0:6]+ "\n\n";
        Wstr+="ASSIGNMENTS = "+ str(assigned) +"\n";
        Wstr+=w_str
        f1 = open(file_name, 'w')
        f1.write(Wstr)
        f1.close()
        print(file_name,Wstr)

        

def post_main_sub():

#    try:
        filter='csv\0*.csv\0'
        customfilter='Other file types\0*.*\0'
        fname, customfilter, flags=win32gui.GetOpenFileNameW(
        InitialDir=project_file_path, #os.environ['temp'],
        Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
        File='somefilename', DefExt='csv',
        Title='GetOpenFileNameW',
        Filter=filter,
        CustomFilter=customfilter,
        FilterIndex=0)
        print ('open file names:', repr(fname))
        print(fname)
        
        with open(fname, encoding="utf-8") as f:
            lst = list(csv.reader(f))
            print("row length=",len(lst))
            #basename = os.path.basename(fname)
            basename_without_ext = os.path.splitext(os.path.basename(fname))[0]
            make_weeks_data(lst,basename_without_ext)
            

def post_main():
    post_main_sub()

0 件のコメント:

コメントを投稿