Created
April 22, 2014 12:51
-
-
Save lucasg/11177852 to your computer and use it in GitHub Desktop.
Worksheet generation for stackoverflow question (using python)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import chain | |
import random | |
import json | |
import xlwt | |
''' | |
Constraints needed to be fullfilled | |
''' | |
scenarios = { | |
# Typical scenario : at least one player in each positions | |
"ok" : [ "Goalkeeper", | |
"Centre back", | |
"Wing", | |
"Centre midfield", | |
"Wide", | |
"Centre forward", | |
"Winger" | |
] , | |
# Warning situations : it might be tricky, but we can play (no wide defensive player for example) | |
"no_wing_def" : [ "Goalkeeper", | |
"Centre back", | |
"Centre midfield", | |
"Wide", | |
"Centre forward", | |
"Winger" | |
] , | |
"no_centre_mid" : [ "Goalkeeper", | |
"Centre back", | |
"Wing", | |
"Wide", | |
"Centre forward", | |
"Winger" | |
] , | |
# Error situations : impossible to play in those situations | |
"no_defense_1" : ["Goalkeeper", "Centre midfield", "Centre forward" ] , | |
"no_defense_2" : ["Goalkeeper", "Centre midfield", "Winger" ] , | |
"no_defense_3" : ["Goalkeeper", "Wide", "Centre forward" ] , | |
"no_defense_4" : ["Goalkeeper", "Wide", "Winger" ] , | |
"no_attack_1" : ["Goalkeeper", "Centre midfield", "Centre back", ] , | |
"no_attack_2" : ["Goalkeeper", "Centre midfield", "Centre back" ] , | |
"no_attack_3" : ["Goalkeeper", "Wide","Wing" ] , | |
"no_attack_4" : ["Goalkeeper", "Wide", "Wing" ] , | |
"no_goal_keeper" : [ ] | |
} | |
''' | |
the constraints are ordered : the first constraint to be matched is the one returned. | |
''' | |
order_scenario = ["ok","no_wing_def","no_centre_mid","no_defense_1","no_defense_2","no_defense_3","no_defense_4","no_attack_1","no_attack_2","no_attack_3","no_attack_4","no_goal_keeper"] | |
''' | |
Styles of playing in every section (defense, mid and attack). | |
Every player has a mandatory style, and some have two. | |
''' | |
styles = { | |
"Goalkeeper" : ["Goalkeeper"], | |
"Defender" : | |
[ | |
"Centre back", | |
"Wing" | |
], | |
"Midfielder" : | |
[ | |
"Centre midfield", | |
"Wide" | |
], | |
"Forward" : | |
[ | |
"Centre forward", | |
"Winger" | |
] | |
} | |
''' | |
Pool of players which will be present or absent at some matchs. | |
''' | |
players = { | |
"Goalkeeper" : 2, | |
"Defender" : 5, | |
"Midfielder" : 7, | |
"Forward" : 4 | |
} | |
''' | |
Example of players availables, with their possible positions. | |
''' | |
example_players = { | |
"Forward": [ | |
[1, "Winger"], | |
[2, "Winger"], | |
[3, "Centre forward"], | |
[4, "Centre forward"] | |
], | |
"Defender": [ | |
[5, "Centre back"], | |
[6, "Centre back", "Wing"], | |
[7, "Centre back", "Wing"], | |
[8, "Wing"], | |
[9, "Centre back"] | |
], | |
"Goalkeeper": [ | |
[10, "Goalkeeper"], | |
[11, "Goalkeeper"] | |
], | |
"Midfielder": [ | |
[12, "Centre midfield"], | |
[13, "Centre midfield"], | |
[14, "Wide", "Centre midfield"], | |
[15, "Centre midfield"], | |
[16, "Centre midfield"], | |
[17, "Wide", "Centre midfield"], | |
[18, "Wide", "Centre midfield"] | |
] | |
} | |
''' | |
Return the positions playable by the id_player | |
''' | |
def pos_player(styled_players,id_player): | |
def flatten_dict_values(dictionary): | |
return chain(*dictionary.values()) | |
return [val for val in flatten_dict_values(styled_players)][id_player - 1][1:] | |
def validate_team(presence_list, styled_players, order_scenario, scenarios): | |
set_of_positions_available = [] | |
#Construct the set of positions given by the players present at one match | |
for player in range(len(presence_list)): | |
if presence_list[player] == 'present': | |
for pos in pos_player(styled_players, player + 1 ): | |
set_of_positions_available.append( pos ) | |
# remove duplicate | |
set_of_positions_available = set(set_of_positions_available) | |
print set_of_positions_available | |
for scenario_name in order_scenario: | |
# test for superset | |
if set_of_positions_available.issuperset( set(scenarios[scenario_name]) ): | |
return scenario_name | |
return 'error' | |
def generate_styled_players( players ): | |
id_player = 0x01 | |
group = {} | |
for positions in players: | |
styled_players = [] | |
# Special case for goalkeeping | |
if positions == "Goalkeeper": | |
for i in range(players[positions]): | |
styled_players.append([id_player,"Goalkeeper"]) | |
id_player+=1 | |
# normal case | |
else: | |
for i in range(players[positions]): | |
player = [id_player] | |
id_player+=1 | |
# Add mandatory position (0 or 1) | |
mandatory_position = random.randint(0,1) | |
player.append( styles[positions][mandatory_position] ) | |
# 30% chance of getting a second position | |
second_position_throw = random.randint(0,100) | |
if second_position_throw > 70: | |
player.append( styles[positions][ 1 - mandatory_position] ) | |
styled_players.append(player) | |
group[positions] = styled_players | |
return group | |
def generate_events(styled_players): | |
choice = ('absent','present') | |
events = [] | |
for i in xrange(100): | |
events.append( [ choice[random.randint(0,100) > 45 ] for j in range(1,19) ] ) | |
return events | |
def gen_excel_input_data(events, styled_players): | |
row, col = 0, 0 | |
wb = xlwt.Workbook() | |
ws_const = wb.add_sheet("constraints") | |
ws_players = wb.add_sheet("players") | |
ws_events = wb.add_sheet("events") | |
# constraint scenario | |
for col,scenario_name in enumerate(order_scenario): | |
ws_const.write(0, col, scenario_name ) | |
for row, data in enumerate(scenarios[scenario_name]): | |
ws_const.write(row+1, col, data ) | |
# players worksheet | |
row = 0 | |
for positions in styled_players: | |
for player in styled_players[positions]: | |
for idx,data in enumerate(player): | |
ws_players.write(row, idx, str(data) ) | |
row +=1 | |
# Event worksheet | |
for col in range(len(events[0])): | |
ws_events.write(0, col, "player #"+str(col+1) ) | |
for row in range(len(events)): | |
for col in range(len(events[row])): | |
ws_events.write(row+1, col, events[row][col] ) | |
#validation | |
validation_col = len(events[0])+1 | |
ws_events.write(0, validation_col , "validate team" ) | |
for row in range(len(events)): | |
ws_events.write(row+1, validation_col, validate_team(events[row], styled_players, order_scenario, scenarios) ) | |
wb.save('input_data.xls') | |
if __name__ == '__main__': | |
random.seed() | |
# Pool generation | |
styled_players = generate_styled_players(players) | |
#print json.dumps(styled_players, indent=4, sort_keys=True) | |
# Events generation | |
events = generate_events(styled_players) | |
# print events | |
# write to excel | |
gen_excel_input_data(events, styled_players) | |
print pos_player(styled_players, 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment