<commit_before>#!/usr/bin/env python

import requests
import click
import leagueids
import authtoken
import json
import teamnames
import leagueproperties

BASE_URL = 'http://api.football-data.org/alpha/'
LIVE_URL = 'http://soccer-cli.appspot.com/'
LEAGUE_IDS = leagueids.LEAGUE_IDS
headers = {
    'X-Auth-Token': authtoken.API_TOKEN
}
TEAM_NAMES = teamnames.team_names
LEAGUE_PROPERTIES = leagueproperties.LEAGUE_PROPERTIES

def get_live_scores():
    """ Gets the live scores """

    req = requests.get(LIVE_URL)
    if req.status_code == 200:
        scores = req.json()
        if len(scores["games"]) == 0:
            click.secho("No live action currently", fg="red", bold=True)
            return
        print_live_scores(scores)
    else:
        click.secho("There was problem getting live scores", fg="red", bold=True)

def print_live_scores(live_scores):
    """ Prints the live scores in a pretty format """

    for game in live_scores["games"]:
        click.echo()
        click.secho("%s\t" % game["league"], fg="green", nl=False)
        if game["goalsHomeTeam"] > game["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (game["homeTeamName"], game["goalsHomeTeam"]),
                bold=True, fg="red", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (game["goalsAwayTeam"], game["awayTeamName"]),
                fg="blue", nl=False)
        else:
            click.secho('%-20s %-5d' % (game["homeTeamName"], game["goalsHomeTeam"]),
                fg="blue", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (game["goalsAwayTeam"], game["awayTeamName"]),
                bold=True, fg="red", nl=False)
        click.secho('%s' % game["time"], fg="yellow")
        click.echo()

def get_team_scores(team, time):
    """ Queries the API and gets the particular team scores """

    team_id = TEAM_NAMES.get(team, None)
    if team_id:
        req = requests.get('{base_url}teams/{team_id}/fixtures?timeFrame=p{time}'.format(
            base_url=BASE_URL, team_id=team_id, time=time), headers=headers)
        if req.status_code == 200:
            team_scores = req.json()
            if len(team_scores["fixtures"]) == 0:
                click.secho("No action during past week. Change the time \
                    parameter to get more fixtures.", fg="red", bold=True)
            else:
                print_team_scores(team_scores)
        else:
            click.secho("No data for the team. Please check the team code.",
                fg="red", bold=True)
    else:
        click.secho("No data for the team. Please check the team code.",
            fg="red", bold=True)

def print_team_scores(team_scores):
    """ Prints the teams scores in a pretty format """

    for score in team_scores["fixtures"]:
        if score["status"] == "FINISHED":
            click.echo()
            click.secho("%s\t" % score["date"].split('T')[0], fg="green", nl=False)
            if score["result"]["goalsHomeTeam"] > score["result"]["goalsAwayTeam"]:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), bold=True, fg="red", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), fg="blue")
            elif score["result"]["goalsHomeTeam"] < score["result"]["goalsAwayTeam"]:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), fg="blue", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), bold=True, fg="red")
            else:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), bold=True, fg="yellow", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), bold=True, fg="yellow")
            click.echo()

def get_standings(league):
    """ Queries the API and gets the standings for a particular league """

    if not league:
        click.secho("Please specify a league. Example --standings --league=EPL",
            fg="red", bold=True)
        return

    league_id = LEAGUE_IDS[league]
    req = requests.get('{base_url}soccerseasons/{id}/leagueTable'.format(
            base_url=BASE_URL, id=league_id), headers=headers)
    if req.status_code == 200:
        print_standings(req.json(), league)
    else:
        click.secho("No standings availble for {league}.".format(league=league),
            fg="red", bold=True)

def print_standings(league_table, league):
    """ Prints the league standings in a pretty way """

    click.secho("%-6s  %-30s    %-10s    %-10s    %-10s" %
                ("POS", "CLUB", "PLAYED", "GOAL DIFF", "POINTS"))
    positionlist = [team["position"] for team in league_table["standing"]]
    for team in league_table["standing"]:
        if team["goalDifference"] >= 0:
            team["goalDifference"] = ' ' + str(team["goalDifference"])
        if LEAGUE_PROPERTIES[league]["cl"][0] <= team["position"] <= LEAGUE_PROPERTIES[league]["cl"][1]:
            click.secho("%-6s  %-30s    %-10s    %-10s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), str(team["goalDifference"]), str(team["points"])),
                bold=True, fg="green")
        elif LEAGUE_PROPERTIES[league]["rl"][0] <= team["position"] <= LEAGUE_PROPERTIES[league]["rl"][1]:  # 5-15 in BL, 5-17 in others
            click.secho("%-6s  %-30s    %-10s    %-10s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), str(team["goalDifference"]), str(team["points"])),
                fg="red")
        else:
            click.secho("%-6s  %-30s    %-10s    %-10s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), str(team["goalDifference"]), str(team["points"])),
                fg="blue")

def get_scores(league, time):
    """ Queries the API and fetches the scores for fixtures
    based upon the league and time parameter """

    if league:
        league_id = LEAGUE_IDS[league]
        fixtures_results = requests.get('{base_url}soccerseasons/{id}/fixtures?timeFrame=p{time}'.format(
            base_url=BASE_URL, id=league_id, time=str(time)), headers=headers).json()

        # no fixtures in the past wee. display a help message and return
        if len(fixtures_results["fixtures"]) == 0:
            click.secho("No {league} matches in the past week.".format(league=league),
                fg="red", bold=True)
            return

        print_league_scores(fixtures_results)
        return

    fixtures_results = requests.get('{base_url}fixtures?timeFrame=p{time}'.format(
        base_url=BASE_URL, time=str(time)), headers=headers).json()
    print_league_scores(fixtures_results)

def print_league_scores(total_data):
    """ Prints the data in a pretty format """

    for data in total_data["fixtures"]:
        if data["result"]["goalsHomeTeam"] > data["result"]["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (data["homeTeamName"],
                data["result"]["goalsHomeTeam"]),
                bold=True, fg="red", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), fg="blue")
        elif data["result"]["goalsHomeTeam"] < data["result"]["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (data["homeTeamName"], data["result"]["goalsHomeTeam"]),
                fg="blue", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), bold=True, fg="red")
        else:
            click.secho('%-20s %-5d' % (data["homeTeamName"], data["result"]["goalsHomeTeam"]),
                bold=True, fg="yellow", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), bold=True, fg="yellow")
        click.echo()

@click.command()
@click.option('--live', is_flag=True, help= 'Shows live scores from various leagues')
@click.option('--standings', is_flag=True, help= 'Standings for a particular league')
@click.option('--league', '-league', type=click.Choice(LEAGUE_IDS.keys()),
    help= (
        "Choose the league whose fixtures you want to see. Bundesliga(BL), Premier League(EPL), La Liga (LLIGA),"
        "Serie A(SA), Ligue 1(FL), Eredivisie(DED), Primeira Liga(PPL), Champions League(CL)')"
    )
)
@click.option('--team', type=click.Choice(TEAM_NAMES.keys()),
    help= (
        "Choose the team whose fixtures you want to see. See the various team codes listed on README')"
    )
)
@click.option('--time', default=6,
    help='The number of days for which you want to see the scores')
def main(league, time, standings, team, live):
    """ A CLI for live and past football scores from various football leagues """

    if live:
        get_live_scores()
        return

    if standings:
        get_standings(league)
        return

    if team:
        get_team_scores(team, time)
        return

    get_scores(league, time)

if __name__ == '__main__':
    main()
<commit_msg>fixed conflicts<commit_after>#!/usr/bin/env python

import requests
import click
import leagueids
import authtoken
import json
import teamnames
import leagueproperties

BASE_URL = 'http://api.football-data.org/alpha/'
LIVE_URL = 'http://soccer-cli.appspot.com/'
LEAGUE_IDS = leagueids.LEAGUE_IDS
headers = {
    'X-Auth-Token': authtoken.API_TOKEN
}
TEAM_NAMES = teamnames.team_names
LEAGUE_PROPERTIES = leagueproperties.LEAGUE_PROPERTIES

def get_live_scores():
    """ Gets the live scores """

    req = requests.get(LIVE_URL)
    if req.status_code == 200:
        scores = req.json()
        if len(scores["games"]) == 0:
            click.secho("No live action currently", fg="red", bold=True)
            return
        print_live_scores(scores)
    else:
        click.secho("There was problem getting live scores", fg="red", bold=True)

def print_live_scores(live_scores):
    """ Prints the live scores in a pretty format """

    for game in live_scores["games"]:
        click.echo()
        click.secho("%s\t" % game["league"], fg="green", nl=False)
        if game["goalsHomeTeam"] > game["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (game["homeTeamName"], game["goalsHomeTeam"]),
                bold=True, fg="red", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (game["goalsAwayTeam"], game["awayTeamName"]),
                fg="blue", nl=False)
        else:
            click.secho('%-20s %-5d' % (game["homeTeamName"], game["goalsHomeTeam"]),
                fg="blue", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (game["goalsAwayTeam"], game["awayTeamName"]),
                bold=True, fg="red", nl=False)
        click.secho('%s' % game["time"], fg="yellow")
        click.echo()

def get_team_scores(team, time):
    """ Queries the API and gets the particular team scores """

    team_id = TEAM_NAMES.get(team, None)
    if team_id:
        req = requests.get('{base_url}teams/{team_id}/fixtures?timeFrame=p{time}'.format(
            base_url=BASE_URL, team_id=team_id, time=time), headers=headers)
        if req.status_code == 200:
            team_scores = req.json()
            if len(team_scores["fixtures"]) == 0:
                click.secho("No action during past week. Change the time \
                    parameter to get more fixtures.", fg="red", bold=True)
            else:
                print_team_scores(team_scores)
        else:
            click.secho("No data for the team. Please check the team code.",
                fg="red", bold=True)
    else:
        click.secho("No data for the team. Please check the team code.",
            fg="red", bold=True)

