import datetime as dt
from dateutil.relativedelta import relativedelta

from sqlalchemy import Column, Date, DateTime, Float, Integer, String, ForeignKey
from sqlalchemy.orm import backref, relationship
from sqlalchemy.schema import ForeignKeyConstraint
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

### data model from mlbam gameday ###

class Game(Base):
    __tablename__ = 'game'
    gid = Column(String(26), primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    game_pk = Column(Integer)
    venue = Column(String(50))
    venue_id = Column(Integer)
    location = Column(String(20), default = '')
    datetime_local = Column(DateTime)
    datetime_et = Column(DateTime)
    first_pitch_et = Column(String(5), default = '')
    home_time = Column(String(5))
    home_time_zone = Column(String(3))
    home_ampm = Column(String(2))
    resume_home_time = Column(String(5), default = '')
    away_time = Column(String(5))
    away_time_zone = Column(String(3))
    away_ampm = Column(String(2))
    resume_away_time = Column(String(5), default = '')
    day = Column(String(3))
    game_type = Column(String(1))
    home_name_abbrev = Column(String(3))
    home_code = Column(String(3))
    home_file_code = Column(String(5))
    home_team_id = Column(Integer)
    home_team_city = Column(String(25))
    home_team_name = Column(String(30))
    home_division = Column(String(2))
    home_league_id = Column(Integer)
    home_sport_code = Column(String(3))
    home_league_id_spring = Column(String(3), default = '')
    home_split_squad = Column(String(1), default = '')
    away_name_abbrev = Column(String(3))
    away_code = Column(String(3))
    away_file_code = Column(String(5))
    away_team_id = Column(Integer)
    away_team_city = Column(String(25))
    away_team_name = Column(String(30))
    away_division = Column(String(2))
    away_league_id = Column(Integer)
    away_sport_code = Column(String(3))
    away_league_id_spring = Column(String(3), default = '')
    away_split_squad = Column(String(1), default = '')
    gameday_sw = Column(String(1))
    tiebreaker_sw = Column(String(1), default = '')
    home_games_back = Column(Float)
    away_games_back = Column(Float)
    home_games_back_wildcard = Column(Float)
    away_games_back_wildcard = Column(Float)
    home_win = Column(Integer)
    home_loss = Column(Integer)
    away_win = Column(Integer)
    away_loss = Column(Integer)
    league = Column(String(4), default = '')
    status = Column(String(15))
    ind = Column(String(2))
    home_team_runs = Column(Integer)
    away_team_runs = Column(Integer)
    home_team_hits = Column(Integer)
    away_team_hits = Column(Integer)
    home_team_errors = Column(Integer)
    away_team_errors = Column(Integer)
    reason = Column(String(17), default = '')
    description = Column(String(50), default = '')
    original_date = Column(Date)
    double_header_sw = Column(String(1), default = '')
    game_nbr = Column(Integer, default = None)
    tbd_flag = Column(String(1), default = '')
    home_team_hr = Column(Integer, default = None)
    away_team_hr = Column(Integer, default = None)
    home_team_sb = Column(Integer, default = None)
    away_team_sb = Column(Integer, default = None)
    home_team_so = Column(Integer, default = None)
    away_team_so = Column(Integer, default = None)
    resume_date = Column(Date, default = None)
    resume_time_date = Column(DateTime, default = None)
    resume_ampm = Column(String(2), default = '')
    resume_home_ampm = Column(String(2), default = '')
    series = Column(String(12), default = '')
    series_num = Column(Integer, default = None)
    ser_home_nbr = Column(Integer, default = None)
    ser_games = Column(Integer, default = None)
    scheduled_innings = Column(Integer)
    if_necessary = Column(String(1), default = '')
    tv_station = Column(String(60))
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    def __repr__(self):
        return '<Game(gid = %s, game_pk = %i, home = %s, away = %s, venue = %s)>' % \
                (self.gid, self.game_pk, str(self.home_team_runs), str(self.away_team_runs), self.venue)

class Player(Base):
    __tablename__ = 'player'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    player_id = Column(Integer, ForeignKey('person.key_mlbam'), primary_key = True)
    home_flag = Column(Integer, primary_key = True)
    game_date = Column(DateTime)
    game_pk = Column(Integer)
    first = Column(String(12))
    last = Column(String(15))
    boxname = Column(String(15))
    position = Column(String(2))
    team_id = Column(Integer, default = None)
    team_abbrev = Column(String(3))
    parent_team_id = Column(Integer)
    parent_team_abbrev = Column(String(3))
    num = Column(Integer)
    bats = Column(String(1))
    rl = Column(String(1))
    game_position = Column(String(2), default = '')
    current_position = Column(String(2), default = '')
    bat_order = Column(Integer, default = None)
    status = Column(String(1))
    avg = Column(Float)
    hr = Column(Integer)
    rbi = Column(Integer)
    wins = Column(Integer, default = None)
    losses = Column(Integer, default = None)
    era = Column(Float, default = None)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    def __repr__(self):
        return '<Player(gid = %s, game_pk = %i, player_id = %i boxname = %s)>' % \
        (self.gid, self.game_pk, self.player_id, self.boxname)

class Coach(Base):
    __tablename__ = 'coach'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    coach_id = Column(Integer, ForeignKey('person.key_mlbam'), primary_key = True)
    home_flag = Column(Integer, primary_key = True)
    game_date = Column(DateTime)
    game_pk = Column(Integer)
    first = Column(String(10))
    last = Column(String(15))
    num = Column(Integer)
    position = Column(String(25))
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    def __repr__(self):
        return '<Coach(gid = %s, last = %s)>' % (self.gid, self.last)

class Umpire(Base):
    __tablename__ = 'umpire'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    umpire_id = Column(Integer, ForeignKey('person.key_mlbam'), primary_key = True)
    position = Column(String(6), primary_key = True)
    game_pk = Column(Integer)
    game_date = Column(DateTime)
    last = Column(String(15), default = '')
    first = Column(String(10), default = '')
    name = Column(String(25))
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    def __repr__(self):
        return '<Umpire(gid = %s, last = %s)>' % (self.gid, self.last)

class HIP(Base):
    __tablename__ = 'hip'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'), primary_key = True)
    batter = Column(Integer, ForeignKey('person.key_mlbam'), primary_key = True)
    inning = Column(Integer, primary_key = True)
    x = Column(Float, primary_key = True)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    game_date = Column(Date)
    venue_id = Column(Integer)
    game_pk = Column(Integer)
    des = Column(String(20))
    y = Column(Float)
    hip_type = Column(String(1))
    team = Column(String(1))
    ### atbat ###
    game_event_number = Column(Integer, default = None)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))
    retro_event_id = Column(Integer, default = None)

    ### table arguements and relationships ###
    __table_args__ = (
                ForeignKeyConstraint(['retro_gid', 'retro_event_id'],
                                ['event.game_id', 'event.event_id']),
                ForeignKeyConstraint(['gid', 'game_event_number'],
                                ['atbat.gid', 'atbat.game_event_number']),
                     )

    retro_event = relationship('Event', primaryjoin = 'and_(Event.game_id == HIP.retro_gid,'\
                    'Event.event_id == HIP.retro_event_id)')

    atbat = relationship('AtBat', primaryjoin = 'and_(AtBat.gid == HIP.gid,'\
                    'AtBat.game_event_number == HIP.game_event_number)')

    def __repr__(self):
        return '<HIP(gid = %s, inning = %s, des = %s)>' \
               % (self.gid, self.inning, self.des)

class AtBat(Base):
    __tablename__ = 'atbat'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    game_event_number = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    datetime = Column(DateTime)
    game_pk = Column(Integer)
    venue_id = Column(Integer)
    event_num = Column(Integer)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    play_guid = Column(String(36), default = '')
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    start_outs = Column(Integer)
    start_base_state = Column(String(3))
    start_out_base_state = Column(String(4))
    start_home_team_runs = Column(Integer)
    start_away_team_runs = Column(Integer)
    start_1B = Column(Integer)
    start_2B = Column(Integer)
    start_3B = Column(Integer)
    b = Column(Integer)
    s = Column(Integer)
    o = Column(Integer)
    num = Column(Integer, default = None)
    p_throws = Column(String(1), default = '')
    stand = Column(String(1), default = '')
    b_height = Column(String(4), default = '')
    score = Column(String(1), default = '')
    start_tfs = Column(String(6), default = '')
    start_tfs_zulu = Column(DateTime)
    des = Column(String(425))
    des_es = Column(String(400))
    event = Column(String(25))
    event_es = Column(String(50), default = '')
    event2 = Column(String(25), default = '')
    event2_es = Column(String(50), default = '')
    event3 = Column(String(25), default = '')
    event3_es = Column(String(50), default = '')
    event4 = Column(String(25), default = '')
    event4_es = Column(String(50), default = '')
    end_outs = Column(Integer)
    end_base_state = Column(String(3))
    end_out_base_state = Column(String(4))
    end_home_team_runs = Column(Integer)
    end_away_team_runs = Column(Integer)
    end_1B = Column(Integer)
    end_2B = Column(Integer)
    end_3B = Column(Integer)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))
    retro_event_id = Column(Integer, default = None)

    def __repr__(self):
        return '<AtBat(gid = %s, game_event_number = %i, inning = %i, des = %s)>' \
               % (self.gid, self.game_event_number, self.inning, self.des)

class Action(Base):
    __tablename__ = 'action'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    game_event_number = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    datetime = Column(DateTime)
    retro_gid = Column(String(12))
    game_pk = Column(Integer)
    venue_id = Column(Integer)
    event_num = Column(Integer)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    play_guid = Column(String(36), default = '')
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    player = Column(Integer, default = None)
    start_outs = Column(Integer)
    start_base_state = Column(String(3))
    start_out_base_state = Column(String(4))
    start_home_team_runs = Column(Integer)
    start_away_team_runs = Column(Integer)
    start_1B = Column(Integer)
    start_2B = Column(Integer)
    start_3B = Column(Integer)
    b = Column(Integer)
    s = Column(Integer)
    o = Column(Integer)
    home_team_runs = Column(Integer, default = None)
    away_team_runs = Column(Integer, default = None)
    pitch = Column(Integer, default = None)
    score = Column(String(1), default = '')
    tfs = Column(String(6), default = '')
    tfs_zulu =  Column(DateTime)
    des = Column(String(425))
    des_es = Column(String(400))
    event = Column(String(25))
    event_es = Column(String(50), default = '')
    event2 = Column(String(25), default = '')
    event2_es = Column(String(50), default = '')
    event3 = Column(String(25), default = '')
    event3_es = Column(String(50), default = '')
    event4 = Column(String(25), default = '')
    event4_es = Column(String(50), default = '')
    end_outs = Column(Integer)
    end_base_state = Column(String(3))
    end_out_base_state = Column(String(4))
    end_home_team_runs = Column(Integer)
    end_away_team_runs = Column(Integer)
    end_1B = Column(Integer)
    end_2B = Column(Integer)
    end_3B = Column(Integer)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    def __repr__(self):
        return '<Action(gid = %s, game_event_number = %i, inning = %i, des = %s)>' \
               % (self.gid, self.game_event_number, self.inning, self.des)

class Pitch(Base):
    __tablename__ = 'pitch'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    game_pitch_count = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    datetime = Column(DateTime)
    game_pk = Column(Integer)
    pitch_id = Column(Integer)
    venue_id = Column(Integer)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    game_event_number = Column(Integer)
    event_num = Column(Integer)
    event = Column(String(35))
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    start_outs = Column(Integer)
    start_base_state = Column(String(3))
    start_out_base_state = Column(String(4))
    start_home_team_runs = Column(Integer)
    start_away_team_runs = Column(Integer)
    start_1B = Column(Integer)
    start_2B = Column(Integer)
    start_3B = Column(Integer)
    des = Column(String(35))
    des_es = Column(String(35))
    p_type = Column(String(1))
    tfs = Column(String(6))
    tfs_zulu =  Column(DateTime)
    x = Column(Float)
    y = Column(Float)
    sv_id = Column(DateTime)
    play_guid = Column(String(36))
    start_speed = Column(Float)
    end_speed = Column(Float)
    sz_top = Column(Float)
    sz_bot = Column(Float)
    pfx_x = Column(Float)
    pfx_z = Column(Float)
    px = Column(Float)
    pz = Column(Float)
    x0 = Column(Float)
    y0 = Column(Float)
    z0 = Column(Float)
    vx0 = Column(Float)
    vy0 = Column(Float)
    vz0 = Column(Float)
    ax = Column(Float)
    ay = Column(Float)
    az = Column(Float)
    break_y = Column(Float)
    break_angle = Column(Float)
    break_length = Column(Float)
    pitch_type = Column(String(2))
    type_confidence = Column(Float)
    zone = Column(Integer)
    nasty = Column(Integer)
    spin_dir = Column(Float)
    spin_rate = Column(Float)
    cc = Column(String(200))
    mt = Column(String(1))
    on_1b = Column(Integer, default = None)
    on_2b = Column(Integer, default = None)
    on_3b = Column(Integer, default = None)
    end_outs = Column(Integer)
    end_base_state = Column(String(3))
    end_out_base_state = Column(String(4))
    end_home_team_runs = Column(Integer)
    end_away_team_runs = Column(Integer)
    end_1B = Column(Integer)
    end_2B = Column(Integer)
    end_3B = Column(Integer)
    ### added ###
    swing = Column(Integer)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12))
    retro_event_id = Column(Integer, default = None)

    ### table arguements and relationships ###
    __table_args__ = (
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['atbat.gid', 'atbat.game_event_number']),
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['action.gid', 'action.game_event_number']),
        ForeignKeyConstraint(['retro_gid', 'retro_event_id'],
                             ['event.game_id', 'event.event_id']),
                     )
    atbat = relationship('AtBat', primaryjoin = 'and_(AtBat.gid == Pitch.gid, '\
                             'AtBat.game_event_number == Pitch.game_event_number)')
    action = relationship('Action', primaryjoin = 'and_(Action.gid == Pitch.gid, '\
                             'Action.game_event_number == Pitch.game_event_number)', viewonly = True)
    retro_event = relationship('Event', primaryjoin = 'and_(Event.game_id == Pitch.retro_gid, '\
                             'Event.event_id == Pitch.retro_event_id)', viewonly = True)

    def __repr__(self):
        return '<Pitch(gid = %s, pitch_num = %i, pitch_type = %s)>' % \
               (self.gid, self.pitch_num, self.pitch_type)

class Runner(Base):
    __tablename__ = 'runner'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    game_runner_count = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    game_pk = Column(Integer)
    runner_id = Column(Integer)
    game_event_number = Column(Integer)
    venue_id = Column(Integer)
    event_num = Column(Integer, default = None)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    start_outs = Column(Integer)
    start_base_state = Column(String(3))
    start_out_base_state = Column(String(4))
    start_home_team_runs = Column(Integer)
    start_away_team_runs = Column(Integer)
    start_1B = Column(Integer)
    start_2B = Column(Integer)
    start_3B = Column(Integer)
    event = Column(String(25))
    start = Column(String(2))
    end = Column(String(2))
    score = Column(String(1), default = '')
    rbi = Column(String(1), default = '')
    earned = Column(String(1), default = '')
    end_outs = Column(Integer)
    end_base_state = Column(String(3))
    end_out_base_state = Column(String(4))
    end_home_team_runs = Column(Integer)
    end_away_team_runs = Column(Integer)
    end_1B = Column(Integer)
    end_2B = Column(Integer)
    end_3B = Column(Integer)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    ### table arguements and relationships ###
    __table_args__ = (
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['atbat.gid', 'atbat.game_event_number']),
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['action.gid', 'action.game_event_number']),
                     )
    atbat = relationship('AtBat', primaryjoin = 'and_(AtBat.gid == Runner.gid, '\
                             'AtBat.game_event_number == Runner.game_event_number)')
    action = relationship('Action', primaryjoin = 'and_(Action.gid == Runner.gid, '\
                             'Action.game_event_number == Runner.game_event_number)', viewonly = True)

    def __repr__(self):
        return '<Runner(game_pk = %s, gid = %s, des = %s)>' % \
               (str(self.game_pk), str(self.event_num), str(self.des))

class Pickoff(Base):
    __tablename__ = 'pickoff'
    gid = Column(String(26), ForeignKey('game.gid'), primary_key = True)
    game_pickofff_count = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    game_pk = Column(Integer)
    game_event_number = Column(Integer)
    venue_id = Column(Integer)
    event_num = Column(Integer, default = None)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    start_outs = Column(Integer)
    start_base_state = Column(String(3))
    start_out_base_state = Column(String(4))
    start_home_team_runs = Column(Integer)
    start_away_team_runs = Column(Integer)
    start_1B = Column(Integer)
    start_2B = Column(Integer)
    start_3B = Column(Integer)
    des = Column(String(20))
    des_es = Column(String(20), default = '')
    play_guid = Column(String(36), default = '')
    end_outs = Column(Integer)
    end_base_state = Column(String(3))
    end_out_base_state = Column(String(4))
    end_home_team_runs = Column(Integer)
    end_away_team_runs = Column(Integer)
    end_1B = Column(Integer)
    end_2B = Column(Integer)
    end_3B = Column(Integer)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12), ForeignKey('game_log.game_id'))

    ### table arguements and relationships ###
    __table_args__ = (
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['atbat.gid', 'atbat.game_event_number']),
        ForeignKeyConstraint(['gid', 'game_event_number'],
                             ['action.gid', 'action.game_event_number']),
                     )
    atbat = relationship('AtBat', primaryjoin = 'and_(AtBat.gid == Pickoff.gid,'\
                             'AtBat.game_event_number == Pickoff.game_event_number)')
    action = relationship('Action', primaryjoin = 'and_(Action.gid == Pickoff.gid,'\
                             'Action.game_event_number == Pickoff.game_event_number)', viewonly = True)

    def __repr__(self):
        return '<Pickoff(gid = %s, game_event_number = %i, atbat_pickoff_number = %s)>' \
               % (self.gid, self.game_event_number, self.atbat_pickoff_numbers)

### data model from baseball savant trajectory csv downloads ###

class Trajectory(Base):
    __tablename__ = 'trajectory'
    game_pk = Column(Integer, ForeignKey('game.game_pk'), primary_key = True)
    pitch_id = Column(Integer, primary_key = True)
    game_date = Column(DateTime, primary_key = True)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    pitch_type = Column(String(2))
    start_speed = Column(Float)
    x0 = Column(Float)
    z0 = Column(Float)
    player_name = Column(String(30))
    batter = Column(Integer, ForeignKey('person.key_mlbam'))
    pitcher = Column(Integer, ForeignKey('person.key_mlbam'))
    events = Column(String(10))
    description = Column(String(20))
    spin_dir = Column(Float)
    spin_rate = Column(Float)
    break_angle = Column(Float)
    break_length = Column(Float)
    zone = Column(Integer)
    des = Column(String(100))
    game_type = Column(String(1))
    stand = Column(String(1))
    p_throws = Column(String(1))
    home_team = Column(String(3))
    away_team = Column(String(3))
    event_type = Column(String(1))
    hit_location = Column(Integer)
    bb_type = Column(Integer)
    balls = Column(Integer)
    strikes = Column(Integer)
    game_year = Column(Integer)
    pfx_x = Column(Float)
    pfx_z = Column(Float)
    px = Column(Float)
    pz = Column(Float)
    on_3b = Column(Integer)
    on_2b = Column(Integer)
    on_1b = Column(Integer)
    outs_when_up = Column(Integer)
    inning = Column(Integer)
    inning_topbot = Column(String(3))
    hc_x = Column(Float)
    hc_y = Column(Float)
    tfs = Column(Integer)
    tfs_zulu = Column(DateTime)
    catcher = Column(Integer, ForeignKey('person.key_mlbam'))
    umpire = Column(Integer, ForeignKey('person.key_mlbam'))
    sv_id = Column(String(13))
    vx0 = Column(Float)
    vy0 = Column(Float)
    vz0 = Column(Float)
    ax = Column(Float)
    ay = Column(Float)
    az = Column(Float)
    sz_top = Column(Float)
    sz_bot = Column(Float)
    hit_distance_sc = Column(Float)
    hit_speed = Column(Float)
    hit_angle = Column(Float)
    effective_speed = Column(Float)
    release_spin_rate = Column(Float)
    release_extension = Column(Float)
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)
    ### retrosheet ###
    retro_gid = Column(String(12))
    retro_event_id = Column(Integer, default = None)

    ### table arguements and relationships ###
    __table_args__ = (
        ForeignKeyConstraint(['retro_gid', 'retro_event_id'],
                             ['event.game_id', 'event.event_id']),
                     )

    retro_event = relationship('Event', primaryjoin = 'and_(Event.game_id == Trajectory.retro_gid,'\
         'Event.event_id == Trajectory.retro_event_id)')

    def __repr__(self):
        return '<Trajectory(game_pk = %i, pitcher = %s, game_date = %s)>' % \
               (self.game_pk, self.player_name, self.game_date.strftime('%Y-%m-%d'))

### data model from retrosheet ###

