from collections import defaultdict
import copy
import numpy as np
import operator

from simulators.fires.LatticeForest import LatticeForest
from filters.observe import get_forest_observation, tree_observation_probability

def reachable_states(input_state, tree_object, forest_dimension):
    """
    Efficiently calculate the possible next states with non-zero probability using recursion.

    :param input_state: list of length forest_dimension*forest_dimension where each element indicates the state of the
    corresponding tree in the forest. A 'flat' representation is used by flattening the matrix representing the state of
    trees in the forest using row-major order.
    :param tree_object: a Tree object from the LatticeForest simulator, to calculate the transition probability for
    different scenarios.
    :param forest_dimension: int representing the size of one side of the square LatticeForest.
    :return: a dictionary where the keys are possible next states (as strings) and their corresponding probability.
    """
    num_trees = len(input_state)
    assert num_trees == forest_dimension**2

    healthy, on_fire, burnt = 0, 1, 2

    def generate(reachable, next_state=input_state, element=0, probability=1):

        if element < num_trees:

            if input_state[element] == healthy:
                # if a given element is healthy, find out how many of its neighbors are on fire
                num_neighbors_on_fire = 0

                # unflatten index to (row, col)
                row, col = np.unravel_index(element, (forest_dimension, forest_dimension), order='C')

                # iterate through cardinal directions and re-flatten to check the state value
                for (dr, dc) in [(-1, 0), (+1, 0), (0, +1), (0, -1)]:
                    if 0 <= row+dr < forest_dimension and 0 <= col+dc < forest_dimension:
                        neighbor_index = np.ravel_multi_index([[row+dr], [col+dc]],
                                                              (forest_dimension, forest_dimension),
                                                              order='C')
                        if input_state[np.squeeze(neighbor_index)] == on_fire:
                            num_neighbors_on_fire += 1

                # if there are no neighbors on fire, the tree must remain healthy, so move on to the next element
                if num_neighbors_on_fire == 0:
                    generate(reachable, next_state=next_state, element=element+1, probability=probability)
                    return

                # otherwise, the tree may transition to on fire ...
                modified_state = copy.copy(next_state)
                modified_state[element] = on_fire
                modified_probability = probability*tree_object.dynamics((healthy, num_neighbors_on_fire, on_fire))
                generate(reachable, modified_state, element=element+1, probability=modified_probability)

                # or the tree may remain healthy
                modified_probability = probability*tree_object.dynamics((healthy, num_neighbors_on_fire, healthy))
                generate(reachable, next_state=next_state, element=element+1, probability=modified_probability)
                return

            elif input_state[element] == on_fire:
                # a tree on fire either burns out ...
                modified_state = copy.copy(next_state)
                modified_state[element] = burnt
                modified_probability = probability*tree_object.dynamics((on_fire, -1, burnt))
                generate(reachable, next_state=modified_state, element=element+1, probability=modified_probability)

                # or the tree may remain on fire
                modified_probability = probability*tree_object.dynamics((on_fire, -1, on_fire))
                generate(reachable, next_state=next_state, element=element+1, probability=modified_probability)

            elif input_state[element] == burnt:
                # a burnt tree must remain burnt
                generate(reachable, next_state=next_state, element=element+1, probability=probability)
                return

            else:
                raise Exception('invalid state value encountered')

        else:
            # after iterating through all elements in the state, store the next state and its probability
            state_string = ''.join(str(e) for e in next_state)
            reachable[state_string] = probability
            return

    result = dict()
    generate(result)
    return result

def rbf(belief, observation, tree_object, forest_dimension):
    """
    Function to implement the one-step update for the recursive Bayesian filter.

    :param belief: dictionary representing the current belief, each key is a flat state (string) and the corresponding
    value is the state probability.
    :param observation: a numpy 2D array representing the observation for each tree.
    :param tree_object: a Tree object to simplify implementing the transition probabilities.
    :param forest_dimension: int representing the size of one side of the square LatticeForest.
    :return: dictionary representing the updated belief.
    """
    num_trees = forest_dimension**2

    next_belief = dict()

    # first, apply the dynamics to produce an open-loop belief (no measurement correction)
    dynamics_update = defaultdict(lambda: 0)
    for state_idx in range(3**num_trees):  # iterating through all states will be slow
        current_state = np.base_repr(state_idx, base=3).zfill(num_trees)

        # only consider reachable (non-zero probability) states, to improve speed
        current_state_list = np.array(list(current_state), dtype=int)
        reachable = reachable_states(current_state_list, tree_object, forest_dimension)

        for next_state in reachable:
            dynamics_update[next_state] += reachable[next_state]*belief[current_state]

    # second, apply measurement to correct belief
    normalization = 0
    for state_idx in range(3**num_trees):
        next_state = np.base_repr(state_idx, base=3).zfill(num_trees)

        observation_prob = 1
        for tree_idx in range(num_trees):
            row, col = np.unravel_index(tree_idx, (forest_dimension, forest_dimension), order='C')
            observation_prob *= tree_observation_probability(int(next_state[tree_idx]), observation[row, col])

        next_belief[next_state] = observation_prob*dynamics_update[next_state]
        normalization += next_belief[next_state]

    # normalize belief
    for next_state in next_belief:
        next_belief[next_state] /= normalization

    return next_belief

def run_simulation(sim_object, forest_dimension):
    """
    Run a single simulation with RBF and report the filter accuracy.

    :param sim_object: LatticeForest simulation object.
    :param forest_dimension: int representing the size of one side of the square LatticeForest.
    :return: tuple of (observation accuracy, filter_accuracy), each of which is a list containing the time-history of
    accuracies for the observation and using the RBF, respectively.
    """
    num_trees = np.squeeze(np.prod(sim_object.dims))
    assert num_trees == forest_dimension**2
    tree = sim_object.group[(0, 0)]

    # exact initial belief
    belief = dict()
    dense_state = sim_object.dense_state()
    for state_idx in range(3**num_trees):
        state = np.base_repr(state_idx, base=3).zfill(num_trees)
        belief[state] = 0.0
    state = ''.join([str(e) for e in dense_state.reshape(num_trees, order='C')])
    belief[state] = 1.0

    observation_acc = []
    filter_acc = []

    while not sim_object.end:

        sim_object.update()
        state = sim_object.dense_state()

        obs = get_forest_observation(sim_object)
        obs_acc = np.sum(obs == state)/num_trees

        belief = rbf(belief, obs, tree, forest_dimension)

        # compare maximum likelihood state from RBF to ground truth
        max_likelihood_state = max(belief.items(), key=operator.itemgetter(1))[0]
        max_likelihood_state = np.array(list(max_likelihood_state), dtype=int).reshape((forest_dimension,
                                                                                forest_dimension),
                                                                                order='C')
        f_acc = np.sum(max_likelihood_state == state)/num_trees

        observation_acc.append(obs_acc)
        filter_acc.append(f_acc)

    return observation_acc, filter_acc

if __name__ == '__main__':
    dimension = 3
    sim = LatticeForest(dimension)

    # running the RBF is slow, even for small LatticeForest sizes
    observation, filter = run_simulation(sim, dimension)
    print('median observation accuracy = {0:0.2f}'.format(np.median(observation)))
    print('median filter accuracy = {0:0.2f}'.format(np.median(filter)))


'''
求两个字符串的最长公共子串
'''
# 先生成一个二维列表
def substrings():
    a = "abcdea"
    b = 'abcde'
    lst1 = len(a)
    lst2 = len(b)
    max = 0 # 最大值,默认为0
    p = 0
    record = [[0 for i in range(lst1+1)] for j in range(lst2+1)]
    # print(record)
    for i in range(lst1):
        for j in range(lst2):
            # record[0][i+1] = a[i]
            # record[j+1][0] = b[j]
            # record[0][0] = 0
            if a[i] == b[j]:
                print(i)
                record[j+1][i+1] = record[j][i] + 1
                if record[j+1][i+1] > max:
                    max = record[j+1][i+1]
                    p = i + 1
    print(*record, sep='\n')
    print(a[p-max:p])
    # print(lst.append(*record))

    # print(*record, sep = "\n")
    # print(lst)
if __name__ == '__main__':
    substrings()


import math
from urllib import parse

import scrapy.http

class Query:
    max_price = 999999999
    min_price = 0
    first_price_cap = 12500
    hit_cap = 200

    def __init__(self, response: scrapy.http.Response, hits: int):
        self.response:scrapy.http.Response = response
        self.components = dict(parse.parse_qsl(parse.urlsplit(response.url).query))
        self.price_from: int = self.__get_component_param_as_int('pricefrom')
        self.price_to: int = self.__get_component_param_as_int('priceto')
        self.country: str = self.components.get('cy')
        self.offer: str = self.components.get('offer')
        self.hits: int = hits
        self.has_upper_query: bool = self.__has_upper_query()

    def refine_query(self):
        if self.price_from is None and self.price_to is None:
            self.price_from = self.min_price
            self.price_to = self.first_price_cap
            return self.response.urljoin(f'?offer{self.offer}&cy={self.country}&pricefrom={self.price_from}&priceto={self.price_to}')
        if self.hits > self.hit_cap:
            return self.__refine_lower_query()
        return self.__refine_upper_query()

    def __has_upper_query(self):
        return False if self.price_to is None or self.price_to == self.max_price else True

    def __replace_param_in_url(self, url, param, old_value, new_value):
        return url.replace(f'{param}={old_value}', f'{param}={new_value}')

    def __refine_lower_query(self):
        price_range = self.price_to - self.price_from
        divider = self.__get_divider(price_range)
        new_price_to = math.floor((self.price_from + self.price_to) / divider)
        return self.__replace_param_in_url(self.response.url, 'priceto', self.price_to, new_price_to)

    def __refine_upper_query(self):
        new_price_from = self.price_to + 1
        new_price_to = self.max_price
        new_url = self.__replace_param_in_url(self.response.url, 'pricefrom', self.price_from, new_price_from)
        new_url = self.__replace_param_in_url(new_url, 'priceto', self.price_to, new_price_to)
        return new_url

    def __get_component_param_as_int(self, param: str):
        query_param = self.components.get(param)
        return None if query_param is None else int(query_param)

    def __get_divider(self, price_range: int):
        if price_range > 500000:
            return 8
        if price_range > 100000:
            return 4
        return 2


file=open("通话内容1.csv","r",encoding="gbk") #原文件“通话内容1.csv”为gbk编码
file1=open("通话内容.csv","w",encoding="utf-8")

Group=["单位","低保","居民","灵活就业","特困","未参保","学生","药店/医院","职工"]

line=file.readline()
file1.write(line) #每一行后面都有换行符，故不加
while True:
    line=file.readline()
    if not line: break
    temp=line.split(",")

    if temp[0] in Group:
        if temp[1][0:1]!=chr(34):
            file1.write(line)
        elif temp[1][0:1]==chr(34) and temp[1][-2:-1]==chr(34):
            file1.write(line[0:])

file.close()
file1.close()


import collections

N = int(input())
A = list(map(int, input().split()))
c = collections.Counter(A)
c = dict(c)

ans = 0
for i in range(N):
    c[A[i]] -= 1
    ans += (N - i - 1) - c[A[i]]
print(ans)


from pydantic import BaseModel
from extractors.util.spacy import SpacySingleton
import re

INPUT_EXAMPLE = {
    "text": "Today is 04.11.2022. Yesterday was 03/11/2022. Tomorrow is 05-11-2022. Day after tomorrow is 6 Nov 2022.",
    "spacyTokenizer": "en_core_web_sm",
}

class DateExtractionModel(BaseModel):
    text: str
    spacyTokenizer: str = "en_core_web_sm"

    class Config:
        schema_extra = {"example": INPUT_EXAMPLE}

def date_extraction(request: DateExtractionModel):
    """Detects dates in a text and returns them in a list."""

    text = request.text
    nlp = SpacySingleton.get_nlp(request.spacyTokenizer)
    doc = nlp(text)
    regex = re.compile(
        r"(?:[0-9]{1,2}|[0-9]{4}|Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)[\/\. -]{1}(?:[0-9]{1,2}|Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)[,\/\. -]{1}(?:[0-9]{2,4})"
    )

    dates = []
    for match in regex.finditer(text):
        start, end = match.span()
        span = doc.char_span(start, end, alignment_mode="expand")
        dates.append(["date", span.start, span.end])

    return {"dates": dates}


#
# @lc app=leetcode id=206 lang=python3
#
# [206] Reverse Linked List
#
# https://leetcode.com/problems/reverse-linked-list/description/
#
# algorithms
# Easy (60.59%)
# Likes:    4008
# Dislikes: 84
# Total Accepted:    918.7K
# Total Submissions: 1.5M
# Testcase Example:  '[1,2,3,4,5]'
#
# Reverse a singly linked list.
#
# Example:
#
#
# Input: 1->2->3->4->5->NULL
# Output: 5->4->3->2->1->NULL
#
#
# Follow up:
#
# A linked list can be reversed either iteratively or recursively. Could you
# implement both?
#
#

# @lc code=start
# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head
        cur = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return cur

    def reverseList(self, head: ListNode) -> ListNode:
        if head is None:
            return
        pre = None
        cur = head
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

# @lc code=end


#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys, os, logging, traceback, time
from PIL import Image,ImageDraw,ImageChops

import setting as ss
import owm, datedisp, garbagecal, googlecal, train
picdir, libdir, srcdir = ss.picdir, ss.libdir, ss.srcdir
logging.basicConfig(level=logging.DEBUG)

from waveshare_epd import epd7in5b_HD

try:
    epd = epd7in5b_HD.EPD()

    logging.info("Drawing ...")

    imgBlk = Image.new('1', (ss.epdWid, ss.epdHei), 255)
    imgRed = Image.new('1', (ss.epdWid, ss.epdHei), 255)
    dr_imgBlk = ImageDraw.Draw(imgBlk)
    dr_imgRed = ImageDraw.Draw(imgRed)

    # --- Date display ------------------
    dr_imgBlk, dr_imgRed = datedisp.draw(dr_imgBlk, dr_imgRed)

    # --- Weather Info ------------------
    owmdata = owm.getOWMdata()
    dr_imgBlk, dr_imgRed = owm.draw(dr_imgBlk, dr_imgRed, owmdata)

    # --- Garbage Info ------------------
    dr_imgBlk, dr_imgRed = garbagecal.draw(dr_imgBlk, dr_imgRed)

    # --- Google Calender ------------------
    dr_imgBlk, dr_imgRed = googlecal.draw(dr_imgBlk, dr_imgRed)

    # --- Train info ------------------
    if ss.visitormode:
        dr_imgBlk, dr_imgRed = train.draw(dr_imgBlk, dr_imgRed)

    # - Wi-Fi QR code ---------------------
    if ss.visitormode:
        qrcode = Image.open(os.path.join(picdir, 'wifi.bmp'))
        imgBlk.paste(qrcode, (700, 250))

    # - DEBUG img export ----------
    imgRGB = Image.new('RGB', (ss.epdWid, ss.epdHei), (255, 255, 255))

    imgBlkInv = ImageChops.invert(imgBlk)
    imgRedInv = ImageChops.invert(imgRed)
    imgRGB.paste(Image.new('RGB', (ss.epdWid, ss.epdHei), (0, 0, 0)), (0, 0), imgBlkInv)
    imgRGB.paste(Image.new('RGB', (ss.epdWid, ss.epdHei), (230, 0, 51)), (0, 0), imgRedInv)

    imgRGB.save('img.bmp')

    # - Display Update ----------
    logging.info("init and Clear")
    epd.init()
    epd.Clear()

    epd.display(epd.getbuffer(imgBlk),epd.getbuffer(imgRed))
    time.sleep(2)

    logging.info("Goto Sleep...")
    epd.sleep()

except IOError as e:
    logging.info(e)

except KeyboardInterrupt:
    logging.info("ctrl + c:")
    epd7in5b_HD.epdconfig.module_exit()
    exit()


# https://www.acmicpc.net/problem/25185
import sys
from collections import defaultdict

input = sys.stdin.readline
T = int(input())
for t in range(T):
    arr = sorted(list(map(str, input().split())))
    if arr[0] == arr[1] and arr[2] == arr[3]:
        print(":)")
        continue
    dic = defaultdict(list)
    for i in arr:
        dic[i[1]].append(int(i[0]))
    bol = False
    for i in dic.values():
        if len(i) >= 3:
            stack_one, stack_two = [i[0]], [i[0]]
            for j in range(1, len(i)):
                if i[j] != stack_one[-1]:
                    if i[j] - stack_one[-1] != 1:
                        stack_one.clear()
                    stack_one.append(i[j])
                if i[j] != stack_two[-1]:
                    stack_two.clear()
                stack_two.append(i[j])
                if len(stack_one) == 3 or len(stack_two) == 3:
                    bol = True
                    print(":)")
                    break
            if bol:
                break
    if not bol:
        print(":(")


from sklearn.cluster import KMeans
from sklearn.mixture import GaussianMixture
import sklearn.metrics as metrics
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

dataset = pd.read_csv("iris.csv")

X = dataset.iloc[:, :-1]

label = {'Iris-setosa': 0,'Iris-versicolor': 1, 'Iris-virginica': 2}

y = [label[c] for c in dataset.iloc[:, -1]]

plt.figure(figsize=(14,7))
colormap=np.array(['red','lime','black'])

# REAL PLOT
plt.subplot(1,3,1)
plt.title('Real')
plt.scatter(X.Petal_Length,X.Petal_Width,c=colormap[y])

# K-PLOT
model=KMeans(n_clusters=3, random_state=0).fit(X)
plt.subplot(1,3,2)
plt.title('KMeans')
plt.scatter(X.Petal_Length,X.Petal_Width,c=colormap[model.labels_])

# GMM PLOT
gmm=GaussianMixture(n_components=3, random_state=0).fit(X)
y_cluster_gmm=gmm.predict(X)
plt.subplot(1,3,3)
plt.title('GMM Classification')
plt.scatter(X.Petal_Length,X.Petal_Width,c=colormap[y_cluster_gmm])


import tkinter as tk

class Konstanta():
    def __init__(self, stevilo):
        self.stevilo = stevilo

#v mainu VRSTICE, STOLPCI in BOMBE niso objekti, ampak stevila
IME = 'Daniel'
VRSTICE = Konstanta(15)
STOLPCI = Konstanta(15)
BOMBE = Konstanta(0)

class Startno_okno():

    def __init__(self):

        self.ime = IME

        #okno
        self.okno = tk.Tk()
        self.okno.title('Minolovec')

        #razdeljeno okno na tri dele
        self.cist_zgoraj = tk.Frame(self.okno)
        self.zgoraj = tk.Frame(self.okno)
        self.spodaj = tk.Frame(self.okno)
        self.cist_zgoraj.grid(row=1, column=1)
        self.zgoraj.grid(row=2, column=1)
        self.spodaj.grid(row=3, column=1)

        #definirani napisi
        pri='Privzete vrednosti so {}, {} in 15% zmnozka.'.format(VRSTICE.stevilo, STOLPCI.stevilo)
        self.napis_privzeto = tk.Label(self.cist_zgoraj, text=pri, fg='grey')
        self.napis_vhod_vrstice = tk.Label(self.zgoraj, text='Število vrstic: ')
        self.napis_vhod_stolpci = tk.Label(self.zgoraj, text='Število stolpcev: ')
        self.napis_vhod_bombe = tk.Label(self.zgoraj, text='Število bomb: ')
        self.napis_vhod_ime = tk.Label(self.zgoraj, text='Vaše ime: ')

        #definirani vhodi
        self.vhod_ime = tk.Entry(self.zgoraj)
        self.vhod_ime.insert(0, self.ime)
        self.vhod_vrstice = tk.Entry(self.zgoraj)
        self.vhod_stolpci = tk.Entry(self.zgoraj)
        self.vhod_bombe = tk.Entry(self.zgoraj)

        #zgornji del
        self.napis_privzeto.grid(row=1, column=1)
        self.napis_vhod_ime.grid(row=1, column=1)
        self.napis_vhod_vrstice.grid(row=2, column=1)
        self.napis_vhod_stolpci.grid(row=3, column=1)
        self.napis_vhod_bombe.grid(row=5, column=1)
        self.vhod_ime.grid(row=1, column=2)
        self.vhod_vrstice.grid(row=2, column=2)
        self.vhod_stolpci.grid(row=3, column=2)
        self.vhod_bombe.grid(row=5, column=2)

        #priporoci
        self.priporoci_gumb = tk.Button(self.spodaj, text='priporoči število bomb', command=self.priporoci)
        self.priporoci_gumb.grid(row=2, column=1)

        #prazna vrstica
        tk.Label().grid(row=5, column=1)

        #opozorila
        self.opozorilo = tk.Label(self.spodaj, text='', fg='red')

        #hvala
        self.hvala = tk.Label(self.spodaj, text='')

        #OK
        self.ok_button = tk.Button(self.okno, text='OK', command=self.ok)
        self.ok_button.grid(row=6, column=1)

        self.okno.mainloop()

    def preveri(self):
        vrstice = self.vhod_vrstice.get()
        stolpci = self.vhod_stolpci.get()
        bombe = self.vhod_bombe.get()
        if vrstice == '':
            vrstice = str(VRSTICE.stevilo)
        if stolpci == '':
            stolpci = str(STOLPCI.stevilo)
        if bombe == '':
            bombe = str(BOMBE.stevilo)
        vse = vrstice + stolpci + bombe
        if self.preveri_digit(vse):
            if self.preveri_stevilo_bomb(vrstice, stolpci, bombe):
                if self.preveri_velikost(vrstice, stolpci):
                    VRSTICE.stevilo = int(vrstice)
                    STOLPCI.stevilo = int(stolpci)
                    BOMBE.stevilo = int(bombe)
                    self.opozorilo.config(text='')
                    self.hvala.config(text='Hvala.')
                    self.hvala.grid(row=3, column=1)
                    return True
        return False

    def preveri_digit(self, vse):
        if not vse.isdigit():
            self.napisi_opozorilo('digit')
            return False
        return True

    def preveri_stevilo_bomb(self, vrstice, stolpci, bombe):
        if int(vrstice) * int(stolpci) < int(bombe):
            self.napisi_opozorilo('bombe')
            return False
        return True

    def preveri_velikost(self, vrstice, stolpci):
        if int(vrstice) < 5 or int(vrstice) > 25:
            self.napisi_opozorilo('vrstice')
            return False
        if int(stolpci) < 5 or int(stolpci) > 25:
            self.napisi_opozorilo('stolpci')
            return False
        return True

    def napisi_opozorilo(self, thing):
        if thing == 'digit':
            self.opozorilo.config(text='Prosim, vpišite le naravna števila ali pustite prazno.')
        elif thing == 'bombe':
            self.opozorilo.config(text='Število bomb presega število polj.', fg='red')
        elif thing == 'vrstice':
            self.opozorilo.config(text='Število vrstic naj bo vsaj 5 in manjše ali enako 25.')
        else:
            self.opozorilo.config(text='Število stolpcev naj bo vsaj 5 in manjše ali enako 25.')
        self.opozorilo.grid(row=3, column=1)
        self.hvala.config(text='')

    def priporoci(self):
        self.preveri()
        if self.preveri():
            vrstice = VRSTICE.stevilo
            stolpci = STOLPCI.stevilo
            if self.vhod_vrstice.get() != '':
                vrstice = int(self.vhod_vrstice.get())
            if self.vhod_stolpci.get() != '':
                stolpci = int(self.vhod_stolpci.get())
            priporocilo = (int(vrstice * stolpci * 0.15))
            napis_priporocilo_bombe = tk.Label(self.spodaj, text='priporočeno število bomb: {}'.format(priporocilo))
            napis_priporocilo_bombe.grid(row=1, column=1)
            BOMBE.stevilo = priporocilo

    def ok(self):
        self.name = self.vhod_ime.get()
        if len(self.name) > 0:
            self.ime = self.name[0].upper() + self.name[1:]
        self.preveri()
        if self.preveri():
            if BOMBE.stevilo == 0:
                BOMBE.stevilo = int(VRSTICE.stevilo * STOLPCI.stevilo * 0.15)
            self.hvala.config(text='Hvala! ;)')
            self.hvala.grid(row=3, column=1)
            print('Izbrano ime: ', self.ime)
            print('Izbrano stevilo vrstic: ', VRSTICE.stevilo)
            print('Izbrano stevilo stolpcev: ', STOLPCI.stevilo)
            print('Izbrano stevilo bomb: ', BOMBE.stevilo)
            self.okno.destroy()


from time import sleep
import os
import rclpy                                     # ROS2 Python Client Library
from rclpy.node import Node                      # ROS2 Node
from sensor_msgs.msg import Joy                  # ROS2 standard Joy Message
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
from pydub import AudioSegment
from pydub.playback import play
import can
import RPi.GPIO as GPIO
import math

class FixedPosition(Node):

    mode = 0  # 0: Null, 1: Relative Position Control, 2: Aboslute Position Control, 3: Velocity Control, 4: Torque Control
    state = 7  # 0: Null, 5: Emergency Stop, 6: Clear Alarm, 7: Disable, 8: Enable

    motors_x = 0
    motors_y = 0
    left_motor_param = 0
    right_motor_param = 0

    state_enable = [False, 0, 0]  # [state_enable, previous_button_pressed, button_pressed]
    state_emerge = 0

    max_speed = 300
    twist_ratio = 0.5

    sleep_time = 0.02

    air_pump = 22
    air_valve = 23
    ac_input = 27

    axis_state = [0, 0]

    valve_state = [False, 0, 0]

    arm_enable = "1\n"
    arm_disable = "2\n"
    arm_down = "3\n"
    arm_up = "4\n"

    def __init__(self,name):
        super().__init__(name)
        # self.hillside = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/hillside.mp3', format='mp3')
        self.initialized = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Initialized.mp3', format='mp3')
        self.enabled = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Enabled.mp3', format='mp3')
        # self.disabled = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Disabled.mp3', format='mp3')
        # self.emergency = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/EmergencyStop.mp3', format='mp3')
        self.stopped = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Stopped.mp3', format='mp3')
        # self.fence = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Fence.mp3', format='mp3')
        # self.stairs = AudioSegment.from_file('/home/skippy/Sundries-Wiper/src/wheel_motors/wheel_motors/audio/Stairs.mp3', format='mp3')
        self.get_logger().info("Audio loaded.")

        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.air_pump, GPIO.OUT)
        GPIO.setup(self.air_valve, GPIO.OUT)
        GPIO.setup(self.ac_input, GPIO.IN)
        self.get_logger().info("Air pump and valve initialized.")

        self.rs485_1 = modbus_rtu.RtuMaster(serial.Serial(port="/dev/ttySC0", baudrate=115200, bytesize=8, parity='N', stopbits=1, xonxoff=0))
        self.rs485_1.set_timeout(0.5)
        self.rs485_1.set_verbose(True)
        self.get_logger().info("RS485-1 initialized.")
        sleep(1)
        self.esc_clear_alarm()
        self.esc_disable()
        self.esc_position_control()
        self.get_logger().info("ESC initialized.")

        self.can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan')
        self.platform_raise = can.Message(arbitration_id=0x00000100, data=[0xf6, 0x00, 0x03, 0xe8, 0x0f, 0xa0, 0x00, 0x6b], is_extended_id=True)
        self.platform_lower = can.Message(arbitration_id=0x00000100, data=[0xf6, 0x01, 0x03, 0xe8, 0x0f, 0xa0, 0x00, 0x6b], is_extended_id=True)
        self.platform_stop = can.Message(arbitration_id=0x00000100, data=[0xf6, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x6b], is_extended_id=True)
        self.get_logger().info("CAN initialized.")

        self.arduino = serial.Serial('/dev/tty_ARM', 9600, timeout=0.1)
        self.get_logger().info("Arduino initialized.")

        self.sub_joy = self.create_subscription(
            Joy,
            "joy",
            self.joy_recv,
            10)

    def joy_recv(self,msg):
        input = {
            'left_joy_x'              : -msg.axes[0]     ,
            'left_joy_y'              :  msg.axes[1]     ,
            'right_joy_x'             : -msg.axes[2]     ,
            'right_joy_y'             :  msg.axes[3]     ,
            'dpad_x'                  : -msg.axes[6]     ,
            'dpad_y'                  :  msg.axes[7]     ,
            'left_shoulder_button'    :  msg.buttons[6]  ,
            'right_shoulder_button'   :  msg.buttons[7]  ,
            'left_shoulder_button_2'  :  msg.buttons[8]  ,
            'right_shoulder_button_2' :  msg.buttons[9]  ,
            'a_button'                :  msg.buttons[0]  ,
            'b_button'                :  msg.buttons[1]  ,
            'x_button'                :  msg.buttons[3]  ,
            'y_button'                :  msg.buttons[4]  ,
            'select_button'           :  msg.buttons[10]  ,
            'start_button'            :  msg.buttons[11]  ,
            'xbox_button'             :  msg.buttons[12]  ,
            'left_joy_button'         :  msg.buttons[13]  ,
            'right_joy_button'        :  msg.buttons[14]
        }
        self.input_processor(input)

    def esc_clear_alarm(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=6)

    def esc_emergency_stop(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=5)

    def esc_enable(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=8)

    def esc_disable(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=7)

    def esc_torque_control(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200d), output_value=4)

    def esc_velocity_control(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200d), output_value=3)

    def esc_position_control(self):
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200d), output_value=1)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200f), output_value=0)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x2080), output_value=1500)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x2081), output_value=1500)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x2082), output_value=1500)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x2083), output_value=1500)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x208E), output_value=20)
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x208F), output_value=20)

    def esc_motor_velocity(self, left_target, right_target):
        self.rs485_1.execute(1, cst.WRITE_MULTIPLE_REGISTERS, int(0x2088), output_value=[left_target, -right_target])

    def esc_motor_position(self, left_target, right_target):
        left_regs = self.number_seprate(left_target)
        right_regs = self.number_seprate(-right_target)
        self.rs485_1.execute(1, cst.WRITE_MULTIPLE_REGISTERS, int(0x208A), output_value=[left_regs[0], left_regs[1], right_regs[0], right_regs[1]])
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=int(0x11))
        self.rs485_1.execute(1, cst.WRITE_SINGLE_REGISTER, int(0x200e), output_value=int(0x12))

    def number_seprate(self, number):
        bytes_rep = number.to_bytes(4, byteorder='big', signed=True)
        high_reg = int.from_bytes(bytes_rep[:2], byteorder='big', signed=True)
        low_reg = int.from_bytes(bytes_rep[2:], byteorder='big', signed=True)
        return [high_reg, low_reg]

    def move_straight(self, distance):
        pulses = int(distance / (math.pi * 0.107) * 1024)
        self.esc_motor_position(pulses, pulses)

    def turn(self, angle):
        pulses = int(angle / 360 * (0.365 * math.pi / (math.pi * 0.107) * 1024))
        self.esc_motor_position(pulses, -pulses)

    def input_processor(self,input):
        self.state_emerge = input['left_shoulder_button']
        if self.state_emerge == 1:
            self.esc_emergency_stop()
            self.state_enable[0] = False
            play(self.emergency)
            self.get_logger().info("Emergency Stop")
        else:
            self.state_enable[1] = self.state_enable[2]
            self.state_enable[2] = input['right_shoulder_button']
            if self.state_enable[1] == 0 and self.state_enable[2] == 1:
                self.state_enable[0] = not self.state_enable[0]
                if self.state_enable[0] == True:
                    self.esc_clear_alarm()
                    self.esc_position_control()
                    self.esc_enable()
                    self.get_logger().info("Motors Enabled")
                    play(self.enabled)
                else:
                    self.esc_clear_alarm()
                    self.esc_position_control()
                    self.esc_disable()
                    self.get_logger().info("Motors Disabled")
                    play(self.stopped)

            if self.state_enable[0] == True:
                if input['dpad_x'] == -1:
                    # self.move_straight(3)
                    # sleep(20)
                    self.turn(360)
                    sleep(20)
                    self.esc_disable()
                    # self.move_straight(3)
                    # sleep(20)
                    # self.arduino.write(self.arm_enable.encode())
                    # self.arduino.write(self.arm_down.encode())
                    # sleep(20)
                    # GPIO.output(self.air_pump, GPIO.HIGH)
                    # sleep(7)
                    # GPIO.output(self.air_pump, GPIO.LOW)
                    # sleep(1)
                    # self.arduino.write(self.arm_up.encode())
                    # sleep(20)
                    # self.arduino.write(self.arm_disable.encode())
                    # GPIO.output(self.air_valve, GPIO.HIGH)
                    # sleep(1)
                    # GPIO.output(self.air_valve, GPIO.LOW)

def main(args=None):
    rclpy.init(args=args)
    node = FixedPosition('fixed_position')
    rclpy.spin(node)
    node.destory_node()
    rclpy.shutdown()


# WARNING! NEVER TESTED!!

import os
from functools import partial

import numpy as np
import torch
from torch.nn.utils import clip_grad_norm_

import allrank.models.metrics as metrics_module
from allrank.data.dataset_loading import PADDED_Y_VALUE
from allrank.models.model_utils import get_num_params, log_num_params
from allrank.training.early_stop import EarlyStop
from allrank.utils.tensorboard_utils import TensorboardSummaryWriter

from typing import Tuple, Dict, List, Generator

from torch.utils.data.dataloader import DataLoader

import allrank.models.losses as losses
from allrank.config import Config
from allrank.data.dataset_loading import LibSVMDataset
from allrank.models.metrics import ndcg, dcg
from allrank.models.model import LTRModel
from allrank.models.model_utils import get_torch_device

def loss_batch(model, loss_func, xb, yb, indices, gradient_clipping_norm, opt=None):
    mask = (yb == PADDED_Y_VALUE)
    loss = loss_func(model(xb, mask, indices), yb)

    if opt is not None:
        loss.backward()
        if gradient_clipping_norm:
            clip_grad_norm_(model.parameters(), gradient_clipping_norm)
        opt.step()
        opt.zero_grad()

    return loss.item(), len(xb)

def metric_on_batch(metric, model, xb, yb, indices):
    mask = (yb == PADDED_Y_VALUE)
    return metric(model.score(xb, mask, indices), yb)

def metric_on_epoch(metric, model, dl, dev):
    metric_values = torch.mean(
        torch.cat(
            [metric_on_batch(metric, model, xb.to(device=dev), yb.to(device=dev), indices.to(device=dev))
             for xb, yb, indices in dl]
        ), dim=0
    ).cpu().numpy()
    return metric_values

def compute_metrics(metrics, model, dl, dev):
    metric_values_dict = {}
    for metric_name, ats in metrics.items():
        metric_func = getattr(metrics_module, metric_name)
        metric_func_with_ats = partial(metric_func, ats=ats)
        metrics_values = metric_on_epoch(metric_func_with_ats, model, dl, dev)
        metrics_names = ["{metric_name}_{at}".format(metric_name=metric_name, at=at) for at in ats]
        metric_values_dict.update(dict(zip(metrics_names, metrics_values)))

    return metric_values_dict

