Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import urllib
- import random
- import time
- import pickle
- import zipfile
- import itertools
- from os import *
- def mysplitcsv(linetosplit):
- #custom line splitting code
- #like line.split(','), except it keeps text surrounded by quotes intact
- items = list()
- currentitem = ''
- currentnest = ''
- for c in linetosplit:
- if currentnest != '':
- if c == currentnest:
- currentnest = ''
- else:
- currentitem = currentitem + c
- else:
- if c == '"':
- currentnest = c
- elif c == ',':
- items.append(currentitem)
- currentitem = ''
- else:
- currentitem = currentitem + c
- items.append(currentitem)
- return items
- def translate_UTF8(line):
- #translate exotic UTF-8 characters - smart quotes and such - to plain ASCII
- utfstat = ''
- newline = ''
- for c in line:
- if c >= '\x80':
- if len(utfstat) < 3:
- utfstat = utfstat + c
- else:
- utfstat = utfstat[1] + utfstat[2] + c
- if UTF8translation.has_key(utfstat):
- newline = newline + UTF8translation[utfstat]
- utfstat = ''
- else:
- newline = newline + c
- utfstat = ''
- return newline
- def process_text_string(line):
- #line2 = line.lower()
- line2 = ''
- p = ''
- for c in line:
- if c.lower() != p.lower() or (c.isupper() and p.isupper()) or c.isdigit():
- p = c
- line2 += p.lower()
- line2 = line2.replace('&','and')
- for c in ('#,:!?"\'.'):
- line2 = line2.replace(c,'')
- line2 = ''.join(line2.split())
- line2 = line2.rstrip('s')
- return line2
- #return 'foo'
- def mysplit(linetosplit):
- #custom line splitting code
- #like line.split(''), except it keeps text surrounded by quotes intact
- items = list()
- currentitem = ''
- currentnest = ''
- for c in linetosplit:
- if currentnest != '':
- if c == currentnest:
- currentnest = ''
- else:
- currentitem = currentitem + c
- else:
- if c == '"' or c == "'":
- currentnest = c
- elif len(c.strip()) == 0:
- if currentitem != '':
- items.append(currentitem)
- currentitem = ''
- else:
- currentitem = currentitem + c
- items.append(currentitem)
- return items
- def non_recursively_solve_schedule(event_info):
- #event_info
- #list of
- #tuple,
- #first element is priority
- #second element is list of
- #tuple
- #first element is list of
- #tuple
- #first element is event ID
- #second element is start time
- #third element is end time
- #fourth element is location
- #second element is total time penalty
- found_schedules = list()
- free_times = []
- free_times.append((time.mktime(min(unique_entries[start_index])),
- time.mktime(max(unique_entries[end_index] )),
- None,
- None
- ))
- found_schedules.append((0.0,[],free_times))
- #schedules:
- #list of found schedules so far
- #each of which is
- #(cost,(list of eventID added so far),(free times remaining))
- while len(event_info) > 0:
- next_event_to_add = event_info[0]
- remaining_events = event_info[1:]
- priority = next_event_to_add[0]
- next_schedules = list()
- for prior_sched in found_schedules:
- #for each schedule found so far...
- score = prior_sched[0]
- schedule = prior_sched[1]
- for eventslot in next_event_to_add[1]:
- #print prior_sched,eventslot
- #for each possible slot for this event...
- events_toadd = list()
- remaining_free = list()
- free_times = prior_sched[2]
- free_slot = True
- penalty = eventslot[1] + priority
- for thiseventinfo in eventslot[0]:
- if free_slot != None:
- free_slot = None
- eventID,slot_start,slot_end,location = thiseventinfo
- time_penalty = penalty
- remaining_free = list()
- for timeslot in free_times:
- if timeslot[0] <= slot_start and timeslot[1] >= slot_end:
- free_slot = timeslot
- else:
- remaining_free.append(timeslot)
- if free_slot != None: #found a slot!
- #if float(unique_entries[cost_index][events_byID[eventID][cost_index]]) != 0.0:
- if True:
- start_time_spare = slot_start - free_slot[0]
- end_time_spare = free_slot[1] - slot_end
- start_time_location = free_slot[2]
- end_time_location = free_slot[3]
- #Penalize events which start or end too close to other events
- if start_time_spare < 900:
- if start_time_location != location:
- time_penalty -= 2.0
- elif start_time_spare < 1800:
- if start_time_location != location:
- time_penalty -= 0.5
- else:
- remaining_free.append((free_slot[0],slot_start,start_time_location,location))
- if end_time_spare < 900:
- if end_time_location != location:
- time_penalty -= 2.0
- elif end_time_spare < 1800:
- if end_time_location != location:
- time_penalty -= 0.5
- else:
- remaining_free.append((slot_end,free_slot[1],location,end_time_location))
- else:
- remaining_free.append(free_slot)
- events_toadd.append(eventID)
- free_times = remaining_free
- if free_slot != None:
- new_score = score + time_penalty
- new_schedule = schedule + events_toadd
- next_schedules.append((new_score,new_schedule,remaining_free))
- if next_event_to_add[0] < 10:
- found_schedules += next_schedules
- else:
- found_schedules = next_schedules
- event_info = remaining_events
- found_schedules.sort(reverse = True)
- found_schedules = found_schedules [:10000]
- return found_schedules
- def solve_schedule(schedule):
- schedule.sort(key = lambda s:len(s[1]) * 1000 - s[0])
- time_one = time.time()
- event_info = list()
- for event in schedule:
- priority = event[0]
- eventlist = event[1]
- events_with_times = list()
- for eventID in eventlist:
- eventstack = [[eventID]]
- if events_following.has_key(eventID):
- eventstack = eventstack + events_following[eventID]
- eventstack = map(list,list(itertools.product(*eventstack)))
- for eventIDlist in eventstack:
- thiseventinfo = list()
- time_penalty = 0.0
- last_end_time = None
- for eventID in eventIDlist:
- anevent = events_byID[eventID]
- location = anevent[location_index]
- starttime = unique_entries[start_index][anevent[start_index]]
- endtime = unique_entries[end_index][anevent[end_index]]
- start_hour = int(time.strftime('%H',starttime))
- end_hour = int(time.strftime('%H',endtime))
- starttime = int(time.mktime(starttime))
- endtime = int(time.mktime(endtime))
- if eventID.startswith('TDA'):
- starttime = starttime - 900 #True Dungeon events need you to be there 15 minutes early
- if last_end_time != None and last_end_time > starttime:
- starttime = last_end_time
- last_end_time = endtime
- #Penalize late-night or early-morning events
- if start_hour > 23:
- time_penalty -= 2.0
- if end_hour > 23:
- time_penalty -= 2.0
- if start_hour < 20:
- time_penalty -= 1.0
- if end_hour > 21:
- time_penalty -= 1.0
- if end_hour > 16:
- time_penalty -= 0.1
- if end_hour > 17:
- time_penalty -= 0.1
- if start_hour < 8:
- time_penalty -= 0.4
- if end_hour < 9:
- time_penalty -= 0.
- if start_hour < 5:
- time_penalty -= 2.0
- if end_hour < 6:
- time_penalty -= 2.0
- thiseventinfo.append((eventID,starttime,endtime,location))
- events_with_times.append((thiseventinfo,time_penalty))
- event_info.append((priority,events_with_times))
- free_times = []
- free_times.append((int(time.mktime(min(unique_entries[start_index]))),
- int(time.mktime(max(unique_entries[end_index] )))))
- found_schedules = non_recursively_solve_schedule(event_info)
- time_four = time.time()
- found_schedules.sort(reverse = True)
- if len(found_schedules) > 0:
- return found_schedules
- else:
- return None
- def dosearch(search,eventpool):
- #print search
- foundevents = list()
- keyword = search[0]
- word = search[1]
- if word == '':
- return eventpool
- if keyword in ['any','all']:
- for eventID in eventpool:
- for i in [title_index,desc_index,long_desc_index,type_index,system_index,rules_index,company_index,gm_index]:
- event = events_byID[eventID]
- if word in filter(lambda c:c.islower() or c.isdigit() or c in word,unique_entries[i][event[i]].lower()):
- foundevents.append(eventID)
- if word.upper() in eventpool:
- foundevents.append(word.upper())
- elif keyword in ['in','at']:
- for eventID in eventpool:
- for i in [location_index,room_index]:
- event = events_byID[eventID]
- if word in filter(lambda c:c.islower() or c.isdigit() or c in word,unique_entries[i][event[i]].lower()):
- foundevents.append(eventID)
- elif keyword in ['by']:
- for eventID in eventpool:
- for i in [company_index,gm_index]:
- event = events_byID[eventID]
- if word in filter(lambda c:c.islower() or c.isdigit() or c in word,unique_entries[i][event[i]].lower()):
- foundevents.append(eventID)
- elif keyword in ['type']:
- for eventID in eventpool:
- for i in [type_index]:
- event = events_byID[eventID]
- if unique_entries[i][event[i]].lower().startswith(word.lower()):
- #if word in filter(lambda c:c.islower() or c.isdigit() or word.startswith(c),unique_entries[i][event[i]].lower()):
- foundevents.append(eventID)
- elif keyword in ['on']:
- for eventID in eventpool:
- for i in [start_index,end_index]:
- event = events_byID[eventID]
- if time.strftime('%A',unique_entries[i][event[i]]).lower().startswith(word):
- foundevents.append(eventID)
- elif keyword in ['age']:
- for eventID in eventpool:
- for i in [age_index]:
- event = events_byID[eventID]
- if word.lower() in unique_entries[i][event[i]].lower():
- foundevents.append(eventID)
- elif keyword in ['before']:
- thetime = None
- try:
- thetime = time.strptime(word,'%H')
- except ValueError:
- try:
- thetime = time.strptime(word,'%H:%M')
- except ValueError:
- try:
- thetime = time.strptime(word,'%I%p')
- except ValueError:
- try:
- thetime = time.strptime(word,'%I:%M%p')
- except ValueError:
- if word == 'noon':
- thetime = time.strptime('12','%H')
- if thetime != None:
- for eventID in eventpool:
- event = events_byID[eventID]
- if time.strptime(time.strftime('%H:%M',unique_entries[end_index][event[end_index]]),'%H:%M') < thetime:
- if time.strptime(time.strftime('%H:%M',unique_entries[start_index][event[start_index]]),'%H:%M') < thetime:
- foundevents.append(eventID)
- elif keyword in ['after']:
- thetime = None
- try:
- thetime = time.strptime(word,'%H')
- except ValueError:
- try:
- thetime = time.strptime(word,'%H:%M')
- except ValueError:
- try:
- thetime = time.strptime(word,'%I%p')
- except ValueError:
- try:
- thetime = time.strptime(word,'%I:%M%p')
- except ValueError:
- if word == 'noon':
- thetime = time.strptime('12','%H')
- if thetime != None:
- for eventID in eventpool:
- event = events_byID[eventID]
- if time.strptime(time.strftime('%H:%M',unique_entries[end_index][event[end_index]]),'%H:%M') > thetime:
- if time.strptime(time.strftime('%H:%M',unique_entries[start_index][event[start_index]]),'%H:%M') > thetime:
- foundevents.append(eventID)
- elif keyword in ['not']:
- not_found_events = dosearch(word,eventpool)
- foundevents = filter(lambda e:e not in not_found_events,eventpool)
- foundevents = list(set(foundevents))
- foundevents.sort()
- return foundevents
- def find_events(wordlist):
- searches = list()
- search_keywords = ['any','all','on','in','at','by','before','after','type','not','age']
- latest_keyword = ''
- #first_permitted_start = min(unique_entries[start_index])
- #last_permitted_end = max(unique_entries[end_index])
- next_not = False
- for word in wordlist:
- if word.lower() in search_keywords:
- if word.lower() == 'not':
- next_not = True
- else:
- latest_keyword = word.lower()
- else:
- if latest_keyword == '':
- if len(searches) > 0:
- last_search = searches.pop()
- if last_search[0] in ['any','all']:
- searches.append((last_search[0],last_search[1] + ' ' + word))
- else:
- searches.append(last_search)
- searches.append(('any',word.lower()))
- latest_keyword = ''
- else:
- searches.append(('any',word.lower()))
- latest_keyword = ''
- else:
- if next_not:
- searches.append(('not',(latest_keyword,word.lower())))
- else:
- searches.append((latest_keyword,word.lower()))
- latest_keyword = ''
- next_not = False
- eventpool = events_canprereg + events_generic
- #eventpool.sort(key = lambda eventID:unique_entries[start_index][events_byID[eventID][start_index]])
- #uncomment this line to filter events with no slots left
- # eventpool = filter(lambda e:unique_entries[tickets_available_index][events_byID[e][tickets_available_index]] > 0,eventpool)
- #eventpool = events_byID.keys()
- for search in searches:
- #print search
- eventpool = dosearch(search,eventpool)
- #results = list()
- event_unique_keys = dict()
- #print 'Finding unique keys...'
- for eventID in eventpool:
- foo = ' '.join(map(str,map(lambda j:j in ident_indices and
- events_byID[eventID][j] or -1,range(number_of_colums))))
- #foo = ' '.join(map(str,map(lambda j:events_byID[eventID][j],ident_indices)))
- event_unique_keys[eventID] = foo
- # print eventID,foo
- unique_keys = set(event_unique_keys.values())
- events_by_unique_keys = dict()
- #eventIDs = events_byID.keys()
- for key in unique_keys:
- matching_events = filter(lambda k:event_unique_keys[k] == key,eventpool)
- #print matching_events
- newkey = map(lambda j:map(lambda eventID:events_byID[eventID][j],matching_events),range(number_of_colums))
- #print foo
- #print foo
- newkey = map(lambda s:len(s) == 1 and list(s)[0] or -1,map(set,newkey))
- newkey = ' '.join(map(str,newkey))
- #print foo
- events_by_unique_keys[newkey] = matching_events
- #events_by_unique_keys.sort(key = lambda eventIDlist:unique_entries[start_index][events_byID[eventIDlist[0]][start_index]])
- #print len(unique_keys),'unique event keys'
- return events_by_unique_keys
- def fix_location(location):
- location = location.replace(' Bllrm',' Ballroom')
- location = location.replace(' Blrm',' Ballroom')
- location = location.replace('Notra ','Notre ')
- location = location.replace('Penn ','Pennsylvania ')
- location = location.replace(' Stn',' Station')
- location = location.replace(' & ',' and ')
- location = location.replace(' SE',' Southeast')
- location = location.replace(' NE',' Southwest')
- location = location.replace(' SW',' Northeast')
- location = location.replace(' NW',' Northwest')
- location = location.replace(' Cntrl',' Central')
- location = location.replace('Exhibit Hl','Exhibit Hall')
- if location.endswith(' I'):
- location = location.replace(' I',' 1')
- elif location.endswith(' II'):
- location = location.replace(' II',' 2')
- elif location.endswith(' III'):
- location = location.replace(' III',' 3')
- elif location.endswith(' IV'):
- location = location.replace(' IV',' 4')
- elif location.endswith(' V'):
- location = location.replace(' V',' 5')
- if location == 'Family Fun Pavilion':
- location = 'Exhibit Hall: Family Fun Pavilion'
- return location
- def get_catalog(url):
- filenames = listdir('.')
- mydir = 'Catalogs'
- if not mydir in filenames:
- mkdir(mydir)
- #filenames = listdir(mydir)
- filenames = []
- try:
- data = urllib.urlopen(url).read()
- #print data
- filefindstring = '<div class="FileFileName">'
- event_file_locations = list()
- while data.find(filefindstring) > -1:
- data = data[data.find(filefindstring) + len(filefindstring):]
- item = data[data.find('<a href'):data.find('</a>')]
- fileloc = item.split('"')[1]
- #print fileloc
- if 'pmcompletecatalogs' in fileloc:
- event_file_locations.append(fileloc)
- #print
- print "Checking for new event catalog files..."
- found = False
- for csvfileloc in event_file_locations:
- #print csvfileloc
- print 'checking',csvfileloc
- url = 'http://community.gencon.com' + csvfileloc
- data = urllib.urlopen(url).read()
- #print data
- data = data[data.find('<div class="CommonContentArea">'):]
- #print data
- data = data[data.find('<a class="CommonImageTextButton CommonDownloadButton'):]
- zipfileloc = data[data.find('href="'):data.find('</a>')]
- zipfileloc = zipfileloc.split('"')[1]
- #print zipfileloc
- while data.find('<td class="FilePropertyName">') > -1:
- data = data[data.find('<td class="FilePropertyName">'):]
- propertyname = data[data.find('>')+1:data.find('</td>')]
- #print propertyname,
- data = data[data.find('<td class="FileProperty">'):]
- propertyvalue = data[data.find('>')+1:data.find('</td>')]
- #print propertyvalue
- data = data[data.find('</td>'):]
- #data =
- url = 'http://community.gencon.com' + zipfileloc
- thisfilename = zipfileloc.split('/')
- print thisfilename
- thisfilename = thisfilename[len(thisfilename)-2]
- #print thisfilename
- #print filenames
- if not thisfilename + '.zip' in filenames:
- found = True
- print 'Found new event catalog:',thisfilename
- print 'Downloading it...'
- urllib.urlretrieve(url,mydir + '/' + thisfilename + '.zip')
- print 'Done. Decompressing and processing now.'
- data = None
- try:
- zf = zipfile.ZipFile(mydir + '/' + thisfilename + '.zip','r')
- files = zf.namelist()
- data = ''
- for filename in files:
- if filename.endswith ('.csv') and filename.find('/') == -1 and filename.find('..') == -1:
- zf.open(filename)
- data = zf.read(filename)
- zf.close()
- except:
- print 'Failed, unable to decompress.'
- data = None
- if data != None:
- lines = data.split('\n')
- lines = map(lambda x:x.rstrip('\r'),lines)
- splitlines = map(mysplitcsv,lines)
- column_titles = map(translate_UTF8,splitlines[0])
- ll = len(column_titles)
- proclines = list()
- for line in splitlines[1:]:
- if len(line) == ll:
- fixedline = list()
- for i in range(len(line)):
- if 'room' in column_titles[i].lower():
- fixedline.append(fix_location(translate_UTF8(line[i])))
- else:
- fixedline.append(translate_UTF8(line[i]))
- proclines.append(fixedline)
- #proclines.append(map(translate_UTF8,line))
- #print
- #print line
- #print fixedline
- columntypes = list()
- unique_entries_by_category = dict()
- #entries_as_shown_by_category = dict()
- unique_to_as_shown_map_by_category = dict()
- unique_to_as_shown_votes_by_category = dict()
- for i in range(len(column_titles)):
- lowtitle = column_titles[i].lower()
- columntype = 'TEXT'
- unique_contents = list()
- nonefailedbool = True
- anybool = False
- nonefailedfloat = True
- anynumeric = False
- nonefaileddate = True
- anydate = False
- for line in proclines:
- item = line[i].lower().strip(' ')
- if nonefailedfloat and item != '':
- try:
- foo = float(item)
- anynumeric = True
- except ValueError:
- nonefailedfloat = False
- if nonefaileddate and item != '':
- try:
- foo = time.strptime(item,'%m/%d/%Y %H:%M')
- anydate = True
- except ValueError:
- nonefaileddate = False
- if nonefailedbool and item != '':
- if (item == 'no' or item == 'yes' or
- item == 'true' or item == 'false'):
- anybool = True
- else:
- nonefailedbool = False
- if not item in unique_contents:
- unique_contents.append(item)
- if nonefailedbool and anybool:
- columntype = 'BOOL'
- elif nonefailedfloat and anynumeric:
- columntype = 'FLOAT'
- elif nonefaileddate and anydate:
- columntype = 'DATE'
- elif len(unique_contents) == len(proclines):
- columntype = 'ID'
- else:
- columntype = 'TEXT'
- columntypes.append(columntype)
- unique_entries_by_category[i] = list()
- #entries_as_shown_by_category[i] = list()
- unique_to_as_shown_map_by_category[i] = dict()
- unique_to_as_shown_votes_by_category[i] = dict()
- events_byID = dict()
- for line in proclines:
- #processed_event = list()
- #eventID = None
- for i in range(len(column_titles)):
- shown_item = line[i]
- if columntypes[i] == 'BOOL':
- item = shown_item.lower()
- if item == 'yes' or item == 'true':
- item = True
- else:
- item = False
- elif columntypes[i] == 'FLOAT':
- if shown_item != '':
- item = float(shown_item)
- else:
- item = 0.0
- elif columntypes[i] == 'DATE':
- if shown_item != '':
- item = time.strptime(shown_item,'%m/%d/%Y %H:%M')
- else:
- item = 0
- elif columntypes[i] == 'TEXT':
- item = process_text_string(shown_item)
- #if i == 4:
- # print item[:20]+'... = '+shown_item[:20]+'...'
- if columntypes[i] != 'ID':
- if not item in unique_entries_by_category[i]:
- unique_entries_by_category[i].append(item)
- #if i == 4:
- # print 'item not in unique_entries_by_category[i]'
- if not unique_to_as_shown_map_by_category[i].has_key(item):
- unique_to_as_shown_map_by_category[i][item] = list()
- unique_to_as_shown_votes_by_category[i][item] = dict()
- #if i == 4:
- # print 'not unique_to_as_shown_map_by_category[i].has_key(item)'
- if not shown_item in unique_to_as_shown_map_by_category[i][item]:
- unique_to_as_shown_map_by_category[i][item].append(shown_item)
- unique_to_as_shown_votes_by_category[i][item][shown_item] = 1
- #if i == 4:
- # print 'not shown_item in unique_to_as_shown_map_by_category[i][item]'
- else:
- unique_to_as_shown_votes_by_category[i][item][shown_item] += 1
- #if i == 4:
- # print 'unique_to_as_shown_votes_by_category[i][item][shown_item] =', unique_to_as_shown_votes_by_category[i][item][shown_item]
- for i in range(len(column_titles)):
- unique_entries_by_category[i].sort()
- for item in unique_to_as_shown_map_by_category[i].keys():
- bestscore = 0
- bestsub = ''
- for shown_item in unique_to_as_shown_map_by_category[i][item]:
- if unique_to_as_shown_votes_by_category[i][item][shown_item] > bestscore:
- bestsub = shown_item
- bestscore = unique_to_as_shown_votes_by_category[i][item][shown_item]
- #if i == 4:
- #if len(unique_to_as_shown_map_by_category[i][item]) > 1:
- #print item
- #for shown_item in unique_to_as_shown_map_by_category[i][item]:
- # print '\t',shown_item,unique_to_as_shown_votes_by_category[i][item][shown_item]
- #print
- #print bestsub
- #print
- unique_to_as_shown_map_by_category[i][item] = bestsub
- for line in proclines:
- processed_event = list()
- eventID = None
- for i in range(len(column_titles)):
- shown_item = line[i]
- if columntypes[i] == 'ID':
- eventID = shown_item
- elif columntypes[i] == 'BOOL':
- item = shown_item.lower()
- if item == 'yes' or item == 'true':
- item = True
- else:
- item = False
- elif columntypes[i] == 'FLOAT':
- if shown_item != '':
- item = float(shown_item)
- else:
- item = 0.0
- elif columntypes[i] == 'DATE':
- if shown_item != '':
- item = time.strptime(shown_item,'%m/%d/%Y %H:%M')
- else:
- item = 0
- elif columntypes[i] == 'TEXT':
- item = process_text_string(shown_item)
- if columntypes[i] != 'ID':
- #if i == 4:
- # print item,unique_entries_by_category[i].index(item)
- item = unique_entries_by_category[i].index(item)
- processed_event.append(item)
- if eventID != None:
- events_byID[eventID] = processed_event
- unique_entries = list()
- for i in range(len(column_titles)):
- if columntypes[i] == 'TEXT':
- mapped_unique = list()
- for item in unique_entries_by_category[i]:
- #if i == 4:
- # print item,unique_to_as_shown_map_by_category[i][item]
- mapped_unique.append(unique_to_as_shown_map_by_category[i][item])
- unique_entries.append(mapped_unique)
- #unique_entries.append(entries_as_shown_by_category[i])
- elif columntypes[i] != 'ID':
- unique_entries.append(unique_entries_by_category[i])
- column_titles.remove(column_titles[columntypes.index('ID')])
- columntypes.remove('ID')
- print 'Saving to disk...'
- outfile = file(mydir + '/' + thisfilename + '_processed.pcl','w')
- pickle.dump(column_titles,outfile)
- pickle.dump(columntypes,outfile)
- pickle.dump(unique_entries,outfile)
- pickle.dump(events_byID,outfile)
- outfile.close()
- print 'Done.'
- else:
- print 'Already have',thisfilename
- if not found:
- print "None found."
- except IOError:
- print "Unable to connect to Internet."
- def print_nicely_formatted(text,linelength):
- print text
- return
- i = 0
- line = ''
- for word in text.split():
- if i + 1 + len(word) > linelength:
- if len(line) < linelength:
- increment = float(linelength) / (linelength - len(line) + 1)
- line_words = line.split()
- line = ''
- index = increment
- for aword in line_words:
- if len(line) > 0:
- while (len(line) + len(aword) >= int(index)) and (len(line) + len(aword)) < linelength:
- line = line + ' '
- index = index + increment
- line = line + aword + ' '
- while len(line) >= int(index):
- line = line + ' '
- index = index + increment
- print line
- line = word
- i = len(word)
- else:
- if i > 0:
- line = line + ' '
- i = i + 1
- line = line + word
- i = i + len(word)
- print line
- UTF8translation = dict()
- UTF8translation['\xe2\x80\x82'] = ' '
- UTF8translation['\xe2\x80\x83'] = ' '
- UTF8translation['\xe2\x80\x89'] = ' '
- UTF8translation['\xe2\x80\x93'] = '-'
- UTF8translation['\xe2\x80\x94'] = '--'
- UTF8translation['\xe2\x80\x98'] = "'"
- UTF8translation['\xe2\x80\x99'] = "'"
- UTF8translation['\xe2\x80\x9A'] = "'"
- UTF8translation['\xe2\x80\x9C'] = '"'
- UTF8translation['\xe2\x80\x9D'] = '"'
- UTF8translation['\xe2\x80\x9E'] = '"'
- UTF8translation['\xe2\x80\xA0'] = '!'
- UTF8translation['\xe2\x80\xA1'] = '!'
- UTF8translation['\xe2\x80\xB0'] = '%o'
- UTF8translation['\xe2\x80\xB9'] = '<'
- UTF8translation['\xe2\x80\xBA'] = '>'
- UTF8translation['\xe2\x80\xAC'] = 'E'
- UTF8translation['\xe2\x80\xA2'] = '*'
- UTF8translation['\xe2\x80\xA6'] = '...'
- UTF8translation['\xe2\x80\xB2'] = "'"
- UTF8translation['\xe2\x80\xB3'] = '"'
- UTF8translation['\xe2\x80\xBE'] = '-'
- UTF8translation['\xe2\x81\x84'] = '/'
- print 'Welcome to Andrew\'s Gencon 2012 Schedule Solver'
- print 'This software is an experimental tool for solving schedules with events'
- print 'with many different slots, where there are large numbers of different combinations'
- print 'possible. Only designed to work with the specific format of the Gencon 2012 csv'
- print 'files. Use at your own risk.'
- print
- reply = raw_input("Download latest events from website?")
- if reply.lower().startswith('y'):
- #Get the calendar from the Gencon community site
- get_catalog('http://community.gencon.com/files/folders/pmcompletecatalogs/default.aspx')
- print 'Reading from disk...'
- mydir = 'Catalogs'
- filenames = listdir('.')
- if not mydir in filenames:
- mkdir(mydir)
- filenames = listdir(mydir)
- files = filter(lambda f:f.endswith('.pcl') and not f.endswith('schedule.pcl'),filenames)
- files.sort()
- column_titles = list()
- unique_entries = dict()
- events_byID = dict()
- for fn in files:
- print 'Loading from',fn
- infile = file(mydir + '/' + fn,'r')
- this_column_titles = pickle.load(infile)
- this_columntypes = pickle.load(infile)
- this_unique_entries = pickle.load(infile)
- this_events_byID = pickle.load(infile)
- infile.close()
- for i in range(len(this_column_titles)):
- ctitle = this_column_titles[i]
- if not ctitle in column_titles:
- column_titles.append(ctitle)
- if not unique_entries.has_key(i):
- unique_entries[i] = list()
- for entry in this_unique_entries[i]:
- if not entry in unique_entries[i]:
- unique_entries[i].append(entry)
- for eventID in this_events_byID:
- processed_event = list()
- this_file_event = this_events_byID[eventID]
- for i in range(len(column_titles)):
- item = this_unique_entries[i][this_file_event[i]]
- processed_event.append(unique_entries[i].index(item))
- events_byID[eventID] = processed_event
- if len(events_byID) == 0:
- print 'No events found.'
- print 'Unable to do anything without a valid event file!'
- exit(1)
- print len(events_byID),'total events'
- number_of_colums = len(column_titles)
- is_tournament_index = None
- can_register = None
- round_number_index = None
- total_rounds_index = None
- start_index = None
- end_index = None
- title_index = None
- desc_index = None
- long_desc_index = None
- type_index = None
- system_index = None
- rules_index = None
- company_index = None
- gm_index = None
- email_index = None
- webaddress_index = None
- age_index = None
- location_index = None
- room_index = None
- table_index = None
- modified_index = None
- tickets_available_index = None
- cost_index = None
- for i in range(number_of_colums):
- if 'room' in column_titles[i].lower():
- room_index = i
- if 'modified' in column_titles[i].lower():
- modified_index = i
- if 'location' in column_titles[i].lower():
- location_index = i
- if 'table' in column_titles[i].lower():
- table_index = i
- if 'title' in column_titles[i].lower():
- title_index = i
- if 'short desc' in column_titles[i].lower():
- desc_index = i
- if 'long desc' in column_titles[i].lower():
- long_desc_index = i
- if 'start ' in column_titles[i].lower():
- start_index = i
- if 'end ' in column_titles[i].lower():
- end_index = i
- if 'round number' in column_titles[i].lower():
- round_number_index = i
- if 'total rounds' in column_titles[i].lower():
- total_rounds_index = i
- if 'cost' in column_titles[i].lower():
- cost_index = i
- if 'tourn' in column_titles[i].lower():
- is_tournament_index = i
- if 'regist' in column_titles[i].lower():
- can_register = i
- if 'type' in column_titles[i].lower():
- type_index = i
- if 'system' in column_titles[i].lower():
- system_index = i
- if 'rules' in column_titles[i].lower():
- rules_index = i
- if 'edition' in column_titles[i].lower():
- edition_index = i
- if 'group' in column_titles[i].lower():
- company_index = i
- if 'company' in column_titles[i].lower():
- company_index = i
- if 'gm' in column_titles[i].lower():
- gm_index = i
- if 'email' in column_titles[i].lower():
- email_index = i
- if 'web' in column_titles[i].lower():
- webaddress_index = i
- if 'tickets ava' in column_titles[i].lower():
- tickets_available_index = i
- if 'age ' in column_titles[i].lower():
- age_index = i
- print
- print 'Event types found:'
- for i in range(len(unique_entries[type_index])):
- foo = len(filter(lambda e:events_byID[e][type_index] == i,events_byID.keys()))
- foo = str(foo)
- print ' ' * (5 - len(foo)),foo,
- print unique_entries[type_index][i]
- print
- VIG_events = list()
- tournament_prelim_events = list()
- tournament_final_events = list()
- tournament_generic_events = list()
- nontournament_prelim_events = list()
- nontournament_final_events = list()
- nontournament_generic_events = list()
- for eventID in events_byID.keys():
- event = events_byID[eventID]
- event_is_tournament = unique_entries[is_tournament_index][event[is_tournament_index]]
- event_can_register = unique_entries[can_register][event[can_register]]
- if 'VIG' in event_can_register:
- VIG_events.append(eventID)
- elif event_is_tournament:
- if event_can_register.lower().startswith('yes'):
- tournament_prelim_events.append(eventID)
- elif 'generic' in event_can_register.lower():
- tournament_generic_events.append(eventID)
- else:
- tournament_final_events.append(eventID)
- else:
- if event_can_register.lower().startswith('yes'):
- nontournament_prelim_events.append(eventID)
- elif 'generic' in event_can_register.lower():
- nontournament_generic_events.append(eventID)
- else:
- nontournament_final_events.append(eventID)
- events_canprereg = tournament_prelim_events + nontournament_prelim_events + nontournament_final_events
- events_generic = tournament_generic_events + nontournament_generic_events
- tournament_eventID = tournament_prelim_events + tournament_final_events + tournament_generic_events
- tournament_eventID.sort()
- events_following = dict()
- for eventID in tournament_eventID:
- #for eventID in events_byID.keys():
- event = events_byID[eventID]
- rounds_total = unique_entries[total_rounds_index][event[total_rounds_index]]
- round_number = unique_entries[round_number_index][event[round_number_index]]
- event_title = unique_entries[title_index][event[title_index]]
- event_desc = unique_entries[desc_index][event[desc_index]]
- if round_number < rounds_total:
- event_system = event[system_index]
- event_end = time.mktime(unique_entries[end_index][event[end_index]])
- event_company = event[company_index]
- #print unique_entries[system_index][event_system],
- #print unique_entries[company_index][event_company]
- #print
- #print eventID
- #print event_title
- #print event_desc
- #print round_number,
- #print rounds_total
- #print time.strftime('%A %I:%M%p',unique_entries[start_index][event[start_index]])
- proc_title = ''
- lastdigit = False
- skip = 0
- for c in event_desc.lower():
- if c.isalnum() or c == ':':
- proc_title = proc_title + c
- if c.isdigit():
- lastdigit = True
- else:
- lastdigit = False
- elif c == ' ':
- if not lastdigit:
- proc_title = proc_title + ' '
- elif c != '.':
- proc_title = proc_title + ' '
- lastdigit = False
- proc_title = proc_title.split()
- alldays = ['monday','tuesday','wednesday','thursday','friday','saturday','sunday']
- thisday = []
- thistime = []
- for item in proc_title:
- if item in alldays and item not in thisday:
- thisday.append(item)
- elif item == 'noon' or item == '12noon':
- thistime.append('12pm')
- elif (item.endswith('am') or item.endswith('pm')) and item[0].isdigit():
- thistime.append(item)
- #if len(thisday) = 0:
- # thisday = alldays
- #print thisday,thistime
- possible_following_events = dict()
- events_following[eventID] = list()
- #for aneventID in events_byID.keys():
- #for aneventID in tournament_prelim_events + tournament_final_events + tournament_generic_events:
- for aneventID in tournament_final_events + nontournament_final_events:
- timeok = True
- anevent = events_byID[aneventID]
- if len(thisday) != 0:
- timeok = False
- for item in thisday:
- timeok = timeok or item == time.strftime('%A',unique_entries[start_index][anevent[start_index]]).lower()
- if timeok and len(thistime) != 0:
- timeok = False
- for item in thistime:
- timeok = timeok or item == time.strftime('%I%p',unique_entries[start_index][anevent[start_index]]).lower().lstrip('0')
- timeok = timeok or item == time.strftime('%I:%M%p',unique_entries[start_index][anevent[start_index]]).lower().lstrip('0')
- if (timeok and anevent[system_index] == event_system and
- anevent[company_index] == event_company and
- time.mktime(unique_entries[start_index][anevent[start_index]]) >= event_end and
- #(event_desc != unique_entries[desc_index][anevent[desc_index]] or
- # event_title != unique_entries[title_index][anevent[title_index]]) and
- unique_entries[round_number_index][anevent[round_number_index]] > round_number and
- unique_entries[total_rounds_index][anevent[total_rounds_index]] == rounds_total and
- unique_entries[round_number_index][anevent[round_number_index]] >= round_number):
- #(unique_entries[total_rounds_index][anevent[total_rounds_index]] != rounds_total or
- #unique_entries[round_number_index][anevent[round_number_index]] != round_number)):
- rkey = str(int(unique_entries[round_number_index][anevent[round_number_index]]))# + '.' + \
- # str(int(unique_entries[total_rounds_index][anevent[total_rounds_index]]))
- if not possible_following_events.has_key(rkey):
- possible_following_events[rkey] = list()
- possible_following_events[rkey].append(aneventID)
- #possible_following_events[aneventID] = unique_entries[title_index][anevent[title_index]]
- best_final = dict()
- akeys = possible_following_events.keys()
- akeys.sort()
- for akey in akeys:
- best_score = 0
- best_final[akey] = list()
- for aneventID in possible_following_events[akey]:
- title = unique_entries[title_index][events_byID[aneventID][title_index]]
- maximum_match = max(map(lambda s:sum(map(lambda x,y:x == y,title,event_title[s:])),range(len(event_title))))
- maximum_match = max(maximum_match,
- max(map(lambda s:sum(map(lambda x,y:x == y,title[s:],event_title)),range(len(title)))))
- #print '\t',maximum_match,title
- if maximum_match > best_score:
- best_final[akey] = list()
- best_score = maximum_match
- if maximum_match == best_score:
- #if maximum_match >= 5:
- best_final[akey].append(aneventID)
- #print best_final
- #best_final_events = list()
- akeys = best_final.keys()
- akeys.sort()
- for akey in akeys:
- events_following[eventID].append(best_final[akey])
- ident_indices = [title_index,is_tournament_index,can_register,round_number_index,total_rounds_index,
- desc_index,type_index,system_index,rules_index,company_index]
- time_indices = [start_index,end_index,modified_index]
- line = ''
- command = ''
- foundevents = dict()
- schedule = list()
- #event_priority = list()
- list_start_offset = 0
- solved_events = None
- registered_events = list()
- showevents = list()
- #print unique_entries[can_register]
- while not command == 'quit':
- line = raw_input(">")
- linesplit = mysplit(line)
- #print linesplit
- command = linesplit[0].lower()
- arguments = linesplit[1:]
- startindex = 0
- endindex = -1
- if len(arguments) == 1:
- if '-' in arguments[0]:
- spl_arguments = arguments[0].split('-')
- if len(spl_arguments) == 2 and spl_arguments[0].isdigit() and spl_arguments[1].isdigit():
- startindex = int(spl_arguments[0])
- endindex = int(spl_arguments[1])
- elif arguments[0] == 'all':
- startindex = 1
- endindex = len(foundevents.keys())+1
- elif arguments[0].isdigit():
- startindex = int(arguments[0])
- endindex = startindex
- elif len(arguments) == 3:
- if arguments[0].isdigit() and arguments[1].lower() in ['-','to'] and arguments[2].isdigit():
- startindex = int(arguments[0])
- endindex = int(arguments[2])
- if command == 'find':
- foundevents = find_events(arguments)
- foundeventkeys = foundevents.keys()
- #if len(foundeventkeys) > 30:
- # showevents = foundeventkeys[:30]
- if len(foundeventkeys) == 0:
- print 'No matching events.'
- showevents = list()
- else:
- showevents = foundeventkeys
- showevents.sort(key = lambda eventID:unique_entries[start_index][events_byID[foundevents[eventID][0]][start_index]])
- index = 1
- for eventkey in showevents[:30]:
- events = foundevents[eventkey]
- eventkey_int = map(int,eventkey.split())
- print '#'+str(index)+':',unique_entries[title_index][eventkey_int[title_index]],
- if len(events) == 1:
- print
- else:
- print '('+str(len(events))+' events)'
- #for eventID in events:
- # print '\t',eventID
- #print
- index = index + 1
- if len(foundeventkeys) > 30:
- print len(foundeventkeys)-30,'more events found, type "more" to see more,'
- print '"add <number>" to add an event to your schedule, "browse" for detailed info'
- list_start_offset = 0
- elif command == 'more':
- list_start_offset += 30
- if list_start_offset > len(showevents):
- print 'No more events to show'
- else:
- for eventkey in showevents[list_start_offset:list_start_offset+30]:
- events = foundevents[eventkey]
- eventkey_int = map(int,eventkey.split())
- print '#'+str(index)+':',unique_entries[title_index][eventkey_int[title_index]],
- if len(events) == 1:
- print
- else:
- print '('+str(len(events))+' events)'
- #for eventID in events:
- # print '\t',eventID
- #print
- index = index + 1
- if len(foundeventkeys) > list_start_offset+30:
- print len(foundeventkeys)-(list_start_offset+30),'more events found, type "more" to see more.'
- print '"add <number>" to add an event to your schedule, "browse" for detailed info'
- elif command == 'browse':
- list_start_offset = 0
- done = False
- while not done:
- if list_start_offset >= len(foundeventkeys):
- done = True
- else:
- eventkey = showevents[list_start_offset]
- events = foundevents[eventkey]
- eventkey_int = map(int,eventkey.split())
- print
- print_nicely_formatted(unique_entries[title_index][eventkey_int[title_index]],80)
- print_nicely_formatted(unique_entries[desc_index][eventkey_int[desc_index]],80)
- if eventkey_int[long_desc_index] >= 0:
- print_nicely_formatted(unique_entries[long_desc_index][eventkey_int[long_desc_index]],80)
- #print unique_entries[desc_index][eventkey_int[desc_index]]
- if len(events) == 1:
- event_ID = events[0]
- print event_ID,
- this_event = events_byID[event_ID]
- event_start = unique_entries[start_index][this_event[start_index]]
- event_end = unique_entries[end_index][this_event[end_index]]
- print time.strftime('%A %I:%M%p',event_start),'-',
- if time.strftime('%A',event_start) == time.strftime('%A',event_end):
- print time.strftime('%I:%M%p',event_end)
- else:
- print time.strftime('%A %I:%M%p',event_end)
- else:
- print '('+str(len(events))+' events)'
- #print location_index,room_index,table_index
- #print eventkey_int[location_index],eventkey_int[room_index],eventkey_int[table_index]
- if eventkey_int[location_index] != -1:
- print unique_entries[location_index][eventkey_int[location_index]],
- if eventkey_int[room_index] != -1:
- print unique_entries[room_index][eventkey_int[room_index]],
- if eventkey_int[table_index] != -1:
- print unique_entries[table_index][eventkey_int[table_index]]
- if eventkey_int[system_index] != -1:
- print unique_entries[system_index][eventkey_int[system_index]],
- if eventkey_int[rules_index] != -1:
- print unique_entries[rules_index][eventkey_int[rules_index]]+',',
- if eventkey_int[company_index] != -1:
- print unique_entries[company_index][eventkey_int[company_index]]+',',
- if eventkey_int[gm_index] != -1:
- print unique_entries[gm_index][eventkey_int[gm_index]],
- print
- if eventkey_int[cost_index] != -1:
- print 'Event cost:',
- print str(unique_entries[cost_index][eventkey_int[cost_index]]) + ',',
- tickets_remaining = 0
- for event_ID in events:
- this_event = events_byID[event_ID]
- tickets_remaining = tickets_remaining + unique_entries[tickets_available_index][this_event[tickets_available_index]]
- print int(tickets_remaining),
- print "tickets remaining"
- list_start_offset = list_start_offset + 1
- already_have = False
- for s in schedule:
- if len(s[1]) == len(events) and all(map(lambda e:e in s[1],events)):
- already_have = True
- #schedule = filter(lambda s:eventID not in s[1],schedule)
- if already_have:
- print 'Already in schedule, moving on...'
- else:
- reply = raw_input("Add/continue?")
- if reply.lower().startswith('n') or reply.lower().startswith('q'):
- done = True
- elif reply.lower().startswith('y') or reply.lower().startswith('q'):
- priority = raw_input('Priority for '+unique_entries[title_index][eventkey_int[title_index]]+'?')
- if priority.isdigit():
- priority = int(priority)
- if priority < 0:
- priority = 0
- elif priority > 10:
- priority = 10
- schedule.append((priority,foundevents[eventkey]))
- #schedule.append((priority,unique_entries[title_index][eventkey_int[title_index]]))
- #event_priority.append(priority)
- if events_following.has_key(events[0]):
- print "Note:",unique_entries[title_index][eventkey_int[title_index]],
- print "is start of a tournament, will attempt to link rest of tournament events to it."
- elif command == 'show':
- for i in range(startindex - 1,endindex):
- if i >= 0 and i < len(showevents):
- eventkey = map(int,showevents[i].split())
- events = foundevents[showevents[i]]
- #eventkey = map(int,foundevents.keys()[i].split())
- for j in range(len(eventkey)):
- if eventkey[j] > -1 and j not in time_indices:
- print column_titles[j] + ':',unique_entries[j][eventkey[j]]
- for eventID in events:
- print '\t',eventID,
- print time.strftime('%A %I:%M%p',unique_entries[start_index][events_byID[eventID][start_index]]),'-',
- print time.strftime('%A %I:%M%p',unique_entries[end_index][events_byID[eventID][end_index]])
- print
- #print eventkey
- elif command in ['add','got']:
- if len(arguments)>0 and events_byID.has_key(arguments[0]):
- eventID = arguments[0]
- priority = raw_input('Priority for '+eventID+'?')
- if priority.isdigit():
- schedule = filter(lambda s:eventID not in s[1],schedule)
- priority = int(priority)
- if priority < 0:
- priority = 0
- elif priority > 10:
- priority = 10
- schedule.append((priority,[eventID]))
- if events_following.has_key(eventID):
- print "Note:",eventID,
- print " is start of a tournament, will attempt to link rest of tournament events to it."
- else:
- for i in range(startindex - 1,endindex):
- if i >= 0 and i < len(foundevents.keys()):
- eventkey_int = map(int,showevents[i].split())
- priority = raw_input('Priority for '+unique_entries[title_index][eventkey_int[title_index]]+'?')
- if priority.isdigit():
- priority = int(priority)
- if priority < 0:
- priority = 0
- elif priority > 10:
- priority = 10
- schedule.append((priority,foundevents[showevents[i]]))
- if events_following.has_key(foundevents[showevents[i]][0]):
- print "Note:",unique_entries[title_index][eventkey_int[title_index]],
- print "is start of a tournament, will attempt to link rest of tournament events to it."
- elif command == 'list':
- index = 1
- schedule.sort(reverse = True)
- for index in range(len(schedule)):
- events = schedule[index][1]
- print '#'+str(index+1)+':',
- print unique_entries[title_index][events_byID[events[0]][title_index]],
- if len(events) > 1:
- print '('+str(len(events))+' events)',
- else:
- print events[0],
- print schedule[index][0]
- elif command in ['change']:
- if startindex <= endindex:
- changing_events = schedule[startindex - 1:endindex]
- schedule = schedule[:startindex - 1]+schedule[endindex:]
- for anevent_info in changing_events:
- anevent = events_byID[anevent_info[1][0]]
- priority = raw_input('Priority for '+unique_entries[title_index][anevent[title_index]]+'?')
- newevent_info = anevent_info
- if priority.isdigit():
- priority = int(priority)
- if priority < 0:
- priority = 0
- elif priority > 10:
- priority = 10
- newevent_info = (priority,anevent_info[1])
- schedule.append(newevent_info)
- elif command in ['combine','merge']:
- if startindex <= endindex:
- combinedevents = list()
- priority = schedule[startindex][0]
- for anevent_info in schedule[startindex - 1:endindex]:
- combinedevents = combinedevents + anevent_info[1]
- schedule = schedule[:startindex - 1]+schedule[endindex:]
- newevent_info = (priority,combinedevents)
- schedule.append(newevent_info)
- elif command in ['del','remove']:
- if len(arguments)>0 and events_byID.has_key(arguments[0]):
- eventID = arguments[0]
- schedule = map(lambda s:(s[0],filter(lambda e:e != eventID,s[1])),schedule)
- #print schedule
- schedule = filter(lambda s:len(s[1])>0,schedule)
- elif startindex <= endindex:
- schedule = schedule[:startindex - 1]+schedule[endindex:]
- #event_priority = event_priority[:startindex - 1]+event_priority[endindex:]
- elif command == 'solve':
- registered_events = list()
- solved_events = None
- all_solved_events = solve_schedule(schedule)
- if startindex > endindex:
- if all_solved_events and len(all_solved_events) > 0:
- solved_events = all_solved_events[0][1]
- if solved_events != None:
- print 'Schedules calculated.'
- print
- reply = raw_input('Proceed to registration?')
- if reply.lower().startswith('y'):
- events_remaining = True
- while events_remaining and all_solved_events != None:
- print "Calculating wish list..."
- print
- fail_check_events = list()
- #fail_check_list = list()
- #schedules_tocheck = [all_solved_events[0][1]]
- fully_solved_schedules = list()
- #while len(schedules_tocheck) > 0:
- for a_schedule in all_solved_events:
- #for a_schedule in schedules_tocheck:
- these_fail_check_events = list()
- for eventID in a_schedule[1]:
- if not eventID in fail_check_events+registered_events:
- thisevent = events_byID[eventID]
- if (int(float(unique_entries[cost_index][thisevent[cost_index]])) > 0 and
- not unique_entries[can_register][thisevent[can_register]].lower().startswith('no')):
- these_fail_check_events.append(eventID)
- #these_fail_check_events.sort(key = lambda e:
- # int(float(unique_entries[tickets_available_index][events_byID[e][tickets_available_index]])))
- if len(these_fail_check_events) == 0:
- fully_solved_schedules.append(a_schedule)
- else:
- these_fail_check_events.sort(key = lambda e:max(map(lambda s:(e in s[1]) and len(s[1]),schedule)))
- #these_fail_check_events.reverse()
- for eventID in these_fail_check_events:
- #print eventID
- fail_check_events.append(eventID)
- fully_solved_schedules.sort(reverse = True)
- solved_events = fully_solved_schedules[0][1]
- if fully_solved_schedules[0] == all_solved_events[0]:
- fail_check_events = list()
- if len(registered_events) > 0:
- print 'Registered events:'
- for eventID in registered_events:
- print eventID+' ('+unique_entries[title_index][events_byID[eventID][title_index]]+')'
- print
- if len(fail_check_events) > 0:
- event_priority = 1
- fail_check_events = fail_check_events[:20]
- print 'Wish list is as follows:'
- for eventID in fail_check_events:
- print event_priority,eventID+' ('+unique_entries[title_index][events_byID[eventID][title_index]]+')'
- event_priority = event_priority + 1
- #print unique_entries[can_register][events_byID[eventID][can_register]]
- print 'Enter wish list in registration site now and submit form.'
- print
- #full_events = list()
- for eventID in fail_check_events:
- reply = raw_input('Did we get '+eventID+'?')
- if reply.lower().startswith('y'):
- registered_events.append(eventID)
- #schedule = filter(lambda s:eventID not in s[1],schedule)
- #schedule.append((10,[eventID]))
- else:
- schedule = map(lambda s:(s[0],filter(lambda e:e != eventID,s[1])),schedule)
- schedule = filter(lambda s:len(s[1]) > 0,schedule)
- print
- print 'Recalculating schedule now...'
- print
- solved_events = None
- all_solved_events = solve_schedule(schedule)
- if all_solved_events and len(all_solved_events) > 0:
- solved_events = all_solved_events[0][1]
- else:
- events_remaining = False
- if solved_events != None:
- drop_events = list()
- for eventID in registered_events:
- if not eventID in solved_events:
- drop_events.append(eventID)
- if len(drop_events) > 0:
- print 'Now remove the following events from your cart:'
- for eventID in drop_events:
- print eventID
- registered_events.remove(eventID)
- reply = raw_input('(Press Enter when finished)')
- print
- solved_events.sort(key = lambda eventID:unique_entries[start_index][events_byID[eventID][start_index]])
- last_day = None
- for eventID in solved_events:
- if eventID in registered_events:
- schedule = filter(lambda s:eventID not in s[1],schedule)
- schedule.append((10,[eventID]))
- thisevent = events_byID[eventID]
- start_time = unique_entries[start_index][thisevent[start_index]]
- end_time = unique_entries[end_index][thisevent[end_index]]
- if last_day != time.strftime('%A',start_time):
- print
- print time.strftime('%A %d %B %Y',start_time)
- print
- last_day = time.strftime('%A',start_time)
- print_nicely_formatted(eventID + ': ' + unique_entries[title_index][thisevent[title_index]],80)
- whenst = time.strftime('%A %I:%M%p',start_time) + '-'
- if time.strftime('%A',end_time) != last_day:
- whenst = whenst + time.strftime('%A %I:%M%p',end_time)
- else:
- whenst = whenst + time.strftime('%I:%M%p',end_time)
- wherest = ' '.join([unique_entries[location_index][thisevent[location_index]],
- unique_entries[room_index][thisevent[room_index]],
- unique_entries[table_index][thisevent[table_index]]])
- print_nicely_formatted(whenst + ', ' + wherest,80)
- event_desc = unique_entries[desc_index][thisevent[desc_index]]
- print_nicely_formatted(event_desc,80)
- whost = ''
- #print whost
- if len(unique_entries[gm_index][thisevent[gm_index]]) > 0:
- whost = whost + unique_entries[gm_index][thisevent[gm_index]] + ', '
- #print whost,unique_entries[company_index][thisevent[company_index]]
- whost = whost + unique_entries[company_index][thisevent[company_index]]
- whost = ' '.join(map(lambda s:s.capitalize(),whost.split()))
- if unique_entries[cost_index][thisevent[cost_index]] > 0:
- whost = whost + ' $'+str(unique_entries[cost_index][thisevent[cost_index]])
- print_nicely_formatted(whost,80)
- #print unique_entries[webaddress_index][thisevent[webaddress_index]],
- #print unique_entries[email_index][thisevent[email_index]]
- #print 'Tickets available:',
- #print unique_entries[tickets_available_index][thisevent[tickets_available_index]],
- #print 'Event cost:',
- #print unique_entries[cost_index][thisevent[cost_index]]
- print
- #if events_following.has_key(eventID):
- # print events_following[eventID]
- print
- else:
- print "Unable to solve schedule - incompatible mandatory events! Remove some or reduce priority below 10."
- else:
- if all_solved_events and len(all_solved_events) > 0:
- print 'Schedules calculated.'
- print
- for solved_event_info in all_solved_events[startindex - 1:endindex]:
- solved_events = solved_event_info[1]
- solved_events.sort(key = lambda eventID:unique_entries[start_index][events_byID[eventID][start_index]])
- print 'Score:',solved_event_info[0]
- for eventID in solved_events:
- if eventID in registered_events:
- schedule = filter(lambda s:eventID not in s[1],schedule)
- schedule.append((10,[eventID]))
- thisevent = events_byID[eventID]
- start_time = unique_entries[start_index][thisevent[start_index]]
- end_time = unique_entries[end_index][thisevent[end_index]]
- whenst = time.strftime('%A %I:%M%p',start_time) + '-'
- whenst = whenst + time.strftime('%A %I:%M%p',end_time)
- wherest = ' '.join([unique_entries[location_index][thisevent[location_index]],
- unique_entries[room_index][thisevent[room_index]],
- unique_entries[table_index][thisevent[table_index]]])
- if len(unique_entries[title_index][thisevent[title_index]]) > 25:
- print_nicely_formatted(whenst + ' ' + eventID + ': ' + unique_entries[title_index][thisevent[title_index]][:22] + '..., ' + wherest,80)
- else:
- print_nicely_formatted(whenst + ' ' + eventID + ': ' + unique_entries[title_index][thisevent[title_index]] + ', ' + wherest,80)
- print
- else:
- print "Unable to solve schedule - incompatible mandatory events! Remove some or reduce priority below 10."
- elif command == 'save':
- if len(arguments) > 0:
- print 'Saving to disk...'
- outfile = file(mydir + '/' + arguments[0] + '_schedule.pcl','w')
- pickle.dump(schedule,outfile)
- outfile.close()
- else:
- print "Not saved, file name needed"
- elif command == 'load':
- if len(arguments) > 0:
- print 'Loading from disk...'
- try:
- infile = file(mydir + '/' + arguments[0] + '_schedule.pcl','r')
- schedule = pickle.load(infile)
- infile.close()
- schedule = map(lambda s:(s[0],filter(lambda e:events_byID.has_key(e),s[1])),schedule)
- schedule = filter(lambda s:len(s[1])>0,schedule)
- except IOError:
- print arguments[0] + '_schedule.pcl not found.'
- schedule = list()
- else:
- print "Not loaded, file name needed"
- elif command == '?' or command == 'help':
- if len(arguments) == 0:
- print "Commands:"
- print
- print "quit - exits this program"
- print "find <keywords> - searches the list of events for matches"
- print "more - lists next 30 found events"
- print "browse - views list of found events in detail one by one"
- print "show # - shows full details on one event"
- print "add # - adds an event from found event list to wishlist"
- print "list - shows your current wishlist"
- print "change # - changes the priority of an item on your wishlist"
- print "merge # - combines two items on wishlist into single item"
- print "del # - removes an item from your wishlist"
- print "solve - solves for best schedules, optionally proceeds to registration"
- print "save <filename> - saves current wishlist to a file"
- print "load <filename> - loads current wishlist from a file"
- print "help <command> - more detailed information on that command"
- print
- print "Commands are not case-sensitive"
- elif arguments[0] == 'find':
- print 'save <keywords>'
- print
- print 'This searches the list of events according to keywords'
- print 'Accepted keywords are any, all, on, in, at, by, before, after, type, not, age'
- print
- print 'Keyword functions:'
- print
- print 'Any, All - followed by a word this searches for all events which contain that word in their'
- print 'title or description. For example, "Find all NASCRAG". You can also omit the keyword for'
- print 'this case and just type "Find NASCRAG"/'
- print
- print 'on - searches for events by day'
- print ' for example, "find on saturday"'
- print
- print 'in - searches for events by location'
- print ' for example, "find in hyatt"'
- print
- print 'by - searches for events by company or group'
- print ' for example, "find by gamebase7"'
- print
- print 'before - searches for events which take place before a certain time'
- print ' for example, "find before 10pm"'
- print
- print 'after - searches for events which take place after a certain time'
- print ' for example, "find after 10am"'
- print
- print 'type - searches by the prefix/type code of the event'
- print ' for example, "find type RPGA"'
- print
- print 'not - inverts action of following keywords'
- print ' for example, "find not on sunday"'
- print
- print 'age - searches by event age restriction'
- print ' for example, "find age 21+"'
- print
- print 'Multiple keyword searches can be combines into a single search line'
- print ' for example, "find sparks by gamebase7 after 1pm not on thursday"'
- print
- print 'This command will return a numbered list of all events matching the search terms'
- print 'and will display the first 30 matches'
- elif arguments[0] == 'more':
- print 'more'
- print
- print 'The command Find will only show the first 30 event matches'
- print 'Typing "more" will then show the next 30 matches'
- elif arguments[0] == 'browse':
- print 'browse'
- print
- print 'After running the find command to generate a list of matches, the browse command'
- print 'will show each matching event one by one in detail, and for each one give the option to add'
- print 'that event to your wish list'
- print
- print 'When you add an item to your wish list, you will be asked for a priority number, which'
- print 'should be a number from 1-10. A priority of 10 indicates a must-have event - the script'
- print 'will reject any calendar which does not include that event. Lower priority events will'
- print 'be added as possible in order of their priority number'
- elif arguments[0] == 'show':
- print 'show #'
- print
- print 'After running the find command to generate a list of matches, the show command will'
- print 'give you all the details of an item on the list.'
- elif arguments[0] == 'add':
- print 'show #'
- print
- print 'After running the find command to generate a list of matches, the add command will'
- print 'allow you to add a single entry from the list to your wishlist.'
- print
- print 'When you add an item to your wish list, you will be asked for a priority number, which'
- print 'should be a number from 1-10. A priority of 10 indicates a must-have event - the script'
- print 'will reject any calendar which does not include that event. Lower priority events will'
- print 'be added as possible in order of their priority number'
- elif arguments[0] == 'list':
- print 'list'
- print
- print 'This command shows your wishlist so far, giving you an index list of event name,'
- print 'event number or number of event slots, and priority'
- elif arguments[0] == 'change':
- print 'change #'
- print
- print 'After running the list command, this command allows you to change the priority of'
- print 'any entry on the wishlist.'
- elif arguments[0] == 'merge':
- print 'merge #'
- print
- print 'This is a semi-experimental command which allows you to combine two items on your wishlist'
- print 'This is used primarily for merging two items which are the same event but weren\'t properly'
- print 'combined by the catelog parses. To use this, add both the events you want to combine to'
- print 'your wishlist, giving them both the same priority so they will show up as adjacent items.'
- print 'Then use the merge command to join them, for example merge 4-5 if they are items 4 and 5.'
- print 'This can also be used when you have a situation where you want to go to either event A or'
- print 'event B but not both, by merging them into a single event with multiple slots.'
- elif arguments[0] == 'del':
- print 'del #'
- print
- print 'After running the list command, this command allows you to remove any one item from your'
- print 'wishlist.'
- elif arguments[0] == 'solve':
- print 'solve'
- print
- print 'This command attempts to derive an optimal schedule from your wishlist. This command takes'
- print 'into account all of the events you have selected, and the priority which you have assigned'
- print 'to each one. It then builds a list of all possible schedule combinations and then ranks'
- print 'them by desirability. When doing so it attempts to get in as many events as possible, but'
- print 'also prefers events in the afternoon or evening over those very late or early, and when'
- print 'possible tries to give you at least 15 minutes between events.'
- print
- print 'After the schedules are produced, you will be given the option to proceed to registration.'
- print 'The script does not fill out the Gencon registration page for you, you have to do that'
- print 'manually.'
- print 'However, it will give you a list of event IDs to enter. Do not be alarmed if you see'
- print 'muliple conflicting events in the event ID list - the script takes a greedy approach where'
- print 'it has you register for all event slots you might want, then depending on which ones you get'
- print 'has you drop some of them later. Just follow the instructions the script prints out, and'
- print 'follow the prompts to tell the script which slots you actually managed to get. When that is'
- print 'done, the script will generate a finished schedule for you to copy and print out.'
- print
- print 'The script does not instruct you to register for free events that do not requie pre-reg,'
- print 'such as seminars. You should probably register for them anyway afterwards.'
- print
- print 'The script attempts to take tournament structure into account. If you register for the'
- print 'first part of a tournament, it will attempt to find the other parts of the tournament and'
- print 'add them to your schedule. This doesn\'t always work.'
- print
- print 'If you answer no to the prompt to proceed to registration, the script will then just print'
- print 'out your optimal schedule - the one you\'ll have if you manage to get every event you try to'
- print 'register for.'
- elif arguments[0] == 'save':
- print 'save <filename>'
- print
- print 'This command immedately saves the current wishlist to a file indicated by the filename'
- print 'This overwrites any existing file of that name without warning.'
- elif arguments[0] == 'load':
- print 'save <filename>'
- print
- print 'This command immedately loads the wishlist from a file indicated by the filename'
- print 'This overwrites the curent wishlist without warning.'
- else:
- print 'No help available for',arguments[0]
- elif command == 'quit' or command == '':
- pass
- else:
- print 'Unrecognized command:',command
Add Comment
Please, Sign In to add comment