<commit_before>from django.db import models

class Rank(models.Model):
    title = models.CharField(max_length=50)
    value = models.PositiveSmallIntegerField()
    can_supervise = models.BooleanField()

    def __str__(self):
        return self.title

class Agent(models.Model):
    first_name = models.CharField(max_length=35)
    last_name = models.CharField(max_length=35)
    email_address = models.CharField(max_length=255)
    is_supervisor = models.BooleanField()
    is_active = models.BooleanField()
    hire_date = models.DateField()
    termination_date = models.DateField(blank=True, null=True)
    pay_rate = models.DecimalField(decimal_places=2, max_digits=8,
                                   blank=True, null=True)
    rank = models.ForeignKey(Rank,
                             on_delete=models.PROTECT,
                             )
    hiring_class = models.ForeignKey("HiringClass",
                                     on_delete=models.PROTECT,
                                     blank=True,
                                     null=True,
                                     )

    def __str__(self):
        return self.first_name + ' ' + self.last_name

class HiringClass(models.Model):
    name = models.CharField(max_length=35)
    start_date = models.DateField()
    live_date = models.DateField()
    hiring_team = models.ForeignKey("Team",
                                    on_delete=models.PROTECT,
                                    )

    def __str__(self):
        return self.name

class Site(models.Model):
    common_name = models.CharField(max_length=35)
    short_name = models.CharField(max_length=5)
    city = models.CharField(max_length=35)
    state = models.CharField(max_length=35)
    country = models.CharField(max_length=35)
    operating_company = models.ForeignKey("Company",
                                          on_delete=models.PROTECT,
                                          null=True,
                                          )
    site_manager = models.ForeignKey(Agent,
                                     on_delete=models.PROTECT,
                                     limit_choices_to={'is_supervisor': True,
                                                       'is_active': True},
                                     )

    def __str__(self):
        return self.common_name