def print_team_scores(team_scores):
    """ Prints the teams scores in a pretty format """

    for score in team_scores["fixtures"]:
        if score["status"] == "FINISHED":
            click.echo()
            click.secho("%s\t" % score["date"].split('T')[0], fg="green", nl=False)
            if score["result"]["goalsHomeTeam"] > score["result"]["goalsAwayTeam"]:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), bold=True, fg="red", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), fg="blue")
            elif score["result"]["goalsHomeTeam"] < score["result"]["goalsAwayTeam"]:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), fg="blue", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), bold=True, fg="red")
            else:
                click.secho('%-20s %-5d' % (score["homeTeamName"],
                    score["result"]["goalsHomeTeam"]), bold=True, fg="yellow", nl=False)
                click.secho("vs\t", nl=False)
                click.secho('%d %-10s\t' % (score["result"]["goalsAwayTeam"],
                    score["awayTeamName"]), bold=True, fg="yellow")
            click.echo()

def get_standings(league):
    """ Queries the API and gets the standings for a particular league """

    if not league:
        click.secho("Please specify a league. Example --standings --league=EPL",
            fg="red", bold=True)
        return

    league_id = LEAGUE_IDS[league]
    req = requests.get('{base_url}soccerseasons/{id}/leagueTable'.format(
            base_url=BASE_URL, id=league_id), headers=headers)
    if req.status_code == 200:
        print_standings(req.json(), league)
    else:
        click.secho("No standings availble for {league}.".format(league=league),
            fg="red", bold=True)

def print_standings(league_table, league):
    """ Prints the league standings in a pretty way """

    click.secho("%-6s  %-30s    %-10s    %-10s    %-10s" %
                ("POS", "CLUB", "PLAYED", "GOAL DIFF", "POINTS"))
    positionlist = [team["position"] for team in league_table["standing"]]
    for team in league_table["standing"]:
        if team["goalDifference"] >= 0:
            team["goalDifference"] = ' ' + str(team["goalDifference"])
        if LEAGUE_PROPERTIES[league]["cl"][0] <= team["position"] <= LEAGUE_PROPERTIES[league]["cl"][1]:
            click.secho("%-6s  %-30s    %-9s    %-11s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), team["goalDifference"],str(team["points"])),
                bold=True, fg="green")
        elif LEAGUE_PROPERTIES[league]["rl"][0] <= team["position"] <= LEAGUE_PROPERTIES[league]["rl"][1]:  # 5-15 in BL, 5-17 in others
            click.secho("%-6s  %-30s    %-9s    %-11s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), team["goalDifference"],str(team["points"])),
                fg="red")
        else:
            click.secho("%-6s  %-30s    %-9s    %-11s    %-10s" %
                (str(team["position"]), team["teamName"],
                str(team["playedGames"]), team["goalDifference"],str(team["points"])),
                fg="blue")

def get_scores(league, time):
    """ Queries the API and fetches the scores for fixtures
    based upon the league and time parameter """

    if league:
        league_id = LEAGUE_IDS[league]
        fixtures_results = requests.get('{base_url}soccerseasons/{id}/fixtures?timeFrame=p{time}'.format(
            base_url=BASE_URL, id=league_id, time=str(time)), headers=headers).json()

        # no fixtures in the past wee. display a help message and return
        if len(fixtures_results["fixtures"]) == 0:
            click.secho("No {league} matches in the past week.".format(league=league),
                fg="red", bold=True)
            return

        print_league_scores(fixtures_results)
        return

    fixtures_results = requests.get('{base_url}fixtures?timeFrame=p{time}'.format(
        base_url=BASE_URL, time=str(time)), headers=headers).json()
    print_league_scores(fixtures_results)

def print_league_scores(total_data):
    """ Prints the data in a pretty format """

    for data in total_data["fixtures"]:
        if data["result"]["goalsHomeTeam"] > data["result"]["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (data["homeTeamName"],
                data["result"]["goalsHomeTeam"]),
                bold=True, fg="red", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), fg="blue")
        elif data["result"]["goalsHomeTeam"] < data["result"]["goalsAwayTeam"]:
            click.secho('%-20s %-5d' % (data["homeTeamName"], data["result"]["goalsHomeTeam"]),
                fg="blue", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), bold=True, fg="red")
        else:
            click.secho('%-20s %-5d' % (data["homeTeamName"], data["result"]["goalsHomeTeam"]),
                bold=True, fg="yellow", nl=False)
            click.secho("vs\t", nl=False)
            click.secho('%d %-10s\t' % (data["result"]["goalsAwayTeam"],
                data["awayTeamName"]), bold=True, fg="yellow")
        click.echo()

@click.command()
@click.option('--live', is_flag=True, help= 'Shows live scores from various leagues')
@click.option('--standings', is_flag=True, help= 'Standings for a particular league')
@click.option('--league', '-league', type=click.Choice(LEAGUE_IDS.keys()),
    help= (
        "Choose the league whose fixtures you want to see. Bundesliga(BL), Premier League(EPL), La Liga (LLIGA),"
        "Serie A(SA), Ligue 1(FL), Eredivisie(DED), Primeira Liga(PPL), Champions League(CL)')"
    )
)
@click.option('--team', type=click.Choice(TEAM_NAMES.keys()),
    help= (
        "Choose the team whose fixtures you want to see. See the various team codes listed on README')"
    )
)
@click.option('--time', default=6,
    help='The number of days for which you want to see the scores')
def main(league, time, standings, team, live):
    """ A CLI for live and past football scores from various football leagues """

    if live:
        get_live_scores()
        return

    if standings:
        get_standings(league)
        return

    if team:
        get_team_scores(team, time)
        return

    get_scores(league, time)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python3

import datetime
import random
import sys

class Stats:
  def __init__(self):
    self._curEq = None
    self._results = []

  def startEq(self, eq):
    self._curEq = eq
    self._start = datetime.datetime.now()

  def endCurrent(self, correct):
    if self._curEq == None:
      return
    self._results.append((self._curEq, datetime.datetime.now() - self._start, correct))
    self._curEq = None

  def cancleCurrent(self):
    self._curEq = None

  def getStats(self):
    stats = {}
    stats['total'] = len(self._results)
    stats['correct'] = len(list(filter(lambda x: x[2], self._results)))
    stats['percent'] = stats['correct'] * 100.0 / stats['total']
    stats['rt'] = (sum(map(lambda x: x[1], self._results), datetime.timedelta()) / stats['total']).total_seconds() * 1000
    return stats

class Trainer:
  def __init__(self, mode):
    if mode == '':
      mode = 'mult'
    self._mode = mode
    self._stats = Stats()
    self._eqs = []
    self._generateEquations()
    self._ops = {
      '*': lambda x, y: x*y,
      '^': lambda x, y: x**y,
      '√': lambda x, y: round(y**(1.0/x))
    }

  def askEquation(self):
    if len(self._eqs) == 0:
      self._showStats()
      print('Done. One next round...')
      self._generateEquations()
    eq = self._eqs.pop()
    self._stats.startEq(eq)
    result, paused = self._readNumber('%d %s %d = ' % eq)
    if paused:
      self._stats.cancleCurrent()
    if result != self._ops[eq[1]](eq[0], eq[2]):
      self._stats.endCurrent(False)
      print('Wrong: %d %s %d = %d' % (eq[0], eq[1], eq[2], self._ops[eq[1]](eq[0], eq[2])))
      self._eqs.append(eq)
      random.shuffle(self._eqs)
    else:
      self._stats.endCurrent(True)
      print('Correct!')

  def run(self):
    try:
      while True:
        self.askEquation()
    except KeyboardInterrupt:
      self._showStats()

  def _showStats(self):
    stats = self._stats.getStats()
    print('\nStatistic:\n  Correct: %d of %d (%.2f %%)\n  Average time per response: %d msec' % (stats['correct'], stats['total'], stats['percent'], stats['rt']))

  def _generateEquations(self):
    if 'multbig' in self._mode:
      self._eqs += [(x, '*', y) for x in range(1, 21) for y in range(1, 21)]
    elif 'mult' in self._mode:
      self._eqs += [(x, '*', y) for x in range(1, 10) for y in range(1, 10)]
    if 'pow' in self._mode:
      self._eqs += [(x, '^', y) for x in range(1, 10) for y in range(2, 4)]
      self._eqs += [(x, '^', 2) for x in range(10, 31)]
    if 'root' in self._mode:
      self._eqs += [(y, '√', x**y) for x in range(1, 10) for y in range(2, 4)]
      self._eqs += [(2, '√', x**2) for x in range(10, 21)]
    if len(self._eqs) == 0:
      raise ValueError('%s is not supported.\nKnown parameters are: mult, multbig, pow, root.' % self._mode)
    random.shuffle(self._eqs)

  @staticmethod
  def _readNumber(prompt):
    paused = False
    while True:
      try:
        number = int(input(prompt))
      except ValueError:
        print('Not a Number. Retry...')
        continue
      except KeyboardInterrupt:
        paused = True
        try:
          input('\nPaused. Press ctrl+C again to exit. Enter to continue...')
        except KeyboardInterrupt as i:
          raise i
        continue
      break
    return (number, paused)

if __name__ == '__main__':
  try:
    trainer = Trainer(''.join(sys.argv[1:]))
    trainer.run()
  except ValueError as v:
    print(v)<commit_msg>Add roots up to 30<commit_after>#!/usr/bin/env python3

import datetime
import random
import sys

class Stats:
  def __init__(self):
    self._curEq = None
    self._results = []

  def startEq(self, eq):
    self._curEq = eq
    self._start = datetime.datetime.now()

  def endCurrent(self, correct):
    if self._curEq == None:
      return
    self._results.append((self._curEq, datetime.datetime.now() - self._start, correct))
    self._curEq = None

  def cancleCurrent(self):
    self._curEq = None

  def getStats(self):
    stats = {}
    stats['total'] = len(self._results)
    stats['correct'] = len(list(filter(lambda x: x[2], self._results)))
    stats['percent'] = stats['correct'] * 100.0 / stats['total']
    stats['rt'] = (sum(map(lambda x: x[1], self._results), datetime.timedelta()) / stats['total']).total_seconds() * 1000
    return stats

