# -*- coding: utf-8 -*-
"""
Created on Thu Jun 24 21:51:36 2021

@author: EnminZhao
"""

import numpy as np
import random
import copy
from .comparehands import compare_hands
#e.g. hands = [['CT', 'ST', 'H9', 'B9', 'C2', 'C8', 'C7'], ['CJ', 'SJ', 'H9', 'B9', 'C2', 'C8', 'C7'], ['CT', 'ST', 'H9', 'B9', 'C2', 'C8', 'C7']]
class holdem2ENV:
    def __init__(self):
        self.player1hand=np.zeros((4,13))
        self.player2hand=np.zeros((4,13))
        #self.publichand=np.zeros((4,13,4))
        self.bet=150
        #self.action_number=0
        self.bet_num=0
        self.player1_bet=50
        self.player2_bet=100
        self.action_history_info=[]
        self.player_id=0
        self.maxpot=20000
        self.player_num=2
        self.fold=[0,0]
        self.allin_true=False
        self.hands_num=52
        self.action_history=[[],[],[],[]]
        self.RANK_TO_STRING = {2: "2", 3: "3", 4: "4", 5: "5", 6: "6",
                               7: "7", 8: "8", 9: "9", 10: "T", 11: "J", 12: "Q", 13: "K", 14: "A"}
        self.STRING_TO_RANK = {v:k for k, v in self.RANK_TO_STRING.items()}
        self.RANK_LOOKUP = "23456789TJQKA"
        self.SUIT_LOOKUP = "scdh"
        self.pid=0

    def reset(self):
        self.player1hand=np.zeros((4,13))
        self.player2hand=np.zeros((4,13))
        #self.publichand0=np.zeros((4,13))
        self.publichand1=np.zeros((4,13))
        self.publichand2=np.zeros((4,13))
        self.publichand3=np.zeros((4,13))
        self.action_record0=np.zeros((4,9,13))
        self.action_record1=np.zeros((4,9,13))
        self.action_record2=np.zeros((4,9,13))
        self.action_record3=np.zeros((4,9,13))
        self.pid=0
        self.turnbet=np.zeros(4)
        self.action_number=np.zeros(4)
        self.turn=0
        self.bet_num=0
        self.bet=150
        self.turn=0

        self.player_num=2
        self.player1_bet=50
        self.player2_bet=100

        self.action_history_info=[]
        self.player_id=0
        self.maxpot=20000
        self.fold=[0,0]
        self.allin_true=False
        self.hands_num=52
        self.done=False
        self.actions=['fold','check','call','bet_halfpot','bet_3quarpot','bet_pot','bet_15pot','bet_2pot','allin']
        self.action_history=[[],[],[],[]]
        self.RANK_TO_STRING = {2: "2", 3: "3", 4: "4", 5: "5", 6: "6",
                               7: "7", 8: "8", 9: "9", 10: "T", 11: "J", 12: "Q", 13: "K", 14: "A"}
        self.STRING_TO_RANK = {v:k for k, v in self.RANK_TO_STRING.items()}
        self.RANK_LOOKUP = "23456789TJQKA"
        self.SUIT_LOOKUP = "scdh"

        self.allhands=list(range(self.hands_num))

        self.publichand_comp=[]
        self.player1hand_comp=[]
        self.player2hand_comp=[]

        self.rewards=np.zeros(2)
        legal_action=np.ones(9)
        legal_action[1]=0
        legal_action[8]=0
        self.legal_action=legal_action
        self.envhands=np.zeros((4,13,6))
        obs=np.zeros(312+1872+10)
        obs[0:312]=self.envhands.reshape(312)
        obs[312:312+468]=self.action_record0.reshape(468)
        obs[312+468:312+468*2]=self.action_record1.reshape(468)
        obs[312+468*2:312+468*3]=self.action_record2.reshape(468)
        obs[312+468*3:312+468*4]=self.action_record3.reshape(468)

        obs[1872+312:1872+312+9]=legal_action
        obs[1872+312+9]=self.player_id
        obs1=obs.copy()
        self.obs=obs

        return obs1

    def judgeallin(self,player_bet):
        if player_bet>self.maxpot-1:
            player_bet=self.maxpot
            self.allin_true=True
        return player_bet

    def getobs(self):
        obs=self.obs
        obs1=obs.copy()
        return obs1

    def step(self,action):
        '''
        Get env step
        Returns:
            (list): the best five cards among the seven cards of a player
        action: fold check call bet 0.25 0.5 0.75 1 2  allin
        '''
        #self.turn=int(self.turn)
        if self.turn==0:
            self.action_record0[self.player_id,action,int(self.action_number[self.turn])]=1
            self.action_record0[2,action,int(self.action_number[self.turn])]=1
            self.action_number[self.turn]=self.action_number[self.turn]+1
        elif self.turn==1:
            self.action_record1[self.player_id,action,int(self.action_number[self.turn])]=1
            self.action_record1[2,action,int(self.action_number[self.turn])]=1
            self.action_number[self.turn]=self.action_number[self.turn]+1
        elif self.turn==2:
            self.action_record2[self.player_id,action,int(self.action_number[self.turn])]=1
            self.action_record2[2,action,int(self.action_number[self.turn])]=1
            self.action_number[self.turn]=self.action_number[self.turn]+1
        else:
            self.action_record3[self.player_id,action,int(self.action_number[self.turn])]=1
            self.action_record3[2,action,int(self.action_number[self.turn])]=1
            self.action_number[self.turn]=self.action_number[self.turn]+1

        if self.legal_action[action]==0 and action==8:
            raise Error
        action=self.actions[action]

        if self.player_id==0:
            if action=='fold':
                self.player_num=self.player_num-1
                self.fold[0]=1
            elif action=='check':
                self.player1_bet=self.player1_bet if self.player1_bet>99 else 100
            elif action=='call':
                self.player1_bet=max(self.player1_bet,self.player2_bet)
            elif action=='bet_halfpot':
                self.player1_bet=2*max(self.player1_bet,self.player2_bet)
            elif action=='bet_3quarpot':
                self.player1_bet=2.5*max(self.player1_bet,self.player2_bet)
            elif action=='bet_pot':
                self.player1_bet=3*max(self.player1_bet,self.player2_bet)
            elif action=='bet_15pot':
                self.player1_bet=4*max(self.player1_bet,self.player2_bet)
            elif action=='bet_2pot':
                self.player1_bet=5*max(self.player1_bet,self.player2_bet)

            else:
                self.player1_bet=self.maxpot
                self.player1_bet=self.judgeallin(self.player1_bet)
            self.bet=self.player1_bet+self.player2_bet
            self.player_id=1

        else:
            if action=='fold':
                self.fold[1]=1
                self.player_num=self.player_num-1
            elif action=='check':
                self.player2_bet=self.player2_bet
            elif action=='call':
                self.player2_bet=max(self.player1_bet,self.player2_bet)

            elif action=='bet_halfpot':
                self.player2_bet=2*max(self.player1_bet,self.player2_bet)
            elif action=='bet_3quarpot':
                self.player2_bet=2.5*max(self.player1_bet,self.player2_bet)
            elif action=='bet_pot':
                self.player2_bet=3*max(self.player1_bet,self.player2_bet)
            elif action=='bet_15pot':
                self.player2_bet=4*max(self.player1_bet,self.player2_bet)
            elif action=='bet_2pot':
                self.player2_bet=5*max(self.player1_bet,self.player2_bet)

            else:
                self.player2_bet=self.maxpot
                self.player2_bet=self.judgeallin(self.player2_bet)
            self.bet=self.player1_bet+self.player2_bet
            self.player_id=0

        self.bet=self.player1_bet+self.player2_bet
        self.action_history[self.turn].append(action[0])
        self.actions_judge()
        self.judgeturndone()
        if self.turn==4:
            legal_action=np.zeros(9)
        else:
            legal_action=self.getlegal_action()

        obs=np.zeros(312+1872+10)
        obs[0:312]=self.envhands.reshape(312)
        obs[312:312+468]=self.action_record0.reshape(468)
        obs[312+468:312+468*2]=self.action_record1.reshape(468)
        obs[312+468*2:312+468*3]=self.action_record2.reshape(468)
        obs[312+468*3:312+468*4]=self.action_record3.reshape(468)
        obs[1872+312:1872+312+9]=legal_action
        obs[1872+312+9]=self.player_id

        obs1=obs.copy()
        self.obs=obs

        rewards=self.rewards/100
        rewards1=rewards.copy()
        done=copy.deepcopy(self.done)
        action_history= copy.deepcopy(self.action_history)

        return obs1

    def getlegal_action(self):
        legal_action=np.ones(9)
        if len(self.action_history[self.turn])==0:

            legal_action[2]=0
        if len(self.action_history[self.turn])==1:
            if self.action_history[self.turn][-1]=='c':
                legal_action[2]=0
            else:
                legal_action[1]=0
        else:
            for i in range(len(self.action_history[self.turn])):
                if self.action_history[self.turn][-i]=='b':
                    legal_action[1]=0
                if self.action_history[self.turn][-i]=='a':
                    legal_action[:]=0
                    legal_action[2]=1
                    legal_action[0]=1

        if self.bet_num[self.turn]>4:
            legal_action[:]=0
            legal_action[2]=1
            legal_action[0]=1

        if 2*max(self.player1_bet,self.player2_bet)>19999:
            legal_action[3:8]=0

        if 2.5*max(self.player1_bet,self.player2_bet)>19999:
            legal_action[4:8]=0
        if 3*max(self.player1_bet,self.player2_bet)>19999:
            legal_action[5:8]=0
        if 4*max(self.player1_bet,self.player2_bet)>19999:
            legal_action[6:8]=0
        if 5*max(self.player1_bet,self.player2_bet)>19999:
            legal_action[7]=0

        if 3*max(self.player1_bet,self.player2_bet)<20000:
            legal_action[8]=0

        self.legal_action=legal_action
        return legal_action

    def judgeturndone(self):
        if len(self.action_history[self.turn])>1 and self.action_history[self.turn][-1]=='c':
            if self.pid==0:
                self.turnbet[self.turn]=self.player1_bet
            else:
                self.turnbet[self.turn]=self.player2_bet
            if self.player1_bet==self.player2_bet:
                self.turn=self.turn+1
                self.player_id=1
            else:
                print("self.player1_bet==self.player2_bet",self.player1_bet,self.player2_bet)
                return Error

    def judgedone(self):

        if self.player_num==1:
            a=1
            self.done=True
            self.rewards[0]=-self.player1_bet
            self.rewards[1]=-self.player2_bet
            for i in range(2):
                if self.fold[i]==0:
                    self.rewards[i]=0
        else:
            if self.turn==3:
                if len(self.action_history[3])>1 and self.action_history[3][-1]=='c':
                    self.done=True
                    self.rewards[0]=-self.player1_bet
                    self.rewards[1]=-self.player2_bet
                    self.player1hand_comp=self.player1hand_comp+self.publichand_comp
                    self.player2hand_comp=self.player2hand_comp+self.publichand_comp
                    result=compare_hands([self.player1hand_comp,self.player2hand_comp])

                    if sum(result)==1:
                        a=1
                        if result[0]==1:
                            self.rewards[0]=0
                        else:
                            self.rewards[1]=0
                    else:
                        a=2
                        self.rewards[0]=0
                        self.rewards[1]=0

        if self.done==True:

            if a==1:
                for i in range(2):
                    if self.rewards[i]==0:
                        self.rewards[i]=-sum(self.rewards)

    def actions_judge(self):
        self.bet_num=np.zeros(4)
        for i in range(len(self.action_history[self.turn])):
            if self.action_history[self.turn][i]=='b' or self.action_history[self.turn][i]=='a':
                self.bet_num[self.turn]=self.bet_num[self.turn]+1

    def getbetaction(self,ratio):
        if ratio<0.625 and ratio>0:
            action=3
        elif ratio>0.625 and ratio<0.875:
            action=4
        elif ratio>0.875 and ratio<1.25:
            action=5
        elif ratio>1.25 and ratio<1.75:
            action==6
        elif ratio>1.75 and ratio<2.01:
            action=7
        else:
            action==0
        return action
    def perform_env_and_oppoaction(self,info):

        self.pid=info['position']
        hole_cards=info['private_card']
        board_cards=info['public_card']
        self.getplayerhands(hole_cards)
        self.getboardhands(board_cards)

        action_history_get=info['action_history']
        action_history_old=self.action_history_info
        action_history_new=[]
        for i in range(len(action_history_get)):
            for j in range(len(action_history_get[i])):
                action_history_new.append(action_history_get[i][j])

        for i in range(len(action_history_old),len(action_history_new)):
            if action_history_new[i]==[]:
                action_his=[]
            else:
                action_his=action_history_new[i]
            if action_his!=[] and action_his['position']==1-self.pid:
                action_this_turn=action_his['action']
                if action_this_turn=='fold':
                    action=0
                elif action_this_turn=='check':
                    action=1
                elif action_this_turn=='call':
                    action=2
                else:
                    if info['players'][1-self.pid]['money_left']==0:
                        action=8
                    else:
                        ratio=0.5*(20000-info['players'][1-self.pid]['money_left']-max(self.player1_bet,self.player2_bet))/max(self.player1_bet,self.player2_bet)
                        action=self.getbetaction(ratio)
                print("player&action",self.player_id,action)
                obs=self.step(action)
                print("playerafteraction",self.player_id)

        self.action_history_info=action_history_new
        obs=self.getobs()
        return obs

    def getplayerhands(self,hole_cards):
        hands=np.zeros((4,13))

        for i in range(13):
            for j in range(4):
                if hole_cards[0][0]==self.RANK_LOOKUP[i] and hole_cards[0][1]==self.SUIT_LOOKUP[j]:
                    hands[j,i]=1
                if hole_cards[1][0]==self.RANK_LOOKUP[i] and hole_cards[1][1]==self.SUIT_LOOKUP[j]:
                    hands[j,i]=1

        self.envhands[:,:,0]=hands

    def getboardhands(self,board_cards):
        hands1=np.zeros((4,13))
        hands2=np.zeros((4,13))
        hands3=np.zeros((4,13))
        lengthborad=len(board_cards)
        #print('lengthborad',lengthborad)
        if lengthborad==3:
            hands2=np.zeros((4,13))
            hands3=np.zeros((4,13))
            for i in range(13):
                for j in range(4):
                    if board_cards[0][0]==self.RANK_LOOKUP[i] and board_cards[0][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[1][0]==self.RANK_LOOKUP[i] and board_cards[1][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[2][0]==self.RANK_LOOKUP[i] and board_cards[2][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
        elif lengthborad==4:
            for i in range(13):
                for j in range(4):
                    if board_cards[0][0]==self.RANK_LOOKUP[i] and board_cards[0][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[1][0]==self.RANK_LOOKUP[i] and board_cards[1][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[2][0]==self.RANK_LOOKUP[i] and board_cards[2][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[3][0]==self.RANK_LOOKUP[i] and board_cards[3][1]==self.SUIT_LOOKUP[j]:
                        hands2[j,i]=1

        elif lengthborad==5:
            for i in range(13):
                for j in range(4):
                    if board_cards[0][0]==self.RANK_LOOKUP[i] and board_cards[0][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[1][0]==self.RANK_LOOKUP[i] and board_cards[1][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[2][0]==self.RANK_LOOKUP[i] and board_cards[2][1]==self.SUIT_LOOKUP[j]:
                        hands1[j,i]=1
                    if board_cards[3][0]==self.RANK_LOOKUP[i] and board_cards[3][1]==self.SUIT_LOOKUP[j]:
                        hands2[j,i]=1
                    if board_cards[4][0]==self.RANK_LOOKUP[i] and board_cards[4][1]==self.SUIT_LOOKUP[j]:
                        hands3[j,i]=1
        else:
            hands1=np.zeros((4,13))
            hands2=np.zeros((4,13))
            hands3=np.zeros((4,13))

        self.envhands[:,0:13,1]=hands1
        self.envhands[:,0:13,2]=hands2
        self.envhands[:,0:13,3]=hands3
        self.envhands[:,0:13,4]=hands1+hands2+hands3
        self.envhands[:,0:13,5]=hands1+hands2+hands3+self.envhands[:,:,0]
        self.obs[0:312]=self.envhands.reshape(312)


#/usr/bin/python
#coding=utf8
#ZigZag Conversion

class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        str_list = [""] * numRows
        group_len= 2 * numRows - 2

        for i in range(len(s)):
            group_id=0
            if(group_len):
                group_id = i%group_len
            if(group_id >= numRows):
                group_id = group_len - group_id
            str_list[group_id] += s[i]

        r_str="".join(str_list)
        return r_str


# -*- coding: utf-8 -*-
"""
Created on Wed Jun  1 12:31:04 2016

@author: azaterka
"""

# import the necessary packages
from __future__ import print_function
import argparse
import datetime
import imutils
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to the input image")
ap.add_argument("-w", "--win-stride", type=str, default="(8, 8)",
	help="window stride")
ap.add_argument("-p", "--padding", type=str, default="(16, 16)",
	help="object padding")
ap.add_argument("-s", "--scale", type=float, default=1.05,
	help="image pyramid scale")
ap.add_argument("-m", "--mean-shift", type=int, default=-1,
	help="whether or not mean shift grouping should be used")
args = vars(ap.parse_args())

# evaluate the command line arguments (using the eval function like
# this is not good form, but let's tolerate it for the example)
winStride = eval(args["win_stride"])
padding = eval(args["padding"])
meanShift = True if args["mean_shift"] > 0 else False

# initialize the HOG descriptor/person detector
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# load the image and resize it
image = cv2.imread(args["image"])
image = imutils.resize(image, width=min(400, image.shape[1]))

# detect people in the image
start = datetime.datetime.now()
(rects, weights) = hog.detectMultiScale(image, winStride=winStride,
	padding=padding, scale=args["scale"], useMeanshiftGrouping=meanShift)
print("[INFO] detection took: {}s".format(
	(datetime.datetime.now() - start).total_seconds()))

# draw the original bounding boxes
for (x, y, w, h) in rects:
	cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# show the output image
cv2.imshow("Detections", image)
cv2.waitKey(0)
cv2.destroyAllWindows()


from common.tree import TreeNode, deserialize_tree, draw_tree, is_same_tree

class Solution(object):
    def countUnivalSubtrees(self, root):
        """
        :type root: TreeNode
        :rtype: int

        ACE
        45 ms

        https://leetcode.com/problems/count-univalue-subtrees/discuss/67573/My-Concise-JAVA-Solution
        https://leetcode.com/problems/count-univalue-subtrees/discuss/67611/Very-easy-JAVA-solution-post-order-recursion
        """
        def helper(node):
            if not node:
                return True
            l = helper(node.left)
            r = helper(node.right)
            if l and r:
                if node.left and node.left.val != node.val:
                    return False
                if node.right and node.right.val != node.val:
                    return False
                self.count += 1
                return True
            return False
        self.count = 0
        helper(root)
        return self.count

    def countUnivalSubtreesV2(self, root):
        """
        :type root: TreeNode
        :rtype: int

        ACE
        45 ms
        """
        def helper(node):
            if not node:
                return True
            luni = helper(node.left)
            runi = helper(node.right)
            lval = node.left.val if node.left else node.val
            rval = node.right.val if node.right else node.val
            is_uni = luni and runi and lval == node.val == rval
            if is_uni:
                self.count += 1
            return is_uni
        self.count = 0
        helper(root)
        return self.count

    def countUnivalSubtreesV1(self, root):
        """
        :type root: TreeNode
        :rtype: int

        ACE
        45 ms

        define a helper which returns (is_uni, count)
        is_uni determines whether or not we are growing a univalue subtree

        base cases:
        if node is none then helper returns True, zero
        if node is leaf then helper can return True, one
        else we can set lval and rval, defaulting to node.val if either is None
        then we can return helper(left) + helper(right) + 1 if lval == node.val == rval else 0
        """
        def helper(node):
            if not node:
                return True, 0
            luni, lres = helper(node.left)
            runi, rres = helper(node.right)
            lval = node.left.val if node.left else node.val
            rval = node.right.val if node.right else node.val
            is_uni = luni and runi and lval == node.val == rval
            return is_uni, lres + (1 if is_uni else 0) + rres
        return helper(root)[1]

if __name__ == '__main__':
    s = Solution()
    tests = [
        (
            "[5,1,5,5,5,null,5]",
            4
        )
    ]
    for ser, exp in tests:
        tree = deserialize_tree(ser)
        draw_tree(tree)
        res = s.countUnivalSubtrees(tree)
        print(res)
        assert res == exp


from sqlalchemy.orm import class_mapper, ColumnProperty
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import models as mf
from database import Base as Base_from
from database import db_session as db_session_from
from sqlalchemy.sql.schema import Table
import settings

engine_to = create_engine(f"sqlite:///{settings.work_dir}/.report/db.db")
db_session_to = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine_to))

def get_list_classes(module):
    """Retorna a lista de models de um modulo"""
    list_ = []
    for item in dir(module):
        obj = getattr(module, item)
        if hasattr(obj, "__tablename__"):
            list_.append(item)
    return list_

def attribute_names(cls):
    """Retorna os atributos da classe que são do tipo Column"""
    return [prop.key for prop in class_mapper(cls).iterate_properties
        if isinstance(prop, ColumnProperty)]

def run_migrate():
    Base_from.metadata.create_all(bind=engine_to)

    for class_name in get_list_classes(mf):
        class_ = getattr(mf, class_name)
        props = attribute_names(class_)
        items = db_session_from.query(class_).all()
        for item in items:
            new_item = class_()
            for prop in props:
                setattr(new_item, prop, getattr(item, prop))
            db_session_to.add(new_item)
    db_session_to.commit()

    #Copiar dados das tabelas ponte
    conn_from = db_session_from.connection()
    conn_to = db_session_to.connection()
    for item in dir(mf):
        obj = getattr(mf, item)
        if obj.__class__ == Table:
            stm = obj.select()
            res = conn_from.execute(stm).fetchall()
            for item in res:
                cols = [c.name for c in obj.columns]
                stm = obj.insert().values(dict(zip(cols, item)))
                conn_to.execute(stm)
    db_session_to.commit()


import datetime
import dateutil.parser
import xml.etree.ElementTree as ET

class TravelDecorator:
    STATUS_CLASSES = {
        'NIET-MOGELIJK': 'impossible',
        'VOLGENS-PLAN':  'planned',
        'NIEUW':         'new',
        'VERTRAAGD':     'delayed',
        'NIET-OPTIMAAL': 'not-optimal'
    }

    def __init__(self, xml):
        self.xml = xml
        self.root = ET.fromstring(self.xml)

    def decorate(self):
        results = []

        for travel_possibility in self.root.findall('.//ReisMogelijkheid'):
            actual_travel_time      = travel_possibility.find('ActueleReisTijd')
            actual_departure_time   = travel_possibility.find('ActueleVertrekTijd')
            actual_arrival_time     = travel_possibility.find('ActueleAankomstTijd')
            status                  = travel_possibility.find('Status')
            delay                   = travel_possibility.find('VertrekVertraging')

            possibility = {
                'actual_travel_time':     actual_travel_time.text,
                'actual_departure_time':  self.get_time(actual_departure_time.text),
                'actual_arrival_time':    self.get_time(actual_arrival_time.text),
                'status':                 status.text,
                'status_class':           self.STATUS_CLASSES[status.text.strip()]
             }

            if delay is not None:
                possibility['delay'] = delay.text

            results.append(possibility)

        return results

    def get_time(self, time):
        return str(dateutil.parser.parse(time).time())


import gym
import numpy as np
import matplotlib.pyplot as plt
from gym.envs.registration import register
import random as pr

env = gym.make('FrozenLake-v0') #미끄러지는 부분

Q = np.zeros([env.observation_space.n, env.action_space.n])

#learning parameter 설정
learning_rate = 0.85
dis = 0.99
num_episodes = 2000

rList=[]
for i in range(num_episodes):
    #Reset environment and 첫번째 관찰
    state = env.reset()
    rAll = 0
    done = False
    # decaying E-greedy
    e = 1. / ((i // 100) + 1)
    #Q-table learning algorithm
    while not done:
        #액션의 greedy 선택
        action = np.argmax(Q[state, :] + np.random.randn(1, env.action_space.n) / (i + 1))

        # S'의 상태와 보상
        new_state, reward, done,_ = env.step(action)

        #Update
        Q[state,action] = (1-learning_rate)*Q[state,action] + learning_rate*(reward + dis*np.max(Q[new_state,:]))

        rAll += reward
        state = new_state

    rList.append(rAll)

print("Success rate : "+str(sum(rList) / num_episodes))#승률
print("Final Q-Table Values")
print(Q)

plt.bar(range(len(rList)), rList, color="blue")
plt.show()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# plot.py

import os
import numpy as np
import matplotlib.pyplot as plt

import config
import constants
import analyze
from fitness_functions import LaTeX_NAMES as fit_funcnames

from analyze import CASE_NAME, RESULT_DIR, ANALYSIS_DIR, ANALYSIS_PATH, RESULT_PATH

FILENAMES = {
    'config': 'config.pkl',
    'hof': 'hof.pkl',
    'logbook': 'logbook.pkl',
    'lineages': 'lineages.pkl',
    'metadata': 'metadata.pkl',
}

# Utilities
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def close():
    """Close a matplotlib figure window."""
    plt.close()

def _get_task_name(tasks):
    return '[' + ',\ '.join(str(task[1].count('1')) for task in tasks) + ']'

def _get_desc(config, seed=False, num_seeds=False):
    if not seed and not num_seeds:
        raise Exception('Must provide either a single seed number or the '
                        'number of seeds.')
    return (str(config['NGEN']) + '\ generations,\ ' +
            ('{}\ seeds'.format(num_seeds) if num_seeds
             else 'seed\ {}'.format(seed)) + ',\ task\ ' +
            _get_task_name(config['TASKS']) + ',\ population\ size\ '
            + str(config['POPSIZE']))

def _get_correct_trials_axis_label(config):
    return ('$\mathrm{Correct\ trials\ (out\ of\ ' + str(constants.NUM_TRIALS)
            + ')}$')

# Correct counts
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def plot_final_correct(case_name=CASE_NAME, force=False,
                       bins=np.arange(64, 128, 2), fontsize=20, title=''):
    data = analyze.get_final_correct(case_name, force)
    correct_counts, config = data['correct_counts'], data['config']
    fig = plt.figure(figsize=(14, 12))
    plt.hist(correct_counts, bins, normed=True, facecolor='blue', alpha=0.8)
    plt.xlabel(_get_correct_trials_axis_label(config), labelpad=20,
               fontsize=fontsize)
    plt.ylabel('$\mathrm{Normalized\ number\ of\ animats}$', labelpad=20,
               fontsize=fontsize)
    plt.title(title + '$\mathrm{Histogram\ of\ animat\ performance:\ '
              + _get_desc(config, num_seeds=len(correct_counts))
              + '}$', fontsize=fontsize)
    plt.grid(True)
    fig.show()
    return fig, data

# LOD Evolution
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def fitness(logbook, fig=None, fontsize=16, cap=None):
    if fig is None:
        fig = plt.figure()
    x = logbook.select('gen')
    y = logbook.chapters['fitness'].select('max')
    plt.plot(x[:cap], y[:cap])
    plt.xlabel('$\mathrm{Generation}$', labelpad=20, fontsize=fontsize)
    ylabel = ('$\mathrm{' + fit_funcnames[config.FITNESS_FUNCTION] + '}$')
    plt.ylabel(ylabel, labelpad=20, fontsize=fontsize)
    plt.grid(True)
    return fig

def plot_lods(case_name=CASE_NAME, force=False, gen_interval=500, seed=0,
              all_seeds=False, avg=False, fontsize=20, title='',
              chapter='fitness', stat='max'):
    data = analyze.get_lods(case_name, force, gen_interval, seed, all_seeds,
                            chapter, stat)
    lods, config = data['lods'], data['config']
    fig = plt.figure(figsize=(14, 12))
    if avg:
        plt.plot(np.arange(lods.shape[1]) * gen_interval, lods.mean(0))
    else:
        for row in lods:
            plt.plot(np.arange(lods.shape[1]) * gen_interval, row)
    plt.xlabel('$\mathrm{Generation}$', labelpad=20, fontsize=fontsize)
    if chapter == 'correct':
        ylabel = _get_correct_trials_axis_label(config)
    elif chapter == 'fitness':
        ylabel = ('$\mathrm{' + fit_funcnames[config.FITNESS_FUNCTION] + '}$')
    plt.ylabel(ylabel, labelpad=20, fontsize=fontsize)

    plt.title(title + '$\mathrm{' + ('Average\ a' if avg else 'A') +
              'nimat\ fitness:\ ' + _get_desc(config, num_seeds=len(lods))
              + '}$', fontsize=fontsize)
    plt.grid(True)
    fig.show()
    return fig, data


from django.conf.urls.defaults import patterns, include, url

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    #(r'^accounts/', include('registration.backends.default.urls')),
    #(r'^facebook/', include('django_facebook.urls')),
    (r'^fbcanvas/', include('fbcanvas.urls')),
)


from collections import deque

from scipy.ndimage.measurements import label

import matplotlib.pyplot as plt
import numpy as np
import logging as log

class VehicleTracking:
    def __init__(self):
        self.labels_queue = deque()
        self.nlabels = 25
        self.boxes_queue = deque()
        self.nboxes_lists = 40

    def __add_heat(self, heatmap, boxlist):
        # Iterate through list of bboxes
        for box in boxlist:
            # Add += 1 for all pixels inside each bbox
            heatmap[box[0][1]:box[1][1], box[0][0]:box[1][0]] += 1

        # Return updated heatmap
        return heatmap

    def __apply_threshold(self, heatmap, threshold = 40):
        # Zero out pixels below the threshold
        heatmap[heatmap <= threshold] = 0
        # Return thresholded map
        return heatmap

    def __filter_non_continuous(self, labels):
        label_mesh, label_count = labels
        label_mesh = label_mesh.astype(np.uint8)

        new_mesh = np.zeros_like(label_mesh, dtype=np.uint8)
        for label in range(1, label_count + 1):
            tmp_mesh = np.zeros_like(label_mesh, dtype=np.uint8)
            # regardless of label start with 1
            tmp_mesh[label_mesh == label] = 1
            for prev_lab in self.labels_queue:
                # reset all values to one and start adding
                prev_lab[prev_lab > 0] = 1
                tmp_mesh += prev_lab
            log.debug('tmp mesh looks like')
            log.debug(np.max(tmp_mesh))
            log.debug(np.min(tmp_mesh))
            log.debug(np.mean(tmp_mesh))
            if np.max(tmp_mesh) > self.nlabels:
                new_mesh[label_mesh == label] = np.max(new_mesh) + 1
        return new_mesh, np.max(new_mesh)

    def remove_false_positives(self, shape, raw_boxes):
        heatmap = np.zeros(shape, dtype=np.float)
        log.debug(heatmap.shape)
        if len(self.boxes_queue) < self.nboxes_lists:
            self.boxes_queue.append(raw_boxes)
            log.debug('not enough boxes history ' + str(len(self.boxes_queue)))
            return [], heatmap

        log.debug('removing false positives')
        self.boxes_queue.popleft()
        self.boxes_queue.append(raw_boxes)

        for boxlist in self.boxes_queue:
            heatmap = self.__add_heat(heatmap, boxlist)

        heatmap = self.__apply_threshold(heatmap)
        labels = label(heatmap)

        log.debug(labels[0].shape)
        log.debug(np.max(labels[0]))
        log.debug(np.mean(labels[0]))
        log.debug(np.median(labels[0]))

        self.labels_queue.append(labels[0].astype(np.uint8))
        if len(self.labels_queue) > self.nlabels:
            self.labels_queue.popleft()
        labels = self.__filter_non_continuous(labels)

        log.debug('ended with ' + str(labels[1]) + ' cars')
        return labels, heatmap


# -*- coding: utf-8 -*-
import scrapy
from ..items import AmazonItem

class AmazonSpider(scrapy.Spider):
    name = 'Amazon'
    page_number = 2
    allowed_domains = ['amazon.com']
    start_urls = ['https://www.amazon.com/b?ie=UTF8&node=17143709011']

    def parse(self, response):
        items = AmazonItem()

        product_name = response.css('.s-access-title::text').extract()
        product_author = response.css('.a-color-secondary .a-text-normal').css('::text').extract()
        product_price = response.css('.a-price-whole::text').extract()
        product_imagelink = response.css('.cfMarker::attr(src)').extract()

        items['product_name'] = product_name
        items['product_author'] = product_author
        items['product_price'] = product_price
        items['product_imagelink'] = product_imagelink

        yield items

        next_page = 'https://www.amazon.com/s?i=specialty-aps&srs=17143709011&page= ' + str(AmazonSpider.page_number) + ' &qid=1575368837&ref=sr_pg_2'
        if AmazonSpider.page_number <= 10:
            AmazonSpider.page_number +=1
            yield response.follow(next_page, callback = self.parse)


'''
was stuck at

1. wordsearch method. After placing the first peg, i forgot to remove it.

'''

def returnTable(table):
    return [['-' for j in range(len(i))] for i in table]

def returnrc(table):
    L = [[[i, j] for j in range(len(letter))] for i, letter in enumerate(table)]
    return [item for sublist in L for item in sublist]

# [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]

def moveList(table, board, r, c):
    maxrowval = len(board) - 1
    maxcolval = len(board[0]) - 1

    allpossiblemoves = [[r + 1, c], [r, c + 1], [r - 1, c], [r, c - 1]]
    # print allpossiblemoves,maxrowval , maxcolval

    availablemoves = [each for each in allpossiblemoves
                      if min(each[0], each[1]) >= 0 and
                      each[0] <= maxrowval and
                      each[1] <= maxcolval
                      ]
    return availablemoves

##[[0, 0], [2, 1], [1, 2]]

def place(board, r, c):
    board[r][c] = 'X'

def remove(board, r, c):
    board[r][c] = '-'

def printBoard(board):
    print
    "\n\n"
    for each in board:
        print
        each
    print
    "\n\n"

def wordsearch(table, word):
    board = returnTable(table)
    prefix = []

    letterList = returnrc(table)

    for row, col in letterList:

        if table[row][col] == word[0]:
            place(board, row, col)

            if wordsearchHelper(table, board, word[1:], prefix, row, col):
                return True
            remove(board, row, col)
    return False

def wordsearchHelper(table, board, word, prefix, row, col):
    if len(word) == 0:
        return True

    else:
        moves = moveList(table, board, row, col)

        for r, c in moves:
            # choose
            if board[r][c] == '-':
                if word[0] == table[r][c]:
                    place(board, r, c)
                    prefix.append(word[0])

                    # explore
                    if wordsearchHelper(table, board, word[1:], prefix, r, c):
                        return True

                    # unchoose
                    prefix.pop()
                    remove(board, r, c)

if __name__ == '__main__':
    # word = "AAB"
    # table = 	[['A','B','C','E'],['S','F','C','S'],['A','D','E','E']]
    # table = [['C','A','A'],['A','A','A'],['B','C','D']]
    table = [
                ['o', 'a', 'a', 'n'],
                ['e', 't', 'a', 'e'],
                ['i', 'h', 'k', 'r'],
                ['i', 'f', 'l', 'v']
    ]
    # table = [["a"]]
    # wordsearch(table,"ABCCED")
    L = ["oath", "pea", "eat", "rain"]

    # printBoard(table)
    for each in L:
        if wordsearch(table, each):
            print(each)

    # wordsearch(table,word)
# print wordsearch(table,"ABCCED")
# wordsearch(table,"CCEE")
# print wordsearch(table,"CCEEE")
# wordsearch(table,"SFCS")

# print returnrc(table)
# print moveList(table,returnTable(table),2,2)


#Hunter Oliver
#1/28/2018
import matplotlib.pyplot as plt
import pandas as pand
import sys

vehicles = ['Small/Sporty/ Compact/Large Sedan','Sports Car','SUV','Wagon', 'Minivan',
'Pickup','HP', 'City MPG', 'Weight']
df = pand.read_csv(sys.argv[1], skipinitialspace=True, usecols=vehicles)

plt.title("City MPG vs Horse Power for a Lot of Cars")
plt.xlabel("HP")
plt.ylabel("City MPG")
plt.scatter(df.loc[df['Small/Sporty/ Compact/Large Sedan'] == 1, 'HP'],
 df.loc[df['Small/Sporty/ Compact/Large Sedan'] == 1, 'City MPG'], c='g', marker='s')
plt.scatter(df.loc[df['Sports Car'] == 1, 'HP'],
 df.loc[df['Sports Car'] == 1, 'City MPG'], c='k', marker='s')
plt.scatter(df.loc[df['SUV'] == 1, 'HP'],
 df.loc[df['SUV'] == 1, 'City MPG'], c='c', marker = 's')
plt.scatter(df.loc[df['Wagon'] == 1, 'HP'],
 df.loc[df['Wagon'] == 1, 'City MPG'], c='r', marker = 's')
plt.scatter(df.loc[df['Minivan'] == 1, 'HP'],
 df.loc[df['Minivan'] == 1, 'City MPG'], c='m', marker = 's')
plt.scatter(df.loc[df['Pickup'] == 1, 'HP'],
 df.loc[df['Pickup'] == 1, 'City MPG'], c='y', marker = 's')
plt.legend(['Compact', 'Sports Cars', 'SUV', 'Wagon', 'Minivan', 'Pickup'])
plt.savefig(sys.argv[2], Transparent=True)


import requests
import random
import data
import time
import testNet2
import testNet3
import testNet1

limit = 10000
j = 1
while (j<=limit):
    f = open("transactions11.txt", "a+")
    p = random.randint(1, 100)
    print(" <<<< --- START ---- >>>> " + str(j))
    i = random.randint(1, 100)
    t1 = random.choice(testNet2.p1)
    #print(" <<<<<<< --------- " + t1 + " ----- >>>>>>>")
    getAccountId = {"": "%2Fapl", "requestType": "getAccountId", "secretPhrase": str(i)}
    response = requests.request("GET", "http://" + t1 + "/apl",
                                params=getAccountId)
    # response.status_code
    # print(response.json())
    accountReceive = response.json()["accountRS"]
    # print("-------------")
    #print(str("accountReceive = " + accountReceive))
    account = response.json()["account"]
    #print(response.json())
    #print("account = " + account)
    # print("-------------")

    getAccountId = {"": "%2Fapl", "requestType": "getAccountId", "secretPhrase": str(p)}
    response = requests.request("GET",
                                "http://" + t1 + "/apl",
                                params=getAccountId)
    # print(response.json())
    accountSender = response.json()["accountRS"]
    sender = response.json()["account"]
    # print("-------------")
    #print(str("accountSender = " + accountSender))
    # print(str("account = " + sender))
    #print(" PEER  = >> " + t1 + " << = ")
    response = requests.request("POST",
                                "http://" + t1 + "/apl",
                                params=data.sendMoneyFromStandardWalletToVaultWallet(str(accountReceive),
                                                                                random.choice([
                                                                                "2000000000",
                                                                                "3000000000",
                                                                                "4000000000", "5000000000",
                                                                                "6000000000", "7000000000",
                                                                                "8000000000"]),
                                                                                str(p),
                                                                                "400000000",
                                                                                sender))
    #print(response.json())
    f.write(response.json()["transaction"] + "\r")
    # print(" <<<<<<< --------- " + t1 + " ----- >>>>>>>")
    print("----------- END -------------")
    #time.sleep()
    j += 1
f.close()


'''
题目描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数，叫做真分数)，
请将该分数分解为埃及分数。如：8/11 = 1/2+1/5+1/55+1/110。
注：真分数指分子小于分母的分数，分子和分母有可能gcd不为1！
如有多个解，请输出任意一个。
请注意本题含有多组样例输入！

输入描述:
输入一个真分数，String型

输出描述:
输出分解后的string
'''

def egyptFunc():
    while True:
        try:
            a = input().split('/')  # a/b=(1/(q+1)+(a-r)/(b*(q+1)))其中q为商，r为余数
            up = int(a[0])
            down = int(a[1])
            res = ''
            while up != 1:
                if down % (up - 1) == 0:
                    res = res + '1/' + str(down // (up - 1)) + '+'
                    up = 1
                else:
                    q = down // up
                    res = res + '1/' + str(q + 1) + '+'
                    up = up - down % up
                    down = down * (q + 1)
                    if down % up == 0:
                        down = down // up
                        up = 1
            res = res + '1/' + str(down)
            print(res)
        except:
            break

egyptFunc()

def egypt(a,b):
    """a/b=1/(q+1）+(a-r)/b(q+1）"""
    assert a<b
    while b%a != 0:
        q, r = b//a, b%a
        a -= r
        b *= (q+1)
        yield q+1
    yield int(b/a)

# print(list(egypt(2,7)))


import re
import parse
from math import log,floor

Node = dict
Leaf = str

def evalTerm(env,t):
    if type(t)== Node:
        for label in t:
            children = t[label]
            if label == 'Number':
                x = children[0]
                return x
            elif label == 'Variable':
                x = children[0]
                if x in env:
                    return env[x]
                else:
                    print(x + " is unbound.")
                    exit()
            elif label == 'Parens':
                x = children[0]
                f= evalTerm(env,x)
                return   f
            elif label == 'Log':
                x = children[0]
                f = evalTerm(env,x)
                v = log(int(f), 2)
                return v
            elif label == 'Plus':
                x = children[0]
                f1 = evalTerm(env,x)
                x2 = children[1]
                f2 = evalTerm(env, x2)
                return int(f1)+ int(f2)
            elif label == 'Mult':
                x = children[0]
                f1 = evalTerm(env,x)
                x2 = children[1]
                f2 = evalTerm(env, x2)
                return int(f1) * int(f2)

def evalFormula(env, t):
    if type(t)== Node:
        for label in t:
            children = t[label]
            if label == 'Variable':
                x = children[0]
                if x in env:
                    return env[x]
                else:
                    print(x + " is unbound.")
                    exit()
            elif label == 'Parens':
                x = children[0]
                f = evalFormula(env,x)
                return f
            elif label == 'Not':
                x = children[0]
                f = evalFormula(env,x)
                return not f
            elif label == 'Xor':
                x = children[0]
                f1 = evalFormula(env,x)
                x2 = children[1]
                f2 = evalFormula(env, x2)
                return bool(f1) != bool(f2)
            elif label == 'Equals':
                x = children[0]
                f1 = evalFormula(env,x)
                if not f1 is None:
                    x2 = children[1]
                    f2 = evalFormula(env, x2)
                    return bool(f1) == bool(f2)
                else:
                    f1 = evalTerm(env,x)
                    x2 = children[1]
                    f2 = evalTerm(env, x2)
                    return int(f1) == int(f2)
            elif label == 'LessThan':
                x = children[0]
                f1 = evalTerm(env,x)
                x2 = children[1]
                f2 = evalTerm(env, x2)
                return int(f1) < int(f2)
    elif type(t) == Leaf:
        if t == 'True':
            return True
        if t == 'False':
            return False
def execProgram(env, s):
    if type(s) == Node:
        for label in s:
            if label == 'Print':
                children = s[label]
                f = children[0]
                p = children[1]
                v = evalTerm(env, f)
                if v is None:
                    v = evalFormula(env, f)
                (env, o) = execProgram(env, p)
                return (env,[v] + o)
            if label == 'Assign':
                children = s[label]
                x = children[0]['Variable'][0]
                f = children[1]
                p = children[2]
                v = evalTerm(env, f)
                if v is None:
                    v = evalFormula(env, f)
                env[x] = v
                (env1,o1) = execProgram(env, p)
                return (env1,o1)
            if label == 'If':
                children = s[label]
                x = children[0]
                f = children[1]
                p = children[2]
                v = evalTerm(env, x)
                if v is None:
                    v = evalFormula(env, x)
                if v == True:
                    (env1, o1) = execProgram(env, f)
                    (env2, o2) = execProgram(env1, p)
                    return  (env2, o1+o2)
                else:
                    return execProgram(env, p)
            if label == 'While':
                children = s[label]
                x = children[0]
                f = children[1]
                p = children[2]
                v = evalTerm(env, x)
                if v is None:
                    v = evalFormula(env, x)
                if v == False:
                    return execProgram(env, p)
                else:
                    (env1, o1) = execProgram(env , f)
                    (env2, o2) = execProgram(env1, s)
                    return (env2, o1+o2)
    elif type(s) == Leaf:
        if s == 'End':
            return (env, [])

def interpret(s):
    tokens = tokenize(['true', 'false','(',')','not','xor','log', '+','*','print','assign', 'if', 'while',';', ':=','{','}','==','<'], s)
    if not tokens is None:
        r = parse.program(tokens)
        if not r is None:
            (parsedTokens,tmp) =r
            r = execProgram({}, parsedTokens)
            if not r is None:
                (env, output)= r
                return output

def tokenize(terminals, str):
    string='(\s+|'
    for x in terminals:
        if x=="+" or x=="(" or x==")" or x=="*" or x==';' or x=='{' or x=='}':
            string += '\\'
        string += x+'|'
    string = string[:(len(string)-1)]
    string+=')'
    tokens = [t for t in re.split(string, str)]
    return [t for t in tokens if not t.isspace() and not t == ""]


# Hacer un programa el cual consiga el peso de la gente y unidad y transformarla (libras y kilos)
weight = input('How much do you weight? ')
measurement = input('Is this value in kilograms or pounds? ')
answer_in_kilograms = 'kilograms'
answer_in_pounds = 'pounds'

if measurement.lower() == answer_in_kilograms:
    conversion = float(weight) * 2.02
    print(f"Your weight is {conversion} pounds")
elif measurement.lower() == answer_in_pounds:
    conversion_2 = float(weight) / 2.02
    print(f"Your weight is {conversion_2} kilograms ")

# se pone .lower para que lo que ponga el usuario sea del mismo formato que nuestras variables.


#  File: BST_Cipher.py
#  Description: This program uses a binary search tree to encrypt any string with a user inputted encryption key.
#  Student Name: Sahil Shah
#  Student UT EID: sbs2756
#  Course Name: CS 313E
#  Unique Number: 50205
#  Date Created: 16 November 2019
#  Date Last Modified: 18 November 2019

class Node():
    def __init__ (self, data):
        self.data = data
        self.lchild = None
        self.rchild = None

class Tree():

  # the init() function creates the binary search tree with the
  # encryption string. If the encryption string contains any
  # character other than the characters 'a' through 'z' or the
  # space character drop that character.
  def __init__ (self, encrypt_str):

    #Initialize variables
    self.root = None
    self.encry = encrypt_str
    self.encry = self.encry.lower()

    encry_string = ''
    for i in range(len(self.encry)):
      if ('a' <= self.encry[i] and self.encry[i] <= 'z') or self.encry[i] == ' ':
        encry_string += self.encry[i]
    self.encry = encry_string
    for i in range(len(self.encry)):
      self.insert(self.encry[i])

  # the insert() function adds a node containing a character in
  # the binary search tree. If the character already exists, it
  # does not add that character. There are no duplicate characters
  # in the binary search tree.
  def insert (self, ch):

    if self.find(ch) != None:
      return
    new_node = Node(ch)
    if self.root == None:
      self.root = new_node
    else:
      current = self.root
      parent = self.root
      while current != None:
        parent = current
        if ch < current.data:
            current = current.lchild
        else:
            current = current.rchild
      if ch < parent.data:
        parent.lchild = new_node
      else:
        parent.rchild = new_node

  # the search() function will search for a character in the binary
  # search tree and return a string containing a series of lefts
  # (<) and rights (>) needed to reach that character. It will
  # return a blank string if the character does not exist in the tree.
  # It will return * if the character is the root of the tree.
  def search (self, ch):

    if self.root.data == ch:
      return '*'
    elif self.find(ch) == None:
      return ''
    else:
        current=self.root
        in_tree_not = ''
        while current != None and current.data != ch:
          if ch < current.data:
            in_tree_not += '<'
            current = current.lchild
          else:
            in_tree_not += '>'
            current = current.rchild
        return in_tree_not

  # the traverse() function will take string composed of a series of
  # lefts (<) and rights (>) and return the corresponding
  # character in the binary search tree. It will return an empty string
  # if the input parameter does not lead to a valid character in the tree.
  def traverse (self, st):

    current = self.root
    if st[0] == '*':
      return current.data
    for i in range(len(st)):
      if st[i] == '<' and current.lchild != None:
        current = current.lchild
      elif st[i] == '>' and current.rchild != None:
        current = current.rchild
      else:
        return ''
    return current.data

  # the encrypt function will take a string as input parameter, convert
  # it to lower case, and return the encrypted string. It will ignore
  # all digits, punctuation marks, and special characters.
  def encrypt (self, st):

    encrypted_str = ''
    st = st.lower()
    if st == '':
      return encrypted_str
    for i in range(len(st)):
      if st[i] in self.encry:
        encrypted_str += self.search(st[i]) + '!'
      else:
          encrypted_str = st[i] + '!'
    final_encry = encrypted_str[:len(encrypted_str)-1]
    return final_encry

  # the decrypt function will take a string as input parameter, and
  # return the decrypted string.
  def decrypt (self, st):

    decrypted_str = ''
    if st == '':
      return decrypted_str
    operators = ['<','>','*','!']
    st = st.split('!')
    for i in range(len(st)):
      bool = True
      for j in range (len(st[i])):
        if not st[i][j] in operators:
          decrypted_str += st[i][j]
          bool = False
      if bool:
        decrypted_str += self.traverse(st[i])
    return decrypted_str

  #search for value in tree
  def find (self, val):

    current = self.root
    while current != None and current.data != val:
      if val < current.data:
        current = current.lchild
      else:
        current = current.rchild
    return current

def main():

    #User inputs
    encryption_key = str(input('Enter encryption key: '))
    print()
    binary_tree = Tree(encryption_key)
    user_input = str(input('Enter string to be encrypted: '))
    encrypted_string = binary_tree.encrypt(user_input)
    print('Encrypted string: ' + encrypted_string)
    print()
    user_dec_string = str(input('Enter string to be decrypted: '))
    decrypted_string = binary_tree.decrypt(user_dec_string)
    print ('Decrypted string: ' + decrypted_string)

main()


import pytest
import os
from collections import defaultdict

import context

@pytest.fixture
def conf():
    conf = defaultdict(str)
    conf['build.exec_paths'] = []
    return conf

@pytest.fixture
def internal_conf():
    internal_conf = defaultdict(str)

    internal_conf['build.exec_names'] = ['cmake', 'make']
    internal_conf['build.required_artifacts'] = 'model.o'
    internal_conf['build.timeouts.cmake'] = 30
    internal_conf['build.timeouts.make'] = 30
    return internal_conf

@pytest.fixture(scope='session')
def working_dir(tmpdir_factory):
    fn = tmpdir_factory.mktemp('csaopt-model')
    context.copy_folder_contents('app/model/', os.path.join(fn.dirname, 'model'))
    return fn

def test_build(working_dir, conf, internal_conf):
    context.copy_folder_contents('tests/testmodel', os.path.join(working_dir.dirname, 'usersrc'))
    model_proj_path = ''
    model_compiler = context.ModelCompiler(model_proj_path, conf, internal_conf)

    result = model_compiler.build()

    assert result.failed()


# coding: utf-8

# parser for pdf scans inside xml-files from German Bundestag / Opendata for periods 1 - 18
# into the django parliament app
# https://www.bundestag.de/services/opendata

from __future__ import print_function
import os, sys
import django
from django.conf import settings
import re
import requests
import dataset
import datetime
from xml.etree import ElementTree
from urllib.parse import urljoin
# Extract agenda numbers not part of normdatei
from normality import normalize
from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import platform
import zipfile

if platform.node() == "srv-mcc-apsis":
    sys.path.append('/home/muef/tmv/BasicBrowser/')
    data_dir = '/usr/local/apsis/parliamentary_protocols/german_bundestag/plenarprotokolle_xml'
elif platform.node() == 'finn-ThinkPadMCC':
    # local paths
    sys.path.append('/media/Data/MCC/tmv/BasicBrowser/')
    data_dir = '/media/Data/MCC/Parliamentary_protocols/Parliament Germany/Plenarprotokolle'
else:
    # local paths
    sys.path.append('/home/leey/Documents/Data/tmv/BasicBrowser/')
    data_dir = '/home/leey/Documents/Data/Plenarprotokolle'

# imports and settings for django and database
# --------------------------------------------

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BasicBrowser.settings")
# alternatively
#settings.configure(DEBUG=True)
django.setup()

# import from appended path
import parliament.models as pm
from parliament.tasks import do_search
import cities.models as cmodels

from scraper.parsing_utils import dehyphenate, POI, clean_text, correct_pdf_parsing_errors, search_party_names, search_person_party
from scraper.find_person_in_db_pdf import find_person_in_db
from scraper.regular_expressions_global import *

import pprint
pretty_printer = pprint.PrettyPrinter(indent=4)

# ============================================================
# write output to file and terminal

time_stamp = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
output_file = "./parlsessions_pdf_parser_output_" + time_stamp + ".log"
print("log file: {}".format(output_file))

class Logger(object):
    def __init__(self):
        self.terminal = sys.stdout
        self.log = open(output_file, "a")

    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)

    def flush(self):
        #this flush method is needed for python 3 compatibility.
        #this handles the flush command by doing nothing.
        #you might want to specify some extra behavior here.
        pass

class SpeechParser(object):

    def __init__(self, lines, verbosity=0):
        self.lines = lines
        self.line_number = 0
        self.was_chair = True
        self.date = None
        self.verbosity = verbosity
        self.in_session = False
        self.in_header = False
        self.in_poi = False
        self.poi_content = ""
        self.poi_linecounter = 0
        self.chair = False
        self.text = []
        self.pars = []
        self.speaker = None
        self.speaker_party = None
        self.speaker_ortszusatz = None
        self.warnings_counter = 0
        self.tops = ""

    def get_date(self):
        for line in self.lines:
            date_match = DATE.search(line)
            if date_match:
                try:
                    d = int(date_match.group(2))
                    m = int(D_MONTHS[date_match.group(3)])
                    y = int(date_match.group(4))
                    date = datetime.date(y, m, d)
                    self.date = date
                    return

                except ValueError:
                    print("date from manuscript not readable: {}".format(DATE.match(line)))
                    print("group 1: {}".format(DATE.match(line).group(1)))
                    print("group 2: {}".format(DATE.match(line).group(2)))
                    print("group 3: {}".format(DATE.match(line).group(3)))
                    print("group 4: {}".format(DATE.match(line).group(4)))
                    raise ValueError

        print("Parser: Did not find date")
        return None

    def append_text_and_poi(self):
        par = {
            'text': dehyphenate(self.text),
            'pois': []
        }
        for poi_raw in re.split(' [-–—]-? ', self.poi_content):
            poi_obj = POI(poi_raw)
            par['pois'].append(poi_obj)
            if self.verbosity > 0:
                print("interjection: speakers: {}, party: {}, speaker_party: {}, speaker_ortszusatz: {}, type: {},"
                      "\ninterjection text: {}".format(poi_obj.speakers, poi_obj.parties, poi_obj.speaker_party, poi_obj.speaker_ortszusatz, poi_obj.type, poi_obj.poitext))

        self.pars.append(par)
        self.text = []
        self.poi_content = ""

    def emit(self):
        data = {
            'speaker': self.speaker,
            'speaker_party': self.speaker_party,
            'speaker_ortszusatz': self.speaker_ortszusatz,
            'type': 'chair' if self.chair else 'speech',
            'pars': self.pars,
            'agenda': self.tops
        }
        self.was_chair = self.chair
        self.text = []
        self.pars = []
        if self.verbosity > 1:
            print("utterance: {}".format(data))
        return data

    def __iter__(self):

        no_lines = len(self.lines)
        self.line_number = -1

        while self.line_number + 1 < no_lines:

            self.line_number += 1
            line = self.lines[self.line_number].strip()
            if self.verbosity > 1:
                print("- l{l:04d}: ".format(l=self.line_number) + line)

            # Check if in session, session beginning, session ending
            if not self.in_session and BEGIN_MARK.match(line):
                print("= matched begin mark at line {}: {}".format(self.line_number, line))
                self.in_session = True
                self.begin_line = self.line_number
                continue
            if not self.in_session and INCOMPLETE_BEGIN_MARK.match(line):
                print("! warning at line {}: Matched only incomplete begin mark: {}".format(self.line_number, line))
                self.warnings_counter += 1
                self.in_session = True
                self.begin_line = self.line_number

            elif not self.in_session:
                continue

            if DISRUPTION_MARK.match(line):
                continue

            # empty line
            if not len(line):
                continue

            # match repeated mentioning of speaker from header
            if self.speaker:
                speaker = self.speaker.replace('Dr. ', '')
                speaker = speaker.split(" (")[0]
                speaker = speaker.split(", ")[0]
                # print("looking for {}".format(speaker))
                try:
                    SPEAKER_HEADER = re.compile('.{0,30}%s' % speaker)
                    if SPEAKER_HEADER.match(line):
                        if verbosity > 0:
                            print("= matched speaker in header: ", line)
                        continue
                except:
                    pass

            header_match = HEADER_MARK.match(line)
            if header_match is not None:
                if verbosity > 0:
                    print("= matched header: ", line)

                self.in_header = True
                continue

            if self.in_header and self.speaker is not None:
                if line.startswith(self.speaker):
                    if verbosity > 0:
                        print("= matched current speaker in header: {}".format(line))
                    continue
                else:
                    self.in_header = False

            #==== still need this? ====#
            has_stopword = False
            for sw in SPEAKER_STOPWORDS:
                if sw.lower() in line.lower():
                    if self.verbosity > 0:
                        print("= setting stopword flag in line {}: {}".format(self.line_number, sw))
                    has_stopword = True
            #==== still need this? ====#

            #===== testing agendas =====#
            is_top = False
            # new point on the agenda (top - tagesordnungspunkt)
            if TOP_MARK.match(line):
                if verbosity > 0:
                    print("= matched top mark: {}".format(line))
                # add one line after for tops as well
                for k in range(1,3):
                    lines = "\n".join(self.lines[self.line_number:self.line_number+k])
                    lines = dehyphenate(lines, nl=True)
                    self.tops = lines
                is_top = True

            #===== testing agendas =====#

            # match speaker not in interjections
            if not self.in_poi:
                for k in range(1,4):
                    lines = "\n".join(self.lines[self.line_number:self.line_number+k])
                    lines = dehyphenate(lines, nl=True)
                    # print(repr(lines)) # print with escape characters
                    speaker_match = (PRESIDENT.match(lines) or
                                     PARTY_MEMBER_PDF.match(lines) or
                                     STAATSSEKR.match(lines) or
                                     STAATSMINISTER.match(lines) or
                                     WEHRBEAUFTRAGTER.match(lines) or
                                     BUNDESKANZLER.match(lines) or
                                     BEAUFTRAGT.match(lines) or
                                     MINISTER.match(lines) or
                                     BERICHTERSTATTER.match(lines) or
                                     PRIME_MINISTER.match(lines))

                    if speaker_match is not None:
                        if self.verbosity > 0:
                            print("= matched speaker at line {}: {}".format(self.line_number, speaker_match))
                        self.line_number += k - 1
                        break

                if speaker_match is not None:

                    if self.speaker is None and self.text == [] and self.pars == []:
                        pass
                    else:
                        if self.text:
                            par = {
                                'text': dehyphenate(self.text),
                                'pois': []
                            }
                            self.pars.append(par)

                        # emit everything if a new speaker has been identified
                        yield self.emit()

                    role = line.strip().split(' ')[0]
                    self.speaker = speaker_match.group(0).strip(' :')
                    if self.verbosity > 0:
                        print("set new speaker: {}".format(self.speaker))
                    self.speaker_party = search_person_party(line.strip().split(':')[0])
                    if speaker_match.group(2) is not None:
                        try:
                            self.speaker_ortszusatz = REMOVE_BRACKET.match(speaker_match.group(2)).group(1)
                        except AttributeError:
                            pass
                    else:
                        self.speaker_ortszusatz = None
                    self.chair = role in CHAIRS

                    # if a new speaker has been identified, add the remainder of the text of that line to self.text
                    self.text = [':'.join(lines.split(':')[1:])]

                    continue

            # match end mark
            for k in range(1,3):
                lines = "\n".join(self.lines[self.line_number:self.line_number+k])
                lines = dehyphenate(lines)
                if END_MARK.search(lines):
                    print("= matched end mark at line {}: {}".format(self.line_number, lines))
                    self.text.append(lines)
                    par = {
                        'text': dehyphenate(self.text),
                        'pois': []
                    }
                    self.pars.append(par)
                    yield self.emit()
                    return

            # match interjections
            poi_match = POI_MARK.match(line)
            if poi_match is not None:
                self.poi_content = poi_match.group(1)
                self.append_text_and_poi()
                continue

            if not self.in_poi:
                poi_begin = POI_BEGIN.match(line)
                if poi_begin:
                    if verbosity > 1:
                        print("= raised in_poi flag")
                    self.in_poi = True
                    self.poi_content = line
                    self.poi_linecounter = 0
                    continue
            else:
                self.poi_content += "\n" + line
                self.poi_linecounter += 1
                if POI_END.match(line):
                    self.poi_content = dehyphenate(self.poi_content).strip().strip('()')
                    self.append_text_and_poi()
                    if verbosity > 1:
                        print("= matched poi end")
                    self.in_poi = False
                if self.poi_linecounter > 10:
                    print("! Warning: No match of poi end after 10 lines. Going back to normal mode.")
                    self.warnings_counter += 1
                    self.in_poi = False
                    self.text.append(self.poi_content)
                continue

            self.text.append(line)

        print("! Warning: Reached end of file without end mark")
        self.warnings_counter += 1
        yield self.emit()

def file_metadata(filename):
    fname = os.path.basename(filename)
    try:
        return int(fname[:2]), int(fname[2:5])
    except:
        return int(fname[:2]), fname[2:5]

def german_date(str):
    if str is None:
        return None
    return datetime.datetime.strptime(str,"%d.%m.%Y").date()

# ====================================================================
# ========== parse function ==========================================
# ====================================================================

def parse_transcript(file, verbosity=1):

    warnings_counter2 = 0
    if isinstance(file, str):
        print("loading text from {}".format(file))
        try:
            with open(file) as fh:
                content = fh.read()
                text = clean_text(content)
        except UnicodeDecodeError:
            print("Reloading in other encoding (windows-1252)")
            with open(file, encoding="windows-1252") as fh:
                content = fh.read()
                text = clean_text(content)
        filename = file
        wp, session = file_metadata(filename)

    # open file in zip archive
    elif isinstance(file, zipfile.ZipExtFile):
        content = file.read()
        filename = file.name
        if filename.endswith(".xml"):
            root = ElementTree.fromstring(content)
            if verbosity > 0:
                print("loading text from {}".format(filename))

            # display contents of xml file
            if verbosity > 1:
                print("xml root: {}, attributes: {}".format(root.tag, root.attrib))
                for child in root:
                    print("xml child: {}, attributes: {}".format(child.tag, child.attrib))
                    print("xml beginning of text: {}".format(child.text[:100].replace('\n', ' ')))

            wp = int(root.find("WAHLPERIODE").text)
            document_type = root.find("DOKUMENTART").text
            if document_type != "PLENARPROTOKOLL":
                print("Warning: document {} is not tagged as Plenarprotokoll but {}".format(filename, document_type))
                warnings_counter2 += 1
            number = root.find("NR").text
            session = int(number.split("/")[1])
            date = root.find("DATUM").text
            titel = root.find("TITEL").text
            text = clean_text(root.find("TEXT").text)
            text = correct_pdf_parsing_errors(text)
        else:
            print("filetype not xml")
            return 0

    else:
        print("invalid filetype")
        return 0

    base_data = {
        'filename': filename,
        'sitzung': session,
        'wahlperiode': wp
    }

    print("\nParsing transcript: {}/{}, from {}".format(wp, session, filename))
    utterance_counter = 0
    paragraph_counter = 0
    interjection_counter = 0

    # start parsing
    parser = SpeechParser(text.split('\n'), verbosity=verbosity)
    # get_date is not working for all documents
    parser.get_date()
    if isinstance(file, zipfile.ZipExtFile):
        if parser.date != german_date(date):
            print("! Warning: dates do not match")
            warnings_counter2 += 1
            print(parser.date)
            print(date)
            print(german_date(date))

    parl, created = pm.Parl.objects.get_or_create(
        country=cmodels.Country.objects.get(name="Germany"),
        level='N'
    )
    if created and verbosity > 0:
        print("created new object for parliament")

    pp, created = pm.ParlPeriod.objects.get_or_create(
                                    parliament=parl,
                                    n=wp)
    if created and verbosity > 0:
        print("created new object for legislative period")

    doc, created = pm.Document.objects.get_or_create(
        parlperiod=pp,
        doc_type="Plenarprotokoll",
        date=german_date(date),
        sitting=session,
        text_source="updated - from https://www.bundestag.de/service/opendata (scans of pdfs with xml metadata)"
    )
    if created:
        print("created new object for plenary session document")
    doc.save()

    doc.utterance_set.all().delete()

    # parser.__iter__ yields dict with paragraphs + speaker + speaker_party + interjections (poi)
    for contrib in parser:

        if verbosity > 1:
            print("saving utterance: {}".format(contrib))

        # update dictionary
        contrib.update(base_data)

        if contrib['speaker']:
            info_dict = {'wp': wp, 'session': session, 'party': contrib['speaker_party'],
                         'ortszusatz': contrib['speaker_ortszusatz'], 'source_type': 'PDF/SP'}
            per = find_person_in_db(contrib['speaker'], add_info=info_dict, verbosity=verbosity)
        else:
            print("! Warning: No speaker given, not saving the following contribution: {}".format(contrib))
            warnings_counter2 += 1
            continue

        if per is None:
            print("! Warning: Not able to match person, not saving the following contribution: {}".format(contrib))
            warnings_counter2 += 1
            continue

        #===== testing agendas =====#
        if contrib['agenda']:
            tops, created = pm.AgendaItem.objects.get_or_create(
            title = contrib['agenda'],
            document = doc
            )
            tops.save()
        #===== testing agendas =====#

        position = PERSON_POSITION.search(contrib['speaker'])

        if position:
            role_description = position.group(0)

            speaker_role_set = pm.SpeakerRole.objects.filter(alt_names__contains=[role_description])
            if len(speaker_role_set) < 1:
                speaker_role = pm.SpeakerRole(name=role_description, alt_names=[role_description])
                speaker_role.save()
            else:
                speaker_role = speaker_role_set.first()
                if len(speaker_role_set) > 1:
                    print("Warning: several speaker roles matching")

            ut = pm.Utterance(
                document=doc,
                speaker=per,
                speaker_role=speaker_role,
            )
        else:
            ut = pm.Utterance(
                document=doc,
                speaker=per
            )
        try:
            ut.agenda_item = tops
        except UnboundLocalError:
            pass

        ut.save()
        utterance_counter += 1

        for par in contrib['pars']:

            if par['text']:
                para = pm.Paragraph(
                    utterance=ut,
                    text=par['text'],
                    word_count=len(par['text'].split()),
                    char_len=len(par['text'])
                )
                para.save()
                paragraph_counter += 1
            else:
                print("! Warning: Empty paragraph ({})".format(par))
                warnings_counter2 += 1
                for ij in par['pois']:
                    print("poi: {}".format(ij.poitext))
                continue

            for ij in par['pois']:
                if ij.type is None:
                    print("! Warning: Omitting interjection. Interjection type not identified for: {}".format(ij.poitext))
                    warnings_counter2 += 1
                    continue
                interjection = pm.Interjection(
                    paragraph=para,
                    text=ij.poitext,
                    type=ij.type
                )
                interjection.save()
                interjection_counter += 1

                if ij.parties:
                    for party_name in ij.parties.split(':'):
                        party, created = pm.Party.objects.get_or_create(
                            name=party_name
                        )

                        interjection.parties.add(party)
                if ij.speakers:
                    for person in ij.speakers:
                        info_dict = {'wp': wp, 'session': session, 'party': ij.speaker_party,
                                     'ortszusatz': ij.speaker_ortszusatz, 'source_type': 'PDF/SP'}
                        per = find_person_in_db(person, add_info=info_dict, verbosity=verbosity)
                        if per is not None:
                            interjection.persons.add(per)
                        else:
                            print("! Warning: Speaker could not be identified")
                            warnings_counter2 += 1

    if not parser.in_session:
        print("! Error: beginning of session not found")
        return (1, 0)

    print("==================================================")
    print("Summary for {}:".format(filename))
    print("number of utterances: {}".format(utterance_counter))
    print("number of paragraphs: {}".format(paragraph_counter))
    print("number of interjections: {}".format(interjection_counter))
    print("warnings in SpeechParser generator: {}".format(parser.warnings_counter))
    print("warnings in parse_transcript function: {}".format(warnings_counter2))
    print("==================================================")

    if utterance_counter <= 0:
        return (1, 0)
    else:
        return (0, parser.warnings_counter + warnings_counter2)

# =================================================================================================================
# =================================================================================================================

def lines_with_one_character(file):

    if isinstance(file, str):
        # print("loading text from {}".format(file))
        with open(file) as fh:
            text = fh.read()
        text = text.replace("\t", "").split("\n")

    # open file in zip archive
    elif isinstance(file, zipfile.ZipExtFile):
        content = file.read()
        filename = file.name
        if filename.endswith(".xml"):
            root = ElementTree.fromstring(content)
            text = root.find("TEXT").text.replace("\t", "").split("\n")
            # print("loading text from {}".format(filename))
        else:
            print("filetype not xml")
            return None
        file.close()

    text = [line.strip() for line in text if line.strip() != '']
    count = sum([1 for line in text if len(line) == 1])

    return count

# =================================================================================================================

# main execution script
if __name__ == '__main__':

    sys.stdout = Logger()

    # settings for parsing
    delete_additional_persons = False
    delete_all = False
    delete_old = False
    verbosity = 0

    if delete_all:
        print("Deleting all documents, utterances, paragraphs and interjections.")
        pm.Interjection.objects.all().delete()
        pm.Paragraph.objects.all().delete()
        pm.Utterance.objects.all().delete()
        pm.Document.objects.all().delete()
        print("Deletion done.")

    if delete_additional_persons:
        print("Deleting all persons added from protocol parsing.")
        pm.Person.objects.filter(information_source__startswith="from protocol scraping").delete()

    document_counter = 0
    count_errors = 0
    count_warnings_docs = 0
    count_warnings_sum = 0

    wps = range(13, 12, -1)
    sessions = range(1, 2)

    print("start parsing...")
    for wp in wps:
        collection = "pp{wp:02d}-data.zip".format(wp=wp)
        print(collection)

        archive = zipfile.ZipFile(os.path.join(data_dir, collection), 'r')
        print("loading files from {}".format(collection))
        filelist = [fzip.filename for fzip in archive.infolist()]

        for session in sessions:
            filename = "{wp:02d}{s:03d}.xml".format(wp=wp, s=session)
            if filename in filelist:

                if delete_old: # delete old protocol
                    pm.Document.objects.filter(parlperiod__n=wp, sitting=session,
                                               text_source="from https://www.bundestag.de/service/opendata "
                                                           "(scans of pdfs with xml metadata)").delete()

                f = archive.open(filename)
                print(f)
                parser_errors, parser_warnings = parse_transcript(f, verbosity=verbosity)
                count_errors += parser_errors
                if parser_warnings > 0:
                    count_warnings_docs += 1
                    count_warnings_sum += parser_warnings

                document_counter += 1
                f.close()

                f = archive.open(filename)
                print("lines with one character: {}".format(lines_with_one_character(f)))
                print("==================================================\n")

                f.close()
            else:
                print("{} not in archive".format(filename))

        archive.close()

    print("\n==================================================")
    print("Summary for {} documents:".format(document_counter))
    print("Documents with errors: {}".format(count_errors))
    print("Documents with warnings: {}".format(count_warnings_docs))
    print("Sum of all warnings: {}".format(count_warnings_sum))


arra1=["aaa","bbb","ccc","ddd","aaa","bbb","ccc","bbb","bbb","bbb","ccc"]
b = []
unique = []
k=0
for i in range(0,len(arra1)):

    presense=False
    for check in range(0,len(unique)):
        presense=False
        if(arra1[i]==unique[check]):
            presense=True
            break
        if(presense==True):break

    if(presense==False):
        unique.append(arra1[i])
        count=0
        b.append(arra1[i])

        for j in range(i,len(arra1)):

            if(arra1[i]==arra1[j]):
                count=count+1
        b.append(count)

#continue with highest number of occurence of words
print(b)
occur = []
occurword = []
for i in range(1,len(b),2):
    occur.append(b[i])

for i in range(0,len(b),2):
    occurword.append(b[i])

print(occur)
print(occurword)

seq=occur.copy()
seqword=occurword.copy()

for i in range(1, len(seq)):
        j = i
        while j > 0 and seq[j - 1] > seq[j]:
            seq[j - 1], seq[j] = seq[j], seq[j - 1]
            seqword[j - 1], seqword[j] = seqword[j], seqword[j - 1]
            j -= 1
seq.reverse()
seqword.reverse()
print(seq)
print(seqword)

#after merge
aftersort = []
for i in range(0,int((len(b))/2)):
    aftersort.append(seqword[i])
    aftersort.append(seq[i])
print(aftersort)