class GameLog(Base):
    __tablename__ = 'game_log'
    game_id = Column(String(12),  primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    game_number = Column(String(1))
    day = Column(String(3))
    away_team_id = Column(String(3), ForeignKey('team.cur_fran_id'))
    away_lg = Column(String(2))
    away_game_number = Column(Integer)
    home_team_id = Column(String(3), ForeignKey('team.cur_fran_id'))
    home_lg = Column(String(2))
    home_game_number = Column(Integer)
    away_score_ct = Column(Integer)
    home_score_ct = Column(Integer)
    outs = Column(Integer)
    daynight = Column(String(1))
    completion = Column(String(255))
    forfeit = Column(String(1))
    protest = Column(String(2))
    park = Column(String(5))
    attendance = Column(Integer)
    game_minutes = Column(Integer)
    away_linescore = Column(String(20))
    home_linescore = Column(String(30))
    away_ab = Column(Integer)
    away_h = Column(Integer)
    away_2b = Column(Integer)
    away_3b = Column(Integer)
    away_hr = Column(Integer)
    away_rbi = Column(Integer)
    away_sh = Column(Integer)
    away_sf = Column(Integer)
    away_hbp = Column(Integer)
    away_bb = Column(Integer)
    away_ibb = Column(Integer)
    away_so = Column(Integer)
    away_sb = Column(Integer)
    away_cs = Column(Integer)
    away_gidp = Column(Integer)
    away_ci = Column(Integer)
    away_lob = Column(Integer)
    away_pitchers_used = Column(Integer)
    away_individual_er = Column(Integer)
    away_team_er = Column(Integer)
    away_wp = Column(Integer)
    away_balks = Column(Integer)
    away_putouts = Column(Integer)
    away_assists = Column(Integer)
    away_errors = Column(Integer)
    away_passed_balls = Column(Integer)
    away_double_plays = Column(Integer)
    away_triple_plays = Column(Integer)
    home_ab = Column(Integer)
    home_h = Column(Integer)
    home_2b = Column(Integer)
    home_3b = Column(Integer)
    home_hr = Column(Integer)
    home_rbi = Column(Integer)
    home_sh = Column(Integer)
    home_sf = Column(Integer)
    home_hbp = Column(Integer)
    home_bb = Column(Integer)
    home_ibb = Column(Integer)
    home_so = Column(Integer)
    home_sb = Column(Integer)
    home_cs = Column(Integer)
    home_gidp = Column(Integer)
    home_ci = Column(Integer)
    home_lob = Column(Integer)
    home_pitchers_used = Column(Integer)
    home_individual_er = Column(Integer)
    home_team_er = Column(Integer)
    home_wp = Column(Integer)
    home_balks = Column(Integer)
    home_putouts = Column(Integer)
    home_assists = Column(Integer)
    home_errors = Column(Integer)
    home_passed_balls = Column(Integer)
    home_double_plays = Column(Integer)
    home_triple_plays = Column(Integer)
    hp_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    hp_ump_name = Column(String(255))
    b1_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    b1_ump_name = Column(String(255))
    b2_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    b2_ump_name = Column(String(255))
    b3_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    b3_ump_name = Column(String(255))
    lf_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    lf_ump_name = Column(String(255))
    rf_ump_id = Column(String(8), ForeignKey('person.key_retro'))
    rf_ump_name = Column(String(255))
    away_manager_id = Column(String(8), ForeignKey('person.key_retro'))
    away_manager_name = Column(String(255))
    home_manager_id = Column(String(8), ForeignKey('person.key_retro'))
    home_manager_name = Column(String(255))
    winning_pitcher_id = Column(String(8), ForeignKey('person.key_retro'))
    winning_pitcher_name = Column(String(255))
    losing_pitcher_id = Column(String(8), ForeignKey('person.key_retro'))
    losing_pitcher_name = Column(String(255))
    saving_pitcher_id = Column(String(8), ForeignKey('person.key_retro'))
    saving_pitcher_name = Column(String(255))
    gwrbi_batter_id = Column(String(8), ForeignKey('person.key_retro'))
    gwrbi_batter_name = Column(String(255))
    away_starting_pitcher_id = Column(String(8), ForeignKey('person.key_retro'))
    away_starting_pitcher_name = Column(String(255))
    home_starting_pitcher_id = Column(String(8), ForeignKey('person.key_retro'))
    home_starting_pitcher_name = Column(String(255))
    away_batter_1_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_1_name = Column(String(255))
    away_batter_1_pos = Column(Integer)
    away_batter_2_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_2_name = Column(String(255))
    away_batter_2_pos = Column(Integer)
    away_batter_3_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_3_name = Column(String(255))
    away_batter_3_pos = Column(Integer)
    away_batter_4_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_4_name = Column(String(255))
    away_batter_4_pos = Column(Integer)
    away_batter_5_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_5_name = Column(String(255))
    away_batter_5_pos = Column(Integer)
    away_batter_6_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_6_name = Column(String(255))
    away_batter_6_pos = Column(Integer)
    away_batter_7_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_7_name = Column(String(255))
    away_batter_7_pos = Column(Integer)
    away_batter_8_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_8_name = Column(String(255))
    away_batter_8_pos = Column(Integer)
    away_batter_9_id = Column(String(8), ForeignKey('person.key_retro'))
    away_batter_9_name = Column(String(255))
    away_batter_9_pos = Column(Integer)
    home_batter_1_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_1_name = Column(String(255))
    home_batter_1_pos = Column(Integer)
    home_batter_2_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_2_name = Column(String(255))
    home_batter_2_pos = Column(Integer)
    home_batter_3_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_3_name = Column(String(255))
    home_batter_3_pos = Column(Integer)
    home_batter_4_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_4_name = Column(String(255))
    home_batter_4_pos = Column(Integer)
    home_batter_5_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_5_name = Column(String(255))
    home_batter_5_pos = Column(Integer)
    home_batter_6_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_6_name = Column(String(255))
    home_batter_6_pos = Column(Integer)
    home_batter_7_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_7_name = Column(String(255))
    home_batter_7_pos = Column(Integer)
    home_batter_8_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_8_name = Column(String(255))
    home_batter_8_pos = Column(Integer)
    home_batter_9_id = Column(String(8), ForeignKey('person.key_retro'))
    home_batter_9_name = Column(String(255))
    home_batter_9_pos = Column(Integer)
    additional_info = Column(String(255))
    acquisition = Column(String(1))

    def __repr__(self):
        return '<GameLog(game_id = %s, away_score_ct = %i, home_score_ct = %i)>' % \
        (self.game_id, self.away_score_ct, self.home_score_ct)

class Event(Base):
    __tablename__ = 'event'
    game_id = Column(String(12), ForeignKey('game_log.game_id'), primary_key = True)
    event_id = Column(Integer, primary_key = True)
    game_date = Column(Date)
    year = Column(Integer)
    month = Column(Integer)
    day = Column(Integer)
    away_team_id = Column(String(3), ForeignKey('team.cur_fran_id'))
    home_team_id = Column(String(3), ForeignKey('team.cur_fran_id'))
    inn_ct = Column(Integer)
    bat_home_id = Column(Integer)
    outs_ct = Column(Integer)
    balls_ct = Column(Integer)
    strikes_ct = Column(Integer)
    pitch_seq_tx = Column(String(40))
    away_score_ct = Column(Integer)
    home_score_ct = Column(Integer)
    bat_id = Column(String(8), ForeignKey('person.key_retro'))
    bat_hand_cd = Column(String(1))
    resp_bat_id = Column(String(8), ForeignKey('person.key_retro'))
    bat_on_deck_id = Column(String(8), ForeignKey('person.key_retro'))
    bat_in_hold_id = Column(String(8), ForeignKey('person.key_retro'))
    resp_bat_hand_cd = Column(String(1))
    pit_id = Column(String(8), ForeignKey('person.key_retro'))
    pit_hand_cd = Column(String(1))
    resp_pit_id = Column(String(8), ForeignKey('person.key_retro'))
    resp_pit_hand_cd = Column(String(1))
    pos2_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos3_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos4_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos5_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos6_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos7_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos8_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    pos9_fld_id = Column(String(8), ForeignKey('person.key_retro'))
    base1_run_id = Column(String(8), ForeignKey('person.key_retro'))
    base2_run_id = Column(String(8), ForeignKey('person.key_retro'))
    base3_run_id = Column(String(8), ForeignKey('person.key_retro'))
    event_tx = Column(String(100))
    leadoff_fl = Column(String(1))
    ph_fl = Column(String(1))
    bat_fld_cd = Column(Integer)
    bat_lineup_id = Column(Integer)
    event_cd = Column(Integer)
    bat_event_fl = Column(String(1))
    ab_fl = Column(String(1))
    h_cd = Column(Integer)
    sh_fl = Column(String(1))
    sf_fl = Column(String(1))
    event_outs_ct = Column(Integer)
    dp_fl = Column(String(1))
    tp_fl = Column(String(1))
    rbi_ct = Column(Integer)
    wp_fl = Column(String(1))
    pb_fl = Column(String(1))
    fld_cd = Column(Integer)
    battedball_cd = Column(String(1))
    bunt_fl = Column(String(1))
    foul_fl = Column(String(1))
    battedball_loc_tx = Column(String(5))
    err_ct = Column(Integer)
    err1_fld_cd = Column(Integer)
    err1_cd = Column(String(1))
    err2_fld_cd = Column(Integer)
    err2_cd = Column(String(1))
    err3_fld_cd = Column(Integer)
    err3_cd = Column(String(1))
    bat_dest_id = Column(Integer)
    run1_dest_id = Column(Integer)
    run2_dest_id = Column(Integer)
    run3_dest_id = Column(Integer)
    bat_play_tx = Column(String(8))
    run1_play_tx = Column(String(15))
    run2_play_tx = Column(String(15))
    run3_play_tx = Column(String(15))
    run1_sb_fl = Column(String(1))
    run2_sb_fl = Column(String(1))
    run3_sb_fl = Column(String(1))
    run1_cs_fl = Column(String(1))
    run2_cs_fl = Column(String(1))
    run3_cs_fl = Column(String(1))
    run1_pk_fl = Column(String(1))
    run2_pk_fl = Column(String(1))
    run3_pk_fl = Column(String(1))
    run1_resp_pit_id = Column(String(8), ForeignKey('person.key_retro'))
    run2_resp_pit_id = Column(String(8), ForeignKey('person.key_retro'))
    run3_resp_pit_id = Column(String(8), ForeignKey('person.key_retro'))
    game_new_fl = Column(String(1))
    game_end_fl = Column(String(1))
    pr_run1_fl = Column(String(1))
    pr_run2_fl = Column(String(1))
    pr_run3_fl = Column(String(1))
    removed_for_pr_run1_id = Column(String(8), ForeignKey('person.key_retro'))
    removed_for_pr_run2_id = Column(String(8), ForeignKey('person.key_retro'))
    removed_for_pr_run3_id = Column(String(8), ForeignKey('person.key_retro'))
    removed_for_ph_bat_id = Column(String(8), ForeignKey('person.key_retro'))
    removed_for_ph_bat_fld_cd = Column(Integer)
    po1_fld_cd = Column(Integer)
    po2_fld_cd = Column(Integer)
    po3_fld_cd = Column(Integer)
    ass1_fld_cd = Column(Integer)
    ass2_fld_cd = Column(Integer)
    ass3_fld_cd = Column(Integer)
    ass4_fld_cd = Column(Integer)
    ass5_fld_cd = Column(Integer)
    ### extended fields ###
    home_team_id = Column(String(3))
    bat_team_id = Column(String(3))
    fld_team_id = Column(String(3))
    bat_last_id = Column(Integer)
    inn_new_fl = Column(String(1))
    inn_end_fl = Column(String(1))
    start_bat_score_ct = Column(Integer)
    start_fld_score_ct = Column(Integer)
    inn_runs_ct = Column(Integer)
    game_pa_ct = Column(Integer)
    inn_pa_ct = Column(Integer)
    pa_new_fl = Column(String(1))
    pa_trunc_fl = Column(String(1))
    start_bases_cd = Column(Integer)
    end_bases_cd = Column(Integer)
    bat_start_fl = Column(String(1))
    resp_bat_start_fl = Column(String(1))
    pit_start_fl = Column(String(1))
    resp_pit_start_fl = Column(String(1))
    run1_fld_cd = Column(Integer)
    run1_lineup_cd = Column(Integer)
    run1_origin_event_id = Column(Integer)
    run2_fld_cd = Column(Integer)
    run2_lineup_cd = Column(Integer)
    run2_origin_event_id = Column(Integer)
    run3_fld_cd = Column(Integer)
    run3_lineup_cd = Column(Integer)
    run3_origin_event_id = Column(Integer)
    run1_resp_cat_id = Column(String(8))
    run2_resp_cat_id = Column(String(8))
    run3_resp_cat_id = Column(String(8))
    pa_ball_ct = Column(Integer)
    pa_called_ball_ct = Column(Integer, default = 0)
    pa_intent_ball_ct = Column(Integer)
    pa_pitchout_ball_ct = Column(Integer)
    pa_hitbatter_ball_ct = Column(Integer)
    pa_other_ball_ct = Column(Integer)
    pa_strike_ct = Column(Integer)
    pa_called_strike_ct = Column(Integer)
    pa_swingmiss_strike_ct = Column(Integer)
    pa_foul_strike_ct = Column(Integer)
    pa_inplay_strike_ct = Column(Integer)
    pa_other_strike_ct = Column(Integer)
    event_runs_ct = Column(Integer)
    fld_id = Column(String(8), ForeignKey('person.key_retro'))
    base2_force_fl = Column(String(1))
    base3_force_fl = Column(String(1))
    base4_force_fl = Column(String(1))
    bat_safe_err_fl = Column(String(1))
    bat_fate_id = Column(Integer)
    run1_fate_id = Column(Integer)
    run2_fate_id = Column(Integer)
    run3_fate_id = Column(Integer)
    fate_runs_ct = Column(Integer)
    ass6_fld_cd = Column(Integer)
    ass7_fld_cd = Column(Integer)
    ass8_fld_cd = Column(Integer)
    ass9_fld_cd = Column(Integer)
    ass10_fld_cd = Column(Integer)
    unknown_out_exc_fl = Column(String(1))
    uncertain_play_exc_fl = Column(String(1))
    ### event descriptions ###
    event_cd_tx = Column(String(4))
    event_cd_des = Column(String(30))
    ### weather ###
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)

    def __repr__(self):
        return '<Event(game_id = %s, event_id = %i, inning = %i)>' % \
                (self.game_id, self.event_id, self.inn_ct)