class Company(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Team(models.Model):
    full_name = models.CharField(max_length=100)
    short_name = models.CharField(max_length=20)
    supervisor = models.ForeignKey(Agent,
                                   on_delete=models.PROTECT,
                                   limit_choices_to={'is_supervisor': True,
                                                     'is_active': True},
                                   )
    primary_site = models.ForeignKey(Site,
                                     on_delete=models.PROTECT,
                                     )

    parent_team = models.ForeignKey("Team",
                                    on_delete=models.PROTECT,
                                    blank=True,
                                    null=True,
                                    )

    def __str__(self):
        return self.full_name

class Channel(models.Model):
    name = models.CharField(max_length=35)
    vendor_name = models.CharField(max_length=35)

    def __str__(self):
        return self.name

class Skill(models.Model):
    full_name = models.CharField(max_length=50)
    channel = models.ForeignKey(Channel,
                                on_delete=models.PROTECT,
                                )
    has_levels = models.BooleanField()
    external_id = models.PositiveIntegerField(blank=True,
                                              null=True,
                                              )

    def __str__(self):
        return self.full_name

class SkillAssignment(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    skill = models.ForeignKey(Skill,
                              on_delete=models.PROTECT,
                              )
    level = models.PositiveIntegerField(blank=True,
                                        null=True,
                                        )
    assigned_date = models.DateField(blank=True,
                                     null=True,
                                     )
    expiration_date = models.DateField(blank=True,
                                       null=True,
                                       )
    is_active = models.NullBooleanField(blank=True,
                                        )

    class Meta:
        unique_together = ('agent', 'skill')

    def __str__(self):
        return self.agent.__str__() + ' has skill ' + self.skill.__str__()

class Shift(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ('start_time', 'end_time')

    def __str__(self):
        return self.start_time.__str__() + ' to ' + self.end_time.__str__()

class Break(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ('start_time', 'end_time')

    def __str__(self):
        return self.start_time.__str__() + ' to ' + self.end_time.__str__()

class Schedule(models.Model):
    name = models.CharField(max_length=50,
                            )
    monday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_monday_shifts',
                                     blank=True,
                                     null=True,
                                     )
    tuesday_shift = models.ForeignKey(Shift,
                                      on_delete=models.PROTECT,
                                      related_name='schedule_tuesday_shifts',
                                      blank=True,
                                      null=True,
                                      )
    wednesday_shift = models.ForeignKey(Shift,
                                        on_delete=models.PROTECT,
                                        related_name='schedule_wednesday_shifts',
                                        blank=True,
                                        null=True,
                                        )
    thursday_shift = models.ForeignKey(Shift,
                                       on_delete=models.PROTECT,
                                       related_name='schedule_thursday_shifts',
                                       blank=True,
                                       null=True,
                                       )
    friday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_friday_shifts',
                                     blank=True,
                                     null=True,
                                     )
    saturday_shift = models.ForeignKey(Shift,
                                       on_delete=models.PROTECT,
                                       related_name='schedule_saturday_shifts',
                                       blank=True,
                                       null=True,
                                       )
    sunday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_sunday_shifts',
                                     blank=True,
                                     null=True,
                                     )

    class Meta:
        unique_together = ('monday_shift', 'tuesday_shift', 'wednesday_shift', 'thursday_shift', 'friday_shift',
                           'saturday_shift', 'sunday_shift')

    def __str__(self):
        return self.name

class AgentAssignment(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    team = models.ForeignKey(Team,
                             on_delete=models.PROTECT,
                             )
    site = models.ForeignKey(Site,
                             on_delete=models.PROTECT,
                             )
    schedule = models.ForeignKey(Schedule,
                                 on_delete=models.PROTECT)
    start_date = models.DateField()
    end_date = models.DateField(blank=True,
                                null=True,
                                )
    is_active = models.NullBooleanField(blank=True,
                                        )

    def __str__(self):
        return self.agent.__str__() + ' is assigned to ' + self.team.__str__()

class AgentScoreType(models.Model):
    name = models.CharField(max_length=35)
    related_channel = models.ForeignKey(Channel,
                                        on_delete=models.PROTECT,
                                        blank=True,
                                        null=True,
                                        )

    def __str__(self):
        return self.name.__str__()

class AgentScore(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    score_type = models.ForeignKey(AgentScoreType,
                                   on_delete=models.PROTECT,
                                   blank=False,
                                   null=False
                                   )
    score = models.FloatField()

    def __str__(self):
        return self.agent.__str__() + ' has score ' + self.score.__str__()
<commit_msg>model updates<commit_after>from django.db import models

class Rank(models.Model):
    title = models.CharField(max_length=50,
                             unique=True,
                             )
    value = models.PositiveSmallIntegerField()
    can_supervise = models.BooleanField()

    def __str__(self):
        return self.title

class Agent(models.Model):
    first_name = models.CharField(max_length=35)
    last_name = models.CharField(max_length=35)
    email_address = models.CharField(max_length=255,
                                     unique=True,
                                     )
    is_supervisor = models.BooleanField()
    is_active = models.BooleanField()
    hire_date = models.DateField()
    termination_date = models.DateField(blank=True, null=True)
    pay_rate = models.DecimalField(decimal_places=2, max_digits=8,
                                   blank=True, null=True)
    rank = models.ForeignKey(Rank,
                             on_delete=models.PROTECT,
                             )
    hiring_class = models.ForeignKey("HiringClass",
                                     on_delete=models.PROTECT,
                                     blank=True,
                                     null=True,
                                     )

    def __str__(self):
        return self.first_name + ' ' + self.last_name

class HiringClass(models.Model):
    name = models.CharField(max_length=35,
                            unique=True,
                            )
    start_date = models.DateField()
    live_date = models.DateField()
    hiring_team = models.ForeignKey("Team",
                                    on_delete=models.PROTECT,
                                    )

    def __str__(self):
        return self.name

class Site(models.Model):
    common_name = models.CharField(max_length=35,
                                   unique=True,
                                   )
    short_name = models.CharField(max_length=5,
                                  unique=True,
                                  )
    city = models.CharField(max_length=35)
    state = models.CharField(max_length=35)
    country = models.CharField(max_length=35)
    operating_company = models.ForeignKey("Company",
                                          on_delete=models.PROTECT,
                                          null=True,
                                          )
    site_manager = models.ForeignKey(Agent,
                                     on_delete=models.PROTECT,
                                     limit_choices_to={'is_supervisor': True,
                                                       'is_active': True},
                                     )

    def __str__(self):
        return self.common_name

class Company(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Team(models.Model):
    full_name = models.CharField(max_length=100,
                                 unique=True,
                                 )
    short_name = models.CharField(max_length=20,
                                  unique=True,
                                  )
    supervisor = models.ForeignKey(Agent,
                                   on_delete=models.PROTECT,
                                   limit_choices_to={'is_supervisor': True,
                                                     'is_active': True},
                                   )
    primary_site = models.ForeignKey(Site,
                                     on_delete=models.PROTECT,
                                     )

    parent_team = models.ForeignKey("Team",
                                    on_delete=models.PROTECT,
                                    blank=True,
                                    null=True,
                                    )

    def __str__(self):
        return self.full_name

class Channel(models.Model):
    name = models.CharField(max_length=35,
                            unique=True,
                            )
    vendor_name = models.CharField(max_length=35,
                                   )

    def __str__(self):
        return self.name

class Skill(models.Model):
    full_name = models.CharField(max_length=50,
                                 unique=True,
                                 )
    channel = models.ForeignKey(Channel,
                                on_delete=models.PROTECT,
                                )
    has_levels = models.BooleanField()
    external_id = models.PositiveIntegerField(blank=True,
                                              null=True,
                                              )

    def __str__(self):
        return self.channel + ' - ' + self.full_name

class SkillAssignment(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    skill = models.ForeignKey(Skill,
                              on_delete=models.PROTECT,
                              )
    level = models.PositiveIntegerField(blank=True,
                                        null=True,
                                        )
    assigned_date = models.DateField(blank=True,
                                     null=True,
                                     )
    expiration_date = models.DateField(blank=True,
                                       null=True,
                                       )
    is_active = models.NullBooleanField(blank=True,
                                        )

    class Meta:
        unique_together = ('agent', 'skill')

    def __str__(self):
        return self.agent.__str__() + ' has skill ' + self.skill.__str__()

class Shift(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ('start_time', 'end_time')

    def __str__(self):
        return self.start_time.__str__() + ' to ' + self.end_time.__str__()

class Break(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ('start_time', 'end_time')

    def __str__(self):
        return self.start_time.__str__() + ' to ' + self.end_time.__str__()

class Schedule(models.Model):
    name = models.CharField(max_length=50,
                            unique=True,
                            )
    monday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_monday_shifts',
                                     blank=True,
                                     null=True,
                                     )
    tuesday_shift = models.ForeignKey(Shift,
                                      on_delete=models.PROTECT,
                                      related_name='schedule_tuesday_shifts',
                                      blank=True,
                                      null=True,
                                      )
    wednesday_shift = models.ForeignKey(Shift,
                                        on_delete=models.PROTECT,
                                        related_name='schedule_wednesday_shifts',
                                        blank=True,
                                        null=True,
                                        )
    thursday_shift = models.ForeignKey(Shift,
                                       on_delete=models.PROTECT,
                                       related_name='schedule_thursday_shifts',
                                       blank=True,
                                       null=True,
                                       )
    friday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_friday_shifts',
                                     blank=True,
                                     null=True,
                                     )
    saturday_shift = models.ForeignKey(Shift,
                                       on_delete=models.PROTECT,
                                       related_name='schedule_saturday_shifts',
                                       blank=True,
                                       null=True,
                                       )
    sunday_shift = models.ForeignKey(Shift,
                                     on_delete=models.PROTECT,
                                     related_name='schedule_sunday_shifts',
                                     blank=True,
                                     null=True,
                                     )

    class Meta:
        unique_together = ('monday_shift', 'tuesday_shift', 'wednesday_shift', 'thursday_shift', 'friday_shift',
                           'saturday_shift', 'sunday_shift')

    def __str__(self):
        return self.name

class AgentAssignment(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    team = models.ForeignKey(Team,
                             on_delete=models.PROTECT,
                             )
    site = models.ForeignKey(Site,
                             on_delete=models.PROTECT,
                             )
    schedule = models.ForeignKey(Schedule,
                                 on_delete=models.PROTECT)
    start_date = models.DateField()
    end_date = models.DateField(blank=True,
                                null=True,
                                )
    is_active = models.NullBooleanField(blank=True,
                                        )

    def __str__(self):
        return self.agent.__str__() + ' is assigned to ' + self.team.__str__()

class AgentScoreType(models.Model):
    name = models.CharField(max_length=35,
                            unique=True,
                            )
    related_channel = models.ForeignKey(Channel,
                                        on_delete=models.PROTECT,
                                        blank=True,
                                        null=True,
                                        )

    def __str__(self):
        return self.name.__str__()

class AgentScore(models.Model):
    agent = models.ForeignKey(Agent,
                              on_delete=models.PROTECT,
                              )
    score_type = models.ForeignKey(AgentScoreType,
                                   on_delete=models.PROTECT,
                                   blank=False,
                                   null=False
                                   )
    score = models.FloatField()

    def __str__(self):
        return self.agent.__str__() + ' has score ' + self.score.__str__()
<|endoftext|>


<commit_before>import calendar

from enerdata.contracts.normalized_power import NormalizedPower
from enerdata.datetime.station import get_station
from enerdata.datetime.holidays import get_holidays

def check_range_hours(hours):
    before = (0, 0)
    for range_hours in sorted(hours):
        start, end = range_hours
        if start >= end:
            return False
        if start < 0 or start > 24:
            return False
        if end < 1 or end > 24:
            return False
        if start < before[1]:
            return False
        before = (start, end)
    return True

def are_powers_ascending(powers):
    power_ant = 0
    for power_new in powers:
        if power_new < power_ant:
            return False
        power_ant = power_new

    return True

class Tariff(object):
    """Energy DSO Tariff.
    """
    def __init__(self, code=None):
        self.code = code
        self._periods = tuple()
        self.cof = None

    @property
    def periods(self):
        return self._periods

    @periods.setter
    def periods(self, value):
        self._periods = value
        hours = {
            'holidays': [],
            'no_holidays': []
        }
        for period in self.energy_periods.values():
            if period.holiday:
                hours['holidays'].append(period)
            else:
                hours['no_holidays'].append(period)

        for station in ('summer', 'winter'):
            for holiday in (False, True):
                total_hours = 0
                range_hours = []
                for period in self.energy_periods.values():
                    if period.holiday == holiday:
                        total_hours += getattr(period, 'total_%s_hours' % station)
                        range_hours += getattr(period, '%s_hours' % station)
                range_hours = sorted(range_hours)
                if total_hours != 24:
                    if (holiday and total_hours) or not holiday:
                        raise ValueError(
                            'The sum of hours in %s%s must be 24h: %s'
                            % (station, holiday and ' (in holidays)' or '',
                            range_hours)
                        )
                if not check_range_hours(range_hours):
                    raise ValueError(
                        'Invalid range of hours in %s%s: %s'
                        % (station, holiday and ' (in holidays)' or '',
                           range_hours)
                    )

    @property
    def energy_periods(self):
        return dict((p.code, p) for p in self.periods if p.type == 'te')

    @property
    def power_periods(self):
        return dict((p.code, p) for p in self.periods if p.type == 'tp')

    def get_number_of_periods(self):
        return len([p for p in self.periods if p.type == 'te'])

    def get_min_power(self):
        return self.min_power

    def get_max_power(self):
        return self.max_power

    def get_period_by_date(self, date_time):
        station = get_station(date_time)
        date = date_time.date()
        holidays = get_holidays(date.year)
        if (calendar.weekday(date.year, date.month, date.day) in (5, 6) or
                date in holidays):
            holiday = True
        else:
            holiday = False
        # Map hour 0 to 24
        hour = date_time.hour or 24
        for period in self.periods:
            if period.holiday == holiday or not self.has_holidays_periods:
                for range_h in getattr(period, '%s_hours' % station):
                    if range_h[0] < hour <= range_h[1]:
                        return period
        return None

    @property
    def has_holidays_periods(self):
        return any(p.holiday for p in self.energy_periods.values())

    def is_maximum_power_correct(self, max_pow):
        return self.min_power < max_pow <= self.max_power

    @staticmethod
    def are_powers_normalized(powers):
        np = NormalizedPower()
        for power in powers:
            if not np.is_normalized(int(power * 1000)):
                return False

        return True

    def evaluate_powers(self, powers):
        if min(powers) <= 0:
            raise NotPositivePower()
        if not len(self.power_periods) == len(powers):
            raise IncorrectPowerNumber(len(powers), len(self.power_periods))
        if not self.is_maximum_power_correct(max(powers)):
            raise IncorrectMaxPower(max(powers), self.min_power, self.max_power)
        if not self.are_powers_normalized(powers):
            raise NotNormalizedPower()

        return True

    def correct_powers(self, powers):
        raise NotImplementedError

class TariffPeriod(object):
    """Tariff period.
    """
    def __init__(self, code, ptype, **kwargs):
        assert ptype in ('te', 'tp')
        self.code = code
        self.type = ptype
        winter_hours = kwargs.pop('winter_hours', [(0, 24)])
        if not check_range_hours(winter_hours):
            raise ValueError('Invalid winter hours')
        self.winter_hours = winter_hours
        summer_hours = kwargs.pop('summer_hours', [(0, 24)])
        if not check_range_hours(summer_hours):
            raise ValueError('Invalid summer hours')
        self.summer_hours = summer_hours
        self.holiday = kwargs.pop('holiday', False)

    @property
    def total_summer_hours(self):
        hours = 0
        for range_h in self.summer_hours:
            hours += (range_h[1] - range_h[0])
        return hours

    @property
    def total_winter_hours(self):
        hours = 0
        for range_h in self.winter_hours:
            hours += (range_h[1] - range_h[0])
        return hours

class T20A(Tariff):
    def __init__(self):
        super(T20A, self).__init__()
        self.code = '2.0A'
        self.cof = 'A'
        self.periods = (
            TariffPeriod('P1', 'te'),
            TariffPeriod('P1', 'tp')
        )
        self.min_power = 0
        self.max_power = 10
        self.type = 'BT'

    def correct_powers(self, powers):
        try:
            if self.evaluate_powers(powers):
                return powers
        except:
            pass

        norm_power = NormalizedPower().get_norm_powers(
            int(self.min_power * 1000), int(self.max_power * 1000)
        ).next()

        return [norm_power / 1000.0] * len(self.power_periods)

class T20DHA(T20A):
    def __init__(self):
        super(T20DHA, self).__init__()
        self.code = '2.0DHA'
        self.cof = 'B'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(12, 22)],
                summer_hours=[(13, 23)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(0, 12), (22, 24)],
                summer_hours=[(0, 13), (23, 24)]
            ),
            TariffPeriod(
                'P1', 'tp'
            )
        )

class T20DHS(T20DHA):
    def __init__(self):
        super(T20DHS, self).__init__()
        self.code = '2.0DHS'
        self.cof = 'D'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(13, 23)],
                summer_hours=[(13, 23)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(0, 1), (7, 13), (23, 24)],
                summer_hours=[(0, 1), (7, 13), (23, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(1, 7)],
                summer_hours=[(1, 7)]
            ),
            TariffPeriod(
                'P1', 'tp'
            )
        )

class T21A(T20A):
    def __init__(self):
        super(T21A, self).__init__()
        self.code = '2.1A'
        self.cof = 'A'
        self.min_power = 10
        self.max_power = 15

class T21DHA(T20DHA):
    def __init__(self):
        super(T21DHA, self).__init__()
        self.code = '2.1DHA'
        self.cof = 'B'
        self.min_power = 10
        self.max_power = 15

class T21DHS(T20DHS):
    def __init__(self):
        super(T21DHS, self).__init__()
        self.code = '2.1DHS'
        self.cof = 'D'
        self.min_power = 10
        self.max_power = 15

class T30A(Tariff):
    def __init__(self):
        super(T30A, self).__init__()
        self.code = '3.0A'
        self.cof = 'C'
        self.min_power = 15
        self.max_power = 1000000
        self.type = 'BT'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(18, 22)],
                summer_hours=[(11, 15)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(8, 18), (22, 24)],
                summer_hours=[(8, 11), (15, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P4', 'te',
                holiday=True,
                winter_hours=[(18, 22)],
                summer_hours=[(11, 15)]
            ),
            TariffPeriod(
                'P5', 'te',
                holiday=True,
                winter_hours=[(8, 18), (22, 24)],
                summer_hours=[(8, 11), (15, 24)]
            ),
            TariffPeriod(
                'P6', 'te',
                holiday=True,
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            )
        )

