""" Order factory to choose order status according to
the service provider
"""
import logging

from django.conf import settings

from oms.custom_requests import GoogleDistanceApiRequest
from order import models as order_model
from service_provider.opinio.functions import OrderStatus

logger = logging.getLogger('common')
logger = logging.LoggerAdapter(logger, settings.LOGGING_EXTRA)

def order_status(workflow):
    """ get the order status on the basis of
    service provider
    Args:
        workflow : workflow instance
    return:
        response_content : parsed response data

    """
    if workflow.state in settings.SYSTEM_STATUS: return {}
    order_event = order_model.get_order_event(workflow.order, workflow.state)
    if order_event:
        additional_data = order_event[0].additional_data
        if 'order_code' or 'state' in additional_data:
            additional_data.pop('order_code', None), additional_data.pop('state', None)
        return additional_data
    return {}

def order_serviceability(order_payload):
    """ get the order status on the basis of
    service provider
    Args:
        merchant_id : merchant id,
        client_id : client id
    return:
        response_content : parsed response data

    """
    try:
        from oms.custom_requests import MerchantRequest
        client_id = order_payload['client_id']
        merchant_id = order_payload['order_details']['pickup']['merchant_id']
        r = MerchantRequest(merchant_id, client_id)
        response = r.send()
        try:
            merchant_id = response.json()[0]['merchant_id']
            if merchant_id:
                from service_provider.opinio.functions import OrderServiceabilityCheck
                order_serviceability = OrderServiceabilityCheck(merchant_id=merchant_id)
                response = order_serviceability.send()
                import ast
                response_content = ast.literal_eval(response.content)
                if response_content['GP_availability'] == 1 or response_content['GP_availability'] == 0:
                    return 1
                else:
                    return 0
            else:
                return
        except:
            return
    except:
        return

def get_order_delivery_distance_time(origin_lat, origin_long, des_lat, des_long,departure_time=None):
    """ get order delivery time accoring to their lat long
    Args:
        origin_lat : origin lattitude
        origin_long : origin longitude
        des_lat : destination lattitude
        des_long : destination longitude
        departure_time : time when fleet departs
    """
    req = GoogleDistanceApiRequest(origin_lat, origin_long, des_lat, des_long, departure_time)
    response = req.send()
    logger.info("google api response status  is %s", response)
    import ast
    response_content = ast.literal_eval(response.content)
    logger.info("google api response is %s", response_content)
    distance = response_content['rows'][0].get('elements')[0].get('distance').get('value')
    if departure_time:
        duration = response_content['rows'][0].get('elements')[0].get('duration_in_traffic').get('value')
    else:
        duration = response_content['rows'][0].get('elements')[0].get('duration').get('value')
    return distance, duration


import pygame
import sys
from random import randint
from enum import Enum

class Incidents(Enum):
    start = 0                       # 起点
    horseField = 1                  # 马场
    encounterThief = 2              # 遭遇小偷
    involvedMurder = 3              # 卷入谋杀案
    changeMoney = 4                 # 资金互换
    explosive = 5                   # 炸药
    reachGoldMine = 6               # 到达金矿
    haveACold = 7                   # 感冒
    strongWind = 8                  # 遭遇大风
    friendshipWithLord = 9          # 与当地领主结好
    houseFiled = 10                 # 无事件
    house = 11                      # 房间

class PlayerTurn(Enum):
    start = 0       # 游戏开始
    PCMove = 1      # PC移动
    NPCMove = 2     # NPC移动
    PCAct = 3       # PC行动
    NPCAct = 4      # NPC行动

class GameTurn(Enum):
    start = 0       # 游戏开始界面
    waitIn = 1      # 等待进入游戏
    initial = 2     # 实例化角色对象、地块对象、掷骰子对象
    playing = 3     # 进入游戏
    over = 4        # 游戏结束界面
    end = 5         # 游戏结束界面绘制完毕

class PC:
    def __init__(self, name):
        self.name = name
        self.position = 0                   # 初始位置
        self.money = 1000                   # 初始资金
        self.houseCounter = [0, 0, 0, 0, 0]
        self.transportation = "无"          # 装备
        self.status = "正常"                # 状态
        self.engine = 0                     # 每回合额外移动一格，需激活
        self.chance = False                 # 互换资金的机会，需激活
        self.item = "无"                    # 持有道具
        self.ill = 0                        # 生病冷却，需激活
        self.wind = False                   # 传送冷却，需激活
        self.free = False                   # 免费冷却，需激活

    def move(self):
        self.engine = 0                                     # 千里马引擎归零

        wind_or_in_jail = False
        point1 = randint(1, 6)
        point2 = 0
        if self.transportation != "无":
            point2 = randint(1, 6)

        if self.status == "监禁":
            self.status = "保释"
            point1, point2, wind_or_in_jail = 0, 0, True
        elif self.status == "保释":
            self.status = "正常"

        roll = point1 + point2

        if self.ill > 0:
            roll = roll // 2                                # 感冒移动速度减半
            roll = 1 if roll == 0 else roll
            self.ill -= 1
            self.status = "正常" if self.ill == 0 else self.status

        if self.wind is True:
            wind_or_in_jail = self.wind
            roll = randint(1, 50)                           # 遭遇大风，随机落地
            self.wind = not self.wind

        self.position += roll
        self.money += 0 if self.position < 50 else 500      # 绕地图一圈奖励
        self.position -= 0 if self.position < 50 else 50    # 坐标限位

        return point1, point2, wind_or_in_jail

    def swift_horse_move(self, forward):
        if forward is False:                           # 后退
            if self.engine == 0 or self.engine == 1:
                self.position -= 1 if self.position > 0 else -49
                self.engine -= 1
        elif forward is True:                          # 前进
            if self.engine == 0 or self.engine == -1:
                self.position += 1 if self.position < 49 else -49
                self.engine += 1

    def incidents(self, Ls):
        land = Ls.lands[self.position]
        # 地块买满的奖励
        if Ls.is_full(self.name) is True:
            self.money += self.houseCounter[0] * 100
            Ls.PCAwardMessage = 2
        # 1.路过敌人房子
        if land.owner != self.name and land.owner != "事件" and land.owner != "系统":
            self.money -= land.level * 100
            return land.level * 100
        # 特殊事件房间
        elif land.owner == "事件" and self.engine == 0:
            if land.incident is Incidents.encounterThief:
                self.money -= 500 if self.transportation == "无" else 0
            elif land.incident is Incidents.involvedMurder:
                self.status = "监禁" if (self.status != "保释" and self.status != "感冒") else self.status
            elif land.incident is Incidents.changeMoney:
                self.chance = True
            elif land.incident is Incidents.explosive:
                self.item = "炸药"
            elif land.incident is Incidents.reachGoldMine:
                self.money += 1000
            elif land.incident is Incidents.haveACold:
                self.status = "感冒"
                self.ill = 3
            elif land.incident is Incidents.strongWind:
                self.wind = True
            elif land.incident == Incidents.friendshipWithLord:
                self.free = True
        return 0

    def messages(self, Ls):
        base_messages = self.__base_messages()
        incidents_messages = self.__incidents_messages(Ls)
        return base_messages, incidents_messages

    def __base_messages(self):
        messages = list()
        for i in range(3):
            messages.append(list())
        messages[0].append("昵称: %s" % self.name)
        messages[0].append("坐标: %d" % self.position)
        messages[1].append("状态: %s" % self.status)
        messages[1].append("装备: %s" % self.transportation)
        messages[2].append("物品: %s" % self.item)
        messages[2].append("资金: %d金币" % self.money)

        return messages

    def __incidents_messages(self, Ls):
        land = Ls.lands[self.position]
        messages = list()

        # 购买或升级地块及炸药使用提示
        if land.owner != "事件":
            if land.owner == "系统":
                messages.append("这里是一片无主的荒地")
                if self.free is True:
                    messages.append("你可以按B键免费建立城堡（仅限一次）")
                    messages.append("省去%d金币" % ((land.level + 1) * 100))
                else:
                    messages.append("按B键花费%d金币建立城堡" % ((land.level + 1) * 100))
            elif land.owner == self.name:
                messages.append("城墙上的卫兵向你举旗致敬")
                if land.level < 5:
                    if self.free is True:
                        messages.append("你可以按B键免费升级城堡（仅限一次）")
                        messages.append("省去%d金币" % ((land.level + 1) * 100))
                    else:
                        messages.append("按B键花费%d金币升级城堡" % ((land.level + 1) * 100))
                else:
                    messages.append("城堡已经很豪华了！")
            else:
                messages.append("高耸的城堡阴沉地矗立于前方")
                if self.engine == 0:
                    messages.append("你到了别人的地盘，不得不支付%d金币过路费" % (land.level * 100))
                if self.item == "炸药":
                    messages.append("按B键使用炸药炸毁城堡")

        elif land.incident is Incidents.start:
            messages.append("事件：你到达了起点")

        elif land.incident is Incidents.horseField:
            messages.append("事件：你来到了马场")
            if self.transportation == "无":
                messages.append("按B键花费1000金币购买一匹战马")
                messages.append("你将以双倍速度进行移动！")
            elif self.transportation == "战马":
                messages.append("按B键花费2000金币将战马升级为千里马")
                messages.append("骑上千里马的你将可以进行额外行动！")
            elif self.transportation == "千里马":
                messages.append("这里已经没有值得购买的好马了")
                messages.append("你失望地离开了马场")

        elif land.incident is Incidents.encounterThief:
            messages.append("事件：走在大街上的你遇到了小偷")
            if self.transportation == "无":
                messages.append("你失去了500金币")
            else:
                messages.append("幸运的是，骑在马上的你没有成为小偷的目标")

        elif land.incident is Incidents.involvedMurder:
            if self.status == "正常" or self.status == "监禁":
                messages.append("事件: 你被卷入一场谋杀案，暂时无法脱身")
                messages.append("你本回合无法移动，不掷骰子")
            elif self.status == "保释":
                messages.append("事件: 你已被保释，下一回合将正常移动")
            elif self.status == "感冒":
                messages.append("事件: 你因生病在医院修养，渡过了平静的一天")
                messages.append("你幸运地避开了谋杀案的牵连")

        elif land.incident is Incidents.changeMoney:
            messages.append("事件: 你碰巧获得了一个与他人互换财富的机会")
            messages.append("按B键与敌人互换资金")

        elif land.incident is Incidents.explosive:
            messages.append("事件: 你在路边捡到了炼金术士丢弃的炸药")
            messages.append("在敌人的城堡中按B键使用炸药，仅限一次")

        elif land.incident is Incidents.reachGoldMine:
            messages.append("事件: 你在山间偶然发现了一座金矿")
            messages.append("你得到了1000金币")

        elif land.incident is Incidents.haveACold:
            messages.append("事件: 你发现自己得了感冒，还好病得不算严重")
            messages.append("你在三回合内的移动速度减半")

        elif land.incident is Incidents.strongWind:
            messages.append("事件:你被一阵狂风卷起，身不由己地飞了起来")
            messages.append("你下次移动后将在随机位置出现，不掷骰子")

        elif land.incident is Incidents.friendshipWithLord:
            messages.append("事件:你与本地领主建立友谊，得到了他的承诺")
            messages.append("你下次修建或升级城堡完全免费")

        # 千里马移动不能触发事件，不需展示事件提示
        if self.engine != 0 and land.owner == "事件" and land.incident is not Incidents.start:
            messages = list()
            messages.append("事件：千里马的额外移动不能激活事件")

        # 地块被买满的奖励提示
        if Ls.PCAwardMessage == 1 and Ls.PCAward is True:
            messages.append("<地块被买满，奖励将在本回合或下一回合到账>")

        return messages

    def buy(self, land):
        self.__buy_land(land)
        self.__buy_horse() if land.incident is Incidents.horseField else False

    def __buy_land(self, land):
        price = land.price(self.name)
        if price != 0:
            self.money -= price if self.free is False else 0
            self.free = not self.free if self.free is True else self.free
            land.change_property(self.name)
            self.houseCounter[land.level - 1] += 1

    def __buy_horse(self):
        if self.money > 1000 and self.transportation == "无":
            self.money -= 1000
            self.transportation = "战马"
        elif self.money > 2000 and self.transportation == "战马":
            self.money -= 2000
            self.transportation = "千里马"