class Trainer:
  def __init__(self, mode):
    if mode == '':
      mode = 'mult'
    self._mode = mode
    self._stats = Stats()
    self._eqs = []
    self._generateEquations()
    self._ops = {
      '*': lambda x, y: x*y,
      '^': lambda x, y: x**y,
      '√': lambda x, y: round(y**(1.0/x))
    }

  def askEquation(self):
    if len(self._eqs) == 0:
      self._showStats()
      print('Done. One next round...')
      self._generateEquations()
    eq = self._eqs.pop()
    self._stats.startEq(eq)
    result, paused = self._readNumber('%d %s %d = ' % eq)
    if paused:
      self._stats.cancleCurrent()
    if result != self._ops[eq[1]](eq[0], eq[2]):
      self._stats.endCurrent(False)
      print('Wrong: %d %s %d = %d' % (eq[0], eq[1], eq[2], self._ops[eq[1]](eq[0], eq[2])))
      self._eqs.append(eq)
      random.shuffle(self._eqs)
    else:
      self._stats.endCurrent(True)
      print('Correct!')

  def run(self):
    try:
      while True:
        self.askEquation()
    except KeyboardInterrupt:
      self._showStats()

  def _showStats(self):
    stats = self._stats.getStats()
    print('\nStatistic:\n  Correct: %d of %d (%.2f %%)\n  Average time per response: %d msec' % (stats['correct'], stats['total'], stats['percent'], stats['rt']))

  def _generateEquations(self):
    if 'multbig' in self._mode:
      self._eqs += [(x, '*', y) for x in range(1, 21) for y in range(1, 21)]
    elif 'mult' in self._mode:
      self._eqs += [(x, '*', y) for x in range(1, 10) for y in range(1, 10)]
    if 'pow' in self._mode:
      self._eqs += [(x, '^', y) for x in range(1, 10) for y in range(2, 4)]
      self._eqs += [(x, '^', 2) for x in range(10, 31)]
    if 'root' in self._mode:
      self._eqs += [(y, '√', x**y) for x in range(1, 10) for y in range(2, 4)]
      self._eqs += [(2, '√', x**2) for x in range(10, 31)]
    if len(self._eqs) == 0:
      raise ValueError('%s is not supported.\nKnown parameters are: mult, multbig, pow, root.' % self._mode)
    random.shuffle(self._eqs)

  @staticmethod
  def _readNumber(prompt):
    paused = False
    while True:
      try:
        number = int(input(prompt))
      except ValueError:
        print('Not a Number. Retry...')
        continue
      except KeyboardInterrupt:
        paused = True
        try:
          input('\nPaused. Press ctrl+C again to exit. Enter to continue...')
        except KeyboardInterrupt as i:
          raise i
        continue
      break
    return (number, paused)

if __name__ == '__main__':
  try:
    trainer = Trainer(''.join(sys.argv[1:]))
    trainer.run()
  except ValueError as v:
    print(v)<|endoftext|>


<commit_before>#!/usr/bin/env python3

from datetime import datetime
import json
import logging.config
import operator
import os
import shelve
import smtplib

from investor import investor

operators = { ">" : operator.gt, ">=" : operator.ge, "<" : operator.lt, "<=" : operator.le, "==" : operator.eq, "!=" : operator.ne }

def filter(loan, exclusion_rules):
	try:
		for rule in exclusion_rules:
			p = True
			comp = rule['comp']
			if comp == 'None':
				comp = None

			# Catch the case where the key value should be None but it isn't
			if loan[rule['key']] != None and comp == None:
				return False
			# Toss loans that do not define the key required by the filter
			if loan[rule['key']] == None and comp != None:
				return False

			# Handle normal comparisons
			if not rule['op'] in operators:
				logger.warn('Unknown operator %s' % (rule['op']))
				p = False
			else:
				op = operators[rule['op']]
				p = not op(loan[rule['key']], comp)

			if not p:
				logger.debug('Value (%s) %s %s' % (loan[rule['key']], rule['op'], comp))
				return False
	except:
		logger.error('Error parsing filter:\nRule: %s\nLoan: %s' % (rule, loan), exc_info=True)
		return False
	return True

def email_notification(recipient, num_loans, email_body=""):
	sender = 'auto-invest@domain.com'
	message = """From: Auto-Invest <%s>
To: <%s>
Subject: %s LendingClub Notes Purchased

%s""" % (sender, recipient, num_loans, email_body)

	try:
		s = smtplib.SMTP('localhost')
		s.sendmail(sender, recipient, message)
		logger.info("Notification email sent successfully.")
	except:
		logger.warn("Failed to send notification email.")
	return

def add_to_db(db_file, loans):
	db = shelve.open(db_file)
	for loan in loans:
		if str(loan['id']) not in db:
			logger.info("Adding loan %s to database" % loan['id'])
			db[str(loan['id'])] = loan
	db.close()
	return

def main():
	rules = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'rules.json')
	cfg_data = json.load(open(rules))
	exclusion_rules = cfg_data['exclusions']
	conf = cfg_data['config']
	db = 'loans.db'

	i = investor(conf['iid'], conf['auth'])

    # Retrieve list of loans and and notes that I current own
	new_loans = i.get_new_loans(showAll=True)
	my_note_ids = i.get_my_note_ids()

	# Filter list
	new_loans = [ loan for loan in new_loans if filter(loan, exclusion_rules) ]
	new_loans = [ loan for loan in new_loans if loan['id'] not in my_note_ids ]

	if not len(new_loans):
		logger.info('No new loans found. Exiting')
		return
	logger.info('Found %s loans to invest in.' % (len(new_loans)))

	# Save loans away for characterization later
	add_to_db(db, new_loans)

	# Bail out if we don't have enough cash to invest
	available_cash = i.get_cash()
	if available_cash < conf['orderamnt']:
		logger.info('Exiting. Not enough cash to invest')
		return

	# Hell yeah, let's order
	#if 'yes' in input('Are you sure you wish to invest in these loans? (yes/no): '):
	num_loans = min( int(available_cash) / conf['orderamnt'], len(new_loans))
	if i.submit_order(new_loans[0 : num_loans]):
		email_notification(conf['email'], num_loans, email_body="Purchased %s loans at %s"%(num_loans, datetime.now()))

	return

if __name__ == "__main__":
	# TODO: This is ugly
	log_config = 'logging.json'
	logging.config.dictConfig(json.load(open(log_config, 'rt')))
	logger = logging.getLogger('investor')

	main()

<commit_msg>Add logging<commit_after>#!/usr/bin/env python3

from datetime import datetime
import json
import logging.config
import operator
import os
import shelve
import smtplib

import investor

operators = { ">" : operator.gt, ">=" : operator.ge, "<" : operator.lt, "<=" : operator.le, "==" : operator.eq, "!=" : operator.ne }

def filter(loan, exclusion_rules):
	try:
		for rule in exclusion_rules:
			p = True
			comp = rule['comp']
			if comp == 'None':
				comp = None

			# Catch the case where the key value should be None but it isn't
			if loan[rule['key']] != None and comp == None:
				return False
			# Toss loans that do not define the key required by the filter
			if loan[rule['key']] == None and comp != None:
				return False

			# Handle normal comparisons
			if not rule['op'] in operators:
				logger.warn('Unknown operator %s' % (rule['op']))
				p = False
			else:
				op = operators[rule['op']]
				p = not op(loan[rule['key']], comp)

			if not p:
				logger.debug('Value (%s) %s %s' % (loan[rule['key']], rule['op'], comp))
				return False
	except:
		logger.error('Error parsing filter:\nRule: %s\nLoan: %s' % (rule, loan), exc_info=True)
		return False
	return True

def email_notification(recipient, num_loans, email_body=""):
	sender = 'auto-invest@domain.com'
	message = """From: Auto-Invest <%s>
To: <%s>
Subject: %s LendingClub Notes Purchased

%s""" % (sender, recipient, num_loans, email_body)

	try:
		s = smtplib.SMTP('localhost')
		s.sendmail(sender, recipient, message)
		logger.info("Notification email sent successfully.")
	except:
		logger.warn("Failed to send notification email.")
	return

def add_to_db(db_file, loans):
	db = shelve.open(db_file)
	for loan in loans:
		if str(loan['id']) not in db:
			logger.info("Adding loan %s to database" % loan['id'])
			db[str(loan['id'])] = loan
	db.close()
	return

def main():
	rules = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'rules.json')
	cfg_data = json.load(open(rules))
	exclusion_rules = cfg_data['exclusions']
	conf = cfg_data['config']
	db = 'loans.db'

	i = investor.investor(conf['iid'], conf['auth'])

    # Retrieve list of loans and and notes that I current own
	new_loans = i.get_new_loans(showAll=True)
	my_note_ids = i.get_my_note_ids()

	# Filter list
	logger.info('Applying filters to %s loans.' % (len(new_loans)))
	new_loans = [ loan for loan in new_loans if filter(loan, exclusion_rules) ]
	new_loans = [ loan for loan in new_loans if loan['id'] not in my_note_ids ]

	if not len(new_loans):
		logger.info('No new loans pass filters. Exiting')
		return

	# Save loans away for characterization later
	logger.info('%s loans pass filters. Adding them to database' % (len(new_loans)))
	add_to_db(db, new_loans)

	# Bail out if we don't have enough cash to invest
	available_cash = i.get_cash()
	if available_cash < conf['orderamnt']:
		logger.warning('Exiting. Not enough cash to invest')
		return

	# Hell yeah, let's order
	#if 'yes' in input('Are you sure you wish to invest in these loans? (yes/no): '):
	num_loans = min( int(available_cash) / conf['orderamnt'], len(new_loans))
	logger.info('Placing order with %s loans.' % (num_loans))
	if i.submit_order(new_loans[0 : num_loans]):
		email_notification(conf['email'], num_loans, email_body="Purchased %s loans at %s"%(num_loans, datetime.now()))

	return

if __name__ == "__main__":
	# TODO: This is ugly
	log_config = 'logging.json'
	logging.config.dictConfig(json.load(open(log_config, 'rt')))
	logger = logging.getLogger('investor')

	main()

<|endoftext|>


<commit_before>from agarnet.agarnet import client
from agarnet.agarnet import utils
import pygame
from pygame import gfxdraw
from pygame.locals import *
import sys
import math
import time
import random
import gui
import stats
from subscriber import DummySubscriber
from interval_utils import *

# global vars
sub = DummySubscriber()
c = client.Client(sub)
stats = stats.Stats()

# find out server and token to connect
try:
    token = sys.argv[1]
    addr, *_ = utils.get_party_address(token)
except:
    addr, token, *_ = utils.find_server()