class T31A(T30A):
    """
    3.1A Tariff
    """
    def __init__(self):
        super(T31A, self).__init__()
        self.code = '3.1A'
        self.cof = 'C'
        self.min_power = 1
        self.max_power = 450
        self.type = 'AT'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(17, 23)],
                summer_hours=[(10, 16)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(8, 17), (23, 24)],
                summer_hours=[(8, 10), (16, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P5', 'te',
                holiday=True,
                winter_hours=[(18, 24)],
                summer_hours=[(18, 24)]
            ),
            TariffPeriod(
                'P6', 'te',
                holiday=True,
                winter_hours=[(0, 18)],
                summer_hours=[(0, 18)]
            ),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            )
        )

    @staticmethod
    def are_powers_normalized(powers):
        # 3.1A doesn't need to have normalized powers
        return True

    def evaluate_powers(self, powers):
        super(T31A, self).evaluate_powers(powers)

        if not are_powers_ascending(powers):
            raise NotAscendingPowers()

        return True

class T61A(Tariff):
    """
    6.1A Tariff
    """
    def __init__(self):
        super(T61A, self).__init__()
        self.code = '6.1A'
        self.cof = 'C'
        self.min_power = 450
        self.max_power = 1000000
        self.type = 'AT'
        self.periods = (
            #
            # TODO: Implement correct energy periods
            #
            TariffPeriod('P1', 'te'),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            ),
            TariffPeriod(
                'P4', 'tp'
            ),
            TariffPeriod(
                'P5', 'tp'
            ),
            TariffPeriod(
                'P6', 'tp'
            ),
        )

    @staticmethod
    def are_powers_normalized(powers):
        # 6.1A doesn't need to have normalized powers
        return True

    def evaluate_powers(self, powers):
        super(T61A, self).evaluate_powers(powers)

        if not are_powers_ascending(powers):
            raise NotAscendingPowers()

        return True

class T61B(T61A):
    """
    6.1B Tariff
    """
    def __init__(self):
        super(T61B, self).__init__()
        self.code = '6.1B'

class NotPositivePower(Exception):
    def __init__(self):
        super(NotPositivePower, self).__init__(
            'Power should allways be higher than 0'
        )

class NotNormalizedPower(Exception):
    def __init__(self):
        super(NotNormalizedPower, self).__init__(
            'One or more of the powers doen\'t have a normalized value'
        )

class IncorrectPowerNumber(Exception):
    def __init__(self, power_number, expected_number):
        super(IncorrectPowerNumber, self).__init__(
            'Expected {0} power(s) and got {1}'.format(
                expected_number, power_number
            )
        )
        self.power_number = power_number
        self.expected_number = expected_number

class IncorrectMaxPower(Exception):
    def __init__(self, power, min_power, max_power):
        super(IncorrectMaxPower, self).__init__(
            'Power {0} is not between {1} and {2}'.format(
                power, min_power, max_power
            )
        )
        self.power = power
        self.min_power = min_power
        self.max_power = max_power

class NotAscendingPowers(Exception):
    def __init__(self):
        super(NotAscendingPowers, self).__init__(
            'For this tariff powers should go in an ascending order (Pn+1>=Pn)'
        )

def get_tariff_by_code(code):
    """Get tariff class by code

    :param code: Tariff code
    :return: Tariff
    """
    available = {
        '2.0A': T20A,
        '2.0DHA': T20DHA,
        '2.0DHS': T20DHS,
        '2.1A': T21A,
        '2.1DHA': T21DHA,
        '2.1DHS': T21DHS,
        '3.0A': T30A,
        '3.1A': T31A,
        '6.1A': T61A,
        '6.1B': T61B,
    }
    return available.get(code, None)
<commit_msg>Update tariff.py<commit_after>import calendar

from enerdata.contracts.normalized_power import NormalizedPower
from enerdata.datetime.station import get_station
from enerdata.datetime.holidays import get_holidays

def check_range_hours(hours):
    before = (0, 0)
    for range_hours in sorted(hours):
        start, end = range_hours
        if start >= end:
            return False
        if start < 0 or start > 24:
            return False
        if end < 1 or end > 24:
            return False
        if start < before[1]:
            return False
        before = (start, end)
    return True

def are_powers_ascending(powers):
    power_ant = 0
    for power_new in powers:
        if power_new < power_ant:
            return False
        power_ant = power_new

    return True

class Tariff(object):
    """Energy DSO Tariff.
    """
    def __init__(self, code=None):
        self.code = code
        self._periods = tuple()
        self.cof = None

    @property
    def periods(self):
        return self._periods

    @periods.setter
    def periods(self, value):
        self._periods = value
        hours = {
            'holidays': [],
            'no_holidays': []
        }
        for period in self.energy_periods.values():
            if period.holiday:
                hours['holidays'].append(period)
            else:
                hours['no_holidays'].append(period)

        for station in ('summer', 'winter'):
            for holiday in (False, True):
                total_hours = 0
                range_hours = []
                for period in self.energy_periods.values():
                    if period.holiday == holiday:
                        total_hours += getattr(period, 'total_%s_hours' % station)
                        range_hours += getattr(period, '%s_hours' % station)
                range_hours = sorted(range_hours)
                if total_hours != 24:
                    if (holiday and total_hours) or not holiday:
                        raise ValueError(
                            'The sum of hours in %s%s must be 24h: %s'
                            % (station, holiday and ' (in holidays)' or '',
                            range_hours)
                        )
                if not check_range_hours(range_hours):
                    raise ValueError(
                        'Invalid range of hours in %s%s: %s'
                        % (station, holiday and ' (in holidays)' or '',
                           range_hours)
                    )

    @property
    def energy_periods(self):
        return dict((p.code, p) for p in self.periods if p.type == 'te')

    @property
    def power_periods(self):
        return dict((p.code, p) for p in self.periods if p.type == 'tp')

    def get_number_of_periods(self):
        return len([p for p in self.periods if p.type == 'te'])

    def get_min_power(self):
        return self.min_power

    def get_max_power(self):
        return self.max_power

    def get_period_by_date(self, date_time):
        station = get_station(date_time)
        date = date_time.date()
        holidays = get_holidays(date.year)
        if (calendar.weekday(date.year, date.month, date.day) in (5, 6) or
                date in holidays):
            holiday = True
        else:
            holiday = False
        # Map hour 0 to 24
        hour = date_time.hour or 24
        for period in self.periods:
            if period.holiday == holiday or not self.has_holidays_periods:
                for range_h in getattr(period, '%s_hours' % station):
                    if range_h[0] < hour <= range_h[1]:
                        return period
        return None

    @property
    def has_holidays_periods(self):
        return any(p.holiday for p in self.energy_periods.values())

    def is_maximum_power_correct(self, max_pow):
        return self.min_power < max_pow <= self.max_power

    @staticmethod
    def are_powers_normalized(powers):
        np = NormalizedPower()
        for power in powers:
            if not np.is_normalized(int(power * 1000)):
                return False

        return True

    def evaluate_powers(self, powers):
        if min(powers) <= 0:
            raise NotPositivePower()
        if not len(self.power_periods) == len(powers):
            raise IncorrectPowerNumber(len(powers), len(self.power_periods))
        if not self.is_maximum_power_correct(max(powers)):
            raise IncorrectMaxPower(max(powers), self.min_power, self.max_power)
        if not self.are_powers_normalized(powers):
            raise NotNormalizedPower()

        return True

    def correct_powers(self, powers):
        raise NotImplementedError

class TariffPeriod(object):
    """Tariff period.
    """
    def __init__(self, code, ptype, **kwargs):
        assert ptype in ('te', 'tp')
        self.code = code
        self.type = ptype
        winter_hours = kwargs.pop('winter_hours', [(0, 24)])
        if not check_range_hours(winter_hours):
            raise ValueError('Invalid winter hours')
        self.winter_hours = winter_hours
        summer_hours = kwargs.pop('summer_hours', [(0, 24)])
        if not check_range_hours(summer_hours):
            raise ValueError('Invalid summer hours')
        self.summer_hours = summer_hours
        self.holiday = kwargs.pop('holiday', False)

    @property
    def total_summer_hours(self):
        hours = 0
        for range_h in self.summer_hours:
            hours += (range_h[1] - range_h[0])
        return hours

    @property
    def total_winter_hours(self):
        hours = 0
        for range_h in self.winter_hours:
            hours += (range_h[1] - range_h[0])
        return hours