class Sub(Base):
    __tablename__ = 'sub'
    game_id = Column(String(12), ForeignKey('game_log.game_id'), primary_key = True)
    sub_id = Column(String(8), primary_key = True)
    sub_fld_cd = Column(Integer, primary_key = True)
    event_id = Column(Integer, primary_key = True)
    inn_ct = Column(Integer)
    bat_home_id = Column(Integer)
    sub_home_id = Column(Integer)
    sub_lineup_id = Column(Integer)
    removed_id = Column(String(8), primary_key = True)
    removed_fld_cd = Column(Integer)

    def __repr__(self):
        return '<Sub(game_id = %s, event_id = %i, inning = %i, remove = %s)>' % \
        (self.game_id, self.event_id, self.inn_ct, self.removed_id)

class Team(Base):
    __tablename__ = 'team'
    cur_fran_id = Column(String(3), primary_key = True)
    start_date = Column(Date, primary_key = True)
    fran_id = Column(String(3))
    lg = Column(String(3))
    div = Column(String(3))
    location = Column(String(15))
    name = Column(String(15))
    alt_name = Column(String(30))
    end_date = Column(Date)
    city = Column(String(15))
    state = Column(String(2))

    def __repr__(self):
        return '<Team(team_id = %s, city = %s, start = %i, end = %s)>' % \
        (self.fran_id, self.city, str(self.start_date), str(self.end_date))

class Person(Base):
    __tablename__ = 'person'
    key_person = Column(String(8), primary_key = True)
    key_uuid = Column(String(36))
    key_retro = Column(String(8))
    key_mlbam = Column(Integer)
    key_bbref = Column(String(9))
    key_bbref_minors = Column(String(12))
    key_fangraphs = Column(Integer)
    key_npb = Column(Integer)
    key_sr_nfl = Column(String(8))
    key_sr_nba = Column(String(10))
    key_sr_nhl = Column(String(9))
    key_findagrave = Column(Integer)
    name_last = Column(String(20))
    name_first = Column(String(20))
    name_given = Column(String(20))
    name_suffix = Column(String(20))
    name_matrilineal = Column(String(20))
    name_nick = Column(String(50))
    birth_year = Column(Integer)
    birth_month = Column(Integer)
    birth_day = Column(Integer)
    death_year = Column(Integer)
    death_month = Column(Integer)
    death_day = Column(Integer)
    pro_played_first = Column(Integer)
    pro_played_last = Column(Integer)
    mlb_played_first = Column(Integer)
    mlb_played_last = Column(Integer)
    col_played_first = Column(Integer)
    col_played_last = Column(Integer)
    pro_managed_first = Column(Integer)
    pro_managed_last = Column(Integer)
    mlb_managed_first = Column(Integer)
    mlb_managed_last = Column(Integer)
    col_managed_first = Column(Integer)
    col_managed_last = Column(Integer)
    pro_umpired_first = Column(Integer)
    pro_umpired_last = Column(Integer)
    mlb_umpired_first = Column(Integer)
    mlb_umpired_last = Column(Integer)

    @hybrid_property
    def birth_date(self):
        if self.birth_year is not None and self.birth_month is not None and self.birth_date is not None:
            return dt.date(self.birth_year, self.birth_month, self.birth_day)
        else:
            return None

    @hybrid_property
    def age(self):
        if self.birth_year is not None and self.birth_month is not None and self.birth_date is not None:
            today = dt.date.today()
            birthday = dt.date(self.birth_year, self.birth_month, self.birth_day)
            return relativedelta(today, birthday).years
        else:
            return None

    def __repr__(self):
        return '<Person(key_person = %s, first = %s, last = %s)>' % \
        (self.key_person, self.name_first, self.name_last)

class Park(Base):
    __tablename__ = 'park'
    park_id = Column(String(5), primary_key = True)
    name = Column(String(40))
    alias = Column(String(100))
    city = Column(String(20))
    state = Column(String(15))
    country = Column(String(2))
    venue_id = Column(Integer)

    def __repr__(self):
        return '<Park(park_id = %s, name = %s, city = %s)>' % \
        (self.park_id, self.name, self.city)

class Weather(Base):
    __tablename__ = 'weather'
    gid = Column(String(26), primary_key = True)
    datetime = Column(DateTime, primary_key = True)
    venue_id = Column(Integer)
    park_id = Column(String(5), ForeignKey('park.park_id'))
    temperature = Column(Float)
    heat_index = Column(Float)
    dew_point = Column(Float)
    humidity = Column(Float)
    pressure = Column(Float)
    visibility = Column(Float)
    wind_dir = Column(String(5))
    wind_speed = Column(Float)
    gust_speed = Column(Float)
    precipitation = Column(Float)

    def __repr__(self):
        return '<Weather(gid = %s, time = %s, temperature = %.1f)>' % \
        (self.gid, self.datetime.strftime('%H:%M'), self.temperature)

def create_db(engine):
    Base.metadata.create_all(engine)


# reference:https://benalexkeen.com/parallel-coordinates-in-matplotlib/

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker

# the reference set loaded as a numpy matrix
all_soln = np.loadtxt(open("GAA-reference-set.csv"), delimiter=",")
nd_indices = np.loadtxt(open("non-dominated-index.csv"), delimiter=",")

# identify and list the objectives of the reference set
objs = ['NOISE', 'WEMP', 'DOC', 'ROUGH', 'WFUEL', 'PURCH', 'RANGE', 'LDMAX', 'VCMAX', 'PFPF']

# create an array of integers ranging from 0 to the number of objectives
x = [i for i, _ in enumerate(objs)]

# sharey=False indicates that all the subplot y-axes will be set to different values
fig, ax = plt.subplots(1,len(x)-1, sharey=False, figsize=(15,5))

min_max_range = {}
for i in range(len(objs)):
    all_soln[:,i] = np.true_divide(all_soln[:,i] - min(all_soln[:,i]), np.ptp(all_soln[:,i]))
    min_max_range[objs[i]] = [min(all_soln[:,i]), max(all_soln[:,i]), np.ptp(all_soln[:,i])]

# enumerate through all the axes in the figure and plot the data
# only the first line of each
# blue for the nondominated solutions
# grey or everthing else
for i, ax_i in enumerate(ax):
    for d in range(len(all_soln)):
        if ((d in nd_indices)== False):
            if (d == 0):
                ax_i.plot(objs, all_soln[d, :], color='lightgrey', alpha=0.3, label='Dominated', linewidth=3)
            else:
                ax_i.plot(objs, all_soln[d, :], color='lightgrey', alpha=0.3, linewidth=3)
    ax_i.set_xlim([x[i], x[i+1]])

for i, ax_i in enumerate(ax):
    for d in range(len(all_soln)):
        if (d in nd_indices):
            if (d == nd_indices[0]):
                ax_i.plot(objs, all_soln[d, :], color='c', alpha=0.7, label='Nondominated', linewidth=3)
            else:
                ax_i.plot(objs, all_soln[d, :], color='c', alpha=0.7, linewidth=3)
    ax_i.set_xlim([x[i], x[i+1]])

# function for setting ticks and tick_lables along the y-axis of each subplot
def set_ticks_for_axis(dim, ax_i, ticks):
    min_val, max_val, v_range = min_max_range[objs[dim]]
    step = v_range/float(ticks)
    tick_labels = [round(min_val + step*i, 2) for i in range(ticks)]
    norm_min = min(all_soln[:,dim])
    norm_range = np.ptp(all_soln[:,dim])
    norm_step =(norm_range/float(ticks-1))
    ticks = [round(norm_min + norm_step*i, 2) for i in range(ticks)]
    ax_i.yaxis.set_ticks(ticks)
    ax_i.set_yticklabels(tick_labels)