class NPC:
    def __init__(self, name):
        self.name = name
        self.position = 0               # 初始位置
        self.money = 1000               # 初始资金
        self.houseCounter = [0, 0, 0, 0, 0]
        self.transportation = "无"      # 装备
        self.status = "正常"            # 状态
        self.engine = 0                 # 每回合额外移动一格，需激活
        self.chance = False             # 互换资金的机会，需激活
        self.item = "无"                # 持有道具
        self.ill = 0                    # 生病冷却，需激活
        self.wind = False               # 传送冷却，需激活
        self.free = False               # 免费冷却，需激活

    def move(self):
        self.engine = 0                                     # 千里马引擎归零

        wind_or_in_jail = False
        point1 = randint(1, 6)
        point2 = 0
        if self.transportation != "无":
            point2 = randint(1, 6)

        if self.status == "监禁":
            self.status = "保释"
            point1, point2, wind_or_in_jail = 0, 0, True
        elif self.status == "保释":
            self.status = "正常"

        roll = point1 + point2

        if self.ill > 0:
            roll = roll // 2                                # 感冒移动速度减半
            roll = 1 if roll == 0 else roll
            self.ill -= 1
            self.status = "正常" if self.ill == 0 else self.status

        if self.wind is True:
            wind_or_in_jail = self.wind
            roll = randint(1, 50)                           # 遭遇大风，随机落地
            self.wind = not self.wind

        # 坐标变化
        self.position += roll
        self.money += 0 if self.position < 50 else 500      # 绕地图一圈奖励
        self.position -= 0 if self.position < 50 else 50    # 坐标限位

        return point1, point2, wind_or_in_jail

    def swift_horse_move(self, lands, land_is_full):
        if self.money > 900:
            forward = self.position + 1 if self.position < 49 else 0
            backward = self.position - 1 if self.position > 0 else 49
            for i in range(5):
                self.__buy_land(lands[forward], land_is_full)
            for i in range(5):
                self.__buy_land(lands[backward], land_is_full)

    def incidents(self, Ls):
        land = Ls.lands[self.position]
        # 地块买满的奖励
        if Ls.is_full(self.name) is True:
            self.money += self.houseCounter[0] * 100
            Ls.NPCAwardMessage = 2
        # 1.路过敌人房子
        if land.owner != self.name and land.owner != "事件" and land.owner != "系统":
            self.money -= land.level * 100
            return land.level * 100
        # 特殊事件房间
        elif land.owner == "事件" and self.engine == 0:
            if land.incident is Incidents.encounterThief:
                self.money -= 500 if self.transportation == "无" else 0
            elif land.incident is Incidents.involvedMurder:
                self.status = "监禁" if (self.status != "保释" and self.status != "感冒") else self.status
            elif land.incident is Incidents.changeMoney:
                self.chance = True
            elif land.incident is Incidents.explosive:
                self.item = "炸药"
            elif land.incident is Incidents.reachGoldMine:
                self.money += 1000
            elif land.incident is Incidents.haveACold:
                self.status = "感冒"
                self.ill = 3
            elif land.incident is Incidents.strongWind:
                self.wind = True
            elif land.incident == Incidents.friendshipWithLord:
                self.free = True
        return 0

    def messages(self, Ls):
        base_messages = self.__base_messages()
        incidents_messages = self.__incidents_messages(Ls)
        return base_messages, incidents_messages

    def __base_messages(self):
        messages = list()
        for i in range(3):
            messages.append(list())
        messages[0].append("昵称: %s" % self.name)
        messages[0].append("坐标: %d" % self.position)
        messages[1].append("状态: %s" % self.status)
        messages[1].append("装备: %s" % self.transportation)
        messages[2].append("物品: %s" % self.item)
        messages[2].append("资金: %d金币" % self.money)

        return messages

    def __incidents_messages(self, Ls):
        land = Ls.lands[self.position]
        messages = list()

        # 购买或升级地块及炸药使用提示
        if land.owner != "事件":
            if land.owner == "系统":
                messages.append("这里是一片无主的荒地")
                if self.free is True:
                    messages.append("你可以按B键免费建立城堡（仅限一次）")
                    messages.append("省去%d金币" % ((land.level + 1) * 100))
                else:
                    messages.append("按B键花费%d金币建立城堡" % ((land.level + 1) * 100))
            elif land.owner == self.name:
                messages.append("城墙上的卫兵向你举旗致敬")
                if land.level < 5:
                    if self.free is True:
                        messages.append("你可以按B键免费升级城堡（仅限一次）")
                        messages.append("省去%d金币" % ((land.level + 1) * 100))
                    else:
                        messages.append("按B键花费%d金币升级城堡" % ((land.level + 1) * 100))
                else:
                    messages.append("城堡已经很豪华了！")
            else:
                messages.append("高耸的城堡阴沉地矗立于前方")
                if self.engine == 0:
                    messages.append("你到了别人的地盘，不得不支付%d金币过路费" % (land.level * 100))
                if self.item == "炸药":
                    messages.append("使用炸药炸毁城堡")

        elif land.incident is Incidents.start:
            messages.append("事件：你到达了起点")

        elif land.incident is Incidents.horseField:
            messages.append("事件：你来到了马场")
            if self.transportation == "无":
                messages.append("花费1000金币购买一匹战马")
                messages.append("你将以双倍速度进行移动！")
            elif self.transportation == "战马":
                messages.append("花费2000金币将战马升级为千里马")
                messages.append("骑上千里马的你将可以进行额外行动！")
            elif self.transportation == "千里马":
                messages.append("这里已经没有值得购买的好马了")
                messages.append("你失望地离开了马场")

        elif land.incident is Incidents.encounterThief:
            messages.append("事件：走在大街上的你遇到了小偷")
            if self.transportation == "无":
                messages.append("你失去了500金币")
            else:
                messages.append("幸运的是，骑在马上的你没有成为小偷的目标")

        elif land.incident is Incidents.involvedMurder:
            if self.status == "正常" or self.status == "监禁":
                messages.append("事件: 你被卷入一场谋杀案，暂时无法脱身")
                messages.append("你本回合无法移动，不掷骰子")
            elif self.status == "保释":
                messages.append("事件: 你已被保释，下一回合将正常移动")
            elif self.status == "感冒":
                messages.append("事件: 你因生病在医院修养，渡过了平静的一天")
                messages.append("你幸运地避开了谋杀案的牵连")

        elif land.incident is Incidents.changeMoney:
            messages.append("事件: 你碰巧获得了一个与他人互换财富的机会")

        elif land.incident is Incidents.explosive:
            messages.append("事件: 你在路边捡到了炼金术士丢弃的炸药")
            messages.append("在敌人的城堡中使用炸药，仅限一次")

        elif land.incident is Incidents.reachGoldMine:
            messages.append("事件: 你在山间偶然发现了一座金矿")
            messages.append("你得到了1000金币")

        elif land.incident is Incidents.haveACold:
            messages.append("事件: 你发现自己得了感冒，还好病得不算严重")
            messages.append("你在三回合内的移动速度减半")

        elif land.incident is Incidents.strongWind:
            messages.append("事件:你被一阵狂风卷起，身不由己地飞了起来")
            messages.append("你下次移动后将在随机位置出现，不掷骰子")

        elif land.incident is Incidents.friendshipWithLord:
            messages.append("事件:你与本地领主建立友谊，得到了他的承诺")
            messages.append("你下次修建或升级城堡完全免费")

        # 千里马移动不能触发事件，不需展示事件提示
        if self.engine != 0 and land.owner == "事件" and land.incident is not Incidents.start:
            messages = list()
            messages.append("事件：千里马的额外移动不能激活事件")

        # 地块被买满的奖励提示
        if Ls.NPCAwardMessage == 1 and Ls.NPCAward is True:
            messages.append("<地块被买满，奖励将在本回合或下一回合到账>")

        return messages

    def buy(self, land, land_is_full):
        price = land.price(self.name)
        if (self.money - price) >= self.__money_left_line() or self.free is True:
            self.__buy_land(land, land_is_full)
            self.__buy_horse() if land.incident is Incidents.horseField else False

    def __buy_land(self, land, land_is_full):
        price = land.price(self.name)
        if price != 0:
            level = land.level
            if level == 0 or self.free or (level == 1 and self.houseCounter[0] > 15) or \
               (level == 2 and self.houseCounter[1] > 10) or (level == 3 and self.houseCounter[2] > 7) \
               or level >= 4 or land_is_full is True or self.money > 2500:
                self.money -= price if self.free is False else 0
                self.free = not self.free if self.free is True else self.free
                land.change_property(self.name)
                self.houseCounter[land.level - 1] += 1

    def __buy_horse(self):
        if self.money > 1600 and self.transportation == "无":
            self.money -= 1000
            self.transportation = "战马"
        elif self.money > 2600 and self.transportation == "战马":
            self.money -= 2000
            self.transportation = "千里马"

    def __money_left_line(self):
        extra_money_for_thief = 0
        if self.transportation == "无" and (self.position + 1 < 10 and self.position + 6 >= 10):
            extra_money_for_thief = 500
        if self.houseCounter[0] <= 15:
            return 500 + extra_money_for_thief
        if self.houseCounter[1] <= 10:
            return 700 + extra_money_for_thief
        if self.houseCounter[2] <= 7:
            return 800 + extra_money_for_thief
        return 900 + extra_money_for_thief

class OneLand:
    def __init__(self, position, owner="系统", incident=Incidents.houseFiled):
        self.owner = owner
        self.position = position
        self.level = 0
        self.incident = incident

    def price(self, who):
        if (who == self.owner and self.level < 5) or self.owner == "系统":
            return (self.level + 1) * 100
        return 0

    def change_property(self, who):
        self.owner = who
        self.level += 1
        self.incident = Incidents.house

    def bang(self):
        self.owner = "系统"
        self.level = 0
        self.incident = Incidents.houseFiled