class T20A(Tariff):
    def __init__(self):
        super(T20A, self).__init__()
        self.code = '2.0A'
        self.cof = 'A'
        self.periods = (
            TariffPeriod('P1', 'te'),
            TariffPeriod('P1', 'tp')
        )
        self.min_power = 0
        self.max_power = 10
        self.type = 'BT'

    def correct_powers(self, powers):
        try:
            if self.evaluate_powers(powers):
                return powers
        except:
            pass

        norm_power = NormalizedPower().get_norm_powers(
            int(self.min_power * 1000), int(self.max_power * 1000)
        ).next()

        return [norm_power / 1000.0] * len(self.power_periods)

class T20DHA(T20A):
    def __init__(self):
        super(T20DHA, self).__init__()
        self.code = '2.0DHA'
        self.cof = 'B'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(12, 22)],
                summer_hours=[(13, 23)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(0, 12), (22, 24)],
                summer_hours=[(0, 13), (23, 24)]
            ),
            TariffPeriod(
                'P1', 'tp'
            )
        )

class T20DHS(T20DHA):
    def __init__(self):
        super(T20DHS, self).__init__()
        self.code = '2.0DHS'
        self.cof = 'D'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(13, 23)],
                summer_hours=[(13, 23)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(0, 1), (7, 13), (23, 24)],
                summer_hours=[(0, 1), (7, 13), (23, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(1, 7)],
                summer_hours=[(1, 7)]
            ),
            TariffPeriod(
                'P1', 'tp'
            )
        )

class T21A(T20A):
    def __init__(self):
        super(T21A, self).__init__()
        self.code = '2.1A'
        self.cof = 'A'
        self.min_power = 10
        self.max_power = 15

class T21DHA(T20DHA):
    def __init__(self):
        super(T21DHA, self).__init__()
        self.code = '2.1DHA'
        self.cof = 'B'
        self.min_power = 10
        self.max_power = 15

class T21DHS(T20DHS):
    def __init__(self):
        super(T21DHS, self).__init__()
        self.code = '2.1DHS'
        self.cof = 'D'
        self.min_power = 10
        self.max_power = 15

class T30A(Tariff):
    def __init__(self):
        super(T30A, self).__init__()
        self.code = '3.0A'
        self.cof = 'C'
        self.min_power = 15
        self.max_power = 1000000
        self.type = 'BT'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(18, 22)],
                summer_hours=[(11, 15)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(8, 18), (22, 24)],
                summer_hours=[(8, 11), (15, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P4', 'te',
                holiday=True,
                winter_hours=[(18, 22)],
                summer_hours=[(11, 15)]
            ),
            TariffPeriod(
                'P5', 'te',
                holiday=True,
                winter_hours=[(8, 18), (22, 24)],
                summer_hours=[(8, 11), (15, 24)]
            ),
            TariffPeriod(
                'P6', 'te',
                holiday=True,
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            )
        )

class T31A(T30A):
    """
    3.1A Tariff
    """
    def __init__(self):
        super(T31A, self).__init__()
        self.code = '3.1A'
        self.cof = 'C'
        self.min_power = 1
        self.max_power = 450
        self.type = 'AT'
        self.periods = (
            TariffPeriod(
                'P1', 'te',
                winter_hours=[(17, 23)],
                summer_hours=[(10, 16)]
            ),
            TariffPeriod(
                'P2', 'te',
                winter_hours=[(8, 17), (23, 24)],
                summer_hours=[(8, 10), (16, 24)]
            ),
            TariffPeriod(
                'P3', 'te',
                winter_hours=[(0, 8)],
                summer_hours=[(0, 8)]
            ),
            TariffPeriod(
                'P5', 'te',
                holiday=True,
                winter_hours=[(18, 24)],
                summer_hours=[(18, 24)]
            ),
            TariffPeriod(
                'P6', 'te',
                holiday=True,
                winter_hours=[(0, 18)],
                summer_hours=[(0, 18)]
            ),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            )
        )

    @staticmethod
    def are_powers_normalized(powers):
        # 3.1A doesn't need to have normalized powers
        return True

    def evaluate_powers(self, powers):
        super(T31A, self).evaluate_powers(powers)

        if not are_powers_ascending(powers):
            raise NotAscendingPowers()

        return True

class T61A(Tariff):
    """
    6.1A Tariff
    """
    def __init__(self):
        super(T61A, self).__init__()
        self.code = '6.1A'
        self.cof = 'C'
        self.min_power = 450
        self.max_power = 1000000
        self.type = 'AT'
        self.periods = (
            #
            # TODO: Implement correct energy periods
            #
            TariffPeriod('P1', 'te'),
            TariffPeriod(
                'P1', 'tp'
            ),
            TariffPeriod(
                'P2', 'tp'
            ),
            TariffPeriod(
                'P3', 'tp'
            ),
            TariffPeriod(
                'P4', 'tp'
            ),
            TariffPeriod(
                'P5', 'tp'
            ),
            TariffPeriod(
                'P6', 'tp'
            ),
        )

    @staticmethod
    def are_powers_normalized(powers):
        # 6.1A doesn't need to have normalized powers
        return True

    def evaluate_powers(self, powers):
        super(T61A, self).evaluate_powers(powers)

        if not are_powers_ascending(powers):
            raise NotAscendingPowers()

        return True

class T61B(T61A):
    """
    6.1B Tariff
    """
    def __init__(self):
        super(T61B, self).__init__()
        self.code = '6.1B'

class NotPositivePower(Exception):
    def __init__(self):
        super(NotPositivePower, self).__init__(
            'Power should allways be higher than 0'
        )

class NotNormalizedPower(Exception):
    def __init__(self):
        super(NotNormalizedPower, self).__init__(
            'One or more of the powers doen\'t have a normalized value'
        )

class IncorrectPowerNumber(Exception):
    def __init__(self, power_number, expected_number):
        super(IncorrectPowerNumber, self).__init__(
            'Expected {0} power(s) and got {1}'.format(
                expected_number, power_number
            )
        )
        self.power_number = power_number
        self.expected_number = expected_number

class IncorrectMaxPower(Exception):
    def __init__(self, power, min_power, max_power):
        super(IncorrectMaxPower, self).__init__(
            'Power {0} is not between {1} and {2}'.format(
                power, min_power, max_power
            )
        )
        self.power = power
        self.min_power = min_power
        self.max_power = max_power

class NotAscendingPowers(Exception):
    def __init__(self):
        super(NotAscendingPowers, self).__init__(
            'For this tariff powers should go in an ascending order (Pn+1>=Pn)'
        )

def get_tariff_by_code(code):
    """Get tariff class by code

    :param code: Tariff code
    :return: Tariff
    """
    available = {
        '2.0A': T20A,
        '2.0DHA': T20DHA,
        '2.0DHS': T20DHS,
        '2.1A': T21A,
        '2.1DHA': T21DHA,
        '2.1DHS': T21DHS,
        '3.0A': T30A,
        '3.1A': T31A,
        '3.1A LB': T31A,
        '6.1A': T61A,
        '6.1B': T61B,
    }
    return available.get(code, None)
<|endoftext|>


<commit_before>{
  'targets': [
    {
        'target_name': 'Resources',
        'product_name': 'MVKMapKit',
        'type': 'loadable_module',
        'mac_bundle': 1,
        'mac_bundle_resources': [
          '<!@(find MVKMapKit/Resources -type f)'
        ],
    },
    {
        'target_name': 'Sample App',
        'product_name': 'MVK Sample',
        'sources': [
            './MVKMapKit/main.m',
            './MVKMapKit/MVKAppDelegate.h',
            './MVKMapKit/MVKAppDelegate.m',
            './MVKMapKit/MVKViewController.h',
            './MVKMapKit/MVKViewController.m',
            './MVKMapKit/MVKMapView.h',
            './MVKMapKit/MVKMapView.mm',
            '../../common/foundation_request.h',
            '../../common/foundation_request.mm',
        ],
        'product_extension': 'app',
        'type': 'executable',
        'mac_bundle': 1,
        'link_settings': {
          'libraries': [
            '$(SDKROOT)/System/Library/Frameworks/CoreGraphics.framework',
            '$(SDKROOT)/System/Library/Frameworks/CoreLocation.framework',
            '$(SDKROOT)/System/Library/Frameworks/GLKit.framework',
            '$(SDKROOT)/System/Library/Frameworks/OpenGLES.framework',
            '$(SDKROOT)/System/Library/Frameworks/UIKit.framework'
          ],
        },
        'xcode_settings': {
          'SDKROOT': 'iphoneos',
          'SUPPORTED_PLATFORMS':['iphonesimulator','iphoneos'],
          'ARCHS': [ 'armv7', 'armv7s', 'arm64', 'i386' ],
          'INFOPLIST_FILE': 'MVKMapKit/MVKMapKit-Info.plist',
          'CLANG_CXX_LIBRARY': 'libc++',
          'CLANG_CXX_LANGUAGE_STANDARD':'c++11',
          'IPHONEOS_DEPLOYMENT_TARGET':'7.0',
          'TARGETED_DEVICE_FAMILY': '1,2',
          'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
          'CLANG_ENABLE_OBJC_ARC': 'YES'
        },
        'configurations': {
          'Debug': {
            'xcode_settings': {
              'CODE_SIGN_IDENTITY': 'iPhone Developer',
            }
          },
          'Release': {
            'xcode_settings': {
              'CODE_SIGN_IDENTITY': 'iPhone Distribution',
            }
          }
        },
        'default_configuration': 'Release',
        'dependencies': [
            '../../llmr.gyp:llmr-ios',
            'Resources'
        ]
    }
  ]
}<commit_msg>move away from resource bundle with GYP<commit_after>{
  'targets': [
    {
        'target_name': 'Sample App',
        'product_name': 'MVK Sample',
        'sources': [
            './MVKMapKit/main.m',
            './MVKMapKit/MVKAppDelegate.h',
            './MVKMapKit/MVKAppDelegate.m',
            './MVKMapKit/MVKViewController.h',
            './MVKMapKit/MVKViewController.m',
            './MVKMapKit/MVKMapView.h',
            './MVKMapKit/MVKMapView.mm',
            '../../common/foundation_request.h',
            '../../common/foundation_request.mm',
        ],
        'product_extension': 'app',
        'type': 'executable',
        'mac_bundle': 1,
        'mac_bundle_resources': [
          '<!@(find MVKMapKit/Resources -type f)'
        ],
        'link_settings': {
          'libraries': [
            '$(SDKROOT)/System/Library/Frameworks/CoreGraphics.framework',
            '$(SDKROOT)/System/Library/Frameworks/CoreLocation.framework',
            '$(SDKROOT)/System/Library/Frameworks/GLKit.framework',
            '$(SDKROOT)/System/Library/Frameworks/OpenGLES.framework',
            '$(SDKROOT)/System/Library/Frameworks/UIKit.framework'
          ],
        },
        'xcode_settings': {
          'SDKROOT': 'iphoneos',
          'SUPPORTED_PLATFORMS':['iphonesimulator','iphoneos'],
          'ARCHS': [ 'armv7', 'armv7s', 'arm64', 'i386' ],
          'INFOPLIST_FILE': 'MVKMapKit/MVKMapKit-Info.plist',
          'CLANG_CXX_LIBRARY': 'libc++',
          'CLANG_CXX_LANGUAGE_STANDARD':'c++11',
          'IPHONEOS_DEPLOYMENT_TARGET':'7.0',
          'TARGETED_DEVICE_FAMILY': '1,2',
          'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
          'CLANG_ENABLE_OBJC_ARC': 'YES'
        },
        'configurations': {
          'Debug': {
            'xcode_settings': {
              'CODE_SIGN_IDENTITY': 'iPhone Developer',
            }
          },
          'Release': {
            'xcode_settings': {
              'CODE_SIGN_IDENTITY': 'iPhone Distribution',
            }
          }
        },
        'default_configuration': 'Release',
        'dependencies': [
            '../../llmr.gyp:llmr-ios'
        ]
    }
  ]
}<|endoftext|>