# connect
c.connect(addr,token)
c.send_facebook(
            'g2gDYQFtAAAAEKO6L3c8C8/eXtbtbVJDGU5tAAAAUvOo7JuWAVSczT5Aj0eo0CvpeU8ijGzKy/gXBVCxhP5UO+ERH0jWjAo9bU1V7dU0GmwFr+SnzqWohx3qvG8Fg8RHlL17/y9ifVWpYUdweuODb9c=')

c.player.nick="test cell pls ignore"

# initialize GUI
gui.set_client(c)

# main loop
while True:
    c.on_message()

    gui.draw_frame()

    if len(list(c.player.own_cells)) > 0:
        runaway=False

        my_smallest = min(map(lambda cell : cell.mass, c.player.own_cells))
        my_largest = max(map(lambda cell : cell.mass, c.player.own_cells))

        forbidden_intervals = []
        for cell in c.world.cells.values():
            relpos = ((cell.pos[0]-c.player.center[0]),(cell.pos[1]-c.player.center[1]))
            dist = math.sqrt(relpos[0]**2+relpos[1]**2)

            if (not cell.is_virus and dist < 300+2*cell.size and  cell.mass > 1.1 * my_smallest) or (cell.is_virus and dist < cell.size and cell.mass < my_largest):
                angle = math.atan2(relpos[1],relpos[0])
                corridor_width = 2 * math.asin(cell.size / dist)
                forbidden_intervals += canonicalize_angle_interval((angle-corridor_width, angle+corridor_width))
                runaway=True

        if c.player.center[0] < c.world.top_left[1]+c.player.total_size:
            forbidden_intervals += [(0.5*pi, 1.5*pi)]
        if c.player.center[0] > c.world.bottom_right[1]-c.player.total_size:
            forbidden_intervals += [(0,0.5*pi), (1.5*pi, 2*pi)]
        if c.player.center[1] < c.world.top_left[0]+c.player.total_size:
            forbidden_intervals += [(0, pi)]
        if c.player.center[1] > c.world.bottom_right[0]-c.player.total_size:
            forbidden_intervals += [(pi, 2*pi)]

        if (runaway):
            forbidden_intervals = merge_intervals(forbidden_intervals)

            for i in forbidden_intervals:
                gui.draw_arc(c.player.center, c.player.total_size+10, i, (255,0,255))

            allowed_intervals = invert_angle_intervals(forbidden_intervals)

            (a,b) = find_largest_angle_interval(allowed_intervals)
            runaway_angle = (a+b)/2
            runaway_x, runaway_y = (c.player.center[0]+int(100*math.cos(runaway_angle))), (c.player.center[1]+int(100*math.sin(runaway_angle)))

            c.send_target(runaway_x, runaway_y)
            print ("Running away: " + str((runaway_x-c.player.center[0], runaway_y-c.player.center[1])))
            gui.draw_line(c.player.center, (runaway_x,runaway_y),(255,0,0))
        else:
            food = list(filter(lambda x: x.is_food or x.mass <= sorted(c.player.own_cells, key = lambda x: x.mass)[0].mass * 0.75 and not x.is_virus, c.world.cells.values()))
            def dist(cell): return math.sqrt((cell.pos[0]-c.player.center[0])**2 + (cell.pos[1]-c.player.center[1])**2)
            food = sorted(food, key = dist)

            if len(food) > 0:
                c.send_target(food[0].pos[0], food[0].pos[1])
                gui.draw_line(c.player.center, food[0].pos,(0,0,255))
                print("Found food at: " + str(food[0].pos))
            else:
                rx = c.player.center[0] + random.randrange(-400, 401)
                ry = c.player.center[1] + random.randrange(-400, 401)
                c.send_target(rx, ry)
                gui.draw_line(c.player.center, (rx, ry),(0,255,0))
                print("Nothing to do, heading to random destination: " + str((rx, ry)))

        gui.update()
        stats.log_pos(c.player.center)
        stats.log_mass(c.player.total_mass)
<commit_msg>Fixed the jerky target selection<commit_after>from agarnet.agarnet import client
from agarnet.agarnet import utils
import pygame
from pygame import gfxdraw
from pygame.locals import *
import sys
import math
import time
import random
import gui
import stats
from subscriber import DummySubscriber
from interval_utils import *

# global vars
sub = DummySubscriber()
c = client.Client(sub)
stats = stats.Stats()
target = (0,0)
has_target = False
target_cell = None
color = (0,0,0)

# find out server and token to connect
try:
    token = sys.argv[1]
    addr, *_ = utils.get_party_address(token)
except:
    addr, token, *_ = utils.find_server()

# connect
c.connect(addr,token)
c.send_facebook(
            'g2gDYQFtAAAAEKO6L3c8C8/eXtbtbVJDGU5tAAAAUvOo7JuWAVSczT5Aj0eo0CvpeU8ijGzKy/gXBVCxhP5UO+ERH0jWjAo9bU1V7dU0GmwFr+SnzqWohx3qvG8Fg8RHlL17/y9ifVWpYUdweuODb9c=')

c.player.nick="test cell pls ignore"

# initialize GUI
gui.set_client(c)

# main loop
while True:
    c.on_message()

    gui.draw_frame()

    if len(list(c.player.own_cells)) > 0:
        runaway = False

        my_smallest = min(map(lambda cell : cell.mass, c.player.own_cells))
        my_largest = max(map(lambda cell : cell.mass, c.player.own_cells))

        forbidden_intervals = []
        for cell in c.world.cells.values():
            relpos = ((cell.pos[0]-c.player.center[0]),(cell.pos[1]-c.player.center[1]))
            dist = math.sqrt(relpos[0]**2+relpos[1]**2)

            if (not cell.is_virus and dist < 300+2*cell.size and  cell.mass > 1.25 * my_smallest) or (cell.is_virus and dist < cell.size and cell.mass < my_largest):
                angle = math.atan2(relpos[1],relpos[0])
                corridor_width = 2 * math.asin(cell.size / dist)
                forbidden_intervals += canonicalize_angle_interval((angle-corridor_width, angle+corridor_width))
                runaway = True

        if c.player.center[0] < c.world.top_left[1]+c.player.total_size:
            forbidden_intervals += [(0.5*pi, 1.5*pi)]
        if c.player.center[0] > c.world.bottom_right[1]-c.player.total_size:
            forbidden_intervals += [(0,0.5*pi), (1.5*pi, 2*pi)]
        if c.player.center[1] < c.world.top_left[0]+c.player.total_size:
            forbidden_intervals += [(0, pi)]
        if c.player.center[1] > c.world.bottom_right[0]-c.player.total_size:
            forbidden_intervals += [(pi, 2*pi)]

        if (runaway):
            forbidden_intervals = merge_intervals(forbidden_intervals)

            for i in forbidden_intervals:
                gui.draw_arc(c.player.center, c.player.total_size+10, i, (255,0,255))

            allowed_intervals = invert_angle_intervals(forbidden_intervals)

            (a,b) = find_largest_angle_interval(allowed_intervals)
            runaway_angle = (a+b)/2
            runaway_x, runaway_y = (c.player.center[0]+int(100*math.cos(runaway_angle))), (c.player.center[1]+int(100*math.sin(runaway_angle)))

            target = (runaway_x, runaway_y)
            has_target = False

            color = (255,0,0)
            print ("Running away: " + str((runaway_x-c.player.center[0], runaway_y-c.player.center[1])))
        else:
            if target_cell != None:
                if target_cell not in c.world.cells.values():
                    target_cell = None
                    has_target = False
                    print("target_cell does not exist any more")
            elif target == tuple(c.player.center):
                has_target = False
                print("Reached random destination")

            if not has_target:
                def eatable(cell): return (cell.is_food) or (cell.mass <= sorted(c.player.own_cells, key = lambda x: x.mass)[0].mass * 0.75) and not (cell.is_virus)
                food = list(filter(eatable, c.world.cells.values()))

                def dist(cell): return math.sqrt((cell.pos[0]-c.player.center[0])**2 + (cell.pos[1]-c.player.center[1])**2)
                food = sorted(food, key = dist)

                if len(food) > 0:
                    target = (food[0].pos[0], food[0].pos[1])
                    target_cell = food[0]
                    has_target = True
                    color = (0,0,255)
                    print("Found food at: " + str(food[0].pos))
                else:
                    rx = c.player.center[0] + random.randrange(-400, 401)
                    ry = c.player.center[1] + random.randrange(-400, 401)
                    target = (rx, ry)
                    has_target = True
                    color = (0,255,0)
                    print("Nothing to do, heading to random targetination: " + str((rx, ry)))

        c.send_target(target[0], target[1])
        gui.draw_line(c.player.center, target, color)
        gui.update()
        stats.log_pos(c.player.center)
        stats.log_mass(c.player.total_mass)
<|endoftext|>


<commit_before>import kaptan
from sh import tmux, cut
from pprint import pprint

class Session(object):

    def __init__(self, **kwargs):
        if 'session_name' not in kwargs:
            raise ValueError('Session requires session_name')
        else:
            for (k, v) in kwargs.items():
                setattr(self, k, v)

    @classmethod
    def from_tmux(cls, **kwargs):
        if 'session_name' not in kwargs:
            raise ValueError('Session requires session_name')

        session = cls(session_name=kwargs['session_name'])
        session._TMUX = dict()
        for (k, v) in kwargs.items():
            session._TMUX[k] = v

        """
            ``tmux list-windows`` outputs 1 session per line ``\n``.

            -F (FORMATS) allows returning custom sessings, we delimit with
            a tab ``\t``.

            we then use dict+zip to align the format variable with the
            output.

            the ``Window`` object accepts the returned properties  and
            ``Session`` (``self``) object.
        """

        formats = WINDOW_FORMATS
        tmux_formats = ['#{%s}\t' % format for format in formats]

        windows = cut(
            tmux(
                'list-windows',                 # ``tmux list-windows``
                '-t%s' % session.session_name,     # target (session name)
                '-F%s' % ''.join(tmux_formats)  # output
            ), '-f1', '-d:'
        )

        # combine format keys with values returned from ``tmux list-windows``
        windows = [dict(zip(formats, window.split('\t'))) for window in windows]

        # clear up empty dict
        windows = [
            dict((k, v) for k, v in window.iteritems() if v) for window in windows
        ]

        session._windows = [Window.from_tmux(session=session, **window) for window in windows]

        return session

    @property
    def windows(self):
        return self._windows

    def __repr__(self):
        # todo test without session_name
        return "%s(%s)" % (self.__class__, self.session_name)