# enumerating over each axis in fig2
for i in range(len(ax)):
    ax[i].xaxis.set_major_locator(ticker.FixedLocator([i]))  # set tick locations along the x-axis
    set_ticks_for_axis(i, ax[i], ticks=10)   # set ticks along the y-axis

# create a twin axis on the last subplot of fig2
# this will enable you to label the last axis with y-ticks
ax2 = plt.twinx(ax[-1])
dim = len(ax)
ax2.xaxis.set_major_locator(ticker.FixedLocator([x[-2], x [-1]]))
set_ticks_for_axis(dim, ax2, ticks=10)
ax2.set_xticklabels([objs[-2], objs[-1]])

plt.subplots_adjust(wspace=0, hspace=0.2, left=0.1, right=0.85, bottom=0.1, top=0.9)
ax[8].legend(bbox_to_anchor=(1.35, 1), loc='upper left', prop={'size': 14})
ax[0].set_ylabel("$\leftarrow$ Direction of preference", fontsize=12)
plt.title("PCP Example", fontsize=12)
plt.savefig("PCP_example.png")
plt.show()


from django.shortcuts import render,redirect,HttpResponse
from .models import *

def index(request):
    book_list=Book.objects.all()
    return render(request,"index.html",locals())

def add_book(request):
    if request.method=="POST":  #点击submit之后走这
        title=request.POST.get("title")
        price=request.POST.get("price")
        pub_date=request.POST.get("pub_date")
        publish_id=request.POST.get("publish_id")
        #  一对多的添加方式
        # 方式1：
        book_obj=Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
        # 方式2：
        # publish_obj=Publish.objects.filter(id=2).first()
        # book_obj=Book.objects.create(title=title, price=price, publishDate=pub_date,publish=publish_obj)
        return redirect("/index/")  #成功之后返回index
    publish_list=Publish.objects.all()      #为了渲染出版社
    return render(request,"add_book.html",locals())

def edit_book(request,edit_book_id):
    if request.method=="POST":
        title = request.POST.get("title")
        price = request.POST.get("price")
        pub_date = request.POST.get("pub_date")
        publish_id = request.POST.get("publish_id")
        Book.objects.filter(nid=edit_book_id).update(title=title,price=price,publishDate=pub_date,publish_id=publish_id)   #更新数据
        return redirect("/index/")
    edit_book=Book.objects.filter(nid=edit_book_id).first()
    publish_list = Publish.objects.all()
    return render(request,"edit_book.html",locals())

def del_book(request,del_book_id):
    Book.objects.filter(nid=del_book_id).delete()
    return redirect("/index/")

def query(request):
    book_obj=Book.objects.filter(nid=1).first()
    print(book_obj.title)
    print(book_obj.price)
    print(book_obj.publishDate)
    print(book_obj.publish_id)
    #print(book_obj.publish) # Publish object
    return HttpResponse("OK")


import pytest
import random
from pathlib import Path
import hashlib

from ophys_etl.modules.suite2p_wrapper.utils import copy_and_add_uid

def path_to_hash(file_path):
    """
    Return the MD5 checksum of the file at file_path
    """
    hasher = hashlib.md5()
    with open(file_path, 'rb') as in_file:
        chunk = in_file.read(10000)
        while len(chunk) > 0:
            hasher.update(chunk)
            chunk = in_file.read(10000)
    return str(hasher.hexdigest())

@pytest.mark.parametrize(
        "basenames, dstsubdir, use_mv, exception",
        [
            (['tmp.txt'], "other", False, False),
            (['tmp.txt', "tmp2.txt"], "other", False, False),
            (['tmp.txt', "tmp.txt"], "other", False, True),
            (['tmp.txt'], "other", True, False),
            (['tmp.txt', "tmp2.txt"], "other", True, False),
            (['tmp.txt', "tmp.txt"], "other", True, True),

            ])
def test_copy_and_add_uid(tmp_path,
                          basenames,
                          dstsubdir,
                          use_mv,
                          exception):
    srcfiles = {}
    for i, bname in enumerate(basenames):
        if i == 0:
            tfile = tmp_path / bname
        else:
            spath = tmp_path / "sub_dir"
            spath.mkdir(exist_ok=True)
            tfile = spath / bname
        with open(tfile, "w") as f:
            f.write("%032x" % random.getrandbits(128))
        srcfiles[bname] = str(tfile)

    other_dir = tmp_path / "other"
    other_dir.mkdir()

    uid = "extra"
    if exception:
        with pytest.raises(ValueError, match=r".* Expected 1 match."):
            dstfiles = copy_and_add_uid(
                    tmp_path,
                    other_dir,
                    basenames,
                    uid,
                    use_mv=use_mv)
    else:

        src_hash = dict()
        for bname in basenames:
            src_hash[bname] = path_to_hash(srcfiles[bname])

        dstfiles = copy_and_add_uid(
                tmp_path,
                other_dir,
                basenames,
                uid,
                use_mv=use_mv)

        for bname in basenames:
            src = Path(srcfiles[bname])
            dst = Path(dstfiles[bname][0])
            dst_hash = path_to_hash(dst)
            assert dst_hash == src_hash[bname]
            assert dst.name == src.stem + f"_{uid}" + src.suffix
            if use_mv:
                assert not src.exists()
            else:
                assert src.is_file()


import os
from flask import Flask, redirect,request,render_template,session
import sqlite3
import random
from datetime import datetime
import json
app=Flask(__name__)
db= 'personalDB.db'
try:
    with open('views.json','r') as f:
        views=json.loads(f.read())
except:

    views = 12
    with open('views.json','w') as f:
        json.dump(views,f)
def increment():
    global views
    views += 1
    with open('views.json','w') as f:
        json.dump(views,f)
@app.route('/')
def gohome():
    return redirect('home')
@app.route('/home')
def home():
    increment()
    return render_template('home.html')
@app.route('/plushies')
def plushies():
    if request.method =='GET':
        conn = sqlite3.connect(db)
        cur = conn.cursor()
        cur.execute('select * from Plushies order by dateObtained desc')
        plushie = cur.fetchall()
        print(plushie[0])
        return render_template('plushies.html',plosh=plushie)

if __name__ == '__main__':
    app.run(debug=True)


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 10 16:36:22 2020