def epoch_summary(epoch, train_loss, val_loss, train_metrics, val_metrics):
    summary = "Epoch : {epoch} Train loss: {train_loss} Val loss: {val_loss}".format(
        epoch=epoch, train_loss=train_loss, val_loss=val_loss)
    for metric_name, metric_value in train_metrics.items():
        summary += " Train {metric_name} {metric_value}".format(
            metric_name=metric_name, metric_value=metric_value)

    for metric_name, metric_value in val_metrics.items():
        summary += " Val {metric_name} {metric_value}".format(
            metric_name=metric_name, metric_value=metric_value)

    return summary

def get_current_lr(optimizer):
    for param_group in optimizer.param_groups:
        return param_group["lr"]

def fit(epochs, model, loss_func, optimizer, scheduler, train_dl, valid_dl, config,
        gradient_clipping_norm, early_stopping_patience, device, output_dir=None, tensorboard_output_path=None):

    if tensorboard_output_path is not None:
        tensorboard_summary_writer = TensorboardSummaryWriter(tensorboard_output_path)

    num_params = get_num_params(model)
    log_num_params(num_params)

    early_stop = EarlyStop(early_stopping_patience)

    for epoch in range(epochs):

        model.train()
        # xb dim: [batch_size, slate_length, embedding_dim]
        # yb dim: [batch_size, slate_length]

        train_losses, train_nums = zip(
            *[loss_batch(model, loss_func, xb.to(device=device), yb.to(device=device), indices.to(device=device),
                         gradient_clipping_norm, optimizer) for
              xb, yb, indices in train_dl])
        train_loss = np.sum(np.multiply(train_losses, train_nums)) / np.sum(train_nums)
        train_metrics = compute_metrics(config.metrics, model, train_dl, device)

        model.eval()
        with torch.no_grad():
            val_losses, val_nums = zip(
                *[loss_batch(model, loss_func, xb.to(device=device), yb.to(device=device), indices.to(device=device),
                             gradient_clipping_norm) for
                  xb, yb, indices in valid_dl])
            val_metrics = compute_metrics(config.metrics, model, valid_dl, device)

        val_loss = np.sum(np.multiply(val_losses, val_nums)) / np.sum(val_nums)

        if tensorboard_output_path is not None:
            tensorboard_metrics_dict = {("train", "loss"): train_loss, ("val", "loss"): val_loss}
            train_metrics_to_tb = {("train", name): value for name, value in train_metrics.items()}
            tensorboard_metrics_dict.update(train_metrics_to_tb)
            val_metrics_to_tb = {("val", name): value for name, value in val_metrics.items()}
            tensorboard_metrics_dict.update(val_metrics_to_tb)
            tensorboard_metrics_dict.update({("train", "lr"): get_current_lr(optimizer)})
            tensorboard_summary_writer.save_to_tensorboard(tensorboard_metrics_dict, epoch)

        current_val_metric_value = val_metrics.get(config.val_metric)
        if scheduler:
            if type(scheduler) == torch.optim.lr_scheduler.ReduceLROnPlateau:
                args = [val_metrics[config.val_metric]]
                scheduler.step(*args)
            else:
                scheduler.step()

        early_stop.step(current_val_metric_value, epoch)
        if early_stop.stop_training(epoch):
            break

    if output_dir is not None:
        torch.save(model.state_dict(), os.path.join(output_dir, "model.pkl"))
    if tensorboard_output_path is not None:
        tensorboard_summary_writer.close_all_writers()

    return {
        "epochs": epoch,
        "train_metrics": train_metrics,
        "val_metrics": val_metrics,
        "num_params": num_params
    }

def __predict(dataloader: DataLoader, model: LTRModel) -> np.ndarray:
    all_scores = []
    reranked_y = []
    model.eval()
    device = get_torch_device()
    with torch.no_grad():
        for xb, yb, _ in dataloader:
            X = xb.type(torch.float32).to(device=device)
            y_true = yb.to(device=device)

            input_indices = torch.ones_like(y_true).type(torch.long)
            mask = (y_true == losses.PADDED_Y_VALUE)
            scores = model.score(X, mask, input_indices)
            scores[mask] = float('-inf')
            all_scores.append(scores.numpy())

    return np.concatenate(scores)

def predict(dataset: LibSVMDataset, model: LTRModel, batch_size: int) -> np.ndarray:
    """
    Ranks given datasets according to a given model
    :param datasets: dictionary of role -> dataset that will be ranked
    :param model: a model to use for scoring documents
    :param config: config for DataLoaders
    :return: dictionary of role -> ranked dataset
        every dataset is a Tuple of torch.Tensor - storing X and y in the descending order of the scores.
    """

    dataloader = DataLoader(dataset, batch_size=batch_size, num_workers=2, shuffle=False)

    return __predict(dataloader, model)


"""Lets create kaggle ML project  ---  kaggle.com/c/titanic   ---  """
"""Problem Statement- Predict survival on Titanic"""

# basic 4 steps. 1) Explanatory data analysis 2) Feature engineering 3) Cross validation 4) hyper parameter tunning.
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
input_file=pd.read_csv(r"D:\Study\titanic\train.csv")
input_file2=pd.read_csv(r"D:\Study\titanic\test.csv")
train_data=pd.DataFrame(input_file)
"""Exploratory Data Analysis (EDA)
EDA is a very useful approach which is in line with the statement that "A picture is worth a thousand words". If done properly,
 it can reveal many secrets about our data,
and it is a very important tool for a competitive Kaggler. So, why it is a good idea to do EDA? Well, some good reasons are the following:
Explore the size of the data. Obviously, a 100 observations times 10 variables dataset is a totally different story than
 a 1000000 observations times 100 variables dataset.
Explore the target variable properties.
Explore features properties.
Explore patterns in the data to help us for feature engineering.
OK, so let's start our EDA! Let's try to follow our previous logic, step by step:"""

"""Feature engineering is the transformation of data into features, with the aim of
representing better the problem we would like to solve, and resulting to a better model performance on unseen data"""
# print(train_data.shape) # 891,12-- means there are 891 rows and 12 columns
pd.set_option('display.max_columns',12)# I selected 12 columns to see at 1 time
# print(train_data.info())
# print(train_data.head(5))
# print(train_data.isnull().sum().sort_values(ascending=False)) # we can see that there are total 687 null
# values in Cabin and 177 in Age and 2 in embarked
# print(train_data.isnull().mean().sort_values(ascending=False)) # percentage wise null value, we can see 77% null value in cabin attributes
# sns.countplot(train_data["Survived"])# Menas approx more than 500 died and approx 350 survived, hmmm means maximum died
# sns.countplot(x="Survived",hue='Sex',data=train_data) # survival of women are much higher
train_data['Sex']=pd.get_dummies(train_data['Sex'])# Dummy vairable add am many dummy number to catogerical value as many as different catogery
#i our case we had male and female as two different catogery so we have used dummy instead of dummy we can
# also use replace method of python as train_data['Sex'].replace('male',0,inplace=True)
# and train_data['Sex'].replace('female',1,inplace=True)
# sns.heatmap(train_data.isnull(), yticklabels = False, cbar = False, cmap = 'plasma')# heatmap of null value data via heatmap
# sns.countplot(train_data['Pclass'])# to check distribution of class
# print(train_data.values)
# sns.heatmap(train_data.corr(), annot = True)# to check co relation
# print(train_data.groupby('Pclass')['Age'].median())
# print(train_data['Name'].values)
train_data.loc[train_data['Age'].isnull(),'Age']=train_data.groupby("Pclass")['Age'].transform('median')
#The loc() function is used to access a group of rows and columns by label(s) or a boolean array.
# print(train_data['Age'].isnull().sum())# now no null values
# sns.distplot(train_data['Age'])
plt.show()
train_data.drop('Cabin',axis=1,inplace=True)
# from sklearn import impute
from statistics import mode
train_data['Embarked']=train_data['Embarked'].fillna(mode(train_data["Embarked"])) # imputing mode of categorical data as we can not apply
# mean and medain as this is catogerical data.
# train_data.info()
# print(train_data.isnull().sum())
# print(train_data["Embarked"])
# train_data["Embarked"]=pd.get_dummies(train_data["Embarked"])# this ia also a way but this is not alz preferd.
import warnings
warnings.filterwarnings('ignore')
# print(train_data["Embarked"].unique())# S,C,Q
train_data["Embarked"][train_data["Embarked"]=="S"]=0
# print(train_data[train_data["Embarked"]!="S"])# select * from train_data where embarked != "S"
train_data["Embarked"][train_data["Embarked"]=="C"]=1
train_data["Embarked"][train_data["Embarked"]=="Q"]=2
# print(train_data["Embarked"])
test_data=pd.DataFrame(input_file2)
train_data.drop('Name',axis=1,inplace=True)
train_data.drop('Ticket',axis=1,inplace=True)
train_data_target=train_data['Survived']
train_data.drop('Survived',axis=1,inplace=True)
from sklearn.model_selection import train_test_split
trainx,testx,trainy,testy=train_test_split(train_data,train_data_target,train_size=0.8,random_state=32)
# print(testy)
from sklearn.linear_model import LinearRegression
log_reg=LinearRegression()
log_reg.fit(trainx,trainy)
predictedq=log_reg.predict(testx)
from sklearn.metrics import mean_squared_error
acc=mean_squared_error(testy,predictedq)
# print(acc)
lin_rmse=np.sqrt(acc)
# print(lin_rmse)

from sklearn.linear_model import LogisticRegression
log_reg=LogisticRegression(max_iter=1000)
log_reg.fit(trainx,trainy)
prediction=log_reg.predict(testx)
# print(round(np.mean(prediction),2))
from sklearn.metrics import confusion_matrix
# print(confusion_matrix(testy,prediction))
from sklearn.metrics import accuracy_score
# print('manually calculated accuracy score',((90+49)/(90+49+22+18))) # 77.65 percent accuracy
# print(accuracy_score(testy,prediction))

#https://www.kaggle.com/kernelgenerator/titanic-tutorial-for-beginners-part-3
# but before doing that we can do feature engineering
# there we can add both feature sibligs and parent to total number of family onboarded.
# we can also change name and cabin to categorical value. but there also we can see total distinct cabnin and if any particualr cabin is repeating
# than we can replace other cabin name with other and then we will have
# 4 or 5 different cabin sets(like in train- AC 1 tear,AC 2 Tear, AC 3 tear and other)

"""Magic Weapon #2: Cross-Validation
Cross-Validation is essentially a more advanced form of our fundamental local validation method above.
 It protects against overfitting, that's why it is often the key to win a Kaggle competition. In a nutshell,
 it is a resampling method which tells us how well our model would generalize to unseen data. This is achieved by fixing a number
of partitions of the dataset called folds, predicting each fold separately, and averaging the predictions in the end."""

from sklearn.model_selection import KFold
kf=KFold(n_splits=5,random_state=32)
from sklearn.model_selection import cross_val_score
score=(cross_val_score(log_reg,testx,testy,cv=kf).mean())
# print(score) #79.3%

#lets do hyperparameter tunning Magic number 3
from sklearn.ensemble import RandomForestClassifier
ran_fst=RandomForestClassifier(random_state=32)
param_grid = {
    'criterion' : ['gini', 'entropy'],
    'n_estimators': [100, 300, 500],
    'max_features': ['auto', 'log2'],
    'max_depth' : [3, 5, 7]
}
"""'criterion' : A function which measures the quality of a split.
'n_estimators': The number of trees of our random forest.
'max_features': The number of features to choose when looking for the best way of splitting.
'max_depth' : the maximum depth of a decision tree."""

from sklearn.model_selection import GridSearchCV

ran_fst_cv=GridSearchCV(estimator=ran_fst,param_grid=param_grid,cv=5)
ran_fst_cv.fit(trainx,trainy)
# print('best parameters',ran_fst_cv.best_params_) # best parameters {'criterion': 'gini', 'max_depth': 3,
# 'max_features': 'log2', 'n_estimators': 300}
# print('best estimator',ran_fst_cv.best_estimator_)
# print('best index',ran_fst_cv.best_index_)
# print('best score',ran_fst_cv.best_score_)
ran_fst_final_mod=RandomForestClassifier(random_state=2,criterion='gini',max_depth=3,max_features='log2',n_estimators=300)
ran_fst_final_mod.fit(trainx,trainy)
final_prediction=ran_fst_final_mod.predict(testx)
print(accuracy_score(testy,final_prediction))