class Landmasses:
    def __init__(self, PCName, NPCName):
        self.lands = list()
        self.PCName = PCName
        self.NPCName = NPCName
        self.PCAward = False
        self.NPCAward = False
        self.PCAwardMessage = 0
        self.NPCAwardMessage = 0

        for i in range(50):
            if (i + 1) % 5 == 1:
                self.lands.append(OneLand(i, owner="事件", incident=Incidents(i // 5)))
            else:
                self.lands.append(OneLand(i))

    def is_full(self, name):
        if name == self.PCName and self.PCAward is True:
            return False
        if name == self.NPCName and self.NPCAward is True:
            return False
        counter = 0
        for one_land in self.lands:
            if one_land.level != 0:
                counter += 1
        if counter == 40:
            if name == self.PCName:
                self.PCAward = True
            else:
                self.NPCAward = True
            return True
        return False

class ShootDice:
    def __init__(self):
        self.randomSeries = list()
        self.finalPoints = list()
        self.finalPoints.append(0)

    def __set_final_points(self, points):
        self.finalPoints = []
        self.finalPoints.append(points[0])
        if points[1] != 0:
            self.finalPoints.append(points[1])

    def __get_random_series(self):
        self.randomSeries = []
        for i in range(200):
            self.randomSeries.append(randint(0, 5))

    def set_dice(self, points):
        if points[2] is False:
            self.__set_final_points(points)
            self.__get_random_series()

class MusicPlay:
    def __init__(self):
        self.music = pygame.mixer.music.load("./source/BackgroundMusic.mp3")
        self.isPlaying = True
        pygame.mixer.music.set_volume(0.618)
        pygame.mixer.music.play(-1)

    def pause(self, pos):
        if pos[0] > (41 * 25 + 8) and pos[0] < (41 * 25 + 94) and pos[1] > (27 * 25 + 4) and pos[1] < (27 * 25 + 68):
            pygame.mixer.music.pause() if self.isPlaying is True else pygame.mixer.music.unpause()
            self.isPlaying = not self.isPlaying
            return True
        return False

class GameManager:
    def __init__(self):
        pygame.init()                                                        # pygame初始化
        self.clock = pygame.time.Clock()                                     # 帧率控制
        self.font = pygame.font.Font("./source/simhei.ttf", 20)              # 游戏字体
        self.screen = pygame.display.set_mode((1200, 825))                   # 窗口初始化
        pygame.display.set_icon(pygame.image.load("./source/Dog.ico").convert_alpha())
        pygame.display.set_caption("大富翁")
        self.backgroundMusic = MusicPlay()                                   # 背景音乐播放

        self.playAgain = False                                               # 多次进行游戏
        self.initialToPlaying = False                                        # 最初进入游戏的标志变量
        self.gameTurn = GameTurn.start                                       # 游戏状态
        self.playerTurn = PlayerTurn.start                                   # 玩家行动回合
        self.PCActKey = [False, False, False]                                # 存储PCAct按键，依次是K_b, K_a, K_d
        self.cheat = [0, 0, 0]                                               # 开发者模式标记
        self.spaceKeyDown = pygame.event                                     # 用于存储空格被按下的事件
        self.winner = ""                                                     # 胜利者

        self.start = pygame.image.load("./source/Start.png").convert_alpha()
        self.gameFail = pygame.image.load("./source/GameFail.png").convert_alpha()
        self.gameWin = pygame.image.load("./source/GameWin.png").convert_alpha()
        self.gameMap = pygame.image.load("./source/Map.png").convert_alpha()
        self.tips = pygame.image.load("./source/Tips.png").convert_alpha()

        self.musicOn = pygame.image.load("./source/MusicOn.png").convert_alpha()
        self.musicOff = pygame.image.load("./source/MusicOff.png").convert_alpha()
        self.musicImage = self.musicOn
        self.musicBarrier = pygame.image.load("./source/MusicBarrier.png").convert_alpha()
        self.musicButtonLocation = (41 * 25, 27 * 25)
        self.musicButtonRect = pygame.Rect(41 * 25, 27 * 25, 100, 75)

        self.activeOn = pygame.image.load("./source/ActiveOn.png").convert_alpha()
        self.activeOff = pygame.image.load("./source/ActiveOff.png").convert_alpha()

        self.PCName = ""
        self.PCImage = pygame.image.load("./source/PC.png").convert_alpha()
        self.PCFixImage = pygame.image.load("./source/PCFix.png").convert_alpha()
        self.PCBoard = [(5 * 25, 4 * 25 + 12), (5 * 25, 8 * 25)]

        self.NPCName = ""
        self.NPCImage = pygame.image.load("./source/NPC.png").convert_alpha()
        self.NPCFixImage = pygame.image.load("./source/NPCFix.png").convert_alpha()
        self.NPCBoard = [(27 * 25, 4 * 25 + 12), (27 * 25, 8 * 25)]

        self.diceImages = list()
        for i in range(6):
            self.diceImages.append(pygame.image.load("./source/Dice" + str(i + 1) + ".png").convert_alpha())
        self.diceBarrier = pygame.image.load("./source/DiceBarrier.png").convert_alpha()
        self.diceBoard = [(22 * 25, 18 * 25 + 5), (19 * 25 + 12, 18 * 25 + 5), (24 * 25 + 13, 18 * 25 + 5)]
        self.diceLocation = list()
        self.diceLocation.append(self.diceBoard[0])
        self.diceSteps = (0, 0, True)

        self.cattleOfPC = list()
        self.wasteland = pygame.image.load("./source/Wasteland.png").convert_alpha()
        self.cattleOfPC.append(self.wasteland)
        for i in range(5):
            self.cattleOfPC.append(pygame.image.load("./source/HouseA" + str(i + 1) + ".png").convert_alpha())

        self.cattleOfNPC = list()
        self.cattleOfNPC.append(self.wasteland)
        for i in range(5):
            self.cattleOfNPC.append(pygame.image.load("./source/HouseB" + str(i + 1) + ".png").convert_alpha())

    def event_deal(self):
        for event in pygame.event.get():
            # 退出游戏
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_e):
                self.__quit()

            # 键盘事件
            if event.type == pygame.KEYDOWN:
                # 重玩游戏
                if event.key == pygame.K_r:
                    self.playAgain = True

                # 进入游戏Play界面
                elif event.key == pygame.K_SPACE and self.gameTurn is GameTurn.waitIn:
                    self.gameTurn = GameTurn.initial
                    self.spaceKeyDown = event

                # 玩家回合切换
                elif event.key == pygame.K_SPACE and self.gameTurn is GameTurn.playing:
                    if self.playerTurn is PlayerTurn.start:
                        self.playerTurn = PlayerTurn.PCMove

                # 开发者模式
                elif self.gameTurn is GameTurn.playing and self.__developer_pattern_check() is False:
                    self.__set_developer_pattern(event.key)

                # PCAct按键检测
                self.__set_PC_act_key(event.key)

            # 音乐播放控制的鼠标事件
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == pygame.BUTTON_LEFT:
                self.__music_pause(event.pos)

    def get_character_name(self, PC, NPC):
        self.PCName = PC
        self.NPCName = NPC

    @staticmethod
    def update():
        pygame.display.update()

    def draw_beginning(self):
        for i in range(150):
            self.clock.tick(300)
            self.screen.blit(self.gameMap, (0, 0))
            self.screen.blit(self.PCFixImage, (6 * 25 + 13 + i * 1 - 10, 6 * 25 + 13 - 10))
            self.screen.blit(self.NPCFixImage, (38 * 25 + 13 - i * 1 - 10, 6 * 25 + 13 - 10))
            self.screen.blit(self.start, (175, 325))
            self.screen.blit(self.musicImage, (41 * 25, 27 * 25))
            pygame.display.update()

    def draw_map(self):
        self.screen.blit(self.gameMap, (0, 0))

    def draw_character(self, PC_pos, NPC_pos):
        # 动态位置绘制
        if self.playerTurn is PlayerTurn.PCAct or self.playerTurn is PlayerTurn.NPCMove or \
           self.playerTurn is PlayerTurn.start or self.initialToPlaying is True:
            self.screen.blit(self.NPCImage, self.__location_convert(NPC_pos))
            self.screen.blit(self.PCImage, self.__location_convert(PC_pos))
        else:
            self.screen.blit(self.PCImage, self.__location_convert(PC_pos))
            self.screen.blit(self.NPCImage, self.__location_convert(NPC_pos))
        # 固定位置绘制
        self.screen.blit(self.PCFixImage, (19 * 25 - 21, 4 * 25))
        self.screen.blit(self.NPCFixImage, (41 * 25 - 21, 4 * 25))

    def draw_active(self):
        if self.playerTurn is PlayerTurn.PCMove or self.playerTurn is PlayerTurn.PCAct:
            self.screen.blit(self.activeOn, (4 * 25, 4 * 25))
            self.screen.blit(self.activeOn, (4 * 25, 8 * 25))
            self.screen.blit(self.activeOff, (26 * 25, 4 * 25))
            self.screen.blit(self.activeOff, (26 * 25, 8 * 25))
        elif self.playerTurn is PlayerTurn.NPCMove or self.playerTurn is PlayerTurn.NPCAct:
            self.screen.blit(self.activeOff, (4 * 25, 4 * 25))
            self.screen.blit(self.activeOff, (4 * 25, 8 * 25))
            self.screen.blit(self.activeOn, (26 * 25, 4 * 25))
            self.screen.blit(self.activeOn, (26 * 25, 8 * 25))
        else:
            self.screen.blit(self.activeOff, (4 * 25, 4 * 25))
            self.screen.blit(self.activeOff, (4 * 25, 8 * 25))
            self.screen.blit(self.activeOff, (26 * 25, 4 * 25))
            self.screen.blit(self.activeOff, (26 * 25, 8 * 25))

    def draw_land(self, all_lands):
        for land in all_lands:
            if land.owner == self.PCName:
                self.screen.blit(self.cattleOfPC[land.level], self.__location_convert(land.position))
            elif land.owner == self.NPCName:
                self.screen.blit(self.cattleOfNPC[land.level], self.__location_convert(land.position))
            else:
                self.screen.blit(self.wasteland, self.__location_convert(land.position))

    def draw_tips(self):
        if self.gameTurn is not GameTurn.over:
            self.screen.blit(self.tips, (3 * 25, 27 * 25))

    def __developer_pattern_check(self):
        if self.cheat[0] * self.cheat[1] * self.cheat[2] == 1:
            return True
        return False

    def __set_developer_pattern(self, event_key):
        if event_key == pygame.K_d:
            self.cheat[0] = 1
        if self.cheat[0] == 1 and event_key == pygame.K_w:
            self.cheat[1] = 1
        if self.cheat[1] == 1 and event_key == pygame.K_q:
            self.cheat[2] = 1

    def __set_PC_act_key(self, event_key):
        if event_key == pygame.K_b:
            self.PCActKey[0] = True
        if event_key == pygame.K_a:
            self.PCActKey[1] = True
        if event_key == pygame.K_d:
            self.PCActKey[2] = True

    def draw_messages(self, messages):
        PC_messages = messages[0]
        for i in range(len(PC_messages[0])):
            for j in range(len(PC_messages[0][i])):
                self.screen.blit(self.font.render(PC_messages[0][i][j], True, [0, 0, 0]),
                                 (self.PCBoard[0][0] + j * 25 * 6, self.PCBoard[0][1] + i * 25))
        for i in range(len(PC_messages[1])):
            self.screen.blit(self.font.render(PC_messages[1][i], True, [0, 0, 255]),
                             (self.PCBoard[1][0], self.PCBoard[1][1] + i * 25))

        NPC_messages = messages[1]
        if self.__developer_pattern_check() is True:
            for i in range(len(NPC_messages[0])):
                for j in range(len(NPC_messages[0][i])):
                    self.screen.blit(self.font.render(NPC_messages[0][i][j], True, [0, 0, 0]),
                                     (self.NPCBoard[0][0] + j * 25 * 6, self.NPCBoard[0][1] + i * 25))
            for i in range(len(NPC_messages[1])):
                self.screen.blit(self.font.render(NPC_messages[1][i], True, [0, 0, 255]),
                                 (self.NPCBoard[1][0], self.NPCBoard[1][1] + i * 25))
        else:
            self.screen.blit(self.font.render("依次按下DWQ进入开发者模式", True, [0, 0, 255]), (27 * 25, 7 * 25))
            self.screen.blit(self.font.render("查看NPC的状态", True, [0, 0, 255]), (27 * 25, 8 * 25))

    def __music_pause(self, mouse_pos):
        if self.backgroundMusic.pause(mouse_pos) is True:
            self.__draw_music_button_change(self.backgroundMusic.isPlaying)

    def draw_music_button(self):
        self.screen.blit(self.musicImage, self.musicButtonLocation)

    def __draw_music_button_change(self, is_playing):
        self.musicImage = self.musicOn if is_playing is True else self.musicOff
        self.screen.blit(self.musicImage, self.musicButtonLocation)     # Button Down
        pygame.display.update(self.musicButtonRect)
        pygame.time.delay(100)
        self.screen.blit(self.musicBarrier, self.musicButtonLocation)
        self.screen.blit(self.musicImage, self.musicButtonLocation)     # Button Up
        pygame.display.update(self.musicButtonRect)

    def __set_dice_location(self):
        self.diceLocation = []
        if self.diceSteps[1] == 0:
            self.diceLocation.append(self.diceBoard[0])
        else:
            self.diceLocation.append(self.diceBoard[1])
            self.diceLocation.append(self.diceBoard[2])

    def draw_dice(self, final_points, random_series):
        if self.diceSteps[2] is False and \
           (self.playerTurn is PlayerTurn.PCMove or self.playerTurn is PlayerTurn.NPCMove):
            self.__set_dice_location()
            len_of_dice_location = len(self.diceLocation)
            self.clock.tick(5 * len_of_dice_location)
            for rand in random_series:
                self.screen.blit(self.diceBarrier, (18 * 25, 17 * 25))
                for i in range(len_of_dice_location):
                    self.screen.blit(self.diceImages[rand], self.diceLocation[i])
                pygame.display.update()
            self.screen.blit(self.diceBarrier, (18 * 25, 17 * 25))
            for i in range(len_of_dice_location):
                self.screen.blit(self.diceImages[final_points[i] - 1], self.diceLocation[i])
            pygame.display.update()
            pygame.time.delay(700)

    def draw_fix_dice(self, final_points):
        for i in range(len(self.diceLocation)):
            self.screen.blit(self.diceImages[final_points[i] - 1], self.diceLocation[i])

    def turn_change(self):
        if self.playerTurn is PlayerTurn.PCMove:
            self.playerTurn = PlayerTurn.NPCMove
        elif self.playerTurn is PlayerTurn.NPCMove:
            self.playerTurn = PlayerTurn.PCAct
        elif self.playerTurn is PlayerTurn.PCAct:
            self.playerTurn = PlayerTurn.NPCAct
        elif self.playerTurn is PlayerTurn.NPCAct:
            self.playerTurn = PlayerTurn.start
            self.initialToPlaying = False
            pygame.event.post(self.spaceKeyDown)  # 抛出一个空格被按下的事件，提高游戏的操作简便性

    def game_end_check(self, PC_money, NPC_money):
        if (PC_money <= 0 or NPC_money <= 0) and self.gameTurn is not GameTurn.end:
            self.winner = self.NPCName if PC_money < NPC_money else self.PCName
            self.gameTurn = GameTurn.over

    def draw_game_end(self):
        if self.gameTurn is GameTurn.over:
            self.gameTurn = GameTurn.end
            self.screen.blit(self.diceBarrier, (18 * 25, 17 * 25))
            if self.winner == self.PCName:
                self.screen.blit(self.gameWin, (175, 325))
            else:
                self.screen.blit(self.gameFail, (175, 325))

    def play_again_check(self):
        if self.playAgain is True:
            self.playAgain = not self.playAgain
            self.gameTurn = GameTurn.start
            self.playerTurn = PlayerTurn.start
            self.PCActKey = [False, False, False]
            self.cheat = [0, 0, 0]
            self.diceLocation = list()
            self.diceLocation.append(self.diceBoard[0])
            self.diceSteps = (0, 0, True)

    @staticmethod
    def __location_convert(position):
        if position <= 15:
            return position * 75, 0
        if position <= 25:
            return 15 * 75, (position - 15) * 75
        if position <= 40:
            return (15 - (position - 25)) * 75, 10 * 75
        if position <= 49:
            return 0, (9 - (position - 41)) * 75

    def __quit(self):
        if self.backgroundMusic.isPlaying is True:
            pygame.mixer.music.fadeout(1500)
            pygame.time.delay(1500)
        pygame.quit()
        sys.exit(0)

gameManager = GameManager()                                                               # 游戏各项初始化，素材载入
while True:
    gameManager.event_deal()                                                              # 事件处理

    if gameManager.gameTurn is GameTurn.start:
        gameManager.draw_beginning()                                                      # 开始界面动画绘制
        gameManager.gameTurn = GameTurn.waitIn                                            # 游戏状态切换

    if gameManager.gameTurn is GameTurn.initial:
        hero = NPC("Naruto")                                                               # PC
        enemy = NPC("Sasuke")                                                             # NPC
        lands = Landmasses(hero.name, enemy.name)                                         # 地块初始化
        shootDice = ShootDice()                                                           # 骰子管理类
        gameManager.get_character_name(hero.name, enemy.name)                             # 获取玩家昵称
        gameManager.gameTurn = GameTurn.playing                                           # 游戏状态切换
        gameManager.initialToPlaying = True

        # 测试代码
        hero.money = 10000
        enemy.money = 10000

    if gameManager.gameTurn is GameTurn.playing:
        gameManager.clock.tick(10)                                                        # 帧数
        gameManager.draw_map()                                                            # 地图绘制
        gameManager.draw_land(lands.lands)                                                # 地块绘制
        gameManager.draw_character(hero.position, enemy.position)                         # 人物绘制
        gameManager.draw_active()                                                         # 活跃状态绘制
        gameManager.draw_messages((hero.messages(lands), enemy.messages(lands)))          # 信息提示绘制
        gameManager.draw_fix_dice(shootDice.finalPoints)                                  # 固定骰子在屏幕上
        gameManager.draw_music_button()                                                   # 音乐播放状态图片绘制
        gameManager.game_end_check(hero.money, enemy.money)                               # 游戏自然结束判定
        gameManager.draw_tips()                                                           # 常态操作提示绘制

        if gameManager.playerTurn is PlayerTurn.PCMove:
            gameManager.diceSteps = hero.move()
            enemy.money += hero.incidents(lands)
            shootDice.set_dice(gameManager.diceSteps)

        elif gameManager.playerTurn is PlayerTurn.PCAct:
            if lands.lands[hero.position].incident is Incidents.changeMoney and enemy.money > hero.money:
                temp = enemy.money
                enemy.money = hero.money
                hero.money = temp
                hero.chance = not enemy.chance
            elif hero.item == "炸药":
                now = hero.position
                if lands.lands[now].owner == enemy.name:
                    hero.item = "无"
                    for i in range(lands.lands[now].level):
                        hero.houseCounter[i] -= 1
                    lands.lands[now].bang()
                    for i in range(5):
                        hero.buy(lands.lands[now], lands.is_full(hero.name))
                elif hero.transportation == "千里马":
                    forward = now + 1 if now < 49 else 0
                    backward = now - 1 if now > 0 else 49
                    if lands.lands[forward].owner == enemy.name:
                        hero.item = "无"
                        for i in range(lands.lands[forward].level):
                            enemy.houseCounter[i] -= 1
                        lands.lands[forward].bang()
                        for i in range(5):
                            hero.buy(lands.lands[forward], lands.is_full(hero.name))
                    elif lands.lands[backward].owner == enemy.name:
                        hero.item = "无"
                        for i in range(lands.lands[backward].level):
                            enemy.houseCounter[i] -= 1
                        lands.lands[backward].bang()
                        for i in range(5):
                            hero.buy(lands.lands[backward], lands.is_full(hero.name))
            for i in range(5):
                hero.buy(lands.lands[hero.position], lands.is_full(hero.name))
            if hero.transportation == "千里马":
                hero.swift_horse_move(lands.lands, lands.is_full(hero.name))

        elif gameManager.playerTurn is PlayerTurn.NPCMove:
            gameManager.diceSteps = enemy.move()
            hero.money += enemy.incidents(lands)
            shootDice.set_dice(gameManager.diceSteps)

        elif gameManager.playerTurn is PlayerTurn.NPCAct:
            if lands.lands[enemy.position].incident is Incidents.changeMoney and hero.money > enemy.money:
                temp = hero.money
                hero.money = enemy.money
                enemy.money = temp
                enemy.chance = not enemy.chance
            elif enemy.item == "炸药":
                now = enemy.position
                if lands.lands[now].owner == hero.name:
                    enemy.item = "无"
                    for i in range(lands.lands[now].level):
                        hero.houseCounter[i] -= 1
                    lands.lands[now].bang()
                    for i in range(5):
                        enemy.buy(lands.lands[now], lands.is_full(enemy.name))
                elif enemy.transportation == "千里马":
                    forward = now + 1 if now < 49 else 0
                    backward = now - 1 if now > 0 else 49
                    if lands.lands[forward].owner == hero.name:
                        enemy.item = "无"
                        for i in range(lands.lands[forward].level):
                            hero.houseCounter[i] -= 1
                        lands.lands[forward].bang()
                        for i in range(5):
                            enemy.buy(lands.lands[forward], lands.is_full(enemy.name))
                    elif lands.lands[backward].owner == hero.name:
                        enemy.item = "无"
                        for i in range(lands.lands[backward].level):
                            hero.houseCounter[i] -= 1
                        lands.lands[backward].bang()
                        for i in range(5):
                            enemy.buy(lands.lands[backward], lands.is_full(enemy.name))
            for i in range(5):
                enemy.buy(lands.lands[enemy.position], lands.is_full(enemy.name))
            if enemy.transportation == "千里马":
                enemy.swift_horse_move(lands.lands, lands.is_full(enemy.name))

        gameManager.draw_dice(shootDice.finalPoints, shootDice.randomSeries)              # 掷骰子动画
        gameManager.turn_change()                                                         # 玩家回合切换
        gameManager.draw_game_end()                                                       # 游戏结束时绘制游戏结束图片
        gameManager.update()                                                              # 画面绘制刷新

    gameManager.play_again_check()                                                        # 重玩游戏检查

OldProject/AlphaVersion/new - Alpha1 - Beta11.py


from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Transaction
from .jobs.sanctionjob import SanctionJob
from .jobs.pepjob import PEPJob
from .jobs.assessmentjob import AssessmentJob

"""
Signals gets triggered when there are
any saves to the database.
"""

@receiver(post_save, sender=Transaction)
def process_transaction(sender, instance, created, **kwarks):
    if created:
        # Lets kick off the first process
        print("POST SAVE CREATED")
        sanctionJob = SanctionJob(transaction=instance)
        sanctionJob.run()
    else:
        # Check where we are in the process
        print ("POST SAVE UPDATED {} {}".format(instance.id, instance.status))
        if instance.status == Transaction.Status.PEPCHECK:
            print('Starting PEP job')
            pepjob = PEPJob(transaction=instance)
            pepjob.run()
        elif instance.status == Transaction.Status.ASSESSMENT:
            print('Starting Assessment job')
            assessmentjob = AssessmentJob(transaction=instance)
            assessmentjob.run()


"""
This file is needed only for future reference to
load data from wiki data.
DOwnload link : http://people.apache.org/~mikemccand/enwiki-20120502-lines-1k.txt.lzma
"""
import glob
import itertools
import os
import random

from couchbase.bucket import Bucket

class Docgen(object):
    def __init__(self, location, cb_url, database, chunk_size=1024):
        self.chunk_size = chunk_size
        self.location = location
        self.cb_url = cb_url
        self.database = database
        self.counts = 0
        '''
        The keygen part to create keys to optimize space
        '''
        self.key1 = self.keygen(2)
        self.key2 = self.keygen(4)
        self.key3 = self.keygen(5)

    @staticmethod
    def keygen(self, keynum):
        '''
        the ranges includes all ascii characters from 47 - 123

        '''
        s = list(map(chr, range(47, 123)))
        random.shuffle(s)
        iters = itertools.permutations(s, keynum)
        return iters

    def read_in_chunks(self, file_object):
        """Lazy function (generator) to read a file piece by piece.
        Default chunk size: 1k."""
        while True:
            data = file_object.read(self.chunk_size)
            if not data:
                break
            yield data

    def insert_cb(self, cb, f):
        for piece in self.read_in_chunks(f):
            test = {}
            piece = piece.replace('\n', ' ')
            test['text'] = piece
            key = ""
            if self.counts < 1000:
                key = self.key1.next()
            elif self.counts < 100000:
                key = self.key2.next()
            else:
                key = self.key3.next()
            key = ''.join(key)
            cb.upsert(key, test)

            if self.counts == 1000000:
                return
            self.counts += 1

    def start_load(self):
        os.chdir(self.location)
        c = Bucket("couchbase://{}/{}?operation_timeout=10".format(self.cb_url, self.database))
        for file in glob.glob("*.txt"):
            try:
                f = open(file)
                self.insert_cb(c, f)
                f.close()
            except Exception as e:
                print (self.counts, file)
                raise e

A = Docgen('/data/wikidata', '172.23.123.38', 'bucket-1')
A.start_load()


# William La Cava
# mock experiment for comparing recommenders.
import pdb
import os
import pandas as pd
import numpy as np
import argparse
from ai.recommender.average_recommender import AverageRecommender
from ai.recommender.random_recommender import RandomRecommender
# from ai.recommender.meta_recommender import MetaRecommender
from ai.recommender.knn_meta_recommender import KNNMetaRecommender
# from ai.recommender.mlp_meta_recommender import MLPMetaRecommender
from ai.recommender.svd_recommender import SVDRecommender
from ai.recommender.surprise_recommenders import *

from joblib import Parallel, delayed
from collections import OrderedDict
from mock_experiment.mf_utils import local_get_metafeatures, update_dataset_mf
import warnings
warnings.simplefilter("ignore")
# define a comparison function that tests a recommender on the datasets,
#using an intial knowledge base.
def run_experiment(rec,data_idx,n_recs,trial,knowledge_base,ml_p,n_init, iters):
    """generates recommendations for datasets, using the first n_init as knowledge base."""
    # set seed
    np.random.seed(trial)
    results = []
    kwargs = {'metric':'bal_accuracy','ml_p':ml_p}
    # if rec == 'svd':
    #     kwargs.update({'datasets':knowledge_base.dataset.unique()})
    rec_choice = {'random': RandomRecommender,
            'average': AverageRecommender,
            'knnmeta': KNNMetaRecommender,
            'svd': SVDRecommender,
            'cocluster': CoClusteringRecommender,
            'knnmeans': KNNWithMeansRecommender,
            'knnml': KNNMLRecommender,
            'knndataset': KNNDatasetRecommender,
            'slopeone': SlopeOneRecommender
            }
    # rec_choice = {'random': RandomRecommender,
    #         'average': AverageRecommender,
    #         # 'meta': MetaRecommender,
    #         # 'mlp': MLPMetaRecommender,
    #         'knn': KNNMetaRecommender,
    #         'svd': SVDRecommender
    #         }

    recommender = rec_choice[rec](**kwargs)
    #pdb.set_trace()
    #################################################### load first n_init results into recommender
    subset_ml = np.random.choice(ml_p['algorithm'].unique(), size= n_init)
    train_subset = []
    for s in subset_ml:
        train_subset.append(np.random.choice(
                knowledge_base.loc[knowledge_base.algorithm==s].index))
    print('setting training data for recommender:')
    tmp = knowledge_base.iloc[train_subset]
    for _,row in tmp.iterrows():
        print(row.algorithm,':',row.dataset,':',row.bal_accuracy)

    init_data = []
    init_data_mf = []
    # for i in train_subset:
        # init_data.append(knowledge_base.loc[knowledge_base['dataset']==i])
        # init_df = pd.concat(init_data)
    init_df = knowledge_base.iloc[train_subset]
    # get the metafeatures for the initial datasets
    for i,_ in init_df.groupby('dataset'):
        init_data_mf.append(local_get_metafeatures(i))

    dataset_mf = pd.concat(init_data_mf).set_index('dataset')
    print('initial training on',len(init_df),'results')
    recommender.update(init_df, dataset_mf)
    ####################################################

    ########################################################################## main experiment loop
    datasets = data_idx
    # loop thru rest of datasets
    # for it,dataset in enumerate(rec_subset):
    for it, dataset in data_idx:
        holdout_accuracy_lookup = knowledge_base.loc[
                knowledge_base['dataset'] == dataset].set_index(
            ['algorithm', 'parameter_hash']).loc[:, 'bal_accuracy'].to_dict()
        holdout_rank_lookup = knowledge_base.loc[
                knowledge_base['dataset'] == dataset].set_index(
            ['algorithm', 'parameter_hash']).loc[:, 'ranking'].to_dict()

        print('generating ',n_recs,'recommendations for',dataset)

        # for each dataset, generate a recommendation
        mls, ps, scores = recommender.recommend(dataset_id=dataset,
                                        n_recs=n_recs,
                                        dataset_mf=local_get_metafeatures(dataset)
                                            )
        print('got',len(mls),'recs')
        updates = []
        for i in np.arange(len(mls)):
            ml = mls[i]
            p = ps[i]
            phash = hash(frozenset(p.items()))

            print('recommending',ml,'with',p,'for',dataset)
            if (ml,phash) not in holdout_accuracy_lookup:
                raise ValueError((ml,phash),'not found')

            # n = n+1
            # retreive the performance of the recommended learner
            actual_score = holdout_accuracy_lookup[(ml, phash)]
            actual_ranking = holdout_rank_lookup[(ml,phash)]
            # find all top ranking algorithms
            dataset_results = knowledge_base.loc[knowledge_base['dataset'] == dataset]
            best_score = dataset_results['bal_accuracy'].max()
            best_algs = dataset_results.loc[dataset_results['ranking']==1]['algorithm'].unique()
            best_algorithm = '|'.join(list(best_algs))
            # Update the recommender with the score from its latest guess
            updates.append(pd.DataFrame(data={'dataset': [dataset],
                                               'algorithm': [ml],
                                               'parameters': [p],
                                               'bal_accuracy': [actual_score]})
                          )

            # store the trial, iteration, dataset, recommender, ml rec, param rec,bal_accuracy
            results.append({'trial':trial,
                            'iteration':it,
                            'n_recs':n_recs,
                            'n_init':n_init,
                            'iters':iters,
                            'recommender':rec,
                            'dataset':dataset,
                            'ml-rec':ml,
                            'p-rec':p,
                            'score-rec':scores[0],
                            'bal_accuracy':actual_score,
                            'max_bal_accuracy':best_score,
                            'best_algorithm':best_algorithm,
                            'ranking':actual_ranking,
                            'delta_bal_accuracy':(best_score-actual_score)/best_score})

        print('updating recommender...')
        if len(updates)>0:
            update_record = pd.concat(updates)
            dataset_mf = update_dataset_mf(dataset_mf, update_record)
            recommender.update(update_record,dataset_mf)
        else:
            print('WARNINING: got no updates for',dataset,'. There are ',
                  len([r for r in results if r['dataset'] == dataset]),
                  'results for this dataset already and',len(ml_p),
                  'unique ml+p combos')

    ########################################################################## main experiment loop
    return results

if __name__ == '__main__':
    """run experiment"""

    parser = argparse.ArgumentParser(description='Run a PennAI a recommender experiment.',
                                     add_help=False)
    parser.add_argument('-h','--help',action='help',
                        help="Show this help message and exit.")
    # parser.add_argument('-rec',action='store',dest='rec',default='random',
    #                     help='Recommender to run.')
    parser.add_argument('-rec',action='store',dest='rec',default='random',
            choices = ['random','average','knnmeta','svd','cocluster','knnmeans',
                       'knnml','knndataset','slopeone'],
            help='Recommender algorithm options.')
    parser.add_argument('-n_recs',action='store',dest='n_recs',type=int,default=1,help='Number of '
                        ' recommendations to make at a time. If zero, will send continous '
                        'recommendations until AI is turned off.')
    parser.add_argument('-v','-verbose',action='store_true',dest='verbose',default=False,
                        help='Print out more messages.')
    parser.add_argument('-n_init',action='store',dest='n_init',type=int,default=10,
                        help='Number of initial datasets to seed knowledge database')
    parser.add_argument('-iters',action='store',dest='iters',type=int,default=100,
                        help='Number of initial datasets to seed knowledge database')
    parser.add_argument('-t',action='store',dest='trial',type=int,default=0,
                        help='Trial number')
    parser.add_argument('-data',action='store',dest='KNOWL',type=str,
                        default='mock_experiment/simulation_experiment.tsv',
                        help='knowledge base')
    parser.add_argument('-resdir',action='store',dest='RESDIR',type=str,
                        default='results',
                        help='results directory')

    args = parser.parse_args()

    # load knowledge base(s)
    if ',' in args.KNOWL:
        data_files = args.KNOWL.split(',')
    else:
        data_files = [args.KNOWL]

    for data_file in data_files:
        print(70*'=','\n','loading',data_file,'\n'+70*'=','\n')
        knowledge_base = pd.read_csv(data_file,
                                compression='gzip', sep='\t').fillna('')#,
        ml_p = knowledge_base.loc[:,['algorithm','parameters']].drop_duplicates()
        ml_p['parameters'] = ml_p['parameters'].apply(
                lambda x: eval(x))
        knowledge_base['parameters'] = knowledge_base['parameters'].apply(
                lambda x: eval(x))
        knowledge_base['parameter_hash'] = knowledge_base['parameters'].apply(
                lambda x: hash(frozenset(x.items())))

        print('len ml_p:',len(ml_p))
        data_idx = np.unique(knowledge_base['dataset'])  # datasets

        # output file
        out_file = ('mock_experiment/' + args.RESDIR + '/experiment_'
                    + data_file.split('/')[-1].split('.')[0]
                    + '_rec-{}'.format(args.rec)
                    + '_ninit-{}'.format(args.n_init)
                    + '_nrecs-{}'.format(args.n_recs)
                    + '_iters-{}'.format(args.iters)
                    + '_trial-{}'.format(args.trial)
                    + '.csv')

        # run experiment
        # np.random.shuffle(data_idx) # shuffle datasets
        print('rec:',args.rec,'n_recs:',args.n_recs,'n_init:',args.n_init,
              'iters:',args.iters)
        results = run_experiment(args.rec,
                                 data_idx,
                                 args.n_recs,
                                 args.trial,
                                 knowledge_base,
                                 ml_p,
                                 args.n_init,
                                 args.iters)

        df_results = pd.DataFrame.from_records(results,columns=results[0].keys())
        # write results
        if os.path.exists(out_file):
            with open(out_file, 'a') as out:
                df_results.to_csv(out,index=False,header=False)
        else:
            df_results.to_csv(out_file,index=False)

        print('done. results written to ', out_file)


#!/usr/bin/env python

""" A unittest script for the WgsAssembledSeqSet module. """

import unittest
import json
import tempfile

from cutlass import WgsAssembledSeqSet

from CutlassTestConfig import CutlassTestConfig
from CutlassTestUtil import CutlassTestUtil

# pylint: disable=W0703, C1801

class WgsAssembledSeqSetTest(unittest.TestCase):
    """ A unit test class for the WgsAssembledSeqSet class. """

    session = None
    util = None

    @classmethod
    def setUpClass(cls):
        """ Setup for the unittest. """
        # Establish the session for each test method
        cls.session = CutlassTestConfig.get_session()
        cls.util = CutlassTestUtil()

    def testImport(self):
        """ Test the importation of the WgsAssembledSeqSet module. """
        success = False
        try:
            from cutlass import WgsAssembledSeqSet
            success = True
        except Exception:
            pass

        self.failUnless(success)
        self.failIf(WgsAssembledSeqSet is None)

    def testSessionCreate(self):
        """ Test the creation of a WgsAssembledSeqSet via the session. """
        success = False
        seq_set = None

        try:
            seq_set = self.session.create_object("wgs_assembled_seq_set")

            success = True
        except Exception:
            pass

        self.failUnless(success)
        self.failIf(seq_set is None)

    def testPrivateFiles(self):
        """ Test the private_files property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.boolTypeTest(self, seq_set, "private_files")

        self.util.boolPropertyTest(self, seq_set, "private_files")

    def testToJson(self):
        """ Test the generation of JSON from a WgsAssembledSeqSet instance. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")
        success = False

        comment = "Test comment"
        private_files = False

        seq_set.comment = comment
        seq_set.private_files = private_files

        seqset_json = None

        try:
            seqset_json = seq_set.to_json()
            success = True
        except Exception:
            pass

        self.assertTrue(success, "Able to use 'to_json'.")
        self.assertTrue(seqset_json is not None, "to_json() returned data.")

        parse_success = False

        try:
            seqset_data = json.loads(seqset_json)
            parse_success = True
        except Exception:
            pass

        self.assertTrue(parse_success, "to_json() did not throw an exception.")
        self.assertTrue(seqset_data is not None, "to_json() returned parsable JSON.")

        self.assertTrue('meta' in seqset_data, "JSON has 'meta' key in it.")

        self.assertEqual(seqset_data['meta']['comment'],
                         comment, "'comment' in JSON had expected value.")

        self.assertEqual(seqset_data['meta']['private_files'],
                         private_files,
                         "'private_files' in JSON had expected value."
                        )

    def testId(self):
        """ Test the id property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.assertTrue(seq_set.id is None,
                        "New template WgsAssembledSeqSet has no ID.")

        with self.assertRaises(AttributeError):
            seq_set.id = "test"

    def testVersion(self):
        """ Test the version property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.assertTrue(seq_set.version is None,
                        "New template WgsAssembledSeqSet has no version.")

        with self.assertRaises(ValueError):
            seq_set.version = "test"

    def testAssembler(self):
        """ Test the assembler property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.stringTypeTest(self, seq_set, "assembler")

        self.util.stringPropertyTest(self, seq_set, "assembler")

    def testAssemblyName(self):
        """ Test the assembly_name property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.stringTypeTest(self, seq_set, "assembly_name")

        self.util.stringPropertyTest(self, seq_set, "assembly_name")

    def testChecksumsLegal(self):
        """ Test the checksums property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")
        success = False
        checksums = {"md5": "asdf32qrfrae"}

        try:
            seq_set.checksums = checksums
            success = True
        except Exception:
            pass

        self.assertTrue(success, "Able to use the 'checksums' setter.")

        self.assertEqual(seq_set.checksums['md5'],
                         checksums['md5'],
                         "Property getter for 'checksums' works.")

    def testComment(self):
        """ Test the comment property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.stringTypeTest(self, seq_set, "comment")

        self.util.stringPropertyTest(self, seq_set, "comment")

    def testIllegalFormat(self):
        """ Test the format property with an illegal value. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        with self.assertRaises(Exception):
            seq_set.format = 1

    def testLegalFormat(self):
        """ Test the format property with a legal value. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")
        seq_set = self.session.create_object("wgs_assembled_seq_set")
        success = False
        format_ = "fasta"

        try:
            seq_set.format = format_
            success = True
        except Exception:
            pass

        self.assertTrue(success, "Able to use the 'format' setter")

        self.assertEqual(seq_set.format, format_,
                         "Property getter for 'format' works.")

    def testFormatDoc(self):
        """ Test the format_doc property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.stringTypeTest(self, seq_set, "format_doc")

        self.util.stringPropertyTest(self, seq_set, "format_doc")

    def testIllegalSequenceType(self):
        """ Test the sequence_type property with an illegal value. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        # Test int argument
        with self.assertRaises(Exception):
            seq_set.sequence_type = 1

        # Test list argument
        with self.assertRaises(Exception):
            seq_set.sequence_type = ['a', 'b', 'c']

        # Test dict argument
        with self.assertRaises(Exception):
            seq_set.sequence_type = {'a': 1, 'b': 2}

    def testLegalSequenceType(self):
        """ Test the sequence_type property with a legal value. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")
        success = False
        sequence_type = "nucleotide"

        try:
            seq_set.sequence_type = sequence_type
            success = True
        except Exception:
            pass

        self.assertTrue(success, "Able to use the 'sequence_type' setter.")

        self.assertEqual(seq_set.sequence_type, sequence_type,
                         "Property getter for 'sequence_type' works.")

    def testSize(self):
        """ Test the size property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        self.util.intTypeTest(self, seq_set, "size")

        self.util.intPropertyTest(self, seq_set, "size")

    def testTags(self):
        """ Test the tags property. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        tags = seq_set.tags
        self.assertTrue(type(tags) == list, "tags() method returns a list.")
        self.assertEqual(len(tags), 0, "Template object 'tags' list is empty.")

        new_tags = ["tagA", "tagB"]

        seq_set.tags = new_tags
        self.assertEqual(seq_set.tags, new_tags,
                         "Can set tags on a WgsAssembledSeqSet.")

        json_str = seq_set.to_json()
        doc = json.loads(json_str)
        self.assertTrue('tags' in doc['meta'],
                        "JSON representation has 'tags' field in 'meta'.")

        self.assertEqual(doc['meta']['tags'], new_tags,
                         "JSON representation had correct tags after setter.")

    def testAddTag(self):
        """ Test the add_tag() method. """
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        seq_set.add_tag("test")
        self.assertEqual(seq_set.tags, ["test"],
                         "Can add a tag to a WgsAssembledSeqSet.")

        json_str = seq_set.to_json()
        doc = json.loads(json_str)

        self.assertEqual(doc['meta']['tags'], ["test"],
                         "JSON representation had correct tags after add_tag().")

        # Try adding the same tag yet again, shouldn't get a duplicate
        with self.assertRaises(ValueError):
            seq_set.add_tag("test")

        json_str = seq_set.to_json()
        doc2 = json.loads(json_str)

        self.assertEqual(doc2['meta']['tags'], ["test"],
                         "JSON document did not end up with duplicate tags.")

    def testRequiredFields(self):
        """ Test the required_fields() static method. """
        required = WgsAssembledSeqSet.required_fields()

        self.assertEqual(type(required), tuple,
                         "required_fields() returns a tuple.")

        self.assertTrue(len(required) > 0,
                        "required_field() did not return empty value.")

    def testLoadSaveDeleteWgsAssembledSeqSet(self):
        """ Extensive test for the load, edit, save and delete functions. """
        temp_file = tempfile.NamedTemporaryFile(delete=False).name

        # attempt to save the WgsAssembledSeqSet at all points before and
        # after adding the required fields
        seq_set = self.session.create_object("wgs_assembled_seq_set")

        assembler = "Test assembler"
        assembly_name = "Test assembly name"
        checksums = {"md5": "68b329da9893e34099c7d8ad5cb9c940"}
        comment = "Test comment"
        format_ = "fasta"
        format_doc = "http://example.com"
        sequence_type = "nucleotide"
        size = 20000
        study = "prediabetes"
        links = {"computed_from":[]}

        self.assertFalse(seq_set.save(),
                         "WgsAssembledSeqSet not saved successfully, " + \
                         "no required fields.")

        seq_set.comment = comment

        # Setting just the comment should not be sufficient. Let's verify.
        self.assertFalse(seq_set.save(),
                         "WgsAssembledSeqSet not saved successfully.")

        seq_set.links = links

        self.assertFalse(seq_set.save(),
                         "WgsAssembledSeqSet not saved successfully.")

        seq_set.assembler = assembler
        seq_set.assembly_name = assembly_name
        seq_set.checksums = checksums
        seq_set.format = format_
        seq_set.format_doc = format_doc
        seq_set.sequence_type = sequence_type
        seq_set.size = size
        seq_set.study = study
        seq_set.local_file = temp_file

        # make sure seq_set does not delete if it does not exist
        with self.assertRaises(Exception):
            seq_set.delete()

        self.assertTrue(seq_set.save() is True,
                        "WgsAssembledSeqSet was not saved successfully.")

        # load the WgsAssembledSeqSet that was just saved from the OSDF instance
        seq_set_loaded = self.session.create_object("wgs_assembled_seq_set")
        seq_set_loaded = seq_set_loaded.load(seq_set.id)

        # check all fields were saved and loaded successfully
        self.assertEqual(seq_set.comment,
                         seq_set_loaded.comment,
                         "WgsAssembledSeqSet comment not saved & loaded successfully.")

        # WgsAssembledSeqSet is deleted successfully
        self.assertTrue(seq_set.delete(),
                        "WgsAssembledSeqSet was not deleted successfully.")

        # the WgsAssembledSeqSet of the initial ID should not load successfully
        load_test = self.session.create_object("wgs_assembled_seq_set")
        with self.assertRaises(Exception):
            load_test = load_test.load(seq_set.id)

if __name__ == '__main__':
    unittest.main()


# -*- coding: utf-8 -*-
"""This file is a careers24 spider created on top of the ATSSpider

scrapy crawl careers24 -a url="http://www.careers24.com" -a mining_job_id=999 -a iteration=1 -a extract=1
sample url:
    http://www.careers24.com
    http://www.careers24.co.ke
    http://www.careers24.com.ng
"""
from urlparse import urljoin
from re import compile

from scrapy.selector import Selector
from scrapy.http import Request

from brightcorp.base.atsspiders import ATSSpider
from brightcorp.items import BrightcorpItemLoader
from brightcorp.processors import ConvertDateString, Prefix , Replace, UrlJoin

class Careers24(ATSSpider):

    name = "careers24"
    url_fragmentanchor = "/jobs/?pagesize=100"
    ref_reg = compile('.*/(\d+)-')

    def parse(self, response):
        sel = Selector(response)

        # Set expected job count
        if not self.expected_job_count_set:
            expected_count = sel.xpath(
                "//div[@class='search_header']/h3/text()"
                ).extract()
            if expected_count:
                self.expected_job_count = expected_count[0]

        jobs = sel.xpath(
            "//div[contains(@id, '_resultContainer')]"
            )
        for job in jobs:
            link = job.xpath(".//*[@itemprop='title']/a/@href").extract()
            if link:
                job_url = urljoin(response.url, link[0])
                meta = {
                    'title': job.xpath(
                        ".//*[@itemprop='title']/a/text()"
                        ).extract(),
                    'logo_url': job.xpath(
                        ".//div[@class='recruiter_logo']/a/img/@src"
                        ).extract(),
                    'baseSalary': job.xpath(
                        ".//*[@itemprop='baseSalary'][last()]/text()"
                        ).extract(),
                    'jobtype': job.xpath(
                        ".//*[@itemprop='employmentType']/text()"
                        ).extract(),
                    'industry': job.xpath(
                        ".//*[@itemprop='baseSalary'][1]/text()"
                        ).extract(),
                    }
                yield Request(
                    job_url, meta=meta, callback=self.parse_job_callback()
                    )

        next_page = sel.xpath(
            "//a[@class='next' and contains(text(),'next')]/@href"
            ).extract()
        if next_page:
            next_url = urljoin(response.url, next_page[0])
            yield Request(next_url, callback=self.parse)

    def parse_job(self, response):
        sel = Selector(response)
        loader = BrightcorpItemLoader(selector=sel)
        loader.add_value('title', response.meta['title'])
        loader.add_value('baseSalary', response.meta['baseSalary'])
        loader.add_value('jobtype', response.meta['jobtype'])
        loader.add_value('industry', response.meta['industry'])
        loader.add_value('url', response.url)
        loader.add_value('apply_url', response.url)
        loader.add_value(
            'logo_url', response.meta['logo_url'], UrlJoin(response.url)
            )
        loader.add_value(
            'referencenumber', response.url, Prefix(self.name+"-"),
            re=self.ref_reg
            )
        loader.add_xpath(
            'description',
            "//div[text()='Job Details']|//div[@class='job_detail_container']/span[@itemprop='hiringOrganization']/node()"
            )
        loader.add_xpath(
            'company',
            "//span[@itemprop='hiringOrganization']/span[@itemprop='name']/text()"
            )
        loader.add_xpath(
            'date',
            "//div[@class='job_page_detail']//span[@class='posted']/text()",
            ConvertDateString("on %A, %B %d, %Y")
            )
        loader.add_xpath(
            'expiration_date',
            "//div[@class='job_page_detail']//span[contains(@id, '_lblClosingDate')]/text()",
            ConvertDateString("Apply before %A, %B %d, %Y -")
            )
        loader.add_xpath('requirements', "//div[contains(@id, '_divCandReq')]")
        loader.add_xpath('location', "//span[@itemprop='jobLocation']/text()")

        yield loader.load_item()


"""Walleter command line entry point."""
# Standard
import argparse
import errno
import logging
import os
import pkg_resources
import sys
import time
from logging.config import dictConfig

# Boltons
from boltons.iterutils import windowed_iter
from log_color import ColorFormatter, ColorStripper

# Project
from walleter.utils.arg_format import ArgFormatter
from walleter.utils.blockchain import BlockchainInfo
from walleter.utils.wallet import Wallet

LOG = logging.getLogger(__name__)
DEST_ADDRESS = '16Mfp5hjBmro5p4Kg6z4XqvVmrWbzq17px'

# Setup the version string globally
try:
    pkg_version = "%(prog)s {0}".format(
        pkg_resources.get_distribution("walleter").version
    )
except pkg_resources.DistributionNotFound:
    pkg_version = '%(prog)s Development'
except Exception:
    pkg_version = '%(prog)s Unknown'

# Py Compat
if sys.version_info[0] == 3:
    xrange = range

def logging_init(level, logfile=None, verbose=False):
    """
    Given the log level and an optional logging file location, configure
    all logging.
    """
    # Get logging related arguments & the configure logging
    if logfile:
        logfile = os.path.abspath(logfile)

    # Don't bother with a file handler if we're not logging to a file
    handlers = ['console', 'filehandler'] if logfile else ['console', ]

    # If the main logging level is any of these, set librarys to WARNING
    lib_warn_levels = ('DEBUG', 'INFO', 'WARNING', )

    # The base logging configuration
    BASE_CONFIG = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'ConsoleFormatter': {
                '()': ColorFormatter,
                'format': '%(levelname)s: %(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
            'FileFormatter': {
                '()': ColorStripper,
                'format': ("%(levelname)-8s: %(asctime)s '%(message)s' "
                           '%(name)s:%(lineno)s'),
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
        },
        'handlers': {
            'console': {
                'level': 'DEBUG' if verbose else level,
                'class': 'logging.StreamHandler',
                'formatter': 'ConsoleFormatter',
            },
        },
        'loggers': {
            'walleter': {
                'handlers': handlers,
                'level': 'DEBUG' if verbose else level,
                'propagate': False,
            },
            'requests': {
                'handlers': handlers,
                'level': 'WARNING' if level in lib_warn_levels else level,
                'propagate': False,
            },
        }
    }

    # If we have a log file, modify the dict to add in the filehandler conf
    if logfile:
        BASE_CONFIG['handlers']['filehandler'] = {
            'level': 'DEBUG' if verbose else level,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': logfile,
            'formatter': 'FileFormatter',
        }

    # Setup the loggers
    dictConfig(BASE_CONFIG)

def cli():
    parser = argparse.ArgumentParser(
        description="Wallet exploration tool",
        formatter_class=ArgFormatter,
    )
    parser.add_argument(
        "-i",
        "--iterations",
        dest="iterations",
        type=int,
        default=1,
        help="Number of iterations to derive"
    )
    parser.add_argument(
        "-b",
        "--bypass-iterations",
        dest="bypass",
        action='store_true',
        help="Skip interstitial iterations"
    )
    parser.add_argument(
        "-V",
        "--version",
        dest="version",
        action="version",
        version=pkg_version,
        help="Display the version number."
    )
    parser.add_argument(
        '-l',
        '--log-level',
        default='INFO',
        choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),
        help='Logging level for command output.',
        dest='log_level'
    )
    parser.add_argument(
        '-L',
        '--logfile',
        dest='logfile',
        default=None,
        help='Location to place a log of the process output'
    )
    parser.add_argument(
        '-s',
        '--seed',
        dest='seed',
        default=None,
        help='Use a specific seed instead of core dataset'
    )
    parsed_args = parser.parse_args()
    logging_init(parsed_args.log_level, logfile=parsed_args.logfile)
    run(parsed_args.iterations,
        force_seed=parsed_args.seed, bypass=parsed_args.bypass)
    LOG.debug(u"#g<\u2713> Complete! Dataset exhausted.")

def iter_wallets(wallet, iterations):
    """Iterate a wallet feeding it's address into the next iteration."""
    prev = None
    for idx in xrange(iterations):
        if not prev:
            prev = wallet.address
            yield wallet
        else:
            try:
                new = Wallet(prev)
            except Exception:
                break
            else:
                prev = new.address
                yield new

def main():
    try:
        cli()
    except KeyboardInterrupt:
        # Write a nice message to stderr
        sys.stderr.write(
            u"\n\033[91m\u2717 Operation canceled by user.\033[0m\n"
        )
        sys.exit(errno.EINTR)

def run(iterations, force_seed=None, bypass=False):
    """Actual code shit."""

    home_folder = os.path.expanduser('~')
    config_dir = os.path.join(home_folder, '.walleter')

    if not os.path.exists(config_dir):
        os.mkdir(config_dir)

    cache_file = os.path.join(config_dir, 'check_cache')
    found_file = os.path.join(config_dir, 'found_coins')

    block_info = BlockchainInfo()
    LOG.info("Opening BlockchainInfo session")
    block_info.open_session()
    LOG.info("Session open")

    cache = []
    if os.path.exists(cache_file):
        with open(cache_file, 'rb') as f:
            cache = [x.strip().strip('\r\n').strip('\n') for x
                     in f.readlines()]

    # If given a specific seed, conjure a dataset from that
    if force_seed is not None:
        if force_seed in ('""', '\'\''):
            force_seed = ''
        all_data = [force_seed]
        LOG.info('Using custom seed: {0}'.format(force_seed))
    else:
        from data import all_data_iter as all_data

    tried = set()
    for dict_word in all_data:
        dict_word = dict_word.strip()

        if dict_word in tried:
            continue  # already did that this session

        tried.add(dict_word)
        LOG.debug('Dict word: "{0}"'.format(dict_word))

        # Create initial wallet
        try:
            wallet = Wallet(dict_word)
        except Exception:
            continue

        for idx, wallet in enumerate(iter_wallets(wallet, iterations)):

            if bypass and idx + 1 != iterations:
                continue

            if wallet.address in cache:
                LOG.debug('Skipping cached address')
                continue

            LOG.debug('Checking address: {0}'.format(wallet.address))

            # Get received bitcoins
            retry = 0
            while retry < 5:
                try:
                    received_bitcoins = block_info.get_received(wallet.address)
                    break
                except Exception:
                    LOG.warning('Response invalid for received bitcoins. '
                                'Retrying in 5 seconds.')
                    time.sleep(5)
                    retry += 1
            if retry == 5:
                LOG.error('Retries exceeded; Skipping.')
                continue

            if not received_bitcoins:
                LOG.info('Wallet never had any coins. Moving along...')

                # Write address to cache file
                with open(cache_file, 'a') as f:
                    f.write("{0}\n".format(wallet.address))
                continue

            # Get current balance
            for _ in xrange(5):
                try:
                    balance = block_info.get_balance(wallet.address)
                    break
                except Exception:
                    LOG.warning('Response invallid for balance. Retrying in '
                                '5seconds.')
                    time.sleep(5)
                    retry += 1
            else:
                LOG.error('Retries exceeded; skipping.'.format(retry_count))
                continue

            if balance == 0.00:
                balance_str = '#y<{:.8f}>'.format(balance)
            else:
                balance_str = '#g<{:.8f}>'.format(balance)

            # Output results
            output = (
                'Wallet found: {}; Received: {:.8f}; Address: {}; Private '
                'Key: {}; Balance: {}'.format(
                    wallet.passphrase,
                    received_bitcoins,
                    wallet.address,
                    wallet.private_key_wif,
                    balance_str
                )
            )

            LOG.info(output)
            with open(found_file, 'a') as f:
                f.write(output)
                f.write("\n")

if __name__ == "__main__":
    main()


import bs4 as bs
import time
import random
import requests
from .login import login_website
from selenium.common.exceptions import TimeoutException

from Utils import DBHelper

def extract_source_torrent(base_url, db, table_name, section):
    TOTAL_ERROR_LIST = list()
    TOTAL_DATA_DIC = dict()

    webhandle = login_website(db)

    login_url = base_url + "/login.php"

    webhandle.get(base_url + "/thread0806.php?fid=" + str(section) + "&search=&page=0")
    soup = bs.BeautifulSoup(webhandle.page_source, "lxml")
    page_total = soup.findAll("input")[0]["onblur"]
    total_page_count = page_total.split("=")[-1].split("/")[-1].split("'")[0]
    cookies = webhandle.get_cookies()
    s = requests.Session()
    for cookie in cookies:
        s.cookies.set(cookie['name'], cookie['value'])

    for index in range(1, int(total_page_count) + 1):
        time.sleep(random.randint(1, 10))
        print("*********************************Current page index is : {}*********************************".format(
            index))
        complete_url = base_url + "/thread0806.php?fid=" + str(section) + "&search=&page=" + str(index)
        try:
            webhandle.get(complete_url)
            #r = s.get(complete_url)
        except Exception as ex:
            print(ex.msg)
            try:
                webhandle.get(complete_url)
            except:
                webhandle.close()
                webhandle = login_website(db)
                try:
                    webhandle.get(complete_url)
                except Exception as e:
                    print(e)
                    print("Skip this loop!")
                    continue

        source = webhandle.page_source
        #source = r.content
        soup = bs.BeautifulSoup(source, "lxml")
        for sub_item in soup.findAll("h3"):
            if len(sub_item.findAll('a')) == 0:
                TOTAL_ERROR_LIST.append(str(sub_item))
                continue
            link = sub_item.findAll('a')[0]
            title = link.text
            try:
                full_link = "/".join(login_url.split('/')[:-1]) + '/' + link["href"]
            except:
                print(link)
                TOTAL_ERROR_LIST.append(str(sub_item))
                continue
            # print("-" * 100)
            if full_link in TOTAL_DATA_DIC:
                print("{} has already exixts".format(full_link))
                continue
            if "htm_data" not in full_link:
                print("Invalid link")
                continue

            cursor = DBHelper.fetchData(db, "SELECT * FROM {} WHERE Link='{}'".format(table_name, full_link))
            if cursor.fetchone() != None:
                print("Record has already existed!")
                continue
            else:
                print("Title : {}".format(title))
                print("link : {}".format(full_link))
                print("\n")

                InsertSQL = u"INSERT INTO {} (Title, Link, Section, TorrentLink, DownloadingCount) VALUES (%s, %s, %s, %s, %s )".format(table_name)
                InsertData = (title, full_link, section, "", 0)
                try:
                    DBHelper.insert_table(db, InsertSQL, InsertData)
                except Exception as err:
                    print(err)
                    continue

    webhandle.close()


from flask import Flask, request
from flask_restful import Resource, Api
from threading import Thread
import DetectEmotionsOnVideo as Deov

app = Flask(__name__)
api = Api(app)
from flask import jsonify

thread = Thread(target=Deov.DetectEmotionsOnVideo.start_video)
thread.start()

class RunVideo(Resource):
    @staticmethod
    def get():
        url = request.args.get('url')
        if url in Deov.pendingResults:
            result = Deov.pendingResults[url]
            if result.progress == 100:
                del Deov.pendingResults[url]
            res = "{\"positionInQueue\":" + str(result.positionInQueue) + \
                  ",\"progress\":" + str(result.progress) + \
                  ",\"emotions\":" + str(result.emotions) + \
                  ",\"error\":" + str(result.error) + "}"
            return res

        result = Deov.Result(Deov.queue.qsize() + 1, 0, [])
        Deov.pendingResults[url] = result
        Deov.queue.put(url)
        res = "{\"positionInQueue\":" + str(result.positionInQueue) + \
              ",\"progress\":" + str(result.progress) + \
              ",\"emotions\":" + str(result.emotions) + \
              ",\"error\":" + str(result.error) + "}"
        return res

api.add_resource(RunVideo, '/runVideo')

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


import numpy as np
import itertools

# Функционал, реализующий комбинаторные задачи

# На вход:
# n_elems - количество элементов
# capacities - list с возможными емкостями контейнеров
def get_containers_by_elems(n_elems, capacities):
    capacities.sort()
    res_array = []

    for m in range(1, n_elems):
        current_min_sum = capacities[0] * m
        current_max_sum = capacities[-1] * m
        if current_min_sum > n_elems or current_max_sum < n_elems:
            continue

        res_array.append([p for p in itertools.combinations_with_replacement(capacities, r=m)])

    containers = []
    for res_series in res_array:
        for res in res_series:
            if sum(res) == n_elems:
                containers.append(res)

    # На выход - list с перечислением контейнеров, где значение - емкость контейнера
    return containers

# if __name__ == '__main__':
#     containers_list_outer = [2, 4, 6, 7]
#     n = 20
#
#     print(get_containers_by_elems(n, containers_list_outer))


# -*- coding: utf-8 -*-
import logging
from pathlib import Path

from pandas import read_csv

def make_epsg_4326_latlon_dataset():
    logger = logging.getLogger(__name__)

    parties = ['PT', 'PSDB']
    min_latitude, max_latitude = -180, 180
    min_longitude, max_longitude = -90, 90

    interim_dir = Path(data_dir, 'interim').resolve()
    processed_dir = Path(data_dir, 'processed').resolve()
    latlon_dir = Path(interim_dir, 'latlon').resolve()

    epsg_4326_latlon_dir = Path(processed_dir, 'epsg_4326').resolve()
    epsg_4326_latlon_dir.mkdir(exist_ok=True)
    for party in parties:
        logger.info('starting to normalize {} series_latlon data'.format(party))

        file_path = Path(latlon_dir, party, 'latlon.csv').resolve()
        dataset = read_csv(file_path)

        dataset.latitude = (dataset.latitude -
                            min_latitude) / (max_latitude - min_latitude)
        dataset.longitude = (dataset.longitude -
                             min_longitude) / (max_longitude - min_longitude)

        party_dir = Path(epsg_4326_latlon_dir, party).resolve()
        party_dir.mkdir(exist_ok=True)
        file_path = Path(party_dir, 'latlon.csv').resolve()
        dataset.to_csv(file_path, index=False)

        logger.info('done normalizing {} series_latlon data'.format(party))

def main():
    """ Runs data processing scripts to turn brazil voting data from (../interim) into
        presidential data (saved in ../interim/presidential).
    """
    logger = logging.getLogger(__name__)

    logger.info(
        'normalizing series_latlon dataset with EPSG:4326... Saving at ../data/processed/latlon')
    make_epsg_4326_latlon_dataset()
    logger.info(
        'done normalizing series_latlon dataset with EPSG:4326... Saved at ../data/processed/latlon')

if __name__ == '__main__':
    log_fmt = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    logging.basicConfig(level=logging.INFO, format=log_fmt)

    project_dir = Path(__file__).resolve().parents[2]
    data_dir = Path(project_dir, 'data').resolve()

    main()


# -*- coding: utf-8 -*-

from hamcrest import assert_that, has_key, equal_to_ignoring_whitespace

from hermes.org import OrgApi

class TestOrg(object):

    def test_check_org_hierarchies_response_items(self, logged_client):
        _, result = OrgApi.hierarchies()
        assert_that(result[0], has_key('id'),
                    'Expect that result has _id_ key.')
        assert_that(result[0], has_key('children'),
                    'Expect that result has _children_ key.')
        assert_that(result[0], has_key('name'),
                    'Expect that result has _name_ key.')

    def test_check_org_hierarchies(self, logged_client, config):
        _, result = OrgApi.hierarchies()
        assert_that(result[0]['name'],
                    equal_to_ignoring_whitespace(config['org2']['name']),
                    'Expect that the org name is "%s", but was "%s".' % (
                        config['org2']['name'], result[0]['name']
                    ))
        assert_that(result[0]['children'][0]['name'],
                    equal_to_ignoring_whitespace(config['org4']['name']),
                    'Expected that org child name is "%s", but was "%s".' % (
                        config['org4']['name'],
                        result[0]['children'][0]['name']
                    ))
        assert_that(result[1]['name'],
                    equal_to_ignoring_whitespace(config['org3']['name']),
                    'Expect that the org name is "%s", but was "%s".' % (
                        config['org3']['name'], result[1]['name']
                    ))
        assert_that(result[1]['children'][0]['name'],
                    equal_to_ignoring_whitespace(config['org5']['name']),
                    'Expected that org child name is "%s", but was "%s".' % (
                        config['org5']['name'],
                        result[1]['children'][0]['name']
                    ))