<commit_before>"""Utility functions for copying files and directory trees.

XXX The functions here don't copy the resource fork or other metadata on Mac.

"""

import os
import sys
import stat

__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
           "copytree","rmtree"]

def copyfileobj(fsrc, fdst, length=16*1024):
    """copy data from file-like object fsrc to file-like object fdst"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)

def copyfile(src, dst):
    """Copy data from src to dst"""
    fsrc = None
    fdst = None
    try:
        fsrc = open(src, 'rb')
        fdst = open(dst, 'wb')
        copyfileobj(fsrc, fdst)
    finally:
        if fdst:
            fdst.close()
        if fsrc:
            fsrc.close()

def copymode(src, dst):
    """Copy mode bits from src to dst"""
    if hasattr(os, 'chmod'):
        st = os.stat(src)
        mode = stat.S_IMODE(st.st_mode)
        os.chmod(dst, mode)

def copystat(src, dst):
    """Copy all stat info (mode bits, atime and mtime) from src to dst"""
    st = os.stat(src)
    mode = stat.S_IMODE(st.st_mode)
    if hasattr(os, 'utime'):
        os.utime(dst, (st.st_atime, st.st_mtime))
    if hasattr(os, 'chmod'):
        os.chmod(dst, mode)

def copy(src, dst):
    """Copy data and mode bits ("cp src dst").

    The destination may be a directory.

    """
    if os.path.isdir(dst):
        dst = os.path.join(dst, os.path.basename(src))
    copyfile(src, dst)
    copymode(src, dst)

def copy2(src, dst):
    """Copy data and all stat info ("cp -p src dst").

    The destination may be a directory.

    """
    if os.path.isdir(dst):
        dst = os.path.join(dst, os.path.basename(src))
    copyfile(src, dst)
    copystat(src, dst)

def copytree(src, dst, symlinks=0):
    """Recursively copy a directory tree using copy2().

    The destination directory must not already exist.
    Error are reported to standard output.

    If the optional symlinks flag is true, symbolic links in the
    source tree result in symbolic links in the destination tree; if
    it is false, the contents of the files pointed to by symbolic
    links are copied.

    XXX Consider this example code rather than the ultimate tool.

    """
    names = os.listdir(src)
    os.mkdir(dst)
    for name in names:
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks)
            else:
                copy2(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error), why:
            print "Can't copy %s to %s: %s" % (`srcname`, `dstname`, str(why))

def rmtree(path, ignore_errors=0, onerror=None):
    """Recursively delete a directory tree.

    If ignore_errors is set, errors are ignored; otherwise, if
    onerror is set, it is called to handle the error; otherwise, an
    exception is raised.

    """
    cmdtuples = []
    _build_cmdtuple(path, cmdtuples)
    for cmd in cmdtuples:
        try:
            apply(cmd[0], (cmd[1],))
        except:
            exc = sys.exc_info()
            if ignore_errors:
                pass
            elif onerror is not None:
                onerror(cmd[0], cmd[1], exc)
            else:
                raise exc[0], (exc[1][0], exc[1][1] + ' removing '+cmd[1])

# Helper for rmtree()
def _build_cmdtuple(path, cmdtuples):
    for f in os.listdir(path):
        real_f = os.path.join(path,f)
        if os.path.isdir(real_f) and not os.path.islink(real_f):
            _build_cmdtuple(real_f, cmdtuples)
        else:
            cmdtuples.append((os.remove, real_f))
    cmdtuples.append((os.rmdir, path))
<commit_msg>shutil.copyfile(src,dst) was clobbering the file when the src and dst were the same.   Added check to verify the two names are not the same.  Does not check the actual files to see if there is a symbolic link.<commit_after>"""Utility functions for copying files and directory trees.

XXX The functions here don't copy the resource fork or other metadata on Mac.

"""

import os
import sys
import stat

__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
           "copytree","rmtree"]

def copyfileobj(fsrc, fdst, length=16*1024):
    """copy data from file-like object fsrc to file-like object fdst"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)

def copyfile(src, dst):
    """Copy data from src to dst"""
    fsrc = None
    fdst = None
    # check for same pathname; all platforms
    _src = os.path.normcase(os.path.abspath(src))
    _dst = os.path.normcase(os.path.abspath(dst))
    if _src == _dst:
        return
    try:
        fsrc = open(src, 'rb')
        fdst = open(dst, 'wb')
        copyfileobj(fsrc, fdst)
    finally:
        if fdst:
            fdst.close()
        if fsrc:
            fsrc.close()

def copymode(src, dst):
    """Copy mode bits from src to dst"""
    if hasattr(os, 'chmod'):
        st = os.stat(src)
        mode = stat.S_IMODE(st.st_mode)
        os.chmod(dst, mode)

def copystat(src, dst):
    """Copy all stat info (mode bits, atime and mtime) from src to dst"""
    st = os.stat(src)
    mode = stat.S_IMODE(st.st_mode)
    if hasattr(os, 'utime'):
        os.utime(dst, (st.st_atime, st.st_mtime))
    if hasattr(os, 'chmod'):
        os.chmod(dst, mode)

def copy(src, dst):
    """Copy data and mode bits ("cp src dst").

    The destination may be a directory.

    """
    if os.path.isdir(dst):
        dst = os.path.join(dst, os.path.basename(src))
    copyfile(src, dst)
    copymode(src, dst)

def copy2(src, dst):
    """Copy data and all stat info ("cp -p src dst").

    The destination may be a directory.

    """
    if os.path.isdir(dst):
        dst = os.path.join(dst, os.path.basename(src))
    copyfile(src, dst)
    copystat(src, dst)

def copytree(src, dst, symlinks=0):
    """Recursively copy a directory tree using copy2().

    The destination directory must not already exist.
    Error are reported to standard output.

    If the optional symlinks flag is true, symbolic links in the
    source tree result in symbolic links in the destination tree; if
    it is false, the contents of the files pointed to by symbolic
    links are copied.

    XXX Consider this example code rather than the ultimate tool.

    """
    names = os.listdir(src)
    os.mkdir(dst)
    for name in names:
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks)
            else:
                copy2(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error), why:
            print "Can't copy %s to %s: %s" % (`srcname`, `dstname`, str(why))

def rmtree(path, ignore_errors=0, onerror=None):
    """Recursively delete a directory tree.

    If ignore_errors is set, errors are ignored; otherwise, if
    onerror is set, it is called to handle the error; otherwise, an
    exception is raised.

    """
    cmdtuples = []
    _build_cmdtuple(path, cmdtuples)
    for cmd in cmdtuples:
        try:
            apply(cmd[0], (cmd[1],))
        except:
            exc = sys.exc_info()
            if ignore_errors:
                pass
            elif onerror is not None:
                onerror(cmd[0], cmd[1], exc)
            else:
                raise exc[0], (exc[1][0], exc[1][1] + ' removing '+cmd[1])

# Helper for rmtree()
def _build_cmdtuple(path, cmdtuples):
    for f in os.listdir(path):
        real_f = os.path.join(path,f)
        if os.path.isdir(real_f) and not os.path.islink(real_f):
            _build_cmdtuple(real_f, cmdtuples)
        else:
            cmdtuples.append((os.remove, real_f))
    cmdtuples.append((os.rmdir, path))
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time: 2017/5/19 上午8:55
# @Author: Matrix
# @Site: https://github.com/blackmatrix7/apizen
# @File: types.py
# @Software: PyCharm
import json
from app.apizen.exceptions import ApiSysExceptions
__author__ = 'blackmatrix'