import os
import tkinter as tk
import tkinter.filedialog as filedialog
import pygame

class MusicPlayer:
    def __init__(self, root):
        self.root = root
        self.root.title("Music Player")
        self.root.geometry("300x150")

        pygame.mixer.init()

        self.frame = tk.Frame(self.root)
        self.frame.pack()

        self.label = tk.Label(self.frame, text="No song selected")
        self.label.pack()

        self.select_button = tk.Button(self.frame, text="Select Song", command=self.select_song)
        self.select_button.pack()

        self.play_button = tk.Button(self.frame, text="Play", command=self.play_song, state=tk.DISABLED)
        self.play_button.pack()

        self.pause_button = tk.Button(self.frame, text="Pause", command=self.pause_song, state=tk.DISABLED)
        self.pause_button.pack()

        self.stop_button = tk.Button(self.frame, text="Stop", command=self.stop_song, state=tk.DISABLED)
        self.stop_button.pack()

    def select_song(self):

        song_path = filedialog.askopenfilename(filetypes=[("MP3 Files", "*.mp3")])
        if song_path:

            song_name = os.path.basename(song_path)
            self.label.config(text=song_name)

            # Load the song
            pygame.mixer.music.load(song_path)

            self.play_button.config(state=tk.NORMAL)

    def play_song(self):

        pygame.mixer.music.play()

        self.pause_button.config(state=tk.NORMAL)
        self.stop_button.config(state=tk.NORMAL)

    def pause_song(self):

        pygame.mixer.music.pause()

    def stop_song(self):

        pygame.mixer.music.stop()

        self.pause_button.config(state=tk.DISABLED)
        self.stop_button.config(state=tk.DISABLED)

root = tk.Tk()
music_player = MusicPlayer(root)

root.mainloop()


from PyQt4.QtCore import QThread, pyqtSignal, QObject, Qt, pyqtSlot
from PyQt4.QtSql import QSqlQuery

from Roadnet.roadnet_dialog import SymbologyDlg
from Roadnet.street_browser.edit import UpdateEsuSymbology

__author__ = 'matthew.walsh'

class UpdateSymbology:
    """
    Update the symbology of the Road Polygon and/or ESU Graphic Layer.
    """

    def __init__(self, db, rdpoly_layer, esu_layer):
        """
        :param db: database connection
        :param rdpoly_layer: road polygon layer
        :param esu_layer: esu graphic layer
        """
        # Set rdpoly layer + feature_count
        self.rdpoly_layer = rdpoly_layer
        self.rdpoly_count = self.rdpoly_layer.featureCount()
        # Set esu layer + feature count
        self.esu_layer = esu_layer
        self.esu_count = self.esu_layer.featureCount()

        self.db = db
        self.rdpoly_worker = None
        # Create dialog instance
        self.symbology_dlg = SymbologyDlg()
        self.symbology_dlg.setWindowFlags(Qt.WindowMinimizeButtonHint)
        self.symbology_dlg.setModal(False)
        self.connect_signals()

    def connect_signals(self):
        """
        Connect signals for GUI buttons and custom signals for updating the GUI from the thread.
        """
        self.symbology_dlg.ui.runPushButton.clicked.connect(self.start_update)

    def show_symbology_dlg(self):
        """
        Main run method for the symbology updater.
        """
        self.symbology_dlg.show()

    def start_update(self):
        """
        Start the update on a thread.
        """
        if self.symbology_dlg.ui.runPushButton.text() == "Run":
            esu_checked = self.symbology_dlg.ui.esuCheckBox.isChecked()
            rdpoly_checked = self.symbology_dlg.ui.rdPolyCheckBox.isChecked()
            if esu_checked or rdpoly_checked:
                self.create_thread(rdpoly_checked, esu_checked)
                # else:
                #     self.rdpoly_worker.terminate()
                #     self.rdpoly_worker.wait()
                #     self.update_terminated()

    def create_thread(self, run_rdpoly, run_esu):
        """
        Create and start the thread that does the heavy lifting.
        :param run_rdpoly: bool to update the rdpoly layer
        :param run_esu: bool to update the esu layer
        """
        self.rdpoly_worker = UpdateSymbologyThread(self.db, self.rdpoly_layer, self.esu_layer, run_rdpoly, run_esu)
        self.rdpoly_worker.setTerminationEnabled(True)
        self.rdpoly_worker.signals.task_started.connect(self.task_started)
        self.rdpoly_worker.signals.task_finished.connect(self.task_finished)
        self.rdpoly_worker.signals.update_progress.connect(self.update_progress)
        self.rdpoly_worker.start()

    @pyqtSlot()
    def task_started(self):
        """
        Set the dialog to its initial run state.
        :return: void
        """
        self.symbology_dlg.ui.progressBar.setValue(0)
        # self.symbology_dlg.ui.runPushButton.setText("Abort")
        self.symbology_dlg.ui.runPushButton.setEnabled(False)

    @pyqtSlot()
    def task_finished(self):
        """
        Enable the 'Run' button.
        """
        # self.symbology_dlg.ui.runPushButton.setText("Run")
        self.symbology_dlg.ui.runPushButton.setEnabled(True)

    # def update_terminated(self):
    #     """
    #     Cleanup for a user cancel event. Discards all changes to both layers.
    #     """
    #     self.esu_layer.rollBack()
    #     # Change GUI back to initial state
    #     self.task_finished()

    @pyqtSlot(int, int, int)
    def update_progress(self, percentage, rdpoly_count, esu_count):
        """
        Update the labels on the dialog and update the progressbar.
        :param percentage: % task is complete
        :param rdpoly_count: Number of symbology updates on the rdpoly layer
        :param esu_count: Number of symbology updates on the esu layer
        """
        self.symbology_dlg.ui.progressBar.setValue(percentage)
        features_updated_text = """

Updated Features

ESU Graphic: {0}/{1}

Road Polygon: {2}/{3}

                                   """.format(esu_count, self.esu_count, rdpoly_count, self.rdpoly_count)
        self.symbology_dlg.ui.updatedFeaturesLabel.setText(features_updated_text)

class UpdateSymbologyThread(QThread):
    """
    Worker thread to update the symbology of each road polygon feature.
    """

    esu_f_count = 0
    rdpoly_f_count = 0
    rdpoly_change_count = 0
    esu_change_count = 0
    features_complete = 0

    def __init__(self, db, rdpoly_layer, esu_layer, run_rdpoly, run_esu):
        """

        :param db: database connection
        :param rdpoly_layer: road polygon layer
        :param esu_layer: esu layer
        :param run_rdpoly: bool whether to run the rdpoly update
        :param run_esu: bool whether to run the esu update
        """
        QThread.__init__(self)
        self.db = db
        self.rdpoly_layer = rdpoly_layer
        self.esu_layer = esu_layer
        self.run_rdpoly = run_rdpoly
        self.run_esu = run_esu
        self._init_data()
        self.total_f_count = self.calculate_total_feature_count()

    def _init_data(self):
        self.signals = ThreadSignals()
        # Total number of features on each layer
        self.rdpoly_f_count = self.rdpoly_layer.dataProvider().featureCount()
        self.esu_f_count = self.esu_layer.dataProvider().featureCount()

    def run(self):
        """
        Override the QThread main run method (never called directly).
        """
        self.signals.task_started.emit()
        if self.run_esu:
            self.run_esu_update()
        if self.run_rdpoly:
            self.run_rdpoly_update()
        self.signals.task_finished.emit()

    def run_esu_update(self):
        """
        Updates the symbology of the esu graphic layer.
        """
        self.esu_layer.startEditing()
        symbology_update = UpdateEsuSymbology(self.db, self.esu_layer)
        for feat in self.esu_layer.getFeatures():
            self.set_percentage_complete()
            esu_id = feat.attribute('esu_id')
            symbol_value = feat.attribute('symbol')
            # calculate the correct symbology values
            types = symbology_update.street_ref_types(esu_id)
            new_symbol_value = symbology_update.calculate_symbol_no(types)
            if new_symbol_value != symbol_value:
                # Only set if its changed
                feat.setAttribute('symbol', new_symbol_value)
                self.esu_layer.updateFeature(feat)
                self.esu_change_count += 1
        self.esu_layer.commitChanges()

    def run_rdpoly_update(self):
        """
        Updates the symbology of the rdpoly layer.
        """
        self.rdpoly_layer.startEditing()
        for feat in self.rdpoly_layer.getFeatures():
            self.set_percentage_complete()
            rd_pol_id = feat.attribute('rd_pol_id')
            symbol_value = feat.attribute('symbol')
            sql = """SELECT maint_id FROM lnkMAINT_RD_POL
                     WHERE rd_pol_id = {rd_pol_id}
                       AND currency_flag = 0""".format(rd_pol_id=rd_pol_id)
            query = QSqlQuery(sql, self.db)
            linked_maint = list()
            while query.next():
                linked_maint.append(query.value(0))
            new_symbol_value = self.calculate_rdpoly_symbology_value(linked_maint)
            if new_symbol_value != symbol_value:
                # Only set if its changed
                feat.setAttribute('symbol', new_symbol_value)
                self.rdpoly_layer.updateFeature(feat)
                self.rdpoly_change_count += 1
        self.rdpoly_layer.commitChanges()

    def calculate_rdpoly_symbology_value(self, maint_ids):
        """
        Calculates the symbology depending on how many maint records are attached to a rdpoly feature.
        :rtype: int
        :param maint_ids: list of maint id's attached to a road polygon feature
        :return: symbology value
        """
        size = len(maint_ids)
        if size == 0:
            # No records attached to rdpoly
            symbology = 1
        elif size == 1:
            # Single attached record, get the record type by query
            maint_id = maint_ids[0]
            road_status_ref = self.get_road_status_ref(maint_id)
            symbology = road_status_ref + 10
        else:
            # More than one other record attached
            symbology = 2  # 2 = multiple
        return symbology

    def get_road_status_ref(self, maint_id):
        """
        Query database to get road status for given maintenance ID.
        :param maint_id: maintenance ID
        :return: integer road status ref.
        """
        sql = """
            SELECT road_status_ref FROM tblMAINT
            WHERE maint_id = {maint_id}
            AND currency_flag = 0
            ;""".format(maint_id=maint_id)
        query = QSqlQuery(sql, self.db)
        query.seek(0)
        road_status_ref = int(query.value(0))
        self.fail_if_invalid_road_status_ref(maint_id, road_status_ref)
        return road_status_ref

    @staticmethod
    def fail_if_invalid_road_status_ref(maint_id, road_status_ref):
        """
        Raise exeption if road status ref is incorrect
        :param road_status_ref:
        :param maint_id:
        """
        if road_status_ref > 4:
            raise ValueError(
                "Maintenance record {} has invalid road_status_ref".format(
                    maint_id))

    def set_percentage_complete(self):
        """
        Calculate the progress percentage of the entire update.
        """
        self.features_complete += 1
        percentage_complete = (self.features_complete * 100) / self.total_f_count
        self.signals.update_progress.emit(percentage_complete, self.rdpoly_change_count, self.esu_change_count)

    def calculate_total_feature_count(self):
        """
        Calculate the total number of features to be processed (used to calculate percentage).
        """
        total = 0
        if self.run_esu:
            total += self.esu_f_count
        if self.run_rdpoly:
            total += self.rdpoly_f_count
        return total

class ThreadSignals(QObject):
    """
    class that holds the signals emitted from the thread and received by the worker to update gui status.
    """
    task_started = pyqtSignal()
    task_finished = pyqtSignal()
    # Params = % complete, rdpoly change count, esu change count
    update_progress = pyqtSignal(int, int, int)


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tabulate import tabulate
import geradenfit as gf