class Window(object):
    """
        todo
            - @has_session property, or throw an Error
            - Pane
            - __cmd__
    """

    """
     Each window displayed by tmux may be split into one or more panes; each pane takes up a certain area of the
     display and is a separate terminal.  A window may be split into panes using the split-window command.  Windows
     may be split horizontally (with the -h flag) or vertically.  Panes may be resized with the resize-pane command
     (bound to 'C-up', 'C-down' 'C-left' and 'C-right' by default), the current pane may be changed with the
     select-pane command and the rotate-window and swap-pane commands may be used to swap panes without changing
     their position.  Panes are numbered beginning from zero in the order they are created.

     A number of preset layouts are available.  These may be selected with the select-layout command or cycled with
     next-layout (bound to 'Space' by default); once a layout is chosen, panes within it may be moved and resized as
     normal.

     The following layouts are supported:

     even-horizontal
             Panes are spread out evenly from left to right across the window.

     even-vertical
             Panes are spread evenly from top to bottom.

     main-horizontal
             A large (main) pane is shown at the top of the window and the remaining panes are spread from left to
             right in the leftover space at the bottom.  Use the main-pane-height window option to specify the
             height of the top pane.

     main-vertical
             Similar to main-horizontal but the large pane is placed on the left and the others spread from top to
             bottom along the right.  See the main-pane-width window option.

     tiled   Panes are spread out as evenly as possible over the window in both rows and columns.

     In addition, select-layout may be used to apply a previously used layout - the list-windows command displays
     the layout of each window in a form suitable for use with select-layout.  For example:

           $ tmux list-windows
           0: ksh [159x48]
               layout: bb62,159x48,0,0{79x48,0,0,79x48,80,0}
           $ tmux select-layout bb62,159x48,0,0{79x48,0,0,79x48,80,0}

    """
    def __init__(self, **kwargs):

        if 'session' in kwargs:
            self._panes = None
            if isinstance(kwargs['session'], Session):
                self._session = kwargs['session']
            else:
                raise TypeError('session must be a Session object')

        [setattr(self, k, v) for (k, v) in kwargs.items() if k is not 'session']

    def __repr__(self):
        # todo test without session_name
        return "%s(%s)" % (self.__class__, self._session)

    __LAYOUTS__ = [
        'even-horizontal',  # Panes are spread out evenly from left to right across the window.
        'even-vertical',  # Panes are spread evenly from top to bottom.
        'main-horizontal',
        'main-vertical',
        'tiled'
    ]

    @classmethod
    def from_tmux(cls, session=None, **kwargs):
        """ parse into normal properties """
        """
            ``tmux list-panes`` outputs 1 session per line ``\n``.

            -F (FORMATS) picks settings return, we delimit with tab ``\t``.

            we then use dict+zip to align the format variable with the
            output.

            the ``Pane`` object accepts the returned properties, ``Session``
            object and ``Window`` (``self``) object.
        """

        if not session:
            raise ValueError('``session`` requires valid ``Session`` object')

        window = cls(session=session)

        window._TMUX = dict()
        for (k, v) in kwargs.items():
            window._TMUX[k] = v

        formats = PANE_FORMATS
        tmux_formats = ['#{%s}\t' % format for format in formats]

        panes = cut(
            tmux(
                'list-panes',
                '-s',                                # for sessions
                '-t%s' % session.session_name,  # target (name of session)
                '-F%s' % ''.join(tmux_formats)       # output
            ), '-f1', '-d:'
        )

        # `tmux list-panes` outputs a session per-line,
        # separate every line from `tmux list-panes` into a pane
        panes = str(panes).split('\n')

        # zip and map the results into the dict of formats used above
        panes = [dict(zip(formats, pane.split('\t'))) for pane in panes]

        # clear up empty dict
        panes = [
            dict((k, v) for k, v in pane.iteritems() if v) for pane in panes
        ]

        window._panes = [Pane.from_tmux(session=session, window=window, **pane) for pane in panes]

        return window

    # __dict__ should return properties that would export into a config

    @property
    def panes(self):
        return self._panes

class Pane(object):

    @classmethod
    def from_tmux(cls, session=None, window=None, **kwargs):
        """ return a Pane object
            arguments are results passed from tmux
        """
        if not session:
            raise ValueError('Pane generated using ``.from_tmux`` must have \
                             ``Session`` object')
            if not isinstance(session, Session):
                raise TypeError('session must be a Session object')

        if not window:
            raise ValueError('Pane generated using ``.from_tmux`` must have \
                             ``Window`` object')
            if not isinstance(window, Window):
                raise TypeError('window must be a Window object')

        pane = cls()

        pane._TMUX = dict()
        for (k, v) in kwargs.items():
            pane._TMUX[k] = v

        pane._session = session
        pane._window = window

        return pane

    def __init__(self, **kwargs):
        pass

    def __repr__(self):
        # todo test without session_name
        return "%s(window=%s)" % (self.__class__, self._window)

def get_sessions():
    formats = SESSION_FORMATS
    tmux_formats = ['#{%s}\t' % format for format in formats]

    sessions = cut(
        tmux(
            'list-sessions',                 # ``tmux list-windows``
            '-F%s' % ''.join(tmux_formats)  # output
        ), '-f1', '-d:'
    )

    # combine format keys with values returned from ``tmux list-windows``
    sessions = [dict(zip(formats, session.split('\t'))) for session in sessions]

    # clear up empty dict
    sessions = [
        dict((k, v) for k, v in session.iteritems() if v) for session in sessions
    ]

    sessions = [Session.from_tmux(**session) for session in sessions]

    for session in sessions:
        yield session

"""
    experiment, ALL_FORMATS parsing for session, window, pane object and
    remove blank values

    http://sourceforge.net/p/tmux/tmux-code/ci/master/tree/format.c
"""

SESSION_FORMATS = [
    'session_group',
    'session_name',
    'session_windows',
    'session_width',
    'session_height',
    'session_id',
    'session_grouped',
    'session_group',
    'session_created',
    'session_created_string',
    'session_attached',
]

CLIENT_FORMATS = [
    'client_cwd',
    'client_height',
    'client_width',
    'client_tty',
    'client_termname',
    'client_created',
    'client_created_string',
    'client_activity',
    'client_activity_string',
    'client_prefix',
    'client_utf8',
    'client_readonly',
    'client_session',
    'client_last_session',
]

WINDOW_FORMATS = [
    # format_window()
    'window_id',
    'window_name',
    'window_width',
    'window_height',
    'window_layout',
    'window_panes',
    # format_winlink()
    'window_index',
    'window_flags',
    'window_active',
    'window_bell_flag',
    'window_activity_flag',
    'window_silence_flag',
]

PANE_FORMATS = [
    'history_size',
    'history_limit',
    'history_bytes',
    'pane_index',
    'pane_width',
    'pane_height',
    'pane_title',
    'pane_id',
    'pane_active',
    'pane_dead',
    'pane_in_mode',
    'pane_synchronized',
    'pane_tty',
    'pane_pid',
    'pane_start_command',
    'pane_start_path',
    'pane_current_path',
    'pane_current_command',

    'cursor_x',
    'cursor_y',
    'scroll_region_upper',
    'scroll_region_lower',
    'saved_cursor_x',
    'saved_cursor_y',

    'alternate_on',
    'alternate_saved_x',
    'alternate_saved_y',

    'cursor_flag',
    'insert_flag',
    'keypad_cursor_flag',
    'keypad_flag',
    'wrap_flag',

    'mouse_standard_flag',
    'mouse_button_flag',
    'mouse_any_flag',
    'mouse_utf8_flag',
]

config = kaptan.Kaptan(handler="yaml")
config.import_config("""
    windows:
        - editor:
            layout: main-vertical
            panes:
                - vim
                - cowsay "hey"
        - server: htop
        - logs: tail -f logs/development.log
    """)

print config
pprint(config.__dict__)
""" expand inline config
    dict({'session_name': { dict })

    to

    dict({ name='session_name', **dict})
"""
windows = list()
for window in config.get('windows'):

    if len(window) == int(1):
        name = window.iterkeys().next()  # get window name

        """expand
            window[name] = 'command'

            to

            window[name] = {
                panes=['command']
            }
        """
        if isinstance(window[name], basestring):
            windowoptions = dict(
                panes=[window[name]]
            )
        else:
            windowoptions = window[name]

        window = dict(name=name, **windowoptions)
        if len(window['panes']) > int(1):
            pprint('omg multiple panes')

    windows.append(window)

for session in get_sessions():
    #pprint(session)
    for window in session.windows:
        #pprint(window)
        pprint(window)

        for pane in window.panes:
            pprint(pane)
            #pprint(pane.__dict__)
            pass
<commit_msg>move session_group to bottom of SESSION_FORMATS<commit_after>import kaptan
from sh import tmux, cut
from pprint import pprint

class Session(object):

    def __init__(self, **kwargs):
        if 'session_name' not in kwargs:
            raise ValueError('Session requires session_name')
        else:
            for (k, v) in kwargs.items():
                setattr(self, k, v)

    @classmethod
    def from_tmux(cls, **kwargs):
        if 'session_name' not in kwargs:
            raise ValueError('Session requires session_name')

        pprint(kwargs)

        session = cls(session_name=kwargs['session_name'])
        session._TMUX = dict()
        for (k, v) in kwargs.items():
            session._TMUX[k] = v

        """
            ``tmux list-windows`` outputs 1 session per line ``\n``.

            -F (FORMATS) allows returning custom sessings, we delimit with
            a tab ``\t``.

            we then use dict+zip to align the format variable with the
            output.

            the ``Window`` object accepts the returned properties  and
            ``Session`` (``self``) object.
        """

        formats = WINDOW_FORMATS
        tmux_formats = ['#{%s}' % format for format in formats]

        windows = cut(
            tmux(
                'list-windows',                 # ``tmux list-windows``
                '-t%s' % kwargs['session_name'],     # target (session name)
                '-F%s' % '\t'.join(tmux_formats)  # output
            ), '-f1', '-d:'
        )

        # combine format keys with values returned from ``tmux list-windows``
        windows = [dict(zip(formats, window.split('\t'))) for window in windows]

        # clear up empty dict
        windows = [
            dict((k, v) for k, v in window.iteritems() if v) for window in windows
        ]

        session._windows = [Window.from_tmux(session=session, **window) for window in windows]

        return session

    @property
    def windows(self):
        return self._windows

    def __repr__(self):
        # todo test without session_name
        return "%s(%s)" % (self.__class__, self.session_name)