class _Typed:
    expected_type = type(None)

    def __call__(self, key, value):
        try:
            return self.expected_type(value)
        except ValueError:
            raise ApiSysExceptions.error_args_type('{0}：{1} <{2}>'.format(ApiSysExceptions.error_args_type.message, key, self.expected_type))

class _Integer(_Typed):
    expected_type = int

    def __call__(self, key, value):
        return int(value) if isinstance(value, str) else value

Integer = _Integer()

class _String(_Typed):
    expected_type = str

String = _String()

class _Float(_Typed):
    expected_type = float

Float = _Typed()

class _DictAndList(_Typed):
    expected_type = dict

    def __call__(self, key, value):
        return json.loads(value) if isinstance(value, str) else value

Dict = _DictAndList()

List = _DictAndList()

if __name__ == '__main__':
    test = {'key': {'value': 'a', 'hello': 'python'}, 'test': 1}
    print(test.keys())
<commit_msg>修改types<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time: 2017/5/19 上午8:55
# @Author: Matrix
# @Site: https://github.com/blackmatrix7/apizen
# @File: types.py
# @Software: PyCharm
import json
from app.database import db
__author__ = 'blackmatrix'

class Typed:
    expected_type = type(None)

    def __call__(self, value):
        return self.expected_type(value)

class TypeInteger(Typed):
    expected_type = int

    def __call__(self, value):
        return int(value) if isinstance(value, str) else value

Integer = TypeInteger()

class TypeString(Typed):
    expected_type = str

String = TypeString()

class TypeFloat(Typed):
    expected_type = float

Float = TypeFloat()

class TypeDict(Typed):
    expected_type = dict

    def __call__(self, value):
        return json.loads(value) if isinstance(value, str) else value

Dict = TypeDict()

class TypeList:

    def __call__(self, typed, value):
        if isinstance(typed, db.Model):
            return typed(**value)
        else:
            return typed(value)

List = TypeList()

if __name__ == '__main__':
    test = {'key': {'value': 'a', 'hello': 'python'}, 'test': 1}
    print(test.keys())
<|endoftext|>


<commit_before>import platform
import shutil
import subprocess
from distutils import dir_util
from os import listdir, makedirs
from os.path import join, exists
from tempfile import mkdtemp

import f90nml
import pandas as pd

from .compat import get_param
from .paths import _magiccbinary, _magiccpath

_WINDOWS = platform.system() == "Windows"

class MAGICC(object):
    """
    Provides access to the MAGICC binary and configuration.

    To enable multiple MAGICC 'packages' to be configured independently,
    the MAGICC directory containing the input files, configuration
    and binary is copied to a new folder. The configuration in this
    MAGICC copy can then be edited without impacting other instances.

    A `MAGICC` instance first has to be setup by calling
    `create_copy`. If many model runs are being performed this step only has
    to be performed once. `run` can be called many times with the
    configuration files being updated between each call.

    Alternatively, an existing MAGICC directory structure can be used by
    setting `root_dir`.
    """

    def __init__(self, root_dir=None):
        self.root_dir = root_dir
        self.config = {}

        if root_dir is not None:
            self.is_temp = False
        else:
            # Create a temp directory
            self.is_temp = True
            self.root_dir = mkdtemp(prefix="pymagicc-")

    def __enter__(self):
        if self.is_temp and not exists(self.run_dir):
            self.create_copy()
        return self

    def __exit__(self, *args, **kwargs):
        if self.is_temp:
            self.remove_temp_copy()

    def create_copy(self):
        """
        Initialises a temporary directory structure and copy of MAGICC
        configuration files and binary.
        """
        if exists(self.run_dir):
            raise Exception("A copy of MAGICC has already been created.")
        if not exists(self.root_dir):
            makedirs(self.root_dir)
        # Copy the MAGICC run directory into the appropriate location
        dir_util.copy_tree(join(_magiccpath, ".."), self.root_dir)

    @property
    def run_dir(self):
        return join(self.root_dir, 'run')

    @property
    def out_dir(self):
        return join(self.root_dir, 'out')

    def run(self, only=None):
        """
        Run MAGICC and parse the output.

        :param only: If not None, only extract variables in this list
        :return: Dict containing DataFrames for each of the extracted variables
        """
        command = [join(self.run_dir, _magiccbinary)]

        if not _WINDOWS and _magiccbinary.endswith(".exe"):  # pragma: no cover
            command.insert(0, 'wine')

        # On Windows shell=True is required.
        subprocess.check_call(command, cwd=self.run_dir, shell=_WINDOWS)

        results = {}

        outfiles = [f for f in listdir(self.out_dir)
                    if f.startswith("DAT_") and f.endswith(".OUT")]

        for filename in outfiles:
            name = filename.replace("DAT_", "").replace(".OUT", "")
            if only is None or name in only:
                results[name] = pd.read_csv(
                    join(self.out_dir, filename),
                    delim_whitespace=True,
                    skiprows=get_param('num_output_headers'),
                    index_col=0,
                    engine="python"
                )

        with open(join(self.out_dir, "PARAMETERS.OUT")) as nml_file:
            parameters = dict(f90nml.read(nml_file))
            for group in ["nml_years", "nml_allcfgs", "nml_outputcfgs"]:
                parameters[group] = dict(parameters[group])
                for k, v in parameters[group].items():
                    if isinstance(v, str):
                        parameters[group][k] = v.strip()
                    elif isinstance(v, list):
                        if isinstance(v[0], str):
                            parameters[group][k] = [
                                i.strip().replace("\n", "") for i in v]
                parameters[group.replace("nml_", "")] = parameters.pop(group)
            self.config = parameters

        return results

    def remove_temp_copy(self):
        """
        Removes a temporary copy of the MAGICC version shipped with Pymagicc.
        """
        if self.is_temp:
            shutil.rmtree(self.root_dir)
<commit_msg>Only check for `is_temp` once<commit_after>import platform
import shutil
import subprocess
from distutils import dir_util
from os import listdir, makedirs
from os.path import join, exists
from tempfile import mkdtemp

import f90nml
import pandas as pd

from .compat import get_param
from .paths import _magiccbinary, _magiccpath

_WINDOWS = platform.system() == "Windows"

class MAGICC(object):
    """
    Provides access to the MAGICC binary and configuration.

    To enable multiple MAGICC 'packages' to be configured independently,
    the MAGICC directory containing the input files, configuration
    and binary is copied to a new folder. The configuration in this
    MAGICC copy can then be edited without impacting other instances.

    A `MAGICC` instance first has to be setup by calling
    `create_copy`. If many model runs are being performed this step only has
    to be performed once. `run` can be called many times with the
    configuration files being updated between each call.

    Alternatively, an existing MAGICC directory structure can be used by
    setting `root_dir`.
    """

    def __init__(self, root_dir=None):
        self.root_dir = root_dir
        self.config = {}

        if root_dir is not None:
            self.is_temp = False
        else:
            # Create a temp directory
            self.is_temp = True
            self.root_dir = mkdtemp(prefix="pymagicc-")

    def __enter__(self):
        if self.is_temp and not exists(self.run_dir):
            self.create_copy()
        return self

    def __exit__(self, *args, **kwargs):
        self.remove_temp_copy()

    def create_copy(self):
        """
        Initialises a temporary directory structure and copy of MAGICC
        configuration files and binary.
        """
        if exists(self.run_dir):
            raise Exception("A copy of MAGICC has already been created.")
        if not exists(self.root_dir):
            makedirs(self.root_dir)
        # Copy the MAGICC run directory into the appropriate location
        dir_util.copy_tree(join(_magiccpath, ".."), self.root_dir)

    @property
    def run_dir(self):
        return join(self.root_dir, 'run')

    @property
    def out_dir(self):
        return join(self.root_dir, 'out')

    def run(self, only=None):
        """
        Run MAGICC and parse the output.

        :param only: If not None, only extract variables in this list
        :return: Dict containing DataFrames for each of the extracted variables
        """
        command = [join(self.run_dir, _magiccbinary)]

        if not _WINDOWS and _magiccbinary.endswith(".exe"):  # pragma: no cover
            command.insert(0, 'wine')

        # On Windows shell=True is required.
        subprocess.check_call(command, cwd=self.run_dir, shell=_WINDOWS)

        results = {}

        outfiles = [f for f in listdir(self.out_dir)
                    if f.startswith("DAT_") and f.endswith(".OUT")]

        for filename in outfiles:
            name = filename.replace("DAT_", "").replace(".OUT", "")
            if only is None or name in only:
                results[name] = pd.read_csv(
                    join(self.out_dir, filename),
                    delim_whitespace=True,
                    skiprows=get_param('num_output_headers'),
                    index_col=0,
                    engine="python"
                )

        with open(join(self.out_dir, "PARAMETERS.OUT")) as nml_file:
            parameters = dict(f90nml.read(nml_file))
            for group in ["nml_years", "nml_allcfgs", "nml_outputcfgs"]:
                parameters[group] = dict(parameters[group])
                for k, v in parameters[group].items():
                    if isinstance(v, str):
                        parameters[group][k] = v.strip()
                    elif isinstance(v, list):
                        if isinstance(v[0], str):
                            parameters[group][k] = [
                                i.strip().replace("\n", "") for i in v]
                parameters[group.replace("nml_", "")] = parameters.pop(group)
            self.config = parameters

        return results

    def remove_temp_copy(self):
        """
        Removes a temporary copy of the MAGICC version shipped with Pymagicc.
        """
        if self.is_temp:
            shutil.rmtree(self.root_dir)
<|endoftext|>


<commit_before>#encoding:utf-8
import wx
from Chordbook import chords, chordSymbols, shiftFactors