execute = 'g'

#{{{ c
def c():
    U0 = 2.2 # V
    R1 = 100 # Ohm
    R2 = 5 # Ohm
    R = np.array([100,200,300,400,500,1000,2000,3000,4000,5000]) # Ohm
    vph = np.array([180,122,94,76,64,36,20,15,11,9]) # mm
    delt_vph = np.array([10,7,4,2,2,1,1,1,1,1]) # mm
    delt_vph_G = 1/vph**2*delt_vph

    zusammen = ['end'] # Welche Plots zusammengehören. Gleiche Buchstaben werden in einem Plot ausgegeben (Beispiel: ['a','a','b'], die ersten beiden x, y Werte werden in einem Plot ausgegeben, die dritten x, y, Werte werden in einem Plot ausgegeben).
    x = [R]
    xerr = [np.zeros(len(R))]
    xlabel = r'Widerstand $[\Omega]$'
    y = [1/vph]
    yerr = [delt_vph_G]
    ylabel = r'1/$\varphi$ [1/Skt]'
    title = '236.c Stromempfindlichkeit und Spulenwiderstand'
    label = '236.c' # label von plt.errorbar und plt.plot
    color = ['red'] # farbe der punkte (geraden sind immer blau)
    Auswertung = gf.Auswertung(x,xerr,xlabel,y,yerr,ylabel,title,label,color,zusammen)
    Auswertung.auswertung()

    m = gf.Gerade()
    m,n,vm,vn = m.mnvmvn(x[0],y[0],yerr[0])

    cI = 1/m*(R1+R2)/(U0*R2)
    delt_cI = cI*1/m*vm
    print(cI,delt_cI)

    Rg = n*(cI*U0*R2)/(R1+R2)
    delt_Rg = Rg/n*vn
    print(Rg,delt_Rg)
#}}}

#{{{ g
def g():

    vph = np.array([35,33,29,16,13]) # Skt
    delt_vph = np.zeros(len(vph))+1 # Skr
    I = np.zeros(len(vph))+1.91e-3 # A
    delt_I = np.zeros(len(vph))+0.01*10**(-3) # A
    delt_I_string = ['0.01*10^(-3)','0.01*10^(-3)','0.01*10^(-3)','0.01*10^(-3)','0.01*10^(-3)']
    cI = vph/I # Skt/A
    delt_cI = np.sqrt((delt_vph/I)**2+(vph/I**2*delt_I)**2) # Skt/A

    data = np.transpose([I,delt_I_string,vph,delt_vph,np.round(cI,1),np.round(delt_cI,1)])
    headers = ['I [A]','ΔI [A]',r'φ [Skt.]',r'Δφ [Skt]',r'cI [Skt./A]','ΔcI [Skt./A]']
    print('Tabelle 236.g: Stromempfindlichkeit verschiedener Trägheitsmomente')
    print(tabulate(data,headers=headers,tablefmt='fancy_grid'))
#}}}

#{{{ h
def h():

    vph = np.array([46,40,37,34,30,28,26,20,12,8]) # Skt
    delt_vph = np.zeros(len(vph))+1 # Skt
    t = np.array([0,2.1,3.1,4.1,5.2,6.1,7.1,10.0,15.1,20.1]) # s
    delt_t = np.zeros(len(t))+0.3 # s

    C = 10e-6 # F
    U0 = 2.2 # V

    zusammen = ['end'] # Welche Plots zusammengehören. Gleiche Buchstaben werden in einem Plot ausgegeben (Beispiel: ['a','a','b'], die ersten beiden x, y Werte werden in einem Plot ausgegeben, die dritten x, y, Werte werden in einem Plot ausgegeben).
    x = [t]
    xerr = [delt_t]
    xlabel = 'Zeit [s]'
    y = [np.log(vph)]
    yerr = [delt_vph/vph]
    ylabel = 'logarithmische Auslenkung [Skt]'
    title = '263.h: Ballistisches Galvanometer'
    label = '236.h' # label von plt.errorbar und plt.plot
    color = ['red'] # farbe der punkte (geraden sind immer blau)

    Auswertung = gf.Auswertung(x,xerr,xlabel,y,yerr,ylabel,title,label,color,zusammen)
    Auswertung.auswertung()

    m = gf.Gerade()
    m,n,vm,vn = m.mnvmvn(x[0],y[0],yerr[0])
    R = 1/(m*C)
    delt_R = 1/(m**2*C)*vm
    print(R,delt_R)
#}}}

for char in execute:
    locals()[char]()

# Plot

zusammen = ['end'] # Welche Plots zusammengehören. Gleiche Buchstaben werden in einem Plot ausgegeben (Beispiel: ['a','a','b'], die ersten beiden x, y Werte werden in einem Plot ausgegeben, die dritten x, y, Werte werden in einem Plot ausgegeben).
x = []
xerr = []
xlabel = []
y = []
yerr = []
ylabel = []
title = ''
label = [] # label von plt.errorbar und plt.plot
color = [] # farbe der punkte (geraden sind immer blau)

Auswertung = gf.Auswertung(x,xerr,xlabel,y,yerr,ylabel,title,label,color,zusammen)
Auswertung.auswertung()


from ctypes import windll, Structure, c_long, byref
import pyautogui
import threading
from threading import Thread
import win32api, win32con
import keyboard
import pyautogui
from PIL import Image
import cv2
from PIL import ImageGrab
import numpy as np

class POINT(Structure):
    _fields_ = [("x", c_long), ("y", c_long)]

def replace_str_index(text,index=0,replacement=''):
    return '%s%s%s'%(text[:index],replacement,text[index+1:])