@author: Trisha
"""
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import numpy as np
from time import time
import pandas as pd
import seaborn as sns

#%% Plot yearly trends
def YearlyTrendsPlot(dSup, P):
    avgP = np.mean(P, axis=1) #np.ones([(2020-1996),1])*

    Years = range(1996,2020)
    # order = [0,3,4,9,11,1,2,5,6,7,8,10,12,13,14]
    fig, ax = plt.subplots(1,3,figsize=(15,5),tight_layout = True)
    start = 0
    for s in range(3):
        end = start + 5
        for i in range(start,end):
            if i==1 or i==3 or i==7 or i==9 or i==6 or i==0:
                ax[s].plot(Years,P[:,i],'-',label=str(i)+' '+str(dSup.topWords[i][:3]), lw = 2)
            else:
                ax[s].plot(Years,P[:,i],'-',label=str(i)+' '+str(dSup.topWords[i][:1]),alpha = 0.3, lw = 2)
        ax[s].plot(Years,avgP,'--')
        ax[s].set_xlabel('Year', fontsize=15)
        ax[s].set_ylabel('Topic Popularity', fontsize=15)
        ax[s].set_ylim([0, 0.4])
        ax[s].legend(loc='lower left', bbox_to_anchor= (0.0, 1.01), ncol=1,
                borderaxespad=0, frameon=False, fontsize=12)
        start = end
    plt.show()

#%% WOrdcloud for overall topics
def TopicWordClout(dSup):
    # Create a list of word
    text = []
    freq = []
    for i in range(len(dSup)):
        for j in range(3):
            text.append(dSup.loc[i].topWords[j])
            freq.append(float(dSup.loc[i].Popularity))

    freq = np.hstack(freq)
    text = np.hstack(text)
    dictionary = dict(zip(text, freq))

    # Create the wordcloud object
    wordcloud = WordCloud(width=480*3, height=480*2, margin=0, colormap='autumn',max_font_size=150, min_font_size=30,
                          background_color='black').fit_words(dictionary)

    # Display the generated image:
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis("off")
    plt.margins(x=10, y=10)
    plt.show()

#%% Plot the number of authors per paper
def CollaborationPlot(dfPlot):
    dfPlot['#Authors'] = dfPlot['#Authors'].astype(float)
    plt.figure(figsize=(10,6))
    ax = sns.boxplot(x="Year", y="#Authors",
                  data=dfPlot, showfliers=False)
    plt.xlabel('Year', fontsize=18)
    plt.ylabel('Authors / Paper', fontsize=18)
    ax.tick_params(axis="x", labelsize=8)
    ax.tick_params(axis="y", labelsize=18)
    plt.show()


import numpy as np
import cv2

import datetime

from essh_detector import ESSHDetector
import argparse
import os

def detect_faces(video, output, w, h, detect_faces_on_img):
    out = cv2.VideoWriter(output, cv2.VideoWriter_fourcc(*'MJPG'), 10, (w, h))

    vs = cv2.VideoCapture(video)
    i = 0

    while True:
        frame = vs.read()[1]

        if frame is None:
            break

        if i % 3 == 0:
            frame = detect_faces_on_img(frame)
            out.write(frame)
        i += 1

    out.release()

class ESSHModel:
    def __init__(self):
        self.total_time = 0
        self.scales = [1200, 1600]
        self.t = 10
        self.esshDetector = ESSHDetector('./model/essh-r50', 0, ctx_id=-1)

    def detect_faces(self, video, output):
        self.total_time = 0
        detect_faces(video, output, 640, 360, self.detect_faces_on_img)
        return self.total_time

    def detect_faces_on_img(self, img):
        im_shape = img.shape
        target_size = self.scales[0]
        max_size = self.scales[1]
        im_size_min = np.min(im_shape[0:2])
        im_size_max = np.max(im_shape[0:2])
        if im_size_min > target_size or im_size_max > max_size:
            im_scale = float(target_size) / float(im_size_min)
            # prevent bigger axis from being more than max_size:
            if np.round(im_scale * im_size_max) > max_size:
                im_scale = float(max_size) / float(im_size_max)
            img = cv2.resize(img, None, None, fx=im_scale, fy=im_scale)
            print('resize to', img.shape)

        # for i in range(t - 1):  # warmup
        #     faces = esshDetector.detect(img)
        timea = datetime.datetime.now()

        faces = self.esshDetector.detect(img, threshold=0.5)
        # print("DETECTED!!!!!!!")
        bbox = np.round(faces[:, 0:5])
        landmark = faces[:, 5:15].reshape(-1, 5, 2)

        timeb = datetime.datetime.now()
        diff = timeb - timea
        diff = diff.total_seconds()
        self.total_time += diff
        # print('detection uses', diff.total_seconds(), 'seconds')
        # print('find', faces.shape[0], 'faces')

        for b in bbox:
            cv2.rectangle(img, (int(b[0]), int(b[1])), (int(b[2]), int(b[3])), (0, 255, 0), 2)
        for p in landmark:
            for i in range(5):
                cv2.circle(img, (p[i][0], p[i][1]), 1, (0, 0, 255), 2)
        return img

def parse_args():
    parser = argparse.ArgumentParser(description='Run detectors')
    parser.add_argument('--video', help='Video', default=None, type=str)
    parser.add_argument('--vroot', help='Video root', default=None, type=str)
    parser.add_argument('-s', help='Save video with detections directory', default=None, type=str)

    args = parser.parse_args()
    return args

def main():
    args = parse_args()
    model = ESSHModel()

    if args.video is not None:
        model.detect_faces(args.video, '{}_essh_detected.avi'.format(args.video))
    else:
        videos = os.listdir(args.vroot)

        for video in videos:
            print('======\nPocessing video : {}\n======'.format(video))
            model.detect_faces(args.vroot + os.sep + video,
                               args.s + os.sep + '{}_essh_detected.avi'.format(video[:-4]))

if __name__ == '__main__':
    main()


import pathlib
from enum import Enum

currentDir = []
treeMap = {}

TOTAL_SYSTEM_SPACE = 70000000
REQUIRED_FREE_SYSTEM_SPACE = 30000000

class Command(Enum):
    CD = 1
    LS = 2

class Filetype(Enum):
    FILE = 1
    DIR = 2

class Item():
    name = "",
    size = 0
    filetype = Filetype.FILE
    def __init__(self, name, size, filetype):
        self.name = name
        self.size = size
        self.filetype = filetype

def openFile(filename):
    currentPath = pathlib.Path(__file__).parent.resolve()
    filepath = pathlib.Path(currentPath, filename)
    return open(filepath)

def getLines(filename):
    lines = []
    for line in openFile(filename):
        lines.append(line.strip())
    return lines

def isCommand(line):
    return line[0] == "$"

def isDir(line):
    return line.split(" ")[0] == "dir"

def isFile(line):
    return line.split(" ")[0].isnumeric()

def getCommandString(line):
    return line.split(" ")[1].strip().lower()

def currentDirStr():
    return '/'.join(currentDir)

def getCommand(line):
    commandString = getCommandString(line)
    if commandString == "cd":
        return Command.CD
    elif commandString == "ls":
        return Command.LS
    else:
        raise Exception(commandString + " is not a command")

def getCdParam(line):
    return line.split(" ")[2].strip().lower()

def cd(dirParam):
    if dirParam == "..":
        print("* Going up a directory *")
        currentDir.pop()
    else:
        print("* Changing to", dirParam, "*")
        currentDir.append(dirParam)
        if currentDirStr() not in treeMap:
            treeMap[currentDirStr()] = []

def executeCommand(line):
    if getCommand(line) == Command.CD:
        dirParam = getCdParam(line)
        cd(dirParam)

def printFile(file):
    print(f'- {file.name} (file, size={file.size})')

def printDir(file):
    print( f'- {file.name} (dir)')

def printTree():
    for dir in treeMap:
        print(dir, "(dir)")
        for item in treeMap[dir]:
            if item.filetype == Filetype.DIR:
                printDir(item)
            else:
                printFile(item)

def getDirSize(dir):
    totalSize = 0
    for item in treeMap[dir]:
        if item.filetype == Filetype.FILE:
            totalSize += item.size
        elif item.filetype == Filetype.DIR:
            pathname = dir + "/" + item.name
            totalSize += getDirSize(pathname)
    return totalSize

def addFileToTree(line):
    size, name = line.split(" ")
    size = int(size)
    treeMap[currentDirStr()].append(Item(name, size, Filetype.FILE))

def addDirToTree(line):
    size = 0
    name = line.split(" ")[1]
    treeMap[currentDirStr()].append(Item(name, size, Filetype.DIR))

def getTotalDirSizesWithUpperLimit(upperLimit):
    total = 0
    dirSizes = [getDirSize(dir) for dir in treeMap.keys()]

    for dirSize in dirSizes:
        if dirSize < upperLimit:
            total += dirSize

    return total

def getUnusedSpace():
    return TOTAL_SYSTEM_SPACE - getDirSize("/")

def findSmallestDirSizeAboveSize(minimum):
    dirSizes = []
    for dir in treeMap.keys():
        dirSizes.append(getDirSize(dir))
    dirSizes = sorted(dirSizes)
    for size in dirSizes:
        if size > minimum:
            return size

def main():
    lines = getLines('input.txt')
    for line in lines:
        if isDir(line):
            print("Dir", line)
            addDirToTree(line)
        elif isFile(line):
            print("File", line)
            addFileToTree(line)
        elif isCommand(line):
            print("Command", line)
            executeCommand(line)
        print(" -", currentDir)
    print()
    printTree()
    print()
    print(treeMap.keys())
    print()
    print("Getting total dir sizes under 100,000")
    print(getTotalDirSizesWithUpperLimit(100000))
    print()
    print("Total space:", TOTAL_SYSTEM_SPACE)
    print("Used space:", getDirSize("/"))
    print("Unused space:", getUnusedSpace())
    print("Required unused space:", REQUIRED_FREE_SYSTEM_SPACE)
    needToFreeUp = REQUIRED_FREE_SYSTEM_SPACE-getUnusedSpace()
    print("Need to free up at least:", needToFreeUp)
    smallestDirSizeAboveSize = findSmallestDirSizeAboveSize(needToFreeUp)
    print("Found dir with size:",smallestDirSizeAboveSize)

main()


from pytest import mark, fixture
from os import path, remove
from moneytoring.csv import setup_csv
from sys import argv

@fixture
def get_dummy_csv_file_path():
    """

    Returns:
        [type]: [description]
    """
    file_path = path.join(path.dirname(__file__), "utils/dummy.csv")
    return file_path

def test_setup_csv(get_dummy_csv_file_path):
    """

    Args:
        get_dummy_csv_file_path ([type]): [description]
    """
    try:
        setup_csv(path=get_dummy_csv_file_path)
        assert path.exists(path.join(path.dirname(
            path.dirname(__file__)), "transactions.csv"))
        remove(path.join(path.dirname(
            path.dirname(__file__)), "transactions.csv"))
    except Exception:
        assert False

def test_wrong_path():
    try:
        setup_csv(path="path/to/nowhere")
    except FileNotFoundError:
        expected_path = path.join(path.dirname(
            path.dirname(__file__)), "transactions.csv")
        assert not path.exists(expected_path)

def test_no_path():
    try:
        setup_csv()
        assert False
    except FileNotFoundError:
        assert True


import nibabel
import os
import numpy
import json
import base64
import StringIO
import PIL
from packaging import version

# Cubicweb import
import cubicweb
cw_version = version.parse(cubicweb.__version__)
if cw_version >= version.parse("3.21.0"):
    from cubicweb import _

from cubicweb.view import View
from cubicweb.web.views.ajaxcontroller import ajaxfunc
from cubicweb.predicates import authenticated_user

###############################################################################
# BrainBrowser
###############################################################################

class ImageViewer(View):
    """ Create an image viewer.
    """
    __regid__ = "brainbrowser-image-viewer"
    __select__ = authenticated_user()
    title = _("Brainbrowser")
    paginable = False
    div_id = "brainbrowser-simple"

    def __init__(self, *args, **kwargs):
        """ Initialize the ImageViewer class.

        If you want to construct the viewer manually in your view pass the
        parent view in the 'parent_view' attribute.
        """
        super(ImageViewer, self).__init__(*args, **kwargs)
        if "parent_view" in kwargs:
            self._cw = kwargs["parent_view"]._cw
            self.w = kwargs["parent_view"].w

    def call(self, imagefiles=None, **kwargs):
        """ Method that will create a simple BrainBrowser image viewer.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the paths that will be rendered.
        """
        # Get the parameters
        imagefiles = imagefiles or self._cw.form.get("imagefiles", "")

        # Guarantee that we have a list of paths
        if not isinstance(imagefiles, list):
            imagefiles = [imagefiles]

        # Get the path to the in progress resource
        wait_image_url = self._cw.data_url("images/please_wait.gif")

        # Add css resources
        self._cw.add_css("brainbrowser-2.3.0/css/ui-darkness/"
                         "jquery-ui-1.8.10.custom.css")
        self._cw.add_css("brainbrowser-2.3.0/css/common.css")
        self._cw.add_css("volume-viewer.css")

        # Add js resources
        self._cw.add_js("brainbrowser-2.3.0/src/jquery-1.6.4.min.js")
        self._cw.add_js("brainbrowser-2.3.0/src/"
                        "jquery-ui-1.8.10.custom.min.js")
        self._cw.add_js("brainbrowser-2.3.0/src/ui.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "brainbrowser.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/core/"
                        "tree-store.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/lib/"
                        "config.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/lib/"
                        "utils.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/lib/"
                        "events.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/lib/"
                        "loader.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/lib/"
                        "color-map.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/lib/display.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/lib/panel.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/lib/utils.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/modules/loading.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/modules/rendering.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/volume-loaders/overlay.js")
        self._cw.add_js("brainbrowser-2.3.0/src/brainbrowser/"
                        "volume-viewer/volume-loaders/minc.js")
        self._cw.add_js("image_viewer.js")

        # Set the brainbrowser viewer navigation tools
        html = self.build_brainbrowser_tools()

        # Create a div for the in progress resource
        html += ("
"
                 "
".format(wait_image_url))

        # Build a brainborwser banner with tools
        html += self.build_brainbrowser_banner(imagefiles)

        # Set brainbrowser colormaps
        html += self.build_color_maps()

        # Define global javascript variables
        html += ""

        # Set brainbrowser nifti image loader
        html += self.build_nifti_image_loader()

        # Set a callback to select the qulity of the rendering
        html += self.build_quality_callback(imagefiles)

        # Set a callback to select an image to render
        html += self.build_image_callback(imagefiles)

        # Set a callback to select the rendering
        html += self.build_rendering_callback(imagefiles)

        # Set the cw brainbrowser image loader
        html += self.build_cw_loader(imagefiles, 0, True)

        html += 'BrainBrowser© visualisation tool :'
        html += '
'
        html += '
Lead Developer

Tarek Sherif
'
        html += '
Full credits

BrainBrowser Website
'
        html += '
'

        # Creat the corresponding html page
        self.w(unicode(html))

    def build_nifti_image_loader(self):
        """ Define a nifti image loader for BrainBrowser based on a CubicWeb
        ajax callback.

        Returns
        -------
        html: str
            the nifti loader definition.
        """
        # Add javascript
        html = ""

        return html

    def build_cw_loader(self, imagefiles, index=0, decorated=False,
                        multiview=False):
        """ Define the script that will load the image in BrainBrowser.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the paths that will be rendered.
        index: int (optional, default 0)
            the index of the image to render.
        decorated: bool (optional, default False)
            add the javascript tag.
        multiview: bool (optional, default False)
            display all the images at the same time.

        Returns
        -------
        html: str
            the loader definition.
        """
        # Add javascript
        html = ""
        if decorated:
            html += ""

        return html

    def build_quality_callback(self, imagefiles):
        """ Define the rendering quality callback.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the images that will be rendered.

        Returns
        -------
        html: str
            the quality definition.
        """
        # Add javascript
        html = ""

        return html

    def build_rendering_callback(self, imagefiles):
        """ Define the rendering callback.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the images that will be rendered.

        Returns
        -------
        html: str
            the rendering definition.
        """
        # Add javascript
        html = ""

        return html

    def build_image_callback(self, imagefiles, decorated=True):
        """ Define the on image change callback.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the paths that will be rendered.
        decorated: bool (optional, default True)
            add the javascript tag.

        Returns
        -------
        html: str
            the callback definition.
        """
        # Add javascript
        html = ""
        if decorated:
            html += ""

        return html

    def build_color_maps(self):
        """ Define the BrainBrowser color-maps.

        Returns
        -------
        html: str
            the color-maps definition.
        """
        # Go through colormaps
        html = ""

        return html

    def build_brainbrowser_tools(self, time=True, contrast=False,
                                 brightness=False):
        """ Define the default BrainBrowser tools.

        Parameters
        ----------
        time: bool (optional, default False)
            add control to display time serie images.
        contrast, brightness: bool (optional, default False)
            add extra controls (not recommended).

        Returns
        -------
        html: str
            the tools definition.
        """
        # Start javascript
        html = ""

        return html

    def build_brainbrowser_banner(self, imagefiles):
        """ Define the default BrainBrowser banner.

        Parameters
        ----------
        imagefiles: list of str (mandatory)
            the path to the paths that will be rendered.

        Returns
        -------
        html: str
            the banner definition.
        """
        # Define a banner divs
        html = "
"
        html += "
"
        html += "
"

        # Define item to select the image rendering
        html += "Select rendering:"
        html += "<select id='volume-rendering'>"
        html += "<option value='single'>Single</option>"
        html += "<option value='multi'>Multi</option>"
        html += "</select>"

        # Define item to select the image to be displayed
        html += "<select id='volume-type'>"
        for cnt, path in enumerate(imagefiles):
            html += "<option value='{0}'>{1}</option>".format(
                cnt, os.path.basename(path))
        html += "</select>"

        # Define item to change the panle size
        html += "<select id='volume-quality'>"
        html += "<option value='RAW' SELECTED>RAW</option>"
        # html += "<option value='LOW JPEG' SELECTED>LOW JPEG</option>"
        html += "</select>"

        # Define item to change the panel size
        html += "Panel size:"
        html += "<select id='panel-size'>"
        html += "<option value='128'>128</option>"
        html += "<option value='256' SELECTED>256</option>"
        html += "<option value='512'>512</option>"
        html += "</select>"

        # Define item to reset displayed views
        # html += ""
        # html += ("<input type='checkbox' class='button' id='reset-volumes'>"
        #          "Reset")
        # html += ""

        # Define item to create a screenshot
        html += "Screenshot"
        html += ("
Shift-click to drag. Hold ctrl "
                 "to measure distance.
")

        # End divs
        html += "
"
        html += "

"
        html += "
"
        html += "
"

        return html

###############################################################################
# Interact with jtable js
###############################################################################

@ajaxfunc(output_type="json")
def get_encoded_brainbrowser_image(self):
    """ Get image information and encoded buffer: formated for BrainBrowser.

    Returns
    -------
    im_info: dict
        the image information and encoded buffer.
    """
    # Get post parameters
    imagefile = self._cw.form["imagefile"]
    dquality = int(self._cw.form["dquality"])
    dtype = "JPEG"

    # Load the image
    im = nibabel.load(imagefile)
    header = im.get_header()
    data = im.get_data()

    # Change the dynamic of the image intensities
    data = numpy.cast[numpy.uint8](
        (data - data.min()) * 255. / (data.max() - data.min()))

    # Build header and encode images
    dim = header["dim"]
    order = ["time", "xspace", "yspace", "zspace"]
    encoded_data = []
    if dim[0] == 3:

        # Build header
        header = {
            "order": order[1:],
            "xspace": {
                "start": float(header["qoffset_x"]),
                "space_length": int(dim[1]),
                "step": float(header["pixdim"][1]),
                "direction_cosines": [float(x) for x in header["srow_x"][:3]]},
            "yspace": {
                "start": float(header["qoffset_y"]),
                "space_length": int(dim[2]),
                "step": float(header["pixdim"][2]),
                "direction_cosines": [float(x) for x in header["srow_y"][:3]]},
            "zspace": {
                "start": float(header["qoffset_z"]),
                "space_length": int(dim[3]),
                "step": float(header["pixdim"][3]),
                "direction_cosines": [float(x) for x in header["srow_z"][:3]]},
        }

        # Encode the slice image data
        for index in range(data.shape[0]):
            slicedata = data[index]
            openfile = StringIO.StringIO()
            img = PIL.Image.fromarray(slicedata)
            img.save(openfile, format=dtype, quality=dquality)
            contents = openfile.getvalue()
            openfile.close()
            encoded_data.append(base64.b64encode(contents))

    elif dim[0] == 4:

        # Build header
        header = {
            "order": order,
            "xspace": {
                "start": float(header["qoffset_x"]),
                "space_length": int(dim[1]),
                "step": float(header["pixdim"][1]),
                "direction_cosines": [float(x) for x in header["srow_x"][:3]]},
            "yspace": {
                "start": float(header["qoffset_y"]),
                "space_length": int(dim[2]),
                "step": float(header["pixdim"][2]),
                "direction_cosines": [float(x) for x in header["srow_y"][:3]]},
            "zspace": {
                "start": float(header["qoffset_z"]),
                "space_length": int(dim[3]),
                "step": float(header["pixdim"][3]),
                "direction_cosines": [float(x) for x in header["srow_z"][:3]]},
            "time": {
                "start": 0,
                "space_length": int(dim[4])}
        }

        # Encode the slice image data
        data = numpy.transpose(data, (3, 0, 1, 2))
        for timepoint in range(data.shape[0]):
            for index in range(data.shape[1]):
                slicedata = data[timepoint, index]
                openfile = StringIO.StringIO()
                img = PIL.Image.fromarray(slicedata)
                img.save(openfile, format=dtype)
                contents = openfile.getvalue()
                openfile.close()
                encoded_data.append(base64.b64encode(contents))
    else:
        raise Exception("Only 3D or 3D + t images are currently supported!")

    # Format the output
    im_info = {
        "header": json.dumps(header),
        "data": encoded_data
    }

    return im_info

@ajaxfunc(output_type="json")
def get_brainbrowser_image(self):
    """ Get image information and buffer: formated for BrainBrowser.

    Returns
    -------
    im_info: dict
        the image information and buffer.
    """
    # Get post parameters
    imagefile = self._cw.form["imagefile"]

    # Load the image
    im = nibabel.load(imagefile)
    header = im.get_header()
    try:
        data = im.get_data()
    # Missing bytes intern specific error that can be overcome with
    # an old lib
    except:
        import nifti
        im = nifti.NiftiImage(imagefile)
        data = im.getDataArray().T

    # Change the dynamic of the image intensities
    data = numpy.cast[numpy.uint16](
        (data - data.min()) * 65535. / (data.max() - data.min()))

    # Format the output
    dim = header["dim"]
    order = ["time", "xspace", "yspace", "zspace"]
    if dim[0] == 3:
        header = {
            "order": order[1:],
            "xspace": {
                "start": float(header["qoffset_x"]),
                "space_length": int(dim[1]),
                "step": float(header["pixdim"][1]),
                "direction_cosines": [float(x) for x in header["srow_x"][:3]]},
            "yspace": {
                "start": float(header["qoffset_y"]),
                "space_length": int(dim[2]),
                "step": float(header["pixdim"][2]),
                "direction_cosines": [float(x) for x in header["srow_y"][:3]]},
            "zspace": {
                "start": float(header["qoffset_z"]),
                "space_length": int(dim[3]),
                "step": float(header["pixdim"][3]),
                "direction_cosines": [float(x) for x in header["srow_z"][:3]]},
        }
    elif dim[0] == 4:
        header = {
            "order": order,
            "xspace": {
                "start": float(header["qoffset_x"]),
                "space_length": int(dim[1]),
                "step": float(header["pixdim"][1]),
                "direction_cosines": [float(x) for x in header["srow_x"][:3]]},
            "yspace": {
                "start": float(header["qoffset_y"]),
                "space_length": int(dim[2]),
                "step": float(header["pixdim"][2]),
                "direction_cosines": [float(x) for x in header["srow_y"][:3]]},
            "zspace": {
                "start": float(header["qoffset_z"]),
                "space_length": int(dim[3]),
                "step": float(header["pixdim"][3]),
                "direction_cosines": [float(x) for x in header["srow_z"][:3]]},
            "time": {
                "start": 0,
                "space_length": int(dim[4])}
        }
        data = numpy.transpose(data, (3, 0, 1, 2))
    else:
        raise Exception("Only 3D or 3D + t images are currently supported!")

    # Format the output
    im_info = {
        "header": json.dumps(header),
        "data": data.flatten().tolist()
    }

    return im_info

###############################################################################
# Update CW registery
###############################################################################

def registration_callback(vreg):
    vreg.register(get_brainbrowser_image)
    vreg.register(get_encoded_brainbrowser_image)
    vreg.register(ImageViewer)


# pylint: disable=C0330
"""
This python file includes server side functions which help to provide
schedule suggestions to the client.
"""
from datetime import timedelta, datetime

def suggest_generator(schedule_dict, suggest_dict):

    """
    A function which takes in a schedule list with times (in chronological order
    AND in 12 hour format, as a string),and a list of items not currently in the
    schedule along with their durations.It outputs a list of suggestions on where
    to fit the itemsinto the current schedule.This function assumes the user starts
    their day at 8:00 am and ends it at 11:59PM

    Time Complexity: O(N*M)
    Here N is the amount of items in the input schedule, and M is the amount of
    items in the suggestions input list. It is worth noting, a user can only physically
    input a limited amount of tasks for a day. So let's say they input a task for each
    minute of the day (very unrealistic but still). This is the highest frequency of events
    they could enter into the app. Therefore the max schedule length will be 1,440. The user
    can still input infinitely many items into the suggestions list theoretically. With this
    logic we can assume that the time complexity is O(M).
    """
    time_start_list = []
    time_end_list = []
    suggest_list = []

    if len(schedule_dict) != 0:
        # Stripping the times in datetime format to make code easier to read
        for item in schedule_dict:
            time_start_list.append(datetime.strptime(item["startTime"], "%I:%M %p"))
            time_end_list.append(datetime.strptime(item["endTime"], "%I:%M %p"))

        initial_time = datetime.strptime("8:00 AM", "%I:%M %p")

        for i in range(len(time_start_list) + 1):
            if i == len(time_start_list):
                floor_time = datetime.strptime("11:59 PM", "%I:%M %p")
            else:
                floor_time = time_start_list[i]

            time_difference = floor_time - initial_time

            for item in suggest_dict:

                suggest_duration = datetime.strptime(
                    item["duration"], "%H hour(s) %M minute(s)"
                )

                # time differance needs to be greater than the event duration plus one hour
                if time_difference > timedelta(
                    hours=suggest_duration.hour + 1, minutes=suggest_duration.minute
                ):
                    start = initial_time.time().strftime("%I:%M %p")
                    end = floor_time.time().strftime("%I:%M %p")

                    string_start_suggest = (
                        (initial_time + timedelta(minutes=30))
                        .time()
                        .strftime("%I:%M %p")
                    )
                    string_end_suggest = (
                        (
                            initial_time
                            + timedelta(minutes=30)
                            + timedelta(
                                hours=suggest_duration.hour,
                                minutes=suggest_duration.minute,
                            )
                        )
                        .time()
                        .strftime("%I:%M %p")
                    )
                    suggest_list.append(
                        {
                            "suggestStartTime": string_start_suggest,
                            "suggestEndTime": string_end_suggest,
                            "suggestEvent": item["suggestion"],
                            "suggestion": "You have enough time to "
                            + item["suggestion"]
                            + " between "
                            + start
                            + " and "
                            + end
                            + ". Would you like to "
                            + item["suggestion"]
                            + " from "
                            + string_start_suggest
                            + " to "
                            + string_end_suggest
                            + " today? (click OK to add, and click cancel to see more suggestions)",
                        }
                    )
            # If all schedule events have been inspected then the loop exists
            if i == len(time_start_list):
                break

            initial_time = time_end_list[i]

    return suggest_list

def sort_dict_time_regular(schedule_dict):
    """
    This function sorts the input schedule dictionary in chronological
    order when events are in regular 12 hour time format.
    """
    if len(schedule_dict) != 0:
        schedule_dict = sorted(
            schedule_dict, key=lambda x: datetime.strptime(x["startTime"], "%I:%M %p")
        )
    return schedule_dict

def convert_schedule_to_reg_time(schedule_dict):

    """
    This function converts a dictionary with both 12hr (ie 10:00 AM) and 24 hr (23:00, 1:00)
    time formats to the same 12 hour format.

    Time Complexity: O(N) where N is the amount of events in the input Schedule dictionary
    Technically the user can input a max of 1,440 events into the schedule so using this logic
    the time complexity is O(1)
    """
    converted_dict = []
    for item in schedule_dict:
        try:
            converted_item_start = datetime.strptime(
                item["startTime"], "%I:%M %p"
            ).strftime("%I:%M %p")
            converted_item_end = datetime.strptime(
                item["endTime"], "%I:%M %p"
            ).strftime("%I:%M %p")
            converted_dict.append(
                {
                    "event": item["event"],
                    "startTime": converted_item_start,
                    "endTime": converted_item_end,
                }
            )
        except ValueError:
            converted_item_start = datetime.strptime(
                item["startTime"], "%H:%M"
            ).strftime("%I:%M %p")
            converted_item_end = datetime.strptime(item["endTime"], "%H:%M").strftime(
                "%I:%M %p"
            )
            converted_dict.append(
                {
                    "event": item["event"],
                    "startTime": converted_item_start,
                    "endTime": converted_item_end,
                }
            )
    return converted_dict


# -*- coding: utf-8 -*-
"""
Created on Wed Feb 23 16:28:01 2022