class CustomFrame(wx.Frame):
	def __init__(self, parent, id, title):
		wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(450, 400))
			#style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)

		notes = sorted(['C','C#','D','D#','Db','E','Eb','F','F#','G','G#','Gb','A','A#','Ab','B','Bb'])

		self.chords = [u'Dm7',u'G7',u'CMaj7'] #initial progression
		self.panel = wx.Panel(self, -1)

		self.btnAdd = wx.Button(self.panel, -1, 'Ajouter accord')
		self.btnAdd.Bind(wx.EVT_BUTTON, self.onAddChord)

		self.btnRemove = wx.Button(self.panel, -1, 'Supprimer accord')
		self.btnRemove.Bind(wx.EVT_BUTTON, self.onDeleteChord)

		self.btnPlay = wx.Button(self.panel, -1, 'PLAY')
		self.btnPlay.Bind(wx.EVT_BUTTON, self.onPlay)

		self.btnStop = wx.Button(self.panel, -1, 'STOP')
		self.btnStop.Bind(wx.EVT_BUTTON, self.onStop)

		self.chordLabel = wx.StaticText(self.panel, id=-1, label=" -- ".join(self.chords), pos=(-1,-1), size=(-1,-1),
			style=wx.ALIGN_CENTRE_HORIZONTAL)

		self.chordKeys = wx.ListBox(self.panel, -1, pos=wx.Point(8, 48), size=wx.Size(75, 256),
			choices = sorted(shiftFactors.keys()), style = wx.LB_SINGLE | wx.LB_ALWAYS_SB)
		self.chordQualities = wx.ListBox(self.panel, -1, pos=wx.Point(32, 64),size=wx.Size(184, 256),
			choices = sorted(chords.keys()), style = wx.LB_SINGLE | wx.LB_ALWAYS_SB)

		self.inversion = wx.ComboBox(self.panel, size=wx.DefaultSize, choices=notes)
		self.inversionLabel = wx.StaticText(self.panel, id=-1, label="Inversion : ")

		self.tempoLabel = wx.StaticText(self.panel, id=-1, label="Tempo : ")
		self.tempoTextBox = wx.TextCtrl(self.panel)
		self.tempoTextBox.SetValue("90")
		self.tempoTextBox.Bind(wx.EVT_CHAR, self.checkForNumber)

		self.containerSizer = wx.BoxSizer(wx.VERTICAL)
		self.chordChooserSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.inversionSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.btnAddRemoveSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.btnPlayStopSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.displaySizer = wx.BoxSizer(wx.HORIZONTAL)
		self.tempoSizer = wx.BoxSizer(wx.HORIZONTAL)

		self.btnAddRemoveSizer.Add(self.btnAdd, 1, wx.EXPAND)
		self.btnAddRemoveSizer.Add(self.btnRemove, 1, wx.EXPAND)

		self.btnPlayStopSizer.Add(self.btnPlay, 1, wx.EXPAND)
		self.btnPlayStopSizer.Add(self.btnStop, 1, wx.EXPAND)

		self.chordChooserSizer.Add(self.chordKeys, 1, wx.EXPAND)
		self.chordChooserSizer.Add(self.chordQualities, 1, wx.EXPAND)

		self.inversionSizer.Add(self.inversionLabel, 0, wx.LEFT | wx.ALIGN_CENTER,150)
		self.inversionSizer.Add(self.inversion, 1, wx.RIGHT,150)

		self.displaySizer.Add(self.chordLabel, 1 , wx.EXPAND)

		self.tempoSizer.Add(self.tempoLabel, 1, wx.LEFT | wx.ALIGN_CENTER, 150)
		self.tempoSizer.Add(self.tempoTextBox, 1, wx.RIGHT, 150)

		self.containerSizer.Add(self.chordChooserSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.inversionSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.btnAddRemoveSizer, 0, wx.EXPAND)
		self.containerSizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
		self.containerSizer.Add(self.displaySizer, 0, wx.ALIGN_CENTER)
		self.containerSizer.Add(self.btnPlayStopSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.tempoSizer, 0, wx.EXPAND)

		self.panel.SetSizer(self.containerSizer)
		self.Centre()

	def _updateLabel(self):
		self.chordLabel.SetLabel(" -- ".join(self.chords))
		self.displaySizer.Layout()
		self.containerSizer.Layout()

	def _updateBoxes(self):
		self.inversion.SetSelection(-1)
		self.chordQualities.SetSelection(-1)
		self.chordKeys.SetSelection(-1)
		self.inversionSizer.Layout()

	def onAddChord(self, event):
		#stack based logic, will change in the future
		inv = ''
		if self.chordQualities.GetSelection() == -1 or self.chordKeys.GetSelection() == -1:
			print "YOU MUST CHOOSE ADDITIONAL DATA"
			return
		if self.inversion.GetSelection != -1:
			inv = self.inversion.GetString(self.inversion.GetSelection())

		key = self.chordKeys.GetString(self.chordKeys.GetSelection())
		quality = self.chordQualities.GetString(self.chordQualities.GetSelection())
		symbol = chordSymbols[quality]

		if inv == '':
			self.chords.append(key+symbol)
		else:
			self.chords.append(key+symbol+'/'+inv)

		self._updateBoxes()
		self._updateLabel()

	def onDeleteChord(self, event):
		#stack based logic, will change in the future
		self.chords.pop()
		self._updateLabel()

	def onPlay(self, event):
		tempo = int(self.tempoTextBox.GetValue().strip())
		if tempo < 30 or tempo > 300:
			print "Tempo must be between 30 and 300"
			return
		print("TWADO PLAY")

	def onStop(self, event):
		print("TWADO STOP")

	def checkForNumber(self, event):
		keycode = event.GetKeyCode()
		if chr(keycode) in [str(i) for i in range(10)] or keycode == 8:
			event.Skip()

	def getChords(self):
		return self.chordProg

	def setChords(self, chord, i = -1):
		if i < 0:
			self.chords.append(chord)
		else:
			self.chords.insert(i, chord)

class ChordManager(wx.App):
	def OnInit(self):
		frame = CustomFrame(None, -1, 'Super Chord Manager 3000')
		frame.Show(True)
		return True

app = ChordManager(0)
app.MainLoop()<commit_msg>fixed inversion box<commit_after>#encoding:utf-8
import wx
from Chordbook import chords, chordSymbols, shiftFactors

class CustomFrame(wx.Frame):
	def __init__(self, parent, id, title):
		wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(450, 400))
			#style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)

		notes = sorted(['C','C#','D','D#','Db','E','Eb','F','F#','G','G#','Gb','A','A#','Ab','B','Bb'])
		notes = ['None'] + notes
		self.chords = [u'Dm7',u'G7',u'CMaj7'] #initial progression
		self.panel = wx.Panel(self, -1)

		self.btnAdd = wx.Button(self.panel, -1, 'Ajouter accord')
		self.btnAdd.Bind(wx.EVT_BUTTON, self.onAddChord)

		self.btnRemove = wx.Button(self.panel, -1, 'Supprimer accord')
		self.btnRemove.Bind(wx.EVT_BUTTON, self.onDeleteChord)

		self.btnPlay = wx.Button(self.panel, -1, 'PLAY')
		self.btnPlay.Bind(wx.EVT_BUTTON, self.onPlay)

		self.btnStop = wx.Button(self.panel, -1, 'STOP')
		self.btnStop.Bind(wx.EVT_BUTTON, self.onStop)

		self.chordLabel = wx.StaticText(self.panel, id=-1, label=" -- ".join(self.chords), pos=(-1,-1), size=(-1,-1),
			style=wx.ALIGN_CENTRE_HORIZONTAL)

		self.chordKeys = wx.ListBox(self.panel, -1, pos=wx.Point(8, 48), size=wx.Size(75, 256),
			choices = sorted(shiftFactors.keys()), style = wx.LB_SINGLE | wx.LB_ALWAYS_SB)
		self.chordQualities = wx.ListBox(self.panel, -1, pos=wx.Point(32, 64),size=wx.Size(184, 256),
			choices = sorted(chords.keys()), style = wx.LB_SINGLE | wx.LB_ALWAYS_SB)

		self.inversion = wx.ComboBox(self.panel, size=wx.DefaultSize, choices=notes)
		self.inversion.SetSelection(0)

		self.inversionLabel = wx.StaticText(self.panel, id=-1, label="Inversion : ")

		self.tempoLabel = wx.StaticText(self.panel, id=-1, label="Tempo : ")
		self.tempoTextBox = wx.TextCtrl(self.panel)
		self.tempoTextBox.SetValue("90")
		self.tempoTextBox.Bind(wx.EVT_CHAR, self.checkForNumber)

		self.containerSizer = wx.BoxSizer(wx.VERTICAL)
		self.chordChooserSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.inversionSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.btnAddRemoveSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.btnPlayStopSizer = wx.BoxSizer(wx.HORIZONTAL)
		self.displaySizer = wx.BoxSizer(wx.HORIZONTAL)
		self.tempoSizer = wx.BoxSizer(wx.HORIZONTAL)

		self.btnAddRemoveSizer.Add(self.btnAdd, 1, wx.EXPAND)
		self.btnAddRemoveSizer.Add(self.btnRemove, 1, wx.EXPAND)

		self.btnPlayStopSizer.Add(self.btnPlay, 1, wx.EXPAND)
		self.btnPlayStopSizer.Add(self.btnStop, 1, wx.EXPAND)

		self.chordChooserSizer.Add(self.chordKeys, 1, wx.EXPAND)
		self.chordChooserSizer.Add(self.chordQualities, 1, wx.EXPAND)

		self.inversionSizer.Add(self.inversionLabel, 0, wx.LEFT | wx.ALIGN_CENTER,150)
		self.inversionSizer.Add(self.inversion, 1, wx.RIGHT,150)

		self.displaySizer.Add(self.chordLabel, 1 , wx.EXPAND)

		self.tempoSizer.Add(self.tempoLabel, 1, wx.LEFT | wx.ALIGN_CENTER, 150)
		self.tempoSizer.Add(self.tempoTextBox, 1, wx.RIGHT, 150)

		self.containerSizer.Add(self.chordChooserSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.inversionSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.btnAddRemoveSizer, 0, wx.EXPAND)
		self.containerSizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
		self.containerSizer.Add(self.displaySizer, 0, wx.ALIGN_CENTER)
		self.containerSizer.Add(self.btnPlayStopSizer, 0, wx.EXPAND)
		self.containerSizer.Add(self.tempoSizer, 0, wx.EXPAND)

		self.panel.SetSizer(self.containerSizer)
		self.Centre()

	def _updateLabel(self):
		self.chordLabel.SetLabel(" -- ".join(self.chords))
		self.displaySizer.Layout()
		self.containerSizer.Layout()

	def _updateBoxes(self):
		self.inversion.SetSelection(0)
		self.chordQualities.SetSelection(-1)
		self.chordKeys.SetSelection(-1)
		self.inversionSizer.Layout()

	def onAddChord(self, event):
		#stack based logic, will change in the future
		inv = ''
		if self.chordQualities.GetSelection() == -1 or self.chordKeys.GetSelection() == -1:
			print "YOU MUST CHOOSE ADDITIONAL DATA"
			return
		if self.inversion.GetSelection > 0:
			inv = self.inversion.GetString(self.inversion.GetSelection())

		key = self.chordKeys.GetString(self.chordKeys.GetSelection())
		quality = self.chordQualities.GetString(self.chordQualities.GetSelection())
		symbol = chordSymbols[quality]

		if inv == '':
			self.chords.append(key+symbol)
		else:
			self.chords.append(key+symbol+'/'+inv)

		self._updateBoxes()
		self._updateLabel()

	def onDeleteChord(self, event):
		#stack based logic, will change in the future
		self.chords.pop()
		self._updateLabel()

	def onPlay(self, event):
		tempo = int(self.tempoTextBox.GetValue().strip())
		if tempo < 30 or tempo > 300:
			print "Tempo must be between 30 and 300"
			return
		print("TWADO PLAY")

	def onStop(self, event):
		print("TWADO STOP")

	def checkForNumber(self, event):
		keycode = event.GetKeyCode()
		if chr(keycode) in [str(i) for i in range(10)] or keycode == 8:
			event.Skip()

	def getChords(self):
		return self.chordProg

	def setChords(self, chord, i = -1):
		if i < 0:
			self.chords.append(chord)
		else:
			self.chords.insert(i, chord)

