Ejemplo n.º 1
0
def _print_qualifying_times(qt_by_event, heading, do_conversion):
    print('<table><tbody><tr class="' + heading.lower() + '"><th>' + heading +
          '</th>')
    for age in range(min_age, max_age + 1):
        print('<th>' + str(age) + '</th>')
    print('</tr>')
    course_code = "S"
    if is_long_course:
        course_code = "L"
    num_events = len(short_course_events)
    precision = 2
    if do_conversion:
        precision = 1
    for event_code in range(num_events):
        times = qt_by_event[event_code]
        if times is not None:
            event = Event.create_from_code(event_code, course_code)
            print('<tr class="' + event.short_stroke_name().lower() +
                  '"><td>' + event.short_name_without_course() + '</td>')
            for time in times:
                converted_time = time
                if do_conversion:
                    converted_time = event.convert_time(time)
                print('<td>' +
                      str(RaceTime(converted_time, precision=precision)) +
                      '</td>')
            print('</tr>')
    print('</tbody></table>')
Ejemplo n.º 2
0
def write_scores(sorted_scores, file_name):
    print('Writing file')
    scores_file = open(folder + file_name, 'w')
    number = 0
    held_number = 0
    previous_points = 0
    for swimmer_times in sorted_scores:
        number = number + 1
        if swimmer_times.points != previous_points:
            held_number = number
        previous_points = swimmer_times.points
        swimmer = swimmer_times.swimmer
        age_for_points = swimmer_times.age
        if age_for_points > 16:
            age_for_points = 16
        age_column = age_for_points - 9
        scores_file.write('<p class="question">')
        scores_file.write(
            str(held_number) + ': ' + swimmer_times.full_name + ' (' +
            str(swimmer_times.points) + ' points)')
        scores_file.write('</p>\n')
        scores_file.write(
            '<div class="answer"><table><tr><th>Event</th><th>Consideration Time</th><th>Race Time</th><th>Points</th></tr>\n'
        )
        for race in swimmer_times.race_by_event:
            if (race is not None) and (race.time is not None):
                scores_file.write('<tr><td>' +
                                  race.event.short_name_without_course() +
                                  '</td>')
                if race.consideration_time is not None:
                    nt_str = ''
                    if race.consideration_is_nt:
                        nt_str = '(NT) '
                    scores_file.write('<td>' + nt_str +
                                      str(RaceTime(race.consideration_time)) +
                                      '</td>')
                else:
                    scores_file.write('<td>Missing Consideration Time</td>')
                scores_file.write('<td>' + str(RaceTime(race.time)) + '</td>')
                scores_file.write('<td>' + str(race.points) + '</td>')
                scores_file.write('</tr>\n')
        scores_file.write('</table></div>\n')
    scores_file.close()
Ejemplo n.º 3
0
    def report(self, file, team, team_name):
        relay = ()
        result = ''
        show_splits = True
        if self.finish_position == -2:
            result = 'DNC'
            show_splits = False
        elif self.finish_position == -1:
            result = 'DQ'
            show_splits = False
        else:
            result = str(RaceTime(self.finish_time))
            show_splits = len(self.splits) > 1

        if len(team.legs) != 1:
            # Relay or DNS or DQ
            file.write(
                '<tr class="team"><th colspan="3">{:}</th><td>{:}</td><td>{:}</td></tr>\n'
                .format(team_name, result, self.points))
            if show_splits:
                if len(team.legs) <= 4:
                    # Also write out the swimmer names
                    file.write('<tr class="splits">')
                    for swimmer in team.legs:
                        file.write('<td>{:}</td>'.format(swimmer.full_name))
                    file.write('</tr>\n')
                file.write('<tr class="splits">')
                for split in self.splits:
                    file.write('<td>{:}</td>'.format(str(RaceTime(split))))
                file.write('</tr>\n')
        else:
            # Individual
            file.write(
                '<tr class="team"><th>{:}</th><td colspan="2">{:}</td><td>{:}</td><td>{:}</td></tr>\n'
                .format(team_name, team.legs[0].full_name, result,
                        self.points))
            if show_splits:
                file.write('<tr class="splits">')
                for split in self.splits:
                    file.write('<td>{:}</td>'.format(str(RaceTime(split))))
                file.write('</tr>\n')
Ejemplo n.º 4
0
    def __init__(self, line):
        tokens = line.split("|")
        num_tokens = len(tokens)
        assert ((num_tokens == 2) or (num_tokens == 3))

        self.event_code = Event.create_from_str(
            tokens[0], "S").get_short_course_event_code()
        self.time = float(RaceTime(tokens[1]))
        if num_tokens == 3:
            self.is_nt = (tokens[2] == 'nt\n')
        else:
            self.is_nt = False
Ejemplo n.º 5
0
    def __init__(self, asa_number, event, tokens):
        token_offset = 0
        if len(tokens) == 6:
            token_offset = 1
        self.asa_number = asa_number
        self.event = event
        self.date = helpers.ParseDate_dmY(tokens[token_offset])
        self.meet = tokens[token_offset + 1].strip()
        self.asa_swim_id = 0
        self.splits = None
        self.level = int(tokens[token_offset + 3])
        self.race_time = float(RaceTime(tokens[token_offset + 4]))

        self.short_course_race_time = self.race_time
        if self.event.is_long_course():
            self.short_course_race_time = self.event.convert_time(
                self.race_time)
Ejemplo n.º 6
0
def _parse_spreadsheet_data( spreadsheet_data ):
  rows = spreadsheet_data.split( '\n' )

  num_events = len( short_course_events )
  nt_times_by_event = [ None ] * num_events
  
  for row in rows:
    columns = row.split( '\t' )
    # Parse the event name
    event_code = Event.create_from_str( columns[0], 'S' ).event_code
    if len( columns ) != 9:
      raise RuntimeError( "Unexpected number of columns in spreadsheet data" )
    nt_times_for_event = []
    nt_times_by_event[ event_code ] = nt_times_for_event
    for i in range( 1, 9 ):
      if len( columns[i] ) == 0:
        nt_times_for_event.append( None )
      else:
        nt_times_for_event.append( float( RaceTime( columns[i] ) ) )
  return nt_times_by_event
Ejemplo n.º 7
0
def _parse_spreadsheet_data(spreadsheet_data):
    rows = spreadsheet_data.split('\n')

    num_events = len(short_course_events)
    qt_by_event = [None] * num_events
    expected_num_columns = max_age - min_age + 2

    for row in rows:
        columns = row.split('\t')
        # Parse the event name
        event_code = Event.create_from_str(columns[0], 'S').event_code
        if len(columns) != expected_num_columns:
            raise RuntimeError(
                "Unexpected number of columns in spreadsheet data")
        qt_for_event = []
        qt_by_event[event_code] = qt_for_event
        for i in range(1, expected_num_columns):
            if len(columns[i]) == 0:
                qt_for_event.append(None)
            else:
                qt_for_event.append(float(RaceTime(columns[i])))
    return qt_by_event
Ejemplo n.º 8
0
def process_swimmer(swimmer, swims):
    age = helpers.CalcAge(swimmer.date_of_birth, age_on_date)

    full_name = swimmer.full_name()
    if full_name in excluded_swimmers:
        return

    if age > maximum_age:
        return

    full_name = swimmer.alternate_name()
    # Find PB in the qualifying window, and qualifying PB
    pb_by_event = []
    qual_pb_by_event = []
    print(full_name)
    for i in range(0, num_events):
        pb_by_event.append(None)
        qual_pb_by_event.append(None)
    for swim in swims:
        if swim.date >= earliest_pb_date:
            event_code = swim.event.get_short_course_event_code()
            swim.converted_time = swim.race_time
            swim.is_converted = False
            swim.qualifies = (swim.level <= max_qualifying_meet_level)
            if swim.event.is_long_course() != is_long_course:
                swim.converted_time = swim.event.convert_time(swim.race_time)
                swim.is_converted = True
                #print( swim.event.short_name_without_course() + "\t" + str( swim.event.to_int() ) + "\t" + str( RaceTime( swim.race_time ) ) + "\t" + str( RaceTime( swim.converted_time ) ) + "\t" + swim.meet )
                # Round to 0.1s
                swim.converted_time = math.floor((swim.converted_time * 10) +
                                                 0.5) * 0.1

            qt = get_qualifying_time(event_code, swimmer.is_male, age)
            if (qt is None) or (swim.converted_time > qt):
                swim.qualifies = False

            if swim.qualifies:
                qual_pb = qual_pb_by_event[event_code]
                #print( "Considering: " + swim.event.short_name_without_course() + "\t" + str( swim.event.to_int() ) + "\t" + str( RaceTime( swim.race_time ) ) + "\t" + str( RaceTime( swim.converted_time ) ) + "\t" + swim.meet )
                if prefer_qualifying_times_in_target_course and (qual_pb
                                                                 is not None):
                    # This meet insists that if you have qualifying times in the target course
                    # then they should take precedence over other swims
                    if qual_pb.is_converted and (not swim.is_converted):
                        # Pretend the current qual_pb does not exist
                        qual_pb = None
                if ((qual_pb is None)
                        or (swim.converted_time < qual_pb.converted_time)):
                    use_this_swim = True
                    if prefer_qualifying_times_in_target_course and (
                            qual_pb is not None):
                        # This meet insists that if you have qualifying times in the target course
                        # then they should take precedence over other swims
                        if (not qual_pb.is_converted) and swim.is_converted:
                            # Which means we can't use this swim
                            use_this_swim = False
                    if use_this_swim:
                        qual_pb_by_event[event_code] = swim

            pb = pb_by_event[event_code]
            if (pb is None) or (swim.converted_time < pb.converted_time):
                #print( "PB: " + swim.event.short_name_without_course() + "\t" + str( swim.event.to_int() ) + "\t" + str( RaceTime( swim.race_time ) ) + "\t" + str( RaceTime( swim.converted_time ) ) + "\t" + swim.meet )
                pb_by_event[event_code] = swim

    printed_name = False
    converted_from_course_name = "LC"
    if is_long_course:
        converted_from_course_name = "SC"

    for i in range(0, num_events):
        qt = get_qualifying_time(i, swimmer.is_male, age)
        if qt is not None:
            pb = qual_pb_by_event[i]
            if (pb is None) or (pb.converted_time > qt):
                # There isn't a time from a qualifying event, or it was too slow.
                # Let's consider a non-qualifying event instead (if there is one).
                #if pb is not None:
                #  print( "Slow: " + str(i) + ", " + str( pb.converted_time ) + ", " + str( qt ) )
                pb = pb_by_event[i]
            if pb is not None:
                race_time = pb.converted_time
                if race_time <= qt:
                    tag_class = "qualified"
                    if not pb.qualifies:
                        tag_class = "not-qualified"
                    if not printed_name:
                        qt_file.write(full_name + " (" + str(age) + ")\n")
                        qt_html_file.write(
                            '<tr class="name"><th colspan="5">' + full_name +
                            " (" + str(age) + ")</th></tr>\n")
                        printed_name = True
                    precision = 2
                    conversion_str = ""
                    if pb.is_converted:
                        precision = 1
                        conversion_str = '<small> (' + str(
                            RaceTime(pb.race_time)
                        ) + ' ' + converted_from_course_name + ')</small>'
                    qt_file.write("\t" + pb.event.short_name_without_course() +
                                  "\t" + str(RaceTime(race_time, precision)) +
                                  "\t" + pb.meet + "\t" +
                                  pb.date.strftime('%d/%m/%Y') + "\n")
                    qt_html_file.write('<tr class="' + tag_class +
                                       '"><td> </td><td>' +
                                       pb.event.short_name_without_course() +
                                       "</td><td>" +
                                       str(RaceTime(race_time, precision)) +
                                       "</td><td>" + pb.meet + "</td><td>" +
                                       pb.date.strftime('%d/%m/%Y') +
                                       "</td></tr>\n")
    if printed_name:
        qt_file.write("\n")
Ejemplo n.º 9
0
            # This is a club champs swim
            swim_by_event[swim.event.get_short_course_event_code()] = swim
            has_entered = True

    if has_entered:
        print(full_name + ', ' + str(age))
        swimmer_times = SwimmerTimes(swimmer, full_name)
        swimmer_times.swim_by_event = swim_by_event
        all_swimmer_times.append(swimmer_times)


# Read all the data from the club rankings exports
swimmers = read_club_rankings.ReadClubRankingsFiles()
for swimmer in swimmers:
    process_swimmer(swimmer, swimmer.swims)

# Now we produce the output file
print('Writing file')
first = True
for swimmer_times in all_swimmer_times:
    if not first:
        race_times_file.write('\n')
    swimmer = swimmer_times.swimmer
    race_times_file.write(str(swimmer) + '\n')
    for swim in swimmer_times.swim_by_event:
        if swim is not None:
            race_times_file.write(swim.event.short_name_without_course() +
                                  '|' + str(RaceTime(swim.race_time)) + '\n')
    first = False
race_times_file.close()
Ejemplo n.º 10
0
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program (file LICENSE); if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import hytek_hy3_parser
import hytek_helpers
from race_time import RaceTime

# Open a sample HY3 file and parse the lines
f = open('C:\Users\Oli\Documents\TimeTrialResults_11_5_2013.HY3', 'r')
parsed_lines = hytek_hy3_parser.parse( f )
f.close()
# Now take those parsed lines and parse them as race results to get
# a list of swimmers, each with a list of race results
swimmers = hytek_helpers.parse_results( parsed_lines )

# Print them out to show it works....
for swimmer in swimmers:
  print( "Swimmer: " + swimmer.first_name + " " + swimmer.last_name + ", DoB: " + str( swimmer.date_of_birth ) )
  for swim in swimmer.swims:
    print( "Meet: " + swim.meet + ", Date: " + str( swim.date ) + ", Event: " + str( swim.event ) + ", Time: " + str( RaceTime( swim.race_time ) ) )
Ejemplo n.º 11
0
def scrape_meet(asa_meet_code, page_number, meet_name, date, course_code):
    logging.info("Attempting to parse meet " + meet_name + ", meet code: " +
                 str(asa_meet_code) + ", page: " + str(page_number))
    # Load a meet page from a URL like this...
    # https://www.swimmingresults.org/showmeetsbyclub/index.php?meetcode=19611&targetclub=WINNCHRN
    url = "https://www.swimmingresults.org/showmeetsbyclub/index.php?meetcode=" + str(
        asa_meet_code) + "&targetclub=WINNCHRN&page=" + str(page_number)
    page = helpers.FetchUrl(url)

    if page is None:
        logging.error("Failed to get page " + url)
        return 503
    tree = html.fromstring(page)
    meet_has_been_parsed(asa_meet_code)
    try:
        table = tree.get_element_by_id("rankTable")
    except:
        logging.info("No rankTable for " + url +
                     ". Presuming no Winsford swimmers at that meet")
        return

    if page_number == 1:
        # When scraping the first page, one of our jobs is to count how many other pages
        # there are and add tasks to scrape those pages
        num_pages = scrape_num_pages(tree)
        logging.info("Meet contains " + str(num_pages) + " pages ")
        date_str = date.strftime("%d/%m/%y")
        for i in range(2, num_pages + 1):
            logging.info("Queing update of page " + str(i) + " of " +
                         meet_name)
            taskqueue.add(url='/admin/scrape_meet',
                          params={
                              'asa_meet_code': str(asa_meet_code),
                              'meet_name': meet_name,
                              'date': date_str,
                              'course_code': course_code,
                              'page': str(i)
                          })

    swimmers_checked = set()
    update_swimmer_list = False
    for row in TableRows(table, _meet_headers_of_interest):
        # First we look at the swimmer.
        # Is it one we've already seen while scraping this meet, or is it a new one?
        # If it's a new one, is it a swimmer that's in our database?
        # Perhaps it's a swimmer that's in our database as Cat 1 and needs upgrading.
        asa_number = int(row[0].text)
        if asa_number not in swimmers_checked:
            swimmers_checked.add(asa_number)
            swimmer = Swimmer.get("Winsford", asa_number)
            if swimmer is None:
                swimmer = SwimmerCat1.get("Winsford", asa_number)
                if swimmer is None:
                    # This looks like a new Winsford swimmer that isn't in the database
                    # Add a task to add them
                    logging.info("Found new Winsford swimmer: " +
                                 str(asa_number) + ". Adding task to scrape.")
                    taskqueue.add(url='/admin/update_swimmers',
                                  params={'name_search': str(asa_number)})
                    #QueueUpdateSwimsForSwimmer( str(asa_number) )
                    update_swimmer_list = True
                else:
                    # This is a swimmer that's in our database as Cat1
                    # Add a task to upgrade them
                    logging.info("Found new Cat 2 Winsford swimmer: " +
                                 str(asa_number) + ". Adding task to upgrade.")
                    taskqueue.add(url='/admin/check_for_swimmer_upgrade',
                                  params={'asa_number': str(asa_number)})
                    update_swimmer_list = True
            else:
                logging.info("Found existing Winsford swimmer: " +
                             swimmer.full_name())

    if update_swimmer_list:
        taskqueue.add(url='/admin/update_swimmer_list')

    swims_for_swimmer = {}
    for row in TableRows(table, _meet_headers_of_interest):
        # Now look at the actual swims.
        # If there's a swim link, then that means there are some splits. In those
        # cases we also add a task to parse the splits and add them to the Swim.
        asa_number = int(row[0].text)
        event_str = row[1].text
        date_of_birth = helpers.ParseDate_dmy(row[2].text)
        race_time = float(RaceTime(row[3].text))
        event = Event.create_from_str(event_str, course_code)
        asa_swim_id = get_asa_swim_id(row[3])

        swim = Swim.create(asa_number, date_of_birth, event, date, meet_name,
                           race_time, asa_swim_id)

        if asa_swim_id is not None:
            # Swim link. Add a task to parse the splits.
            swim_key_str = swim.create_swim_key_str()
            logging.info("Adding split scraping task for swim " + swim_key_str)
            taskqueue.add(url='/admin/scrape_splits',
                          params={'swim': swim_key_str})

        # Record this swim
        if asa_number not in swims_for_swimmer:
            swims_for_swimmer[asa_number] = []

        swims_for_swimmer[asa_number].append(swim)

    for asa_number, swims in swims_for_swimmer.iteritems():
        num_swims = len(swims)
        logging.info("Putting " + str(num_swims) + " swims for " +
                     str(asa_number))
        put_new_swims(asa_number, swims)
Ejemplo n.º 12
0
 def post(self):
     records_for_each_gender = [{}, {}]
     swimmers = Swimmer.query_club("Winsford")
     num_event_codes = len(short_course_events)
     for gender_idx in range(0, 2):
         gender_code = gender_codes[gender_idx]
         is_male = (gender_idx == 0)
         records_for_each_age = records_for_each_gender[gender_idx]
         for age in range(9, 17):
             records_for_this_age = {}
             records_for_each_age[age] = records_for_this_age
             for event_code in range(0, num_event_codes):
                 sc_event = short_course_events[event_code]
                 lc_event = long_course_events[event_code]
                 best_race_time = 9999999
                 best_swimmer = None
                 best_swim = None
                 for swimmer in swimmers:
                     if swimmer.is_male == is_male:
                         # Figure out this swimmer's best time at this age converted
                         # to short course time
                         sc_pb_time = 9999999
                         sc_pb_swim = Swim.fetch_pb(swimmer, sc_event, age)
                         pb_swim = sc_pb_swim
                         lc_pb_swim = Swim.fetch_pb(swimmer, lc_event, age)
                         if sc_pb_swim is not None:
                             sc_pb_time = sc_pb_swim.race_time
                         if lc_pb_swim is not None:
                             lc_pb_time_converted = lc_event.convertTime(
                                 lc_pb_swim.race_time)
                             if lc_pb_time_converted < sc_pb_time:
                                 sc_pb_time = lc_pb_time_converted
                                 pb_swim = lc_pb_swim
                         if (pb_swim is not None) and (sc_pb_time <
                                                       best_race_time):
                             # This is the best time we've seen so far
                             best_race_time = sc_pb_time
                             best_swimmer = swimmer
                             best_swim = pb_swim
                 if best_swim is not None:
                     record = Record(age, best_swimmer, best_swim,
                                     best_race_time)
                     records_for_this_age[event_code] = record
                     logging.info('Record for ' + gender_code + ' ' +
                                  str(age) + ' ' +
                                  sc_event.short_name_without_course() +
                                  ': ' + str(RaceTime(best_race_time)) +
                                  ', ' + best_swimmer.full_name())
     # Now tabulate and send a plain text response
     club_records = ''
     self.response.headers['Content-Type'] = 'text/plain'
     for gender_idx in range(0, 2):
         records_for_each_age = records_for_each_gender[gender_idx]
         gender_code = gender_codes[gender_idx]
         for age, records_for_age in records_for_each_age.iteritems():
             for event_code, record in records_for_age.iteritems():
                 swimmer = record.swimmer
                 swim = record.swim
                 club_records += (gender_code + '^' + str(record.age) +
                                  '^' + str(event_code) + '^' +
                                  swimmer.full_name() + '^' + str(swim) +
                                  '\n')
     self.response.out.write(club_records)
     StaticData.set_club_records(club_records)