green = np.uint8([[[241,119,221 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print(hsv_green)
data=str(hsv_green).replace("[", "").replace("]", "")

data=replace_str_index(data,3,',')
data=replace_str_index(data,7,',')
s3=data.split(",")
s4=s3[0].replace(" ","")
xx=int(s4)
s4=s3[1].replace(" ","")
yy=int(s4)
s4=s3[2].replace(" ","")
zz=int(s4)

range =  np.array([xx, yy, zz], dtype=np.uint8)
#upper_range =  np.array([5, 236, 252], dtype=np.uint8)

triangle = np.array([120, 136, 252], dtype=np.uint8) #RGB=252,118,119
squares = np.array([95, 150, 255], dtype=np.uint8) #RGB=255,232,105
polygon = np.array([5, 136, 252], dtype=np.uint8) #RGB-118 141 252

im = pyautogui.screenshot()
rgb_im = im.convert('RGB')
r, g, b = rgb_im.getpixel((776/2, 410))
print(r, g, b)

"""
if(r==0 and g==178 and b==225):
	lower_range = np.array([80, 100, 100], dtype=np.uint8)
	upper_range = np.array([255, 255, 255], dtype=np.uint8)
	print("Blue Team")
else:
	lower_range = np.array([90, 100, 100], dtype=np.uint8)
	upper_range = np.array([105, 255, 255], dtype=np.uint8)
	print("Red team")
"""
while(True):
		img2 = ImageGrab.grab(bbox=(70,70,800,720))
		img = np.array(img2)
		hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

		"""
		mask1 = cv2.inRange(hsv, triangle, triangle)
		mask2 = cv2.inRange(hsv, squares, squares)
		mask3 = cv2.inRange(hsv, polygon, polygon)

		fmask1 = cv2.add(mask1,mask2)
		mask = cv2.add(fmask1,mask3)
		"""
		mask = cv2.inRange(hsv, range, range)

		cv2.imshow('mask',mask)

		global coord
		coord=cv2.findNonZero(mask)

		if cv2.waitKey(1) & 0xFF == ord('q'):
			runningg=False
			break

#CENTER-388,392
#END-769,513

"""
im = pyautogui.screenshot()
rgb_im = im.convert('RGB')
r, g, b = rgb_im.getpixel((776/2, 410))
print(r, g, b)
"""

#BY DEFAULT FIREFOX= X-776, Y-413


#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/17 8:40
# @Author  : LI Dongdong
# @FileName: 260. Single Number III.py
''''''
'''
题目分析
1.要求：Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
    Input:  [1,2,1,3,2,5]
    Output: [3,5]
    The order of the result is not important. So in the above example, [5, 3] is also correct.
    Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
2.理解：一组数，有两个值只出现了一次，其余的都出现两次，求这两个值
3.类型：bit
4.确认输入输出及边界条件：
    input：list[int], repeated? Y order?N
    output：two value of once
    corner case：None? Y only one elem? N
4.方法及方法分析：dic store, XOR
time complexity order: dic store O(N) = XOR O(N)
space complexity order: XOR(1) < dic storeO(N)
'''
'''
A.
思路：brute force - dic store
方法：
    1. scan list, store value and time in dic's key and value
    2. output 1 value's key
time complex: O(N)
space complex: O(N)
易错点：for k, v in dic.items(): 从value查key
'''

class Solution:
    def singleNumber(self, nums) -> int:
        dic = {}
        for elem in nums:  # store value, times in dic
            if elem in dic:
                dic[elem] += 1
            else:
                dic[elem] = 1

        res = []
        for k, v in dic.items():  # output 1 times key
            if v == 1:
                res.append(k)
        return res

'''
B.
优点：技巧性太强
思路：bit XOR
方法：
    1. 由于出现一次的两个数不等，故两数异或结果不为0，也就是说结果的二进制中至少有一位是1，
    记为第n位。
    2. 我们以第n位是否为1，来把输入分为两个数组，这两个为一的数分别在这两个数组中
    3. 对这两个数组分别求只出现一次的数，即我们要求的数，然后输出
time complex: O(N)
space complex: O(1)
易错点：0 和一个数异或后得到那个数，两个相同的数异或后则为 0。
'''

class Solution:
    def singleNumber(self, nums) -> int:
        if nums == []:  # corner case
            return None

        xor = 0
        for elem in nums:  # get a^b
            xor = xor ^ elem

        for i in range(32):  # find first dif value in bit
            if xor >> i & 1 == 1:
                loc1 = i
                break

        a = 0
        b = 0
        for val in nums:  # divide nums into two groups and find one elem in each group
            if val >> loc1 & 1 == 1:
                a = a ^ val
            else:
                b = b ^ val

        return [a, b]

x = Solution()
print(x.singleNumber([1,2,1,3,2,5]))


import os
import re
import json
import numpy as np
import pandas as pd
import tensorflow as tf

from tensor2tensor.data_generators import problem
from tensor2tensor.data_generators import text_problems, text_encoder
from tensor2tensor.layers import modalities
from tensor2tensor.utils import registry

from . import config
from .utils import extract_flatworld_tags, get_line_context, normalize_text, split_lines, span2bio, bio2span

@registry.register_problem
class HansardLineHasSpeaker(text_problems.Text2ClassProblem):
    """Predicts whether a line from a Hansard transcript contains a speaker name."""

    CONTEXT_SEPARATOR = "<EOC>"
    CONTEXT_SEPARATOR_ID = 2

    @property
    def additional_reserved_tokens(self):
        return [self.CONTEXT_SEPARATOR]

    @property
    def vocab_type(self):
        return text_problems.VocabType.SUBWORD

    @property
    def approx_vocab_size(self):
        """Approximate vocab size to generate. Only for VocabType.SUBWORD."""
        return 2**16  # ~64k

    @property
    def is_generate_per_split(self):
        return True

    @property
    def num_classes(self):
        """The number of classes."""
        return 2

    def class_labels(self, data_dir):
        """String representation of the classes."""
        del data_dir
        return ['no', 'yes']

    @property
    def dataset_splits(self):
        """Splits of data to produce and number of output shards for each."""
        # 10% evaluation data
        return [{
            "split": problem.DatasetSplit.TRAIN,
            "shards": 9,
        }, {
            "split": problem.DatasetSplit.EVAL,
            "shards": 1,
        }]

    def feature_encoders(self, data_dir):
        encoder = self.get_or_create_vocab(data_dir, None, force_get=True)
        encoders = {'inputs': encoder, 'context': encoder}
        return encoders

    def generate_text_for_vocab(self, data_dir, tmp_dir):
        for i, sample in enumerate(self.generate_samples(data_dir, tmp_dir, problem.DatasetSplit.TRAIN)):
            yield sample["inputs"]
            yield sample["context"]
            # yield sample["targets"]
            if self.max_samples_for_vocab and (i + 1) >= self.max_samples_for_vocab:
                break

    def generate_encoded_samples(self, data_dir, tmp_dir, dataset_split):
        generator = self.generate_samples(data_dir, tmp_dir, dataset_split)
        encoder = self.get_or_create_vocab(data_dir, tmp_dir)
        encoders = {'inputs': encoder, 'context': encoder}
        # vocab = self.feature_encoders(data_dir)["context"]
        for sample in generator:
            encoded_sample = self.encode_example(sample, encoders)
            yield encoded_sample

    def encode_example(self, example, encoders):
        """encodes an example.

        example is a dict containing the inputs (str), context (str), and label (int).
        """
        inputs = encoders['inputs'].encode(example["inputs"])
        inputs.append(text_encoder.EOS_ID)
        context = encoders['context'].encode(example["context"])
        context.append(text_encoder.EOS_ID)
        label = example["label"]
        return {"inputs": inputs, "context": context, "targets": [label]}

    def hparams(self, defaults, unused_model_hparams):
        super().hparams(defaults, unused_model_hparams)
        p = defaults
        p.modality["context"] = modalities.ModalityType.SYMBOL
        p.vocab_size["context"] = self._encoders["context"].vocab_size
        if self.packed_length:
            raise NotImplementedError("HansardLineType4 does not "
                                      "support packed_length")

    def example_reading_spec(self):
        data_fields, data_items_to_decoders = (super(HansardLineHasSpeaker, self).example_reading_spec())
        data_fields["context"] = tf.VarLenFeature(tf.int64)
        return (data_fields, data_items_to_decoders)

    def preprocess_example(self, example, mode, hparams):
        sep = tf.convert_to_tensor([self.CONTEXT_SEPARATOR_ID],
                                    dtype=example["inputs"].dtype)
        example["inputs"] = tf.concat([example["inputs"][:-1], sep, example["context"]], 0)
        example = super().preprocess_example(example, mode, hparams)
        return example

    def generate_samples(self, data_dir, tmp_dir, dataset_split):
        is_train = dataset_split == problem.DatasetSplit.TRAIN
        assert 'train.csv' in os.listdir(tmp_dir)
        if is_train:
            dataset_path = os.path.join(tmp_dir, 'train.csv')
        else:
            dataset_path = os.path.join(tmp_dir, 'dev.csv')
        lines = pd.read_csv(dataset_path, encoding='latin')
        lines = lines[lines.text.notnull()]
        lines['text'] = lines.text.apply(normalize_text)
        assert lines.text.isnull().sum() == 0, "Every line should have a non-null text value."
        assert (lines.text.str.len() > 0).all(), "Every line must have a text value with len > 0."
        lines.start[lines.start.isnull() & lines.end.notnull()] = 1
        lines.end[lines.start.notnull() & lines.end.isnull()] = lines.text[lines.start.notnull() & lines.end.isnull()].apply(len)
        lines.start -= 1
        # lines.end -= 1
        has_start_end = lines.start.notnull() & lines.end.notnull()
        assert (lines.start.min() >= 0).all()
        assert lines.start[lines.end.notnull()].isnull().sum() == 0
        assert lines.end[lines.start.notnull()].isnull().sum() == 0
        assert (lines.start[has_start_end] <= lines.end[has_start_end]).all()
        assert (lines.end[has_start_end] <= lines[has_start_end].text.str.len()).all()
        lines['bio'] = lines.apply(lambda row: span2bio(s=row['text'], start=row['start'], end=row['end']), axis=1)
        if is_train and config.N_SPLIT_LINES_PASSES > 0:
            # randomly splits lines to create more training data.
            lines_split = []
            for i in range(config.N_SPLIT_LINES_PASSES):
                lines_split_temp = split_lines(lines)
                lines_split_temp['file'] += f'_{i}'
                lines_split.append(lines_split_temp)
            lines_split = pd.concat(lines_split, axis=0, ignore_index=True, sort=True)
            lines_split[['start', 'end']] = pd.DataFrame(lines_split.bio.apply(bio2span).values.tolist(), index=lines_split.index)
            # idx = np.random.randint(low=0, high=lines_split.shape[0])
            # lines_split.iloc[idx:idx+10,:]
            lines = pd.concat([lines, lines_split], axis=0, ignore_index=True, sort=True)
            lines.sort_values(by=['year', 'file', 'line'], inplace=True)
        # assigns `has_speaker` variable.
        assert (lines.bio.str.len() == lines.text.str.len()).all()
        lines['has_speaker'] = lines.bio.apply(lambda x: bool(re.search(r'[BI]', x))).astype(int)
        assert lines.has_speaker.isnull().sum() == 0
        # retrieves context surrounding each line.
        contexts = get_line_context(lines, n=config.CONTEXT_N_LINES)
        assert contexts.prev_context.isnull().sum() == 0
        assert contexts.next_context.isnull().sum() == 0
        lines = pd.merge(lines, contexts, on=['year', 'file', 'line'], how='left', validate='1:1')
        # drops lines that have a null prev_context and are not the first line.
        lines = lines[~((lines.prev_context.str.len() == 0) & (lines.line > config.CONTEXT_N_LINES))]
        assert (lines[lines.line == 1].prev_context.str.len() == 0).all()
        # drops lines that have a null next_context and are not an end-of-document line.
        lines = lines[~((lines.next_context.str.len() == 0) & ~lines.text.str.contains(r'<EOD>$', flags=re.IGNORECASE))]
        lines[lines.text.str.contains(r'<EOD>$', flags=re.IGNORECASE)]['next_context'] = ''
        # lines[lines.text.str.contains(r'<EOD>$', flags=re.IGNORECASE)]['next_context'] = None
        # lines['line_length'] = lines.text.str.len()
        # lines['line_context_length'] = lines.text.str.len() + lines.prev_context.str.len() + lines.next_context.str.len()
        # lines.line_length.quantile(q=pd.np.arange(0, 1.1, 0.1))
        # lines.line_context_length.quantile(q=pd.np.arange(0, 1.1, 0.1))
        # lines[lines.line_context_length < 10]
        if is_train and config.UPSAMPLE:
            weights = (1 / (lines.has_speaker.dropna().value_counts() / lines.has_speaker.dropna().shape[0])).to_dict()
            lines['class_weight'] = lines.has_speaker.apply(lambda x: weights[x])
            lines = lines.sample(lines.shape[0] * config.UPSAMPLE_FACTOR, weights=lines['class_weight'].values, replace=True)
        for _, line in lines.iterrows():
            line_text = line['text']
            prev_context = line['prev_context'] if pd.notnull(line['prev_context']) else ''
            next_context = line['next_context'] if pd.notnull(line['next_context']) else ''
            if config.RM_FLATWORLD_TAGS:
                # removes Flatworld tags from lines.
                line_text, _ = extract_flatworld_tags(line_text)
                prev_context, _ = extract_flatworld_tags(prev_context)
                next_context, _ = extract_flatworld_tags(next_context)
            # label: 1 if 'start' or 'end' column is not null; 0 otherwise.
            context = '\n'.join([prev_context, next_context])
            label = line['has_speaker']
            assert label in [0, 1]
            yield {'inputs': line_text, 'context': context, 'label': label}

@registry.register_problem
class HansardLineHasSpeakerChar(HansardLineHasSpeaker):
    @property
    def vocab_type(self):
        return text_problems.VocabType.CHARACTER


import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

if __name__ == "__main__":
    data = np.random.rand(10, 10)
    data = (data + data.T)/2
    data = (data - data.min()) / (data.max() - data.min()) * 2 - 1
    fig, ax = plt.subplots()
    sns.heatmap(data, vmin=-1, vmax=1, cmap=sns.diverging_palette(220, 20, as_cmap=True), cbar=False,
                xticklabels=False, yticklabels=False)
    ax.set_aspect("equal")
    fig.savefig("corr.svg", bbox_inches="tight")


from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from ElevatorSystem.models import (ElevatorModel, ElevatorRequestModel,
                                   ElevatorSystemModel)
from ElevatorSystem.serializers import ElevatorSystemSerializer

class ElevatorSystemViewSet(viewsets.ModelViewSet):

    serializer_class = ElevatorSystemSerializer
    queryset = ElevatorSystemModel.objects.all()

    """ method to initiate the elevator system"""
    @action(detail=True, methods=['GET'])
    def elevator_system(self, request):

            """checking if an elevator system already exists"""
            if not self.queryset:
                """creating a default elevator system"""
                default_elevator_system = {"system_name":"Default_Elevator_Sytem",
                                   "elevator_count": 10,
                                   "floor_count": 10}
                serializer = self.get_serializer(data = default_elevator_system)

                if serializer.is_valid():
                    serializer.save()
                    """creating elevators for the default elevator system """
                    self.createElevators(ElevatorSystemModel.objects.first())
                    return Response(serializer.data)
                else:
                     return Response({"Invalid Elevator System Model"})

            serializer = self.get_serializer(self.queryset, many = True)
            return Response(serializer.data)

    """method to create elevators for a elevator system"""
    def create_elevators(self, elevator_system):
         elevator_count = elevator_system.get().elevator_count

         if elevator_count :

            for elevator_id in range(elevator_count):
                ElevatorModel.objects.create(elevator_system = elevator_system, elevator_id = elevator_id + 1)


# # 7.3.2 check if user won
# def check_win(secret_word,old_letters_guessed):
#     for letter in secret_word:
#         if letter not in old_letters_guessed:
#             return False
#     return True

# # 7.3.1
# def show_hidden_word(secret_word,old_letters_guessed):
#     res = []
#     is_guessed = False
#     for letter in secret_word:
#         for old_letter in old_letters_guessed:
#             if old_letter == letter:
#                 res.append(old_letter)
#                 is_guessed = True
#                 break
#         if not is_guessed:
#             res.append("_")
#         is_guessed = False
#     return ' '.join(res)

# # 6.4.1
# def check_valid_input(letter_guessed,old_letter_guessed):
#     char = letter_guessed.isalpha()
#     num = len(letter_guessed)
#     if num == 1 and char == True and letter_guessed.isascii() and letter_guessed not in old_letter_guessed:
#         return True
#     else:
#         return False
# print(check_valid_input("a",["b","w"]))

# # 6.4.2
# def try_update_letter_guessed(letter_guessed, old_letters_guessed):
#     lower_char= letter_guessed.casefold()
#     if check_valid_input(lower_char,old_letters_guessed):
#         old_letters_guessed.append(lower_char)
#         return True
#     else:
#         print("X")
#         print_guessed_letters(old_letters_guessed)
#         return False

# # Relevant to 6.4.2
# def print_guessed_letters(old_letters):
#     old_letters.sort()
#     stam=""
#     for x in old_letters:
#         stam=stam+x+" -> "
#     length=len(stam)
#     y=stam[:length-4]
#     print(y)

# old_letters = ['a', 'p', 'c', 'f']
# try_update_letter_guessed('$', old_letters)

# 9.4.1
import os
dirname = os.path.dirname(__file__)
def choose_word(file_path, index):                  #הגדרת הפונקציה- 2 ערכים : נתיב ומיקום המילה בתוך הרשימה
    filename = os.path.join(dirname, file_path)
    read_txt = open(filename)                      #פתיחת הקובץ לקריאה עם מילים לניחוש
    content = read_txt.read()                       #הכנסת הרשימה למשתנה
    all_words = content.split(" ")                  #הפרדת הקובץ למילים בתוך מערך/רשימה
    unique_words = list(dict.fromkeys(all_words))   #ביטול הכפילויות ע"י הפיכת המערך למילון,ואח"כ הפיכת המילון לרשימה
    print(unique_words)                             #הדפס את המערך/רשימה
    length_unique = len(unique_words)               #כמות המילים ברשימה
    print(length_unique)                            #הדפסת האורך של הרשימה -ללא כפילויות
    #print(all_words[index-1])                       #הדפסת המילה במיקום המסויים
    times_circle = index%(len(all_words))
    the_word = all_words[times_circle-1]
    print("the word is : ",the_word)
    print("x :",times_circle)
    return(length_unique,the_word)

choose_word("./words_to_guess.txt",-1)               #הפונקציה מקבלת את הנתיב ואת מיקום המילה שתנוחש ע"י המשתמש


#!/usr/bin/env python
import argparse

from gpmap.src.utils import (read_split_data, evaluate_predictions,
                             read_dataframe, write_dataframe, LogTrack)

def main():
    description = 'Calculates evaluation metrics values of a set of predicted '
    description += 'genotype-phenotype data subsets'

    # Create arguments
    parser = argparse.ArgumentParser(description=description)
    input_group = parser.add_argument_group('Input')

    input_group.add_argument('data', help='CSV or parquet table with genotype-phenotype data')
    input_group.add_argument('-p', '--prefix', required=True,
                             help='Files prefix')
    input_group.add_argument('-s', '--suffix', default=None,
                             help='Files suffix')
    help_msg = 'CSV or parquet table containing annotations to add to metrics table'
    input_group.add_argument('-c', '--config', default=None, help=help_msg)

    output_group = parser.add_argument_group('Output')
    output_group.add_argument('-o', '--output', required=True, help='Output file')

    # Parse arguments
    parsed_args = parser.parse_args()
    data_fpath = parsed_args.data
    prefix = parsed_args.prefix
    suffix = parsed_args.suffix
    config_fpath = parsed_args.config
    out_fpath = parsed_args.output

    # Load data
    log = LogTrack()

    log.write('Reading landscape data from {}'.format(data_fpath))
    data = read_dataframe(data_fpath)

    log.write('Reading split data from {}*{}'.format(prefix, suffix))
    splits = read_split_data(prefix, suffix=suffix)

    log.write('Evaluating predictions')
    results = evaluate_predictions(splits, data)

    if config_fpath is not None:
        log.write('Merging with datasets information')
        config = read_dataframe(config_fpath)
        results.join(config, on='label')

    log.write('Writing output to {}'.format(out_fpath))
    write_dataframe(results, out_fpath)

if __name__ == '__main__':
    main()


import numpy as np

#im2col -> image to columns

def im2col(input_data, filter_h, filter_w, stride = 1,pad=0):
    """
    converting images to 2-D array

    :param input_data: Input data in 4-D(# of images, # of channels, height, width)
    :param filter_h: height of filters
    :param filter_w: width of filters
    :param stride: stride
    :param pad: padding

    :return: col : 2-D array
    """

    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h) // stride + 1
    out_w = (H + 2*pad - filter_w) // stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad,pad), (pad, pad)], 'constant') #padding the height and width of input with 0
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w)) #

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.Transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1) #after transpose -> N, out_h, out_w, c, filter_h, filter_w
    return col