class Window(object):
    """
        todo
            - @has_session property, or throw an Error
            - Pane
            - __cmd__
    """

    """
     Each window displayed by tmux may be split into one or more panes; each pane takes up a certain area of the
     display and is a separate terminal.  A window may be split into panes using the split-window command.  Windows
     may be split horizontally (with the -h flag) or vertically.  Panes may be resized with the resize-pane command
     (bound to 'C-up', 'C-down' 'C-left' and 'C-right' by default), the current pane may be changed with the
     select-pane command and the rotate-window and swap-pane commands may be used to swap panes without changing
     their position.  Panes are numbered beginning from zero in the order they are created.

     A number of preset layouts are available.  These may be selected with the select-layout command or cycled with
     next-layout (bound to 'Space' by default); once a layout is chosen, panes within it may be moved and resized as
     normal.

     The following layouts are supported:

     even-horizontal
             Panes are spread out evenly from left to right across the window.

     even-vertical
             Panes are spread evenly from top to bottom.

     main-horizontal
             A large (main) pane is shown at the top of the window and the remaining panes are spread from left to
             right in the leftover space at the bottom.  Use the main-pane-height window option to specify the
             height of the top pane.

     main-vertical
             Similar to main-horizontal but the large pane is placed on the left and the others spread from top to
             bottom along the right.  See the main-pane-width window option.

     tiled   Panes are spread out as evenly as possible over the window in both rows and columns.

     In addition, select-layout may be used to apply a previously used layout - the list-windows command displays
     the layout of each window in a form suitable for use with select-layout.  For example:

           $ tmux list-windows
           0: ksh [159x48]
               layout: bb62,159x48,0,0{79x48,0,0,79x48,80,0}
           $ tmux select-layout bb62,159x48,0,0{79x48,0,0,79x48,80,0}

    """
    def __init__(self, **kwargs):

        if 'session' in kwargs:
            self._panes = None
            if isinstance(kwargs['session'], Session):
                self._session = kwargs['session']
            else:
                raise TypeError('session must be a Session object')

        [setattr(self, k, v) for (k, v) in kwargs.items() if k is not 'session']

    def __repr__(self):
        # todo test without session_name
        return "%s(%s)" % (self.__class__, self._session)

    __LAYOUTS__ = [
        'even-horizontal',  # Panes are spread out evenly from left to right across the window.
        'even-vertical',  # Panes are spread evenly from top to bottom.
        'main-horizontal',
        'main-vertical',
        'tiled'
    ]

    @classmethod
    def from_tmux(cls, session=None, **kwargs):
        """ parse into normal properties """
        """
            ``tmux list-panes`` outputs 1 session per line ``\n``.

            -F (FORMATS) picks settings return, we delimit with tab ``\t``.

            we then use dict+zip to align the format variable with the
            output.

            the ``Pane`` object accepts the returned properties, ``Session``
            object and ``Window`` (``self``) object.
        """

        if not session:
            raise ValueError('``session`` requires valid ``Session`` object')

        window = cls(session=session)

        window._TMUX = dict()
        for (k, v) in kwargs.items():
            window._TMUX[k] = v

        formats = PANE_FORMATS
        tmux_formats = ['#{%s}\t' % format for format in formats]

        panes = cut(
            tmux(
                'list-panes',
                '-s',                                # for sessions
                '-t%s' % session.session_name,  # target (name of session)
                '-F%s' % ''.join(tmux_formats)       # output
            ), '-f1', '-d:'
        )

        # `tmux list-panes` outputs a session per-line,
        # separate every line from `tmux list-panes` into a pane
        panes = str(panes).split('\n')

        # zip and map the results into the dict of formats used above
        panes = [dict(zip(formats, pane.split('\t'))) for pane in panes]

        # clear up empty dict
        panes = [
            dict((k, v) for k, v in pane.iteritems() if v) for pane in panes
        ]

        window._panes = [Pane.from_tmux(session=session, window=window, **pane) for pane in panes]

        return window

    # __dict__ should return properties that would export into a config

    @property
    def panes(self):
        return self._panes

class Pane(object):

    @classmethod
    def from_tmux(cls, session=None, window=None, **kwargs):
        """ return a Pane object
            arguments are results passed from tmux
        """
        if not session:
            raise ValueError('Pane generated using ``.from_tmux`` must have \
                             ``Session`` object')
            if not isinstance(session, Session):
                raise TypeError('session must be a Session object')

        if not window:
            raise ValueError('Pane generated using ``.from_tmux`` must have \
                             ``Window`` object')
            if not isinstance(window, Window):
                raise TypeError('window must be a Window object')

        pane = cls()

        # keep tmux variables into _TMUX
        pane._TMUX = dict()
        for (k, v) in kwargs.items():
            pane._TMUX[k] = v

        pane._session = session
        pane._window = window

        return pane

    def __init__(self, **kwargs):
        pass

    def __repr__(self):
        # todo test without session_name
        return "%s(window=%s)" % (self.__class__, self._window)

def get_sessions():
    formats = SESSION_FORMATS
    tmux_formats = ['#{%s}' % format for format in formats]

    sessions = cut(
        tmux(
            'list-sessions',                 # ``tmux list-windows``
            '-F%s' % '\t'.join(tmux_formats)  # output
        ), '-f1', '-d:'
    )
    pprint('-F%s' % '\t'.join(tmux_formats))

    pprint(sessions)
    pprint(str(sessions))
    sessions = str(sessions).strip()
    sessions = [session.strip() for session in str(sessions).split('\n')]

    pprint(sessions)
    pprint(sessions.__len__())

    # combine format keys with values returned from ``tmux list-windows``
    sessions = [dict(zip(formats, session.split('\t'))) for session in sessions]

    # clear up empty dict
    nsessions = [
        dict((k, v) for k, v in session.iteritems() if v) for session in sessions
    ]

    sessions = [Session.from_tmux(**session) for session in sessions]

    for session in sessions:
        yield session

"""
    experiment, ALL_FORMATS parsing for session, window, pane object and
    remove blank values

    http://sourceforge.net/p/tmux/tmux-code/ci/master/tree/format.c
"""

SESSION_FORMATS = [
    'session_name',
    'session_windows',
    'session_width',
    'session_height',
    'session_id',
    'session_grouped',
    'session_group',
    'session_created',
    'session_created_string',
    'session_attached',
    'session_group',
]

CLIENT_FORMATS = [
    'client_cwd',
    'client_height',
    'client_width',
    'client_tty',
    'client_termname',
    'client_created',
    'client_created_string',
    'client_activity',
    'client_activity_string',
    'client_prefix',
    'client_utf8',
    'client_readonly',
    'client_session',
    'client_last_session',
]

WINDOW_FORMATS = [
    # format_window()
    'window_id',
    'window_name',
    'window_width',
    'window_height',
    'window_layout',
    'window_panes',
    # format_winlink()
    'window_index',
    'window_flags',
    'window_active',
    'window_bell_flag',
    'window_activity_flag',
    'window_silence_flag',
]

PANE_FORMATS = [
    'history_size',
    'history_limit',
    'history_bytes',
    'pane_index',
    'pane_width',
    'pane_height',
    'pane_title',
    'pane_id',
    'pane_active',
    'pane_dead',
    'pane_in_mode',
    'pane_synchronized',
    'pane_tty',
    'pane_pid',
    'pane_start_command',
    'pane_start_path',
    'pane_current_path',
    'pane_current_command',

    'cursor_x',
    'cursor_y',
    'scroll_region_upper',
    'scroll_region_lower',
    'saved_cursor_x',
    'saved_cursor_y',

    'alternate_on',
    'alternate_saved_x',
    'alternate_saved_y',

    'cursor_flag',
    'insert_flag',
    'keypad_cursor_flag',
    'keypad_flag',
    'wrap_flag',

    'mouse_standard_flag',
    'mouse_button_flag',
    'mouse_any_flag',
    'mouse_utf8_flag',
]

config = kaptan.Kaptan(handler="yaml")
config.import_config("""
    windows:
        - editor:
            layout: main-vertical
            panes:
                - vim
                - cowsay "hey"
        - server: htop
        - logs: tail -f logs/development.log
    """)

#print config
#pprint(config.__dict__)
""" expand inline config
    dict({'session_name': { dict })

    to

    dict({ name='session_name', **dict})
"""
windows = list()
for window in config.get('windows'):

    if len(window) == int(1):
        name = window.iterkeys().next()  # get window name

        """expand
            window[name] = 'command'

            to

            window[name] = {
                panes=['command']
            }
        """
        if isinstance(window[name], basestring):
            windowoptions = dict(
                panes=[window[name]]
            )
        else:
            windowoptions = window[name]

        window = dict(name=name, **windowoptions)
        if len(window['panes']) > int(1):
            #pprint('omg multiple panes')
            pass

    windows.append(window)

for session in get_sessions():
    #pprint(session)
    for window in session.windows:
        pprint(window)
        #pprint(window)

        for pane in window.panes:
            #pprint(pane)
            #pprint(pane.__dict__)
            pass
<|endoftext|>


<commit_before>### Author: @floppy
### Description: 3d rotating polyhedra
### Category: Graphics
### License: MIT
### Appname : 3D Spin

import ugfx
import buttons
import pyb
import math

matrix = __import__("apps/3dspin/matrix")

ugfx.init()
buttons.init()
ugfx.clear(ugfx.BLACK)

vertices = []
faces = []

viewport_x = 320
viewport_y = 240
aspect = viewport_x / viewport_y

proj = matrix.Matrix(4, 4)

fov = 110.0
zfar = 100.0
znear = 0.1
s = 1/(math.tan(math.radians(fov/2)))
proj.m[0][0] = s
proj.m[1][1] = s
proj.m[2][2] = -zfar/(zfar-znear)
proj.m[3][2] = -1.0
proj.m[2][3] = -(zfar*znear)/(zfar-znear)