class ChordManager(wx.App):
	def OnInit(self):
		frame = CustomFrame(None, -1, 'Super Chord Manager 3000')
		frame.Show(True)
		return True

app = ChordManager(0)
app.MainLoop()<|endoftext|>


<commit_before>from pyramid.config import Configurator
from sqlalchemy import engine_from_config

from .models import (
    DBSession,
    Base,
    )

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    config = Configurator(settings=settings)
    config.add_static_view('static', 'static', cache_max_age=3600)
    #config.add_route('home', '/')
    config.scan()
    return config.make_wsgi_app()
<commit_msg>add routes for site graph and entity graph<commit_after>from pyramid.config import Configurator
from sqlalchemy import engine_from_config

from .models import (
    DBSession,
    Base,
    )

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    config = Configurator(settings=settings)
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('site_graph', '/site/{code}')
    config.add_route('entity_graph', '/entity/{id}')
    config.scan()
    return config.make_wsgi_app()
<|endoftext|>


<commit_before>"""
This module helps with 'tiling' which is the process
of pattern matching against AST trees. This can be
used either for optimizations by re-writing the
AST tree, or for things like expression counting and
merging.
"""

class Pattern(object):
    "Base class for patterns"
    def matches(self, node):
        "Returns if the current node matches the pattern"
        return False

class SimplePattern(object):
    "Implements a simple DSL for patterns"
    def __init__(self, node_p, left_p=None, right_p=None):
        """
        Initializes a pattern that checks against the
        given node, and optionally against the left and right
        nodes as well. The base Pattern implementation understands
        patters in the form of:
        * types:ASTType1,ASTType2
        * op:NodeType
        * AND

        As an example, a pattern like:
        types:CompareOperator AND op:=

        Will match a comparison operator which checks for equality.
        """
        self.node_p = node_p
        self.left_p = left_p
        self.right_p = right_p

    def matches(self, node):
        "Returns if the current node matches the pattern"
        if not self._check_pattern(self.node_p, node):
            return False
        if self.left_p and not self._check_pattern(self.left_p, node.left):
            return False
        if self.right_p and not self._check_pattern(self.right_p, node.right):
            return False
        return True

    @classmethod
    def _check_pattern(cls, pattern, node):
        clauses = pattern.split(" AND ")
        for clause in clauses:
            # Check the node type
            if clause.startswith("types:"):
                types = clause[6:].split(",")
                if cls.node_type(node) not in types:
                    return False

            # Check the node op
            elif clause.startswith("op:"):
                op = clause[3:]
                if cls.node_op(node) != op:
                    return False

            else:
                raise Exception("Invalid pattern clause %s" % clause)
        return True

    @classmethod
    def node_type(cls, node):
        return node.__class__.__name__

    @classmethod
    def node_op(cls, node):
        if hasattr(node, "type"):
            return node.type
        else:
            return None

def tile(ast, patterns, func):
    """
    Tiles over the given AST tree with a list of patterns,
    applying each. When a given pattern matches, the callback
    function is invoked with the pattern, and current node.
    The function can return either None or a new AST node
    which replaces the node that was passed in.

    Returns the new AST tree.
    """
    for p in patterns:
        if p.matches(ast):
            result = func(p, ast)
            if result:
                ast=result

    # Tile the left
    if hasattr(ast, "left"):
        result = tile(ast.left, patterns, func)
        if result:
            ast.left=result

    # Tile the right side
    if hasattr(ast, "right"):
        result = tile(ast.right, patterns, func)
        if result:
            ast.right=result

    return ast

<commit_msg>Extend the SimplePattern and add an ASTPattern<commit_after>"""
This module helps with 'tiling' which is the process
of pattern matching against AST trees. This can be
used either for optimizations by re-writing the
AST tree, or for things like expression counting and
merging.
"""

class Pattern(object):
    "Base class for patterns"
    def matches(self, node):
        "Returns if the current node matches the pattern"
        return False

class ASTPattern(object):
    "Implements AST based pattern"
    def __init__(self, ast):
        self.ast = ast

    def matches(self, node):
        "Returns if the current node matches the ast"
        return self.compare_nodes(self.ast, node)

    @classmethod
    def compare_nodes(cls, a, b):
        if a.__class__ != b.__class__:
            return False
        if hasattr(a, "value") and a.value != b.value:
            return False
        if hasattr(a, "type") and a.type != b.type:
            return False
        if hasattr(a, "left") and \
            not cls.compare_nodes(a.left, b.left):
            return False
        if hasattr(b, "right") and \
            not cls.compare_nodes(a.right, b.right):
            return False
        return True

class SimplePattern(object):
    "Implements a simple DSL for patterns"
    def __init__(self, node_p, left_p=None, right_p=None):
        """
        Initializes a pattern that checks against the
        given node, and optionally against the left and right
        nodes as well. The base Pattern implementation understands
        patters in the form of:
        * types:ASTType1,ASTType2
        * op:NodeType
        * value:ValueStr
        * AND

        As an example, a pattern like:
        types:CompareOperator AND op:=

        Will match a comparison operator which checks for equality.
        """
        self.node_p = node_p
        self.left_p = left_p
        self.right_p = right_p

    def matches(self, node):
        "Returns if the current node matches the pattern"
        if not self._check_pattern(self.node_p, node):
            return False
        if self.left_p and not self._check_pattern(self.left_p, node.left):
            return False
        if self.right_p and not self._check_pattern(self.right_p, node.right):
            return False
        return True

    @classmethod
    def _check_pattern(cls, pattern, node):
        clauses = pattern.split(" AND ")
        for clause in clauses:
            # Check the node type
            if clause.startswith("types:"):
                types = clause[6:].split(",")
                if cls.node_type(node) not in types:
                    return False

            # Check the node op
            elif clause.startswith("op:"):
                op = clause[3:]
                if cls.node_op(node) != op:
                    return False

            # Check the node op
            elif clause.startswith("value:"):
                val = clause[6:]
                if cls.node_value(node) != val:
                    return False

            else:
                raise Exception("Invalid pattern clause %s" % clause)
        return True

    @classmethod
    def node_type(cls, node):
        return node.__class__.__name__

    @classmethod
    def node_op(cls, node):
        if hasattr(node, "type"):
            return node.type
        else:
            return None

    @classmethod
    def node_value(cls, node):
        if hasattr(node, "value"):
            return str(node.value)
        else:
            return None

def tile(ast, patterns, func):
    """
    Tiles over the given AST tree with a list of patterns,
    applying each. When a given pattern matches, the callback
    function is invoked with the pattern, and current node.
    The function can return either None or a new AST node
    which replaces the node that was passed in.

    Returns the new AST tree.
    """
    for p in patterns:
        if p.matches(ast):
            result = func(p, ast)
            if result:
                ast=result

    # Tile the left
    if hasattr(ast, "left"):
        result = tile(ast.left, patterns, func)
        if result:
            ast.left=result

    # Tile the right side
    if hasattr(ast, "right"):
        result = tile(ast.right, patterns, func)
        if result:
            ast.right=result

    return ast

<|endoftext|>