@author: Mateus
"""

import cv2
import glob

red_lights = [img for img in glob.glob("./assets/add_decision_tree/red/*.jpg")]
yellow_lights = [img for img in glob.glob("./assets/add_decision_tree/yellow/*.jpg")]
green_lights = [img for img in glob.glob("./assets/add_decision_tree/green/*.jpg")]

images = red_lights + yellow_lights + green_lights

if __name__ == '__main__':
    i=0

    for image in images:
        img = cv2.imread(image, 0)

        # cv2.imshow("capture", img)

        cv2.imwrite('./imagesGray/'+str(i)+'.jpg',img)
        i+=1

        # k=cv2.waitKey(1)
        # if k==ord('s'):
        #     cv2.imwrite('./images/'+str(i)+'.jpg',frame)
        #     i+=1
        #     print('SALVOU')
        # elif k==ord("q"):
        #     break

    cv2.waitKey(0)
    cv2.destroyAllWindows()


#
import logging
from typing import Optional, Dict, Tuple

from torch import Tensor

import torch
import torch.nn as nn

from lib.utils import count_parameters, SupObs
from lib.networks.encoders import NodeEncoder, VRPCenterEncoder
import lib.networks.decoders as decoders

logger = logging.getLogger(__name__)

class VRPModel(nn.Module):
    """
    Model wrapping encoder and decoder models.

    Args:
        input_dim: input dimension of nodes
        decoder_type: type of decoder to use
        node_encoder_args: additional arguments for encoder creation
        center_encoder_args:
        decoder_args: additional arguments for decoder creation
        embedding_dim: general embedding dimension of model

    """

    def __init__(self,
                 input_dim: int,
                 decoder_type: str = "PointwiseDecoder",
                 node_encoder_args: Optional[Dict] = None,
                 center_encoder_args: Optional[Dict] = None,
                 decoder_args: Optional[Dict] = None,
                 embedding_dim: int = 256,
                 **kwargs):
        super(VRPModel, self).__init__()

        self.input_dim = input_dim
        self.decoder_type = decoder_type
        self.node_encoder_args = node_encoder_args if node_encoder_args is not None else {}
        self.center_encoder_args = center_encoder_args if center_encoder_args is not None else {}
        self.decoder_args = decoder_args if decoder_args is not None else {}
        self.embedding_dim = embedding_dim

        # initialize encoder models
        self.node_encoder = NodeEncoder(
            input_dim=input_dim,
            output_dim=embedding_dim,
            edge_feature_dim=1,
            **self.node_encoder_args, **kwargs
        )

        self.center_encoder = VRPCenterEncoder(
            input_dim=embedding_dim,
            output_dim=embedding_dim,
            **self.center_encoder_args, **kwargs
        )

        # initialize decoder model
        d_cl = getattr(decoders, decoder_type)
        self.decoder = d_cl(
            center_emb_dim=embedding_dim,
            node_emb_dim=embedding_dim,
            **self.decoder_args, **kwargs
        )

        self.reset_parameters()

    def __repr__(self):
        super_repr = super().__repr__()  # get torch module str repr
        n_enc_p = count_parameters(self.node_encoder)
        c_enc_p = count_parameters(self.center_encoder)
        dec_p = count_parameters(self.decoder)
        add_repr = f"\n-----------------------------------" \
                   f"\nNum Parameters: " \
                   f"\n  (node_encoder): {n_enc_p} " \
                   f"\n  (center_encoder): {c_enc_p} " \
                   f"\n  (decoder): {dec_p} " \
                   f"\n  total: {n_enc_p + c_enc_p + dec_p}\n"
        return super_repr + add_repr

    def reset_parameters(self):
        """Reset model parameters."""
        self.node_encoder.reset_parameters()
        self.center_encoder.reset_parameters()
        self.decoder.reset_parameters()

    def forward(self,
                nodes: Tensor,
                centroids: Tensor,
                medoids: Tensor,
                c_mask: Optional[Tensor] = None,
                edges: Optional[Tensor] = None,
                weights: Optional[Tensor] = None,
                node_emb: Optional[Tensor] = None,
                assignment: Optional[Tensor] = None,
                n_mask: Optional[Tensor] = None,
                ) -> Tuple[Tensor, Tensor]:
        """

        Args:
            nodes: (BS, N, D)
            centroids: (BS, K, 2)
            medoids: (BS, K)
            c_mask: (BS, K)     # masks dummy centers
            edges: (2, BSM, )
            weights: (BSM, )
            node_emb: (BS, N, emb_dim)
            assignment: (BS, N, )
            n_mask: (BS, N, )   # masks nodes

        Returns:

        """
        bs, n, d = nodes.size()
        assert len(medoids.shape) == 2
        assert len(centroids.shape) == 3
        assert medoids.size(0) == centroids.size(0) == bs

        if node_emb is None:
            # run node encoder to create node embeddings
            obs = SupObs(
                stat_node_features=nodes,
                stat_edges=edges,   # type: ignore
                stat_weights=weights,
            )
            node_emb = self.node_encoder(obs).view(bs, -1, self.embedding_dim)
        else:
            assert node_emb.size(0) == bs and \
                   node_emb.size(1) == n and \
                   node_emb.size(2) == self.embedding_dim

        # encode centers
        center_emb = self.center_encoder(
            centroids, medoids, node_emb, c_mask, assignment
        )

        scores = self.decoder(
            center_emb=center_emb,
            node_emb=node_emb[:, 1:],   # without depot node!
            mask=n_mask,
        )
        return scores, node_emb

# ============= #
# ### TEST #### #
# ============= #
def _test():
    from torch.utils.data import DataLoader
    from lib.ltr.utils import NPZProblemDataset, collate_batch

    PTH = "data/VRP/VRP200/raw/train_mixed_unf0.2_n200_kmax30_s5120_cap1_1_seed1234_labeled_part0.npz"
    BS = 8
    CUDA = False
    SEED = 123
    IDIM = 3

    device = torch.device("cuda" if CUDA else "cpu")
    torch.manual_seed(SEED-1)
    data = NPZProblemDataset(npz_file_pth=PTH)
    dl = DataLoader(
        data,
        batch_size=BS,
        collate_fn=lambda x: x,  # identity -> returning simple list of instances
        shuffle=False,
        num_workers=0
    )

    model = VRPModel(
        input_dim=IDIM,
        embedding_dim=64,
        center_encoder_args=None
    )
    model.to(device=device)

    for i, batch in enumerate(dl):
        if i >= 2:
            break

        x, y = collate_batch(batch, device=device, vrp=True)

        scores, node_emb = model(
            nodes=x.nodes,
            centroids=x.centroids,
            c_mask=x.c_mask,
            edges=x.edges,
            weights=x.weights,
        )


import cv2
import numpy as np

img = cv2.imread("unidade 01\decomposicao_img_bits\imgs\desafio-esteganografia.png")

if img is None:
    print("Erro ao abrir a imagem")
    exit()

img_carrier = np.copy(img)
img_encoded = np.copy(img)
nbits = 3

img_carrier = img >> nbits << nbits
img_encoded = img << (8 - nbits)

cv2.imshow("Imagem portadora", img_carrier)
cv2.imshow("Imagem codificada", img_encoded)
cv2.waitKey()