def loadObject():
    global vertices
    global faces
    vertices = [
    	matrix.Vector3D(-0.5,0.5,-0.5),
    	matrix.Vector3D(0.5,0.5,-0.5),
    	matrix.Vector3D(0.5,-0.5,-0.5),
    	matrix.Vector3D(-0.5,-0.5,-0.5),
    	matrix.Vector3D(-0.5,0.5,0.5),
    	matrix.Vector3D(0.5,0.5,0.5),
    	matrix.Vector3D(0.5,-0.5,0.5),
    	matrix.Vector3D(-0.5,-0.5,0.5)
    ]
    faces = [(0,1,2,3),(1,5,6,2),(5,4,7,6),(4,0,3,7),(0,4,5,1),(3,2,6,7)]

def toScreenCoords(pv):
	px = ((pv.x+1)*0.5*viewport_x)
	py = ((1-(pv.y+1)*0.5)*viewport_y)
	return matrix.Vector3D(int(px), int(py), 1)

def render(x_rotation, y_rotation, z_rotation):

    rot_x = matrix.Matrix(4,4)
    rot_x.m[1][1] = math.cos(math.radians(x_rotation))
    rot_x.m[1][2] = -math.sin(math.radians(x_rotation))
    rot_x.m[2][1] = math.sin(math.radians(x_rotation))
    rot_x.m[2][2] = math.cos(math.radians(x_rotation))

    rot_y = matrix.Matrix(4,4)
    rot_y.m[0][0] = math.cos(math.radians(y_rotation))
    rot_y.m[0][2] = math.sin(math.radians(y_rotation))
    rot_y.m[2][0] = -math.sin(math.radians(y_rotation))
    rot_y.m[2][2] = math.cos(math.radians(y_rotation))

    rot_z = matrix.Matrix(4,4)
    rot_z.m[0][0] = math.cos(math.radians(z_rotation))
    rot_z.m[0][1] = -math.sin(math.radians(z_rotation))
    rot_z.m[1][0] = math.sin(math.radians(z_rotation))
    rot_z.m[1][1] = math.cos(math.radians(z_rotation))

    rot = rot_x * rot_y * rot_z

    polys = []
    for i in range(len(faces)):
    	poly = [] #transformed polygon
    	for j in range(len(faces[0])):
    		v = vertices[faces[i][j]]
    		# Rotate
    		r = rot*v
    		# Transform the point from 3D to 2D
    		ps = proj*r
    		# Put the screenpoint in the list of transformed vertices
    		p = toScreenCoords(ps)
    		x = int(p.x)
    		y = int(p.y)
    		poly.append([x, y])
    	polys.append(poly)

    # Render
    ugfx.clear(ugfx.BLACK)
    for poly in polys:
    	# Render polygon
     	ugfx.polygon(0,0, poly, ugfx.WHITE)

loadObject()
x_rotation = 0
y_rotation = 0
z_rotation = 0
while not buttons.is_pressed("BTN_MENU"):
	render(x_rotation, y_rotation, z_rotation)
	x_rotation += 1
	if x_rotation >= 360:
		x_rotation = 0
	y_rotation += 2
	if y_rotation >= 360:
		y_rotation = 0
	z_rotation += 3
	if z_rotation >= 360:
		z_rotation = 0<commit_msg>app path variable<commit_after>### Author: @floppy
### Description: 3d rotating polyhedra
### Category: Graphics
### License: MIT
### Appname : 3D Spin

import ugfx
import buttons
import pyb
import math

app_path = "apps/3dspin/"
matrix = __import__(app_path + "matrix")

ugfx.init()
buttons.init()
ugfx.clear(ugfx.BLACK)

vertices = []
faces = []

viewport_x = 320
viewport_y = 240
aspect = viewport_x / viewport_y

proj = matrix.Matrix(4, 4)

fov = 110.0
zfar = 100.0
znear = 0.1
s = 1/(math.tan(math.radians(fov/2)))
proj.m[0][0] = s
proj.m[1][1] = s
proj.m[2][2] = -zfar/(zfar-znear)
proj.m[3][2] = -1.0
proj.m[2][3] = -(zfar*znear)/(zfar-znear)

def loadObject():
    global vertices
    global faces
    vertices = [
    	matrix.Vector3D(-0.5,0.5,-0.5),
    	matrix.Vector3D(0.5,0.5,-0.5),
    	matrix.Vector3D(0.5,-0.5,-0.5),
    	matrix.Vector3D(-0.5,-0.5,-0.5),
    	matrix.Vector3D(-0.5,0.5,0.5),
    	matrix.Vector3D(0.5,0.5,0.5),
    	matrix.Vector3D(0.5,-0.5,0.5),
    	matrix.Vector3D(-0.5,-0.5,0.5)
    ]
    faces = [(0,1,2,3),(1,5,6,2),(5,4,7,6),(4,0,3,7),(0,4,5,1),(3,2,6,7)]

def toScreenCoords(pv):
	px = ((pv.x+1)*0.5*viewport_x)
	py = ((1-(pv.y+1)*0.5)*viewport_y)
	return matrix.Vector3D(int(px), int(py), 1)

def render(x_rotation, y_rotation, z_rotation):

    rot_x = matrix.Matrix(4,4)
    rot_x.m[1][1] = math.cos(math.radians(x_rotation))
    rot_x.m[1][2] = -math.sin(math.radians(x_rotation))
    rot_x.m[2][1] = math.sin(math.radians(x_rotation))
    rot_x.m[2][2] = math.cos(math.radians(x_rotation))

    rot_y = matrix.Matrix(4,4)
    rot_y.m[0][0] = math.cos(math.radians(y_rotation))
    rot_y.m[0][2] = math.sin(math.radians(y_rotation))
    rot_y.m[2][0] = -math.sin(math.radians(y_rotation))
    rot_y.m[2][2] = math.cos(math.radians(y_rotation))

    rot_z = matrix.Matrix(4,4)
    rot_z.m[0][0] = math.cos(math.radians(z_rotation))
    rot_z.m[0][1] = -math.sin(math.radians(z_rotation))
    rot_z.m[1][0] = math.sin(math.radians(z_rotation))
    rot_z.m[1][1] = math.cos(math.radians(z_rotation))

    rot = rot_x * rot_y * rot_z

    polys = []
    for i in range(len(faces)):
    	poly = [] #transformed polygon
    	for j in range(len(faces[0])):
    		v = vertices[faces[i][j]]
    		# Rotate
    		r = rot*v
    		# Transform the point from 3D to 2D
    		ps = proj*r
    		# Put the screenpoint in the list of transformed vertices
    		p = toScreenCoords(ps)
    		x = int(p.x)
    		y = int(p.y)
    		poly.append([x, y])
    	polys.append(poly)

    # Render
    ugfx.clear(ugfx.BLACK)
    for poly in polys:
    	# Render polygon
     	ugfx.polygon(0,0, poly, ugfx.WHITE)

loadObject()
x_rotation = 0
y_rotation = 0
z_rotation = 0
while not buttons.is_pressed("BTN_MENU"):
	render(x_rotation, y_rotation, z_rotation)
	x_rotation += 1
	if x_rotation >= 360:
		x_rotation = 0
	y_rotation += 2
	if y_rotation >= 360:
		y_rotation = 0
	z_rotation += 3
	if z_rotation >= 360:
		z_rotation = 0<|endoftext|>


<commit_before>import copy
import glob
import os
import time

import gym
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

from arguments import get_args
from baselines.common.vec_env.dummy_vec_env import DummyVecEnv
from baselines.common.vec_env.subproc_vec_env import SubprocVecEnv
from baselines.common.vec_env.vec_normalize import VecNormalize
from envs import make_env
from model import Policy
from storage import RolloutStorage
from visualize import visdom_plot

import algo

args = get_args()

assert args.algo in ['a2c', 'ppo', 'acktr']
if args.recurrent_policy:
    assert args.algo in ['a2c', 'ppo'], \
        'Recurrent policy is not implemented for ACKTR'

num_updates = int(args.num_frames) // args.num_steps // args.num_processes

torch.manual_seed(args.seed)
if args.cuda:
    torch.cuda.manual_seed(args.seed)

try:
    os.makedirs(args.log_dir)
except OSError:
    files = glob.glob(os.path.join(args.log_dir, '*.monitor.csv'))
    for f in files:
        os.remove(f)