#col2im -> columns to images

def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
    """
    converting 2-D arrays to images

    :param col: 2-D array
    :param input_shape: original shape of the image
    :param filter_h: height of filters
    :param filter_w: width of filters
    :param stride: stride
    :param pad: padding

    :return: img : converted images
    """

    N, C, H, W = input_shape
    out_h = (H + (2*pad) - filter_h) // stride + 1
    out_w = (W + (2*pad) - filter_w) // stride + 1
    col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2) #trying to make 'col' before transpose and reshape were done(from im2col)
                                                                                #after transpose -> N, C, filter_h, filter_w, out_h, out_w

    img = np.zeros((N, C, H + 2 * pad + stride - 1, W + 2 * pad + stride - 1))
    for y in range(filter_h):
        y_max = y + stride * out_h
        for x in range(filter_w):
            x_max = x + stride * out_w
            img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]

    return img[:, :, pad:H + pad, pad:W + pad]

#Convolutional Layer

class Convolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = 1
        self.pad = 0

        self.x = None
        self.col = None
        self.col_W = None

        self.dW = None
        self.db = None

    def forward(self, x):
        FN, C, FH, FW = self.W.shape
        N, C, H, W = x.shape
        out_h = int(1 + (H + 2*self.pad - FH) / self.stride)
        out_w = int(1 + (W + 2*self.pad - FW) / self.stride)

        col = im2col(x, FH, FW, self.stride, self.pad)
        col_W = self.W.reshape(FN, -1)
        out = np.dot(col, col_W) + self.b

        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) #makes it 4-D and then changes it to N, C, H, W

        self.x = x
        self.col = col
        self.col_W = col_W

        return out

    def backward(self, dout):
        FN, C, FH, FW = self.W.shape
        dout = dout.transpose(0, 2, 3, 1).reshape(-1, FN) #N, H, W, C. and then makes it 2-D

        self.db = np.sum(dout, axis = 0) #derivative of b
        self.dW = np.dot(self.col.T, dout) #derivative of W
        self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW) #transposes it so that it becomes (FN, _) , then reshapes it to 4-D

        dcol = np.dot(dout, self.col_W.T) #derivatives of image columns
        dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad) #columns to image

        return dx

#Pooling Layer

class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad

        self.x = None
        self.argmax = None

    def forward(self, x):
        N, C, H, W = x.shape
        out_h = (H + (2*self.pad) - self.pool_h) // self.stride + 1
        out_w = (W + (2*self.pad) - self.pool_w) // self.stride + 1

        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w) # to place all the data that is in the pooling application area in a row

        arg_max = np.argmax(col, axis = 1)
        out = np.max(col, axis = 1) #finding the biggest data for every row

        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        self.x = x
        self.arg_max = arg_max
        return out

    def backward(self, dout):
        dout = dout.transpose(0, 2, 3, 1) #after transpose -> N, out_h, out_w, C. reverse of transpose(0, 3, 1, 2)

        pool_size = self.pool_h * self.pool_w
        dmax = np.zeros((dout.size, pool_size))
        dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten() #reverse of reshape(N,out_h,out_w,c)
        dmax = dmax.reshape(dout.shape + (pool_size,))

        dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)
        dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)

        return dx

#ConvNet

class SimpleConvNet:
    def __init__(self, input_dim=(1, 28, 28),
                 conv_param={'filter_num':30, 'filter_size':5,
                             'pad':0, 'stride':1},
                 hidden_size=100, output_size=10, weight_init_std=0.01):
        filter_num = conv_param['filter_num']
        filter_size = conv_param['filter_size']
        filter_pad = conv_param['pad']
        filter_stride = conv_param['stride']
        input_size = input_dim[1]
        conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1
        pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))

        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(filter_num, input_dim[0], filter_size, filter_size)
        self.params['b1'] = np.zeros(filter_num)
        self.params['W2'] = weight_init_std * np.random.randn(pool_output_size, hidden_size)
        self.params['b2'] = np.zeros(hidden_size)
        self.params['W3'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b3'] = np.zeros(output_size)

        self.layers = OrderedDict()
        self.layers['Conv1'] = Convolution(self.params['W1'],
                                           self.params['b1'],
                                           conv_param['stride'],
                                           conv_param['pad'])
        self.layers['Relu1'] = Relu()
        self.layers['Pool1'] = Pooling(pool_h = 2, pool_w = 2, stride = 2)
        self.layers['Affine1'] = Affine(self.params['W2'],
                                        self.params['b2'])
        self.layers['Relu2'] = Relu()
        self.layers['Affine2'] = Affine(self.params['W3'],
                                        self.params['b3'])
        self.last_layer = SofmaxWithLoss()

    def predict(self, x):
        for layer in self.layers.values():
            x = layer.forward(x)

        return x

    def loss(self, x, t):
        y = self.predict(x)
        return self.last_layer.forward(y, t)

    def gradient(self, x, t):
        self.loss(x, t)

        dout = 1
        dout = self.last_layer.backward(dout)

        layers = list(self.layers.values())
        layers.reverse()
        for layer in layers:
            dout = layer.backward(dout)

        grads = {}
        grads['W1'] = self.layers['Conv1'].dW
        grads['b1'] = self.layers['Conv1'].db
        grads['W2'] = self.layers['Affine1'].dW
        grads['b2'] = self.layers['Affine1'].db
        grads['W3'] = self.layers['Affine2'].dW
        grads['b3'] = self.layers['Affine2'].db

        return grads


#%%
import os
import numpy as np
import module_single_language_rational as rm
from module_prior import get_prior
from multiprocessing import Pool, cpu_count
import time
import yaml
import pickle
from munch import munchify
from tqdm import tqdm
#%% INITALISE CONFIG
with open("config.yaml", "r") as f:
    doc = yaml.safe_load(f)
config = munchify(doc)

def file_id(name, pkl = True, directory = None):
    """
    Returns:
        Returns the file name with all the relevant directories
    """
    if directory == None:
        dir_path = os.path.dirname(os.path.realpath(__file__))

        directory = dir_path
    else:
        directory = directory
    if pkl == True:
        pkl = 'pkl'
    else:
        pkl = pkl
    __file_name = f'{name}'
    _file_name = str(__file_name).replace(' ', '-').replace(',', '').replace('[', '-').replace(']','-').replace('.','-')
    file_name = os.path.join(directory, 'ILM_data_files/multiple_irrational_data', f'{_file_name}.pkl')
    return file_name

#%% READ CONSTANTS FROM CONFIG
generations = config.constants.generations
expressivity = config.constants.expressivity
MAP = config.constants.MAP
bottlerange = config.constants.bottlerange
iterations = config.constants.iterations
prior_type = config.prior_constants.prior_type
fname = '%s_%s_%s_%s_%s' % (prior_type, expressivity, MAP, generations, iterations)
#%% INITALISE PRIOR
prior = get_prior()
#%% DEFINE GENERATION FUNCTION
def simulation(b):
    language_agent, posterior_agent, _ = rm.iterate(prior, bottleneck=b)
    return  language_agent, posterior_agent
#%%
start = time.perf_counter()
sim = []
for b in tqdm([(b) for b in bottlerange for _ in range(iterations)]):
    sim.append(simulation(b))
print('Time elapsed: %s'% (time.perf_counter()-start))


from tensorflow import keras
from tensorflow.keras import layers

def make_conv_lstm(input_shape, output_classes):
    """
    Convolutional LSTM Model.
    """
    model = keras.Sequential()
    # Convolutional encoder (non-shallow features)
    model.add(layers.Conv1D(64, kernel_size=3, activation='relu', input_shape=input_shape))
    # Time series classification
    model.add(layers.LSTM(128))
    model.add(layers.Dense(64))
    model.add(layers.Dense(1, activation='sigmoid'))
    return model


# -*- coding: utf-8 -*-
"""
Created on Sun Aug 12 23:49:37 2018

@author: Rishabh
"""

import scrapy

class Electrician(scrapy.Spider):
    name = "elec"
    start_urls = ["https://www.justdial.com/Alwar/Electricians/nct-10184166"]

    def parse(self, response):
        for href in response.xpath('//li[@class="cntanr"]/@data-href'):
            yield response.follow(href,self.getdetails)

        for href in response.xpath('//div[@class="jpag"]/a/@href'):
            yield response.follow(href,self.parse)

    def getdetails(self,response):

        yield{
                'Name':response.xpath('//*[@id="setbackfix"]/div[1]/div/div[1]/div[2]/div/div/h1/span/span/text()').extract_first(),
                'address':(response.xpath('//*[@id="setbackfix"]/div[1]/div/div[1]/div[2]/div/ul/li[1]/span[2]/span/span/text()').extract_first()).strip()
                }