def main():
    print("#######")
    print("WARNING: All rewards are clipped or normalized so you need to use a monitor (see envs.py) or visdom plot to get true rewards")
    print("#######")

    torch.set_num_threads(1)

    if args.vis:
        from visdom import Visdom
        viz = Visdom(port=args.port)
        win = None

    envs = [make_env(args.env_name, args.seed, i, args.log_dir, args.add_timestep)
                for i in range(args.num_processes)]

    if args.num_processes > 1:
        envs = SubprocVecEnv(envs)
    else:
        envs = DummyVecEnv(envs)

    if len(envs.observation_space.shape) == 1:
        envs = VecNormalize(envs)

    obs_shape = envs.observation_space.shape
    obs_shape = (obs_shape[0] * args.num_stack, *obs_shape[1:])

    actor_critic = Policy(obs_shape, envs.action_space, args.recurrent_policy)

    if envs.action_space.__class__.__name__ == "Discrete":
        action_shape = 1
    else:
        action_shape = envs.action_space.shape[0]

    if args.cuda:
        actor_critic.cuda()

    if args.algo == 'a2c':
        agent = algo.A2C_ACKTR(actor_critic, args.value_loss_coef,
                               args.entropy_coef, lr=args.lr,
                               eps=args.eps, alpha=args.alpha,
                               max_grad_norm=args.max_grad_norm)
    elif args.algo == 'ppo':
        agent = algo.PPO(actor_critic, args.clip_param, args.ppo_epoch, args.num_mini_batch,
                         args.value_loss_coef, args.entropy_coef, lr=args.lr,
                               eps=args.eps,
                               max_grad_norm=args.max_grad_norm)
    elif args.algo == 'acktr':
        agent = algo.A2C_ACKTR(actor_critic, args.value_loss_coef,
                               args.entropy_coef, acktr=True)

    rollouts = RolloutStorage(args.num_steps, args.num_processes, obs_shape, envs.action_space, actor_critic.state_size)
    current_obs = torch.zeros(args.num_processes, *obs_shape)

    def update_current_obs(obs):
        shape_dim0 = envs.observation_space.shape[0]
        obs = torch.from_numpy(obs).float()
        if args.num_stack > 1:
            current_obs[:, :-shape_dim0] = current_obs[:, shape_dim0:]
        current_obs[:, -shape_dim0:] = obs

    obs = envs.reset()
    update_current_obs(obs)

    rollouts.observations[0].copy_(current_obs)

    # These variables are used to compute average rewards for all processes.
    episode_rewards = torch.zeros([args.num_processes, 1])
    final_rewards = torch.zeros([args.num_processes, 1])

    if args.cuda:
        current_obs = current_obs.cuda()
        rollouts.cuda()

    start = time.time()
    for j in range(num_updates):
        for step in range(args.num_steps):
            # Sample actions
            with torch.no_grad():
                value, action, action_log_prob, states = actor_critic.act(
                        rollouts.observations[step],
                        rollouts.states[step],
                        rollouts.masks[step])
            cpu_actions = action.squeeze(1).cpu().numpy()

            # Obser reward and next obs
            obs, reward, done, info = envs.step(cpu_actions)
            reward = torch.from_numpy(np.expand_dims(np.stack(reward), 1)).float()
            episode_rewards += reward

            # If done then clean the history of observations.
            masks = torch.FloatTensor([[0.0] if done_ else [1.0] for done_ in done])
            final_rewards *= masks
            final_rewards += (1 - masks) * episode_rewards
            episode_rewards *= masks

            if args.cuda:
                masks = masks.cuda()

            if current_obs.dim() == 4:
                current_obs *= masks.unsqueeze(2).unsqueeze(2)
            else:
                current_obs *= masks

            update_current_obs(obs)
            rollouts.insert(current_obs, states, action, action_log_prob, value, reward, masks)

        with torch.no_grad():
            next_value = actor_critic.get_value(rollouts.observations[-1],
                                                rollouts.states[-1],
                                                rollouts.masks[-1]).detach()

        rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.tau)

        value_loss, action_loss, dist_entropy = agent.update(rollouts)

        rollouts.after_update()

        if j % args.save_interval == 0 and args.save_dir != "":
            save_path = os.path.join(args.save_dir, args.algo)
            try:
                os.makedirs(save_path)
            except OSError:
                pass

            # A really ugly way to save a model to CPU
            save_model = actor_critic
            if args.cuda:
                save_model = copy.deepcopy(actor_critic).cpu()

            save_model = [save_model,
                            hasattr(envs, 'ob_rms') and envs.ob_rms or None]

            torch.save(save_model, os.path.join(save_path, args.env_name + ".pt"))

        if j % args.log_interval == 0:
            end = time.time()
            total_num_steps = (j + 1) * args.num_processes * args.num_steps
            print("Updates {}, num timesteps {}, FPS {}, mean/median reward {:.1f}/{:.1f}, min/max reward {:.1f}/{:.1f}, entropy {:.5f}, value loss {:.5f}, policy loss {:.5f}".
                format(j, total_num_steps,
                       int(total_num_steps / (end - start)),
                       final_rewards.mean(),
                       final_rewards.median(),
                       final_rewards.min(),
                       final_rewards.max(), dist_entropy,
                       value_loss, action_loss))
        if args.vis and j % args.vis_interval == 0:
            try:
                # Sometimes monitor doesn't properly flush the outputs
                win = visdom_plot(viz, win, args.log_dir, args.env_name,
                                  args.algo, args.num_frames)
            except IOError:
                pass

if __name__ == "__main__":
    main()
<commit_msg>Added gamma parameter to VecNormalize init<commit_after>import copy
import glob
import os
import time

import gym
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

from arguments import get_args
from baselines.common.vec_env.dummy_vec_env import DummyVecEnv
from baselines.common.vec_env.subproc_vec_env import SubprocVecEnv
from baselines.common.vec_env.vec_normalize import VecNormalize
from envs import make_env
from model import Policy
from storage import RolloutStorage
from visualize import visdom_plot

import algo

args = get_args()

assert args.algo in ['a2c', 'ppo', 'acktr']
if args.recurrent_policy:
    assert args.algo in ['a2c', 'ppo'], \
        'Recurrent policy is not implemented for ACKTR'

num_updates = int(args.num_frames) // args.num_steps // args.num_processes

torch.manual_seed(args.seed)
if args.cuda:
    torch.cuda.manual_seed(args.seed)

try:
    os.makedirs(args.log_dir)
except OSError:
    files = glob.glob(os.path.join(args.log_dir, '*.monitor.csv'))
    for f in files:
        os.remove(f)

def main():
    print("#######")
    print("WARNING: All rewards are clipped or normalized so you need to use a monitor (see envs.py) or visdom plot to get true rewards")
    print("#######")

    torch.set_num_threads(1)

    if args.vis:
        from visdom import Visdom
        viz = Visdom(port=args.port)
        win = None

    envs = [make_env(args.env_name, args.seed, i, args.log_dir, args.add_timestep)
                for i in range(args.num_processes)]

    if args.num_processes > 1:
        envs = SubprocVecEnv(envs)
    else:
        envs = DummyVecEnv(envs)

    if len(envs.observation_space.shape) == 1:
        envs = VecNormalize(envs, gamma=args.gamma)

    obs_shape = envs.observation_space.shape
    obs_shape = (obs_shape[0] * args.num_stack, *obs_shape[1:])

    actor_critic = Policy(obs_shape, envs.action_space, args.recurrent_policy)

    if envs.action_space.__class__.__name__ == "Discrete":
        action_shape = 1
    else:
        action_shape = envs.action_space.shape[0]

    if args.cuda:
        actor_critic.cuda()

    if args.algo == 'a2c':
        agent = algo.A2C_ACKTR(actor_critic, args.value_loss_coef,
                               args.entropy_coef, lr=args.lr,
                               eps=args.eps, alpha=args.alpha,
                               max_grad_norm=args.max_grad_norm)
    elif args.algo == 'ppo':
        agent = algo.PPO(actor_critic, args.clip_param, args.ppo_epoch, args.num_mini_batch,
                         args.value_loss_coef, args.entropy_coef, lr=args.lr,
                               eps=args.eps,
                               max_grad_norm=args.max_grad_norm)
    elif args.algo == 'acktr':
        agent = algo.A2C_ACKTR(actor_critic, args.value_loss_coef,
                               args.entropy_coef, acktr=True)

    rollouts = RolloutStorage(args.num_steps, args.num_processes, obs_shape, envs.action_space, actor_critic.state_size)
    current_obs = torch.zeros(args.num_processes, *obs_shape)

    def update_current_obs(obs):
        shape_dim0 = envs.observation_space.shape[0]
        obs = torch.from_numpy(obs).float()
        if args.num_stack > 1:
            current_obs[:, :-shape_dim0] = current_obs[:, shape_dim0:]
        current_obs[:, -shape_dim0:] = obs

    obs = envs.reset()
    update_current_obs(obs)

    rollouts.observations[0].copy_(current_obs)

    # These variables are used to compute average rewards for all processes.
    episode_rewards = torch.zeros([args.num_processes, 1])
    final_rewards = torch.zeros([args.num_processes, 1])

    if args.cuda:
        current_obs = current_obs.cuda()
        rollouts.cuda()

    start = time.time()
    for j in range(num_updates):
        for step in range(args.num_steps):
            # Sample actions
            with torch.no_grad():
                value, action, action_log_prob, states = actor_critic.act(
                        rollouts.observations[step],
                        rollouts.states[step],
                        rollouts.masks[step])
            cpu_actions = action.squeeze(1).cpu().numpy()

            # Obser reward and next obs
            obs, reward, done, info = envs.step(cpu_actions)
            reward = torch.from_numpy(np.expand_dims(np.stack(reward), 1)).float()
            episode_rewards += reward

            # If done then clean the history of observations.
            masks = torch.FloatTensor([[0.0] if done_ else [1.0] for done_ in done])
            final_rewards *= masks
            final_rewards += (1 - masks) * episode_rewards
            episode_rewards *= masks

            if args.cuda:
                masks = masks.cuda()

            if current_obs.dim() == 4:
                current_obs *= masks.unsqueeze(2).unsqueeze(2)
            else:
                current_obs *= masks

            update_current_obs(obs)
            rollouts.insert(current_obs, states, action, action_log_prob, value, reward, masks)

        with torch.no_grad():
            next_value = actor_critic.get_value(rollouts.observations[-1],
                                                rollouts.states[-1],
                                                rollouts.masks[-1]).detach()

        rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.tau)

        value_loss, action_loss, dist_entropy = agent.update(rollouts)

        rollouts.after_update()

        if j % args.save_interval == 0 and args.save_dir != "":
            save_path = os.path.join(args.save_dir, args.algo)
            try:
                os.makedirs(save_path)
            except OSError:
                pass

            # A really ugly way to save a model to CPU
            save_model = actor_critic
            if args.cuda:
                save_model = copy.deepcopy(actor_critic).cpu()

            save_model = [save_model,
                            hasattr(envs, 'ob_rms') and envs.ob_rms or None]

            torch.save(save_model, os.path.join(save_path, args.env_name + ".pt"))

        if j % args.log_interval == 0:
            end = time.time()
            total_num_steps = (j + 1) * args.num_processes * args.num_steps
            print("Updates {}, num timesteps {}, FPS {}, mean/median reward {:.1f}/{:.1f}, min/max reward {:.1f}/{:.1f}, entropy {:.5f}, value loss {:.5f}, policy loss {:.5f}".
                format(j, total_num_steps,
                       int(total_num_steps / (end - start)),
                       final_rewards.mean(),
                       final_rewards.median(),
                       final_rewards.min(),
                       final_rewards.max(), dist_entropy,
                       value_loss, action_loss))
        if args.vis and j % args.vis_interval == 0:
            try:
                # Sometimes monitor doesn't properly flush the outputs
                win = visdom_plot(viz, win, args.log_dir, args.env_name,
                                  args.algo, args.num_frames)
            except IOError:
                pass

if __name__ == "__main__":
    main()
<|endoftext|>