# -*- coding: utf-8 -*-
import json

import numpy as np
import math
import pandas as pd
from sklearn.model_selection import StratifiedKFold
from tensorflow import keras
from joblib import dump, load
from utils.helpers import *
# from RAAC import read_fasta

if __name__ == '__main__':
    # TFPM_val, TFPM_val_labels = read_fasta('../data/TFPM vs TFPNM/TFPM_independent_dataset.txt')
    # TFPNM_val, TFPNM_val_labels = read_fasta('../data/TFPM vs TFPNM/TFPNM_independent_dataset.txt')
    #
    # path = 'F:/BioInformatic/Dataset/TFPM vs TFPNM/PSSM/'
    # TFPM_val_pssm, TFPM_val_pssm_labels = read_data(path + 'TFPM_independent_dataset/', padding='none')
    # TFPNM_val_pssm, TFPNM_val_pssm_labels = read_data(path + 'TFPNM_independent_dataset/', padding='none')
    #
    # reduced_TFPM, _ = reduce_pssms(TFPM_val, TFPM_val_labels, TFPM_val_pssm, TFPM_val_pssm_labels)
    # reduced_TFPNM, _ = reduce_pssms(TFPNM_val, TFPNM_val_labels, TFPNM_val_pssm, TFPNM_val_pssm_labels)
    #
    # data = np.append(reduced_TFPM, reduced_TFPNM, axis=0)
    # labels = np.append(np.ones(len(reduced_TFPM)), np.zeros(len(reduced_TFPNM)))
    #
    # data = data.reshape((data.shape[0], -1))

    TFPM_val, _ = read_fasta('../data/TFPM vs TFPNM/TFPM_independent_dataset.txt')
    TFPNM_val, _ = read_fasta('../data/TFPM vs TFPNM/TFPNM_independent_dataset.txt')

    # TFPM_val, _ = read_fasta('../data/TF vs non-TF/TF_independent_dataset.txt')
    # TFPNM_val, _ = read_fasta('../data/TF vs non-TF/non-TF_independent_dataset.txt')

    gap = 4
    # op = 'op13'
    # ops = ['op5', 'op8', 'op9', 'op11', 'op13']
    ops = ['op13']

    TFPM_val_all = [[] for i in range(len(TFPM_val))]
    TFPNM_val_all = [[] for i in range(len(TFPNM_val))]

    for op in ops:
        reduced_TFPM_val = RAACs(TFPM_val, op=op)
        RGDP_TFPM_val = RGDPs(reduced_TFPM_val, gap=gap, op=op)
        reduced_TFPNM_val = RAACs(TFPNM_val, op=op)
        RGDP_TFPNM_val = RGDPs(reduced_TFPNM_val, gap=gap, op=op)

        TFPM_val_all = np.append(TFPM_val_all, RGDP_TFPM_val, axis=-1)
        TFPNM_val_all = np.append(TFPNM_val_all, RGDP_TFPNM_val, axis=-1)

    # reduced_TFPM_val = RAACs(TFPM_val, op=op)
    # RGDP_TFPM_val = RGDPs(reduced_TFPM_val, gap=gap, op=op)
    # reduced_TFPNM_val = RAACs(TFPNM_val, op=op)
    # RGDP_TFPNM_val = RGDPs(reduced_TFPNM_val, gap=gap, op=op)

    # RGDP_TFPM_val = GDPs(TFPM_val, gap=gap)
    # RGDP_TFPNM_val = GDPs(TFPNM_val, gap=gap)

    # validating data
    data = np.append(TFPM_val_all, TFPNM_val_all, axis=0)
    labels = np.append(np.ones(len(TFPM_val_all)), np.zeros(len(TFPNM_val_all)), axis=0)

    # # BERT
    # path = 'F:/BioInformatic/Dataset/TFPM vs TFPNM/BERT/'
    # data, labels = read_h5py(path, 'TFPM_testing_top100')
    # print(data.shape)
    # data = data[:, 0]

    # DCT_TFPM_GGAP = load('../saved_models/DCT_TFPM_GGAP.joblib')
    # # importance = DCT_TFPM_GGAP.feature_importances_
    # importance = DCT_TFPM_GGAP.coef_[0]
    # importance = np.argsort(importance)[::-1]

    # file = h5py.File('mrmr' + '.h5', 'r')
    # importance = np.asarray(file['mrmr'])

    # pick = importance[:37]
    # data = data[:, pick]

    path = "../saved_models/TFPM/"
    model_paths = os.listdir(path)
    model = []
    i = 0
    for model_path in model_paths:
        model.append(load('../saved_models/TFPM op5/' + str(i) + '_SVM.joblib'))
        i += 1

    i = 0
    a = []
    b = []
    for i in range(len(model)):
        pre = model[i].predict_proba(data)
        print("model: " + str(i))
        sen = sensitivity(labels, pre)
        spe = specificity(labels, pre)
        accc = acc(labels, pre)
        mccc = mcc(labels, pre)
        aucc = auc(labels, pre)
        b.append(math.floor(sen * 1000) / 1000)
        b.append(math.floor(spe * 1000) / 1000)
        b.append(math.floor(accc * 1000) / 1000)
        b.append(math.floor(mccc * 1000) / 1000)
        b.append(math.floor(aucc * 1000) / 1000)
        a.append(b)
        b = []
        i += 1

    vote = voting(model, data)
    ave = average(model, data)
    med = median(model, data)

    print("voting:")
    sen = sensitivity(labels, vote)
    spe = specificity(labels, vote)
    accc = acc(labels, vote)
    mccc = mcc(labels, vote)
    aucc = auc(labels, vote)
    b.append(math.floor(sen * 1000) / 1000)
    b.append(math.floor(spe * 1000) / 1000)
    b.append(math.floor(accc * 1000) / 1000)
    b.append(math.floor(mccc * 1000) / 1000)
    b.append(math.floor(aucc * 1000) / 1000)
    a.append(b)
    b = []

    print("ave:")
    sen = sensitivity(labels, ave)
    spe = specificity(labels, ave)
    accc = acc(labels, ave)
    mccc = mcc(labels, ave)
    aucc = auc(labels, ave)
    b.append(math.floor(sen * 1000) / 1000)
    b.append(math.floor(spe * 1000) / 1000)
    b.append(math.floor(accc * 1000) / 1000)
    b.append(math.floor(mccc * 1000) / 1000)
    b.append(math.floor(aucc * 1000) / 1000)
    a.append(b)
    b = []

    print("med:")
    sen = sensitivity(labels, med)
    spe = specificity(labels, med)
    accc = acc(labels, med)
    mccc = mcc(labels, med)
    aucc = auc(labels, med)
    b.append(math.floor(sen * 1000) / 1000)
    b.append(math.floor(spe * 1000) / 1000)
    b.append(math.floor(accc * 1000) / 1000)
    b.append(math.floor(mccc * 1000) / 1000)
    b.append(math.floor(aucc * 1000) / 1000)
    a.append(b)
    b = []

    pd.DataFrame(a).to_csv('../test.csv')


import pandas as pd
from pyspark.sql import SparkSession, Window
from pyspark.sql.functions import col, avg, min, max, count

if __name__ == '__main__':

    class HybridPandasSerie:

        def __init__(self, serie):
            self.serie = serie

        def __mul__(self, other):
            self.serie = self.serie * other
            return self

        def __add__(self, other):
            if isinstance(other, HybridPandasSerie):
                other = other.serie
            self.serie = self.serie + other
            return self

        def __gt__(self, other):
            if isinstance(other, HybridPandasSerie):
                other = other.serie
            self.serie = self.serie > other
            return self

        def __str__(self):
            return str(self.serie)

        def max(self):
            return self.serie.max()

    class HybridPandasDataFrame:

        def __init__(self, df):
            self.df = df

        def __getitem__(self, other):
            #Si es una columna utilizar DataFrame
            if isinstance(other, list):
                return HybridPandasDataFrame(df[other])
            if isinstance(other, HybridPandasSerie):
                return HybridPandasDataFrame(df[other.serie])
            return HybridPandasSerie(df[other])

        def __str__(self):
            return str(self.df)

    df = pd.DataFrame([[1, 2], [2, 2], [3, 3]], columns=['A', 'B'])
    df2 = HybridPandasDataFrame(df)
    print(df2['A'] + 2)
    print(df2[['A']])
    print(df2[df2['A'] > 1])
    print((df2['A'] + df2['B']) * 2)
    print(df2['A'].max())

    class A:

        def __init__(self, value):
            self.value = value

        def __add__(self, other):
            self.value = self.value + other
            return self

        def __mul__(self, other):
            self.value = self.value * other
            return self

        def __str__(self):
            return str(self.value)

    print((A(1) + 1) * 2)

    spark = SparkSession.builder.master("local").getOrCreate()
    df = spark.read.format('csv')\
                  .option('header', True)\
                  .option('sep', ';')\
                  .schema("id INT, name STRING, surname STRING, age INT ")\
                  .load('user.csv')

    import databricks.koalas as ks
    df = ks.read_csv('user.csv', sep=";", header=0)
    print(df[df['age'] > 30])

    (df.to_spark())
    df.toPandas()

    #Pandas to koalas
    ks.from_pandas(df)
    #Spark to koalas
    ks.DataFrame(df.to_spark())

    from pyspark.sql.types import *
    schema = StructType(
        [StructField('id', IntegerType()), StructField('name', StringType()), StructField('surname', StringType()),
         StructField('age', IntegerType(), False)])
    df = spark.read.format('csv').option('header', 'True').option('sep', ';').schema(schema).load(
        'user.csv')
    df.show()

    df.groupby('surname').pivot('name').agg(avg(col('age'))).show()

    df.filter(col('surname').isNull()).show()
    df_aux = df.filter(col('age') < 30)

    df_aux.cache()
    df_aux.count()

    df_aux.show()

    miwindow = Window.partitionBy('surname').orderBy(col('age').asc()).rowsBetween(Window.unboundedPreceding, Window.currentRow )
    df.select("name", "surname", min(col('age')).over(miwindow).alias('min_age')).show()

    b = spark.createDataFrame([[1002], [3001], [4002], [2003], [2002], [3004], [1003], [4006]], ['id']).\
            withColumn("x", col("id") % 1000)

    c = b.groupBy(col("x"))\
    .agg(count("x"), sum("value"))\
    .drop("x")\
    .toDF("count", "total")\
    .orderBy(col("count").desc, col("total"))\
    .limit(1)\
    .show()


# coding=utf-8
import os
import cv2
from xml.dom.minidom import Document

# category_set = ['car']

def custombasename(fullname):
    return os.path.basename(os.path.splitext(fullname)[0])

def limit_value(a, b):
    if a < 1:
        a = 1
    if a >= b:
        a = b - 1
    return a

def readlabeltxt(txtpath, height, width, hbb=False):
    print(txtpath)
    with open(txtpath, 'r') as f_in:  # 打开txt文件
        lines = f_in.readlines()
        splitlines = [x.strip().split(',') for x in lines]  # 根据空格分割
        boxes = []
        for i, splitline in enumerate(splitlines):
            label = splitline[8]
            # if label not in category_set:  # 只书写制定的类别
            #     continue
            x1 = int(float(splitline[0]))
            y1 = int(float(splitline[1]))
            x2 = int(float(splitline[2]))
            y2 = int(float(splitline[3]))
            x3 = int(float(splitline[4]))
            y3 = int(float(splitline[5]))
            x4 = int(float(splitline[6]))
            y4 = int(float(splitline[7]))
            # 如果是hbb
            if hbb:
                xx1 = min(x1, x2, x3, x4)
                xx2 = max(x1, x2, x3, x4)
                yy1 = min(y1, y2, y3, y4)
                yy2 = max(y1, y2, y3, y4)

                xx1 = limit_value(xx1, width)
                xx2 = limit_value(xx2, width)
                yy1 = limit_value(yy1, height)
                yy2 = limit_value(yy2, height)

                box = [xx1, yy1, xx2, yy2, label]
                boxes.append(box)
            else:  # 否则是obb
                x1 = limit_value(x1, width)
                y1 = limit_value(y1, height)
                x2 = limit_value(x2, width)
                y2 = limit_value(y2, height)
                x3 = limit_value(x3, width)
                y3 = limit_value(y3, height)
                x4 = limit_value(x4, width)
                y4 = limit_value(y4, height)

                box = [x1, y1, x2, y2, x3, y3, x4, y4, label]
                boxes.append(box)
    return boxes

def writeXml(tmp, imgname, w, h, d, bboxes, hbb=False):
    doc = Document()
    # owner
    annotation = doc.createElement('annotation')
    doc.appendChild(annotation)

    # source
    source = doc.createElement('source')
    annotation.appendChild(source)
    filename = doc.createElement('filename')
    source.appendChild(filename)
    filename_txt = doc.createTextNode(imgname)
    filename.appendChild(filename_txt)
    origin = doc.createElement('origin')
    source.appendChild(origin)
    origin_txt = doc.createTextNode('GF2/GF3')
    origin.appendChild(origin_txt)

    # research
    research = doc.createElement('research')
    annotation.appendChild(research)

    version = doc.createElement('version')
    research.appendChild(version)
    version_txt = doc.createTextNode("4.0")
    version.appendChild(version_txt)

    provider = doc.createElement('provider')
    research.appendChild(provider)
    provider_txt = doc.createTextNode("Company/School of team")
    provider.appendChild(provider_txt)

    author = doc.createElement('author')
    research.appendChild(author)
    author_txt = doc.createTextNode("team name")
    author.appendChild(author_txt)

    pluginname = doc.createElement('pluginname')
    research.appendChild(pluginname)
    pluginname_txt = doc.createTextNode("Airplane Detection and Recognition")
    pluginname.appendChild(pluginname_txt)

    pluginclass = doc.createElement('pluginclass')
    research.appendChild(pluginclass)
    pluginclass_txt = doc.createTextNode("Detection")
    pluginclass.appendChild(pluginclass_txt)

    time = doc.createElement('time')
    research.appendChild(time)
    time_txt = doc.createTextNode("2020-07-2020-11")
    time.appendChild(time_txt)

    # objects
    objects = doc.createElement('objects')
    annotation.appendChild(objects)

    for bbox in bboxes:
        # threes#
        object_new = doc.createElement("object")
        objects.appendChild(object_new)

        coordinate = doc.createElement('coordinate')
        object_new.appendChild(coordinate)
        coordinate_txt = doc.createTextNode('pixel')
        coordinate.appendChild(coordinate_txt)

        typenode = doc.createElement('type')
        object_new.appendChild(typenode)
        typenode_txt = doc.createTextNode('rectangle')
        typenode.appendChild(typenode_txt)

        description = doc.createElement('description')
        object_new.appendChild(description)
        description_txt = doc.createTextNode('None')
        description.appendChild(description_txt)

        possibleresult = doc.createElement('possibleresult')
        object_new.appendChild(possibleresult)
        name = doc.createElement('name')
        possibleresult.appendChild(name)
        name_txt = doc.createTextNode(str(bbox[-1]))
        name.appendChild(name_txt)
        probability = doc.createElement('probability')
        possibleresult.appendChild(probability)
        probability_txt = doc.createTextNode('1')
        probability.appendChild(probability_txt)

        # threes-1#
        bndbox = doc.createElement('points')
        object_new.appendChild(bndbox)
        for i in range(5):
            point = doc.createElement('point')
            bndbox.appendChild(point)
            point_txt = doc.createTextNode('{:.6f},{:.6f}'.format(bbox[2 * i % 8], bbox[2 * i % 8 + 1]))
            point.appendChild(point_txt)

    xmlname = os.path.splitext(imgname)[0]
    tempfile = os.path.join(tmp, xmlname + '.xml')
    with open(tempfile, 'wb') as f:
        # f.write(doc.toprettyxml(indent='\t', encoding='utf-8'))
        f.write(doc.toprettyxml(indent='\t', encoding='utf-8'))
    return

if __name__ == '__main__':
    data_path = './annotation'
    images_path = os.path.join(data_path, 'images')  # 样本图片路径
    labeltxt_path = os.path.join(data_path, 'txtlabels')  # DOTA标签的所在路径
    anno_new_path = os.path.join(data_path, 'xmllabels_new')  # 新的voc格式存储位置（hbb形式）
    ext = '.tif'  # 样本图片的后缀
    filenames = os.listdir(labeltxt_path)  # 获取每一个txt的名称
    for filename in filenames:
        filepath = labeltxt_path + '/' + filename  # 每一个DOTA标签的具体路径
        picname = os.path.splitext(filename)[0] + ext
        pic_path = os.path.join(images_path, picname)
        im = cv2.imread(pic_path)  # 读取相应的图片
        (H, W, D) = im.shape  # 返回样本的大小
        boxes = readlabeltxt(filepath, H, W, hbb=False)  # 默认是矩形（hbb）得到gt
        if len(boxes) == 0:
            print('文件为空', filepath)
        # 读取对应的样本图片，得到H,W,D用于书写xml

        # 书写xml
        writeXml(anno_new_path, picname, W, H, D, boxes, hbb=False)
        print('正在处理%s' % filename)


from flask import Flask, jsonify, request

from src.backend import process

app = Flask(__name__)

TEXT = "text"
ROOMS_N_MIN = "rooms_n_min"
ROOMS_N_MAX = "rooms_n_max"
SIZE_MIN = "size_min"
SIZE_MAX = "size_max"
PRICE_MIN = "price_min"
PRICE_MAX = "price_max"

@app.route('/real_estates', methods=['POST'])
def tmp():
    content = request.json
    real_estates = process(
        content[TEXT],
        content[PRICE_MAX],
        content[PRICE_MIN],
        content[SIZE_MAX],
        content[SIZE_MIN],
        content[ROOMS_N_MAX],
        content[ROOMS_N_MIN],
    )

    return jsonify(real_estates)


from typing import Optional
from collections import deque

class Node:
    """
    Binary tree node.
    """

    def __init__(self, level: int, data: Optional[int] = None):
        self.level = level
        self.data = data
        self.left = None
        self.right = None

    def print_tree(self):
        output = []
        if not self.data:
            return output
        if self.left:
            output.extend(self.left.print_tree())
        output.append(self.data)
        if self.right:
            output.extend(self.right.print_tree())
        return output

class BinaryTree:
    """
    This is different from a binary search tree
    Because a binary search tree, left is always smaller than right.
    This is not the case here.
    """
    def __init__(self, root=None):
        self.root = root if root else Node(1, 1)

    def insert(self, value, level):
        # works on a binary search tree
        current = self.root
        while current:
            if value > current.data:
                if current.right:
                    current = current.right
                else:
                    current.right = Node(level, value)
                    break
            else:
                if current.left:
                    current = current.left
                else:
                    current.left = Node(level, value)
                    break
        return 1

    def custom_insert(self, indexes):
        queue = deque([self.root])
        for count, value in enumerate(indexes):
            if len(queue) > 0:
                node_of_interest = queue.popleft()
                left_value, right_value = value[0], value[1]
                if left_value > 0:
                    node_of_interest.left = Node(node_of_interest.level + 1, left_value)
                    queue.append(node_of_interest.left)
                if right_value > 0:
                    node_of_interest.right = Node(node_of_interest.level + 1, right_value)
                    queue.append(node_of_interest.right)
        return 1

    def swap(self, level_to_swap):
        queue = deque([self.root])
        while queue:
            node = queue.popleft()
            if node.level % level_to_swap == 0:
                node.left, node.right = node.right, node.left
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

def print_tree(root: Node):
    output = []
    if not root:
        return output
    if root.left:
        output.extend(print_tree(root.left))
    output.append(root.data)
    if root.right:
        output.extend(print_tree(root.right))
    return output

def swap_nodes(indexes, queries):
    output = []
    binary_tree = BinaryTree(Node(1, 1))
    binary_tree.custom_insert(indexes)
    for query in queries:
        binary_tree.swap(query)
        output.append(binary_tree.root.print_tree())
    return 0

if __name__ == "__main__":
    # above solution is running into a runtime error when given larger data sets
    # swap_nodes([[2, 3], [-1, 4], [-1, 5], [-1, -1], [-1, -1]], [2])
    swap_nodes([[2, 3]], [1])


'''
  Author: Jon Paul Miles
  Date Created: March 15, 2022

  Daily data README:
  https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt
'''

from globals import *
import pandas as pd
import numpy as np
import glob
from bs4 import BeautifulSoup
import urllib.request
from termcolor import colored, cprint
import os

# When parsing rows for the temperature files for this network, these set the bounds for each column
DATA_COLUMNS = [(0,11), (11, 15)] + generate_month_boundaries([5,6,7,8], 19)

check_mark = colored(u'\u2713', 'green', attrs=['bold'])

attention_mark = colored('!', 'yellow', attrs=['bold'])

# All GHCNd .dly station files have 31 days even if some days are missing
DAYS_IN_MONTH = 31

def download_and_compile_uscrn_data(compiled_file, folder_name, url):

  TEMPERATURES_FILE_PATH = ""

  # Check if the compiled USCRN data exists
  matching_compiled_uscrn_files = glob.glob(compiled_file)

  # The compiled daily data file was found
  if len(matching_compiled_uscrn_files):

    TEMPERATURES_FILE_PATH = matching_compiled_uscrn_files[0]

    print(f"{check_mark} Found '{compiled_file}'")

  # If the compiled daily data doesn't exist
  else:

    print(f"{attention_mark} Missing '{compiled_file}'")

    # Check if the folder of USCRN station files has already been downloaded
    matching_extracted_uscrn_files = glob.glob(os.path.join('.', folder_name, '*'))

    # If so, use it when compiling the data
    if len(matching_extracted_uscrn_files):

      print(f"{check_mark} Found '{folder_name}':")

      print(f'  {check_mark} ' + f'\n  {check_mark} '.join(matching_extracted_uscrn_files))

    # If not, download the USCRN data
    else:

      station_files = []

      print(f"{attention_mark} Missing '{folder_name}'. Downloading from {url}")

      # Make a folder to save the USCRN station files to
      if not os.path.exists(folder_name):

        os.mkdir(folder_name)

      # Read the link to all the station files
      soup = BeautifulSoup(urllib.request.urlopen(url), features="html.parser")

      # Get the links for this HTML page
      for a in soup.find_all('a'):

        link = a['href']

        # If the link is a CRN station .txt file:
        if 'CRN' in link and link.endswith('.txt'):

          # Join the link file name with the url
          station_url = os.path.join(url, link)

          # Join the folder name with the file name
          station_file_path = os.path.join(folder_name, link)

          # Download the file
          urllib.request.urlretrieve(station_url, station_file_path)

          # Add to our station file list for displaying in the console later
          station_files.append(station_file_path)

      print(f"  {check_mark} Downloaded:")

      print(f'    {check_mark} ' + f'\n  {check_mark} '.join(station_files))

    TEMPERATURES_FILE_PATH = compile_uscrn_data(VERSION, folder_name)

  return TEMPERATURES_FILE_PATH

def get_files():

  COUNTRIES_FILE_PATH = ""

  STATION_FILE_PATH = 'stations.tsv'

  TEMPERATURES_FILE_PATH = download_and_compile_uscrn_data(
    compiled_file = 'uscrn.tavg.v1.dat',
    folder_name = 'uscrn_stations_v1',
    url = 'https://www.ncei.noaa.gov/pub/data/uscrn/products/monthly01/'
  )

  return STATION_FILE_PATH, TEMPERATURES_FILE_PATH, COUNTRIES_FILE_PATH

def get_stations(station_file_name):

  names = [ 'station_id', 'country_code', 'state', 'LOCATION', 'VECTOR', 'name', 'latitude', 'longitude', 'elevation', 'STATUS', 'COMMISSIONING', 'CLOSING', 'OPERATION', 'PAIRING', 'network', 'other_station_id' ]
  # names=names,

  stations = pd.read_csv(
    station_file_name,
    sep="\t",
    names = names,
    header=None,
    skiprows=[0],
    encoding='utf-8',
  ).reset_index()

  # Pad Station ID
  stations['station_id'] = 'USCRN' + stations['station_id'].astype('str').apply(lambda s: str(s).rjust(6, '0') )

  stations = stations[['country_code', 'station_id', 'latitude', 'longitude', 'elevation', 'name', 'state']]

  stations['country'] = 'United States of America'

  return stations

def has_passing_flags(MFLAG, QFLAG, SFLAG):

  return True

def average_tmax_and_tmin(TMAX_AND_TMIN):

  tavg = math.nan if len(TMAX_AND_TMIN) != 2 or TMAX_AND_TMIN.isnull().any() else int(normal_round(TMAX_AND_TMIN.mean()))

  return tavg

def parse_daily_row(unparsed_row):

  parsed_row = []

  ELEMENT = str(unparsed_row[17:21])

  if not ELEMENT == "TMAX" and not ELEMENT == "TMIN":
    return False

  try:

    STATION_ID = str(unparsed_row[0:11]).strip()
    YEAR = int(unparsed_row[11:15])
    MONTH = int(unparsed_row[15:17])

    parsed_row.append(STATION_ID)
    parsed_row.append(YEAR)
    parsed_row.append(MONTH)
    parsed_row.append(ELEMENT)

    DAYS_IN_MONTH = 31
    FIRST_DAY_INDEX = 21
    CHARACTERS_NEEDED_FOR_READING_AND_FLAGS = 8

    FULL_RANGE = (DAYS_IN_MONTH * CHARACTERS_NEEDED_FOR_READING_AND_FLAGS) + FIRST_DAY_INDEX

    for index in range(FIRST_DAY_INDEX, FULL_RANGE, CHARACTERS_NEEDED_FOR_READING_AND_FLAGS):

      # Temperature comes in tenths of degrees C
      temperature_reading = int(unparsed_row[index:index + 5])

      '''
        https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt
        MFLAG1     is the measurement flag for the first day of the month.  There are
                   ten possible values:

                   Blank = no measurement information applicable
                   B     = precipitation total formed from two 12-hour totals
                   D     = precipitation total formed from four six-hour totals
             H     = represents highest or lowest hourly temperature (TMAX or TMIN)
                     or the average of hourly values (TAVG)
             K     = converted from knots
             L     = temperature appears to be lagged with respect to reported
                     hour of observation
                   O     = converted from oktas
             P     = identified as "missing presumed zero" in DSI 3200 and 3206
                   T     = trace of precipitation, snowfall, or snow depth
             W     = converted from 16-point WBAN code (for wind direction)

      '''
      MFLAG = str(unparsed_row[index+5:index+6])

      '''
        https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt
        QFLAG1     is the quality flag for the first day of the month.  There are
                   fourteen possible values:

                   Blank = did not fail any quality assurance check
                   D     = failed duplicate check
                   G     = failed gap check
                   I     = failed internal consistency check
                   K     = failed streak/frequent-value check
             L     = failed check on length of multiday period
                   M     = failed megaconsistency check
                   N     = failed naught check
                   O     = failed climatological outlier check
                   R     = failed lagged range check
                   S     = failed spatial consistency check
                   T     = failed temporal consistency check
                   W     = temperature too warm for snow
                   X     = failed bounds check
             Z     = flagged as a result of an official Datzilla
                     investigation
      '''
      QFLAG = str(unparsed_row[index+6:index+7])

      '''
        https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt
        SFLAG1     is the source flag for the first day of the month.  There are
                   thirty possible values (including blank, upper and
             lower case letters):

                   Blank = No source (i.e., data value missing)
                   0     = U.S. Cooperative Summary of the Day (NCDC DSI-3200)
                   6     = CDMP Cooperative Summary of the Day (NCDC DSI-3206)
                   7     = U.S. Cooperative Summary of the Day -- Transmitted
                     via WxCoder3 (NCDC DSI-3207)
                   A     = U.S. Automated Surface Observing System (ASOS)
                           real-time data (since January 1, 2006)
             a     = Australian data from the Australian Bureau of Meteorology
                   B     = U.S. ASOS data for October 2000-December 2005 (NCDC
                           DSI-3211)
             b     = Belarus update
             C     = Environment Canada
             D     = Short time delay US National Weather Service CF6 daily
                     summaries provided by the High Plains Regional Climate
               Center
             E     = European Climate Assessment and Dataset (Klein Tank
                     et al., 2002)
                   F     = U.S. Fort data
                   G     = Official Global Climate Observing System (GCOS) or
                           other government-supplied data
                   H     = High Plains Regional Climate Center real-time data
                   I     = International collection (non U.S. data received through
                     personal contacts)
                   K     = U.S. Cooperative Summary of the Day data digitized from
                     paper observer forms (from 2011 to present)
                   M     = Monthly METAR Extract (additional ASOS data)
             m     = Data from the Mexican National Water Commission (Comision
                     National del Agua -- CONAGUA)
             N     = Community Collaborative Rain, Hail,and Snow (CoCoRaHS)
             Q     = Data from several African countries that had been
                     "quarantined", that is, withheld from public release
               until permission was granted from the respective
                     meteorological services
                   R     = NCEI Reference Network Database (Climate Reference Network
                     and Regional Climate Reference Network)
             r     = All-Russian Research Institute of Hydrometeorological
                     Information-World Data Center
                   S     = Global Summary of the Day (NCDC DSI-9618)
                           NOTE: "S" values are derived from hourly synoptic reports
                           exchanged on the Global Telecommunications System (GTS).
                           Daily values derived in this fashion may differ significantly
                           from "true" daily data, particularly for precipitation
                           (i.e., use with caution).
             s     = China Meteorological Administration/National Meteorological Information Center/
                     Climatic Data Center (http://cdc.cma.gov.cn)
                   T     = SNOwpack TELemtry (SNOTEL) data obtained from the U.S.
                     Department of Agriculture's Natural Resources Conservation Service
             U     = Remote Automatic Weather Station (RAWS) data obtained
                     from the Western Regional Climate Center
             u     = Ukraine update
             W     = WBAN/ASOS Summary of the Day from NCDC's Integrated
                     Surface Data (ISD).
                   X     = U.S. First-Order Summary of the Day (NCDC DSI-3210)
             Z     = Datzilla official additions or replacements
             z     = Uzbekistan update

             When data are available for the same time from more than one source,
             the highest priority source is chosen according to the following
             priority order (from highest to lowest):
             Z,R,D,0,6,C,X,W,K,7,F,B,M,m,r,E,z,u,b,s,a,G,Q,I,A,N,T,U,H,S
      '''
      SFLAG = str(unparsed_row[index+7:index+8])

      corrected_temperature = math.nan if temperature_reading == -9999 or not has_passing_flags(MFLAG, QFLAG, SFLAG) else int(temperature_reading)

      parsed_row.append(corrected_temperature)

    return parsed_row

  except:

    print(f"\nCould not parse row:")
    print(unparsed_row)
    print()

    return False

def gather_station_files(FOLDER_WITH_DAILY_DATA):

  # Find all station data files in folder
  station_files = []

  all_stations = os.listdir(FOLDER_WITH_DAILY_DATA)

  # Create an array of all our .dly station file URLs
  for station_file_url in all_stations:

    if 'CRN' in station_file_url and station_file_url.endswith('.txt'):

      station_files.append(os.path.join(FOLDER_WITH_DAILY_DATA, station_file_url))

  return station_files

def convert_to_hundreds(tavg):

  if math.isnan(tavg):

    return math.nan

  elif tavg == -9999.0:

    return -9999

  else:

    return int(normal_round(tavg * 100))

def compile_uscrn_data(VERSION, FOLDER_WITH_DAILY_DATA):

  # Prepare our mega file to save all combined station temperatures too
  OUTPUT_FILE_URL = f"./uscrn.tavg.{VERSION}.dat"

  if os.path.exists(OUTPUT_FILE_URL):

    os.remove(OUTPUT_FILE_URL)

  print(f"\nCompiling USCRN data into a GHCNm-like monthly TAVG file to be named '{OUTPUT_FILE_URL}'\n")

  # Prepare the file for editing
  OUTPUT_CONTENT = open(OUTPUT_FILE_URL, 'a')

  station_files = gather_station_files(FOLDER_WITH_DAILY_DATA)

  total_stations = len(station_files)

  station_iterator = 0

  # For each daily station file
  for station_file_url in station_files:

    station_iterator += 1

    print(f"Composing station {station_iterator} of {total_stations}")

    names = [ 'station_id', 'year', 'month', 'tavg' ]

    colspecs = [ (0,5), (6,10), (10, 12), (56,64) ]

    station_daily_values = pd.read_fwf(station_file_url, names = names, colspecs=colspecs)

    # Convert each tavg into an int
    station_daily_values['tavg'] = station_daily_values['tavg'].apply(convert_to_hundreds).astype('Int64')

    station_daily_values['station_id'] = 'USCRN' + station_daily_values['station_id'].astype('str').apply(lambda s: str(s).rjust(6, '0') )

    # Convert the vertical months, into horizontal ones across each year
    station_daily_values = station_daily_values.pivot(

      index=['station_id', 'year'], columns='month', values='tavg'

    ).reset_index()

    # If the file has 12 columns, one for each month
    if len(station_daily_values.columns) == 14 and len(station_daily_values.values) > 1:

      # For each row in the station's data
      for year, row in station_daily_values.iterrows():

        # Create a representative string line to save in the output file
        output_row_string = f"\n{row['station_id']}{row['year']}TAVG"

        for month in range(1, 13):

          month_string = str(row[month]).replace('<NA>', '-9999').rjust(5, " ")

          output_row_string = output_row_string + f"{month_string}   "

        # Add the representative line to the output file
        OUTPUT_CONTENT.write(output_row_string)

  print(f"\n{check_mark} USCRN station data compiled into '{OUTPUT_FILE_URL}'\n")

  return OUTPUT_FILE_URL


import cv2
import numpy as np

import time
#from Whatsappmassage import Whatappmassagefunction
#from EmailAleert import MailAllertFunc
#number of constant for calculations
#EmptyParking=1;
FullParking=0;
avialibalrparkingspot=1;#inital number->emptyparking=1=number of all the spots
counter_of_frames_leaving_park=0;
counterofspot1_in=0;
counterofspot1_out=0;
counterofspot2_in=0;
counterofspot2_out=0;
counterofspot3_in=0;
counterofspot3_out=0;
counterofspot4_in=0;
counterofspot4_out=0;
counterofspot5_in=0;
counterofspot5_out=0;
counterofspot6_in=0;
counterofspot6_out=0;
counterofspot7_in=0;
counterofspot7_out=0;
counterofspot8_in=0;
counterofspot8_out=0;
bool("Entrparking");
Entrparking=False;#iniatializ
bool("Leavingparking");
bool("catch_spot_num_1");
bool("catch_spot_num_2");
bool("catch_spot_num_3");
bool("catch_spot_num_4");
bool("catch_spot_num_5");
bool("spot_num_1_ready_out");
bool("spot_num_1_ready_in");

#initiliaz catch const as a function of the spots status
#False=>spot caught
#True=>Spot free
catch_spot_num_1=False;
catch_spot_num_2=False;
catch_spot_num_3=False;
catch_spot_num_4=False;
catch_spot_num_5=False;
spot_num_1_ready_out=False;
spot_num_1_ready_in=False;
Leavingparking=False;
cap = cv2.VideoCapture('shalom-alichem-keren-shalom-day-23-10-20_a.avi')#VideoCapture(0)-for camera live
frame_width = int( cap.get(cv2.CAP_PROP_FRAME_WIDTH))

frame_height =int( cap.get( cv2.CAP_PROP_FRAME_HEIGHT))

fourcc = cv2.VideoWriter_fourcc('X','V','I','D')

out = cv2.VideoWriter("output.avi", fourcc, 5.0, (1280,720))#record the output and send it to some path

font = cv2.FONT_HERSHEY_COMPLEX
ret, frame1 = cap.read()
ret, frame2 = cap.read()
print(frame1.shape)

while cap.isOpened():
    diff = cv2.absdiff(frame1, frame2)
    image1=out.write(diff)
    gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5,5), 0)
    _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
    dilated = cv2.dilate(thresh, None, iterations=3)
    contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cv2.putText(frame1, "{}".format('Num of available parking spots:'+ str(avialibalrparkingspot)+''), (10, 20), cv2.FONT_HERSHEY_SIMPLEX,
                0.7, (0, 0, 255), 2)
    if avialibalrparkingspot <= 0:
         avialibalrparkingspot=0
    if avialibalrparkingspot==10:
        cv2.putText(frame1, "Status: {}".format('All parking spots available' ),
                    (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
                    0.6, (0, 0, 255), 2)
    if  avialibalrparkingspot==FullParking:
        cv2.putText(frame1, "Status: {}".format('All parking spots caught!'),
                    (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
                    0.6, (0, 0, 255), 2)
    for contour in contours:
        (x, y, w, h) = cv2.boundingRect(contour)
        print('Number of available parking spot:'+ str(avialibalrparkingspot)+'')

        if cv2.contourArea(contour) < 520:#The number is the area of the rectangle
            continue
        cv2.rectangle(frame1, (x, y), (x+w, y+h), (0, 255, 0), 2)
        #showing coordinats on screen
        string = str(x) + " " + str(y)
        cv2.putText(frame1, string, (x, y),font, 0.7, (0, 255, 0))

        outallert='Watch-out! Car going out the parking spot!';
        inallert='Watch-out! Car enter the parking spot!';
        spot1Out= 'Allert:"Hovevi Chion street":Car going out, parking Spots number 1 available'
        spot1In= 'Allert:"Hovevi Chion street": parking Spots number 1 caught'
        spot2Out = 'Allert:"Hovevi Chion street":Car going out, parking Spots number 2 available'
        spot2In = 'Allert:"Hovevi Chion street": parking Spots number 2 caught'
        spot3Out = 'Allert:"Hovevi Chion street":Car going out, parking Spots number 3 available'
        spot3In = 'Allert:"Hovevi Chion street": parking Spots number 3 caught!'
        spot4Out = 'Allert:"Hovevi Chion street":Car going out, parking Spots number 4 available'
        spot4In = 'Allert:"Hovevi Chion street": parking Spots number 4 caught!'
        spot5Out = 'Allert:"Hovevi Chion street":Car going out, parking Spots number 5 available'
        spot5In = 'Allert:"Hovevi Chion street": parking Spots number 5 caught!'
        if (x>40 and x<78) and (y>51 and y<72):
            print(inallert)
            Entrparking=True;
            cv2.putText(frame1, "{}".format('Car/s enter the parking spot!'), (50, 400), cv2.FONT_HERSHEY_SIMPLEX,
                        0.9, (0, 0, 255),3)

            # Spots number 1 Checking
            # if car catch spot num 1
            #option 1-front
        if (x > 470 and x < 475) and (y > 447 and y < 452) and (catch_spot_num_1 == True):
            print(spot1In)
            counterofspot1_in = counterofspot1_in + 1;  # counter of changes of frames at spot parking
            if counterofspot1_in > 4:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_1 = False;
                counterofspot1_in = 0;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 1 caught'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            #option 2-reverse
            ##if car going to catch spot num 1 by reverse
        if (x > 554 and x <559 ) and (y > 447 and y < 452) and (catch_spot_num_1 == True):
            print("car going to catch spot number 1 by reverse,ready==True")
            spot_num_1_ready_in=True;

        if (x > 520 and x < 558) and (y > 442 and y < 452) and (catch_spot_num_1 == True) and (spot_num_1_ready_in==True):
            print(spot1In)
            counterofspot1_in = counterofspot1_in + 1;  # counter of changes of frames at spot parking
            if counterofspot1_in > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_1 = False;
                counterofspot1_in = 0;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 1 caught'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            ##if car going to leave spot num 1
        if (x > 534 and x < 567) and (y > 437 and y < 459) and (catch_spot_num_1 == False):
            print("car going to leave spot number 1,ready==True")
            spot_num_1_ready_out=True;

            ##if car leaving spot num 1
        if (x > 520 and x < 570 ) and (y > 435 and y < 460) and (catch_spot_num_1 == False) and ( spot_num_1_ready_out==True):
            print(spot1Out)
            counterofspot1_out = counterofspot1_out + 1;  # counter of changes of frames at spot parking
            if counterofspot1_out > 2:
                avialibalrparkingspot = avialibalrparkingspot + 1;
                counterofspot1_out = 0;
                catch_spot_num_1 = True;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 1 is available to park'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            # Spots number 2 Checking
            # if car catch spot num 2
        if (x > 336 and x < 341) and (y > 328 and y < 333) and (catch_spot_num_2 == True):
            print(spot2In)
            counterofspot2_in = counterofspot2_in + 1;  # counter of changes of frames at spot parking
            if counterofspot2_in > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_2 = False;
                counterofspot2_in = 0;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 2 caught'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)
            ##if car leaving spot num 2
        if (x > 336 and x < 341) and (y > 328 and y < 333) and (catch_spot_num_2 == False):
            print(spot2Out)
            counterofspot2_out = counterofspot2_out + 1;  # counter of changes of frames at spot parking
            if counterofspot2_out > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                counterofspot2_out = 0;
                catch_spot_num_2 = True;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 2 is available to park'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            # Spots number 3 Checking
            # if car catch spot num 3
        if (x > 213 and x < 218) and (y > 228 and y < 233) and (catch_spot_num_3 == True):
            print(spot3In)
            counterofspot3_in = counterofspot3_in + 1;  # counter of changes of frames at spot parking
            if counterofspot3_in > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_3 = False;
                counterofspot3_in = 0
                cv2.putText(frame1, "Status: {}".format('Parking spot num 3 caught'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)
            ##if car leaving spot num 3
        if (x > 213 and x < 218) and (y > 228 and y < 233) and (catch_spot_num_3 == False):
            print(spot3Out)
            counterofspot3_out = counterofspot3_out + 1;  # counter of changes of frames at spot parking
            if counterofspot3_out > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                counterofspot3_out = 0;
                catch_spot_num_3 = True;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 3 is available to park'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            # Spots number 4 Checking
            # if car catch spot num 4
        if (x > 156 and x < 161) and (y > 185 and y < 190) and (catch_spot_num_4 == True):
            print(spot4In)
            counterofspot4_in = counterofspot4_in + 1;  # counter of changes of frames at spot parking
            if counterofspot4_in > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_4 = False;
                counterofspot4_in = 0;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 4 caught!'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)
            ##if car leaving spot num 4
        if (x > 156 and x < 161) and (y > 185 and y < 190) and (catch_spot_num_4 == False):
            print(spot4Out)
            counterofspot4_out = counterofspot4_out + 1;  # counter of changes of frames at spot parking
            if counterofspot4_out > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                counterofspot4_out = 0;
                catch_spot_num_4 = True;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 4 is available to park'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

            # Spots number 5 Checking
            # if car catch spot num 5
        if (x > 115 and x < 120) and (y > 150 and y < 155) and (catch_spot_num_5 == True):
            print(spot5In)
            counterofspot5_in = counterofspot5_in + 1;  # counter of changes of frames at spot parking
            if counterofspot5_in > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                catch_spot_num_5 = False;
                counterofspot5_in = 0;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 5 caught'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)
            ##if car leaving spot num 5
        if (x > 115 and x < 120) and (y > 150 and y < 155) and (catch_spot_num_5 == False):
            print(spot5Out)
            counterofspot5_out = counterofspot5_out + 1;  # counter of changes of frames at spot parking
            if counterofspot5_out > 2:
                avialibalrparkingspot = avialibalrparkingspot - 1;
                counterofspot5_out = 0;
                catch_spot_num_5 = True;
                cv2.putText(frame1, "Status: {}".format('Parking spot num 5 is available to park'), (10, 100),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            0.6, (0, 0, 255), 1)

                # if car leaving the parking
        if (x>420 and x<641) and (y>370 and y<480):
            print(outallert)
            Leavingparking=True;
            cv2.putText(frame1, "Status: {}".format('Car/s leaving parking spot'), (50, 370), cv2.FONT_HERSHEY_SIMPLEX,
                        0.8, (0, 0, 255), 3)
            Exitparking=True;

        #Whatappmassagefunction(allert);
    #cv2.drawContours(frame1, contours, -1, (0, 255, 0), 2)

    image = cv2.resize(frame1, (1280,720))
    out.write(image)
    cv2.imshow("feed", frame1)

    frame1 = frame2
    ret, frame2 = cap.read()

    # channels = cv2.mean(frame2)
    # observation = np.array([(channels[2], channels[1], channels[0])])
    # if np.mean(observation)<130 and np.mean(observation)>120:#128 value is gray in RGB
    #     print("Gray image/Empty parking")

    # _, binaryimage = cv2.threshold( frame2, 209, 255, cv2.THRESH_BINARY)
    # print(binaryimage)

    if cv2.waitKey(40) == 27:#Esc for exit camera
        break

cv2.destroyAllWindows()
cap.release()
out.release()


import pprint
from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects, HTTPError
import json
import keys
import traceback

pp = pprint.PrettyPrinter(indent=4)

# ID:
# BTC: 1
# ETH: 1027
# SOL: 5426
# MOB: 7878
# FTT: 4195
# BEAN: 12503
# GOLD: 3575

class Crypto(object):
    def __init__(self, *args, **kwargs):
        self.url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
        self.parameters = {
          'convert':'USD',
          # 'symbol':'BTC,ETH,SOL,FTT,GOLD'
          'id':'1,1027,5426,4195,3575'
        }
        self.headers = {
          'Accepts': 'application/json',
          'X-CMC_PRO_API_KEY': keys.coinmarketcap_key,
        }

    def get_crypto_quotes(self):
        session = Session()
        session.headers.update(self.headers)

        response = session.get(self.url, params=self.parameters)
        response.raise_for_status()

        data = json.loads(response.text)

        watched_tickers = {"BTC":"1", "ETH":"1027", "SOL":"5426", "FTT":"4195","GOLD":"3575"}
        reported_tickers = {}
        crypto_list = data["data"]

        for symbol,id in watched_tickers.items():
            crypto = crypto_list[id]
            current_price = crypto["quote"]["USD"]["price"]
            daily_volume = crypto["quote"]["USD"]["volume_24h"]
            daily_percent_change = crypto["quote"]["USD"]["percent_change_24h"]

            reported_tickers[symbol] = {}
            reported_tickers[symbol]["price"] = current_price
            reported_tickers[symbol]["volume"] = daily_volume
            reported_tickers[symbol]["change"] = daily_percent_change

        status_string = ""
        status_tuples = []
        for reported_ticker, values in reported_tickers.items():
            trend = "↓"
            trend_status = "down"
            if values["change"]>=0:
                trend = "↑"
                trend_status = "up"

            status_string = reported_ticker + ": " + "$" + "{:.2f}".format(values["price"]) + " "  + trend + " {:.2f}".format(values["change"]) + "%  "
            status_tuples.append((status_string, trend_status))
           #  print(status_string)
        return(status_tuples)

    def getMap(self):
        url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
        parameters = {
          # 'convert':'USD'z,
          # 'symbol':'BTC,ETH,SOL,MOB'
          # 'id':'1,1027,5426'
        }
        session = Session()
        session.headers.update(self.headers)

        response = session.get("https://pro-api.coinmarketcap.com/v1/cryptocurrency/map", params=parameters)
        response.raise_for_status()

        data = json.loads(response.text)
        return data

if __name__ == "__main__":
    ticker = Crypto()
    pp.pprint(ticker.getMap())
    # pp.pprint(ticker.get_crypto_quotes())


from collections import deque
from datetime import timedelta

robots = [r for r in input().split(';')]
free_robots = deque([[el for el in r.split('-')] for r in robots])
hours, minutes, seconds = [int(t) for t in input().split(':')]
robots_working = {}
current_time = timedelta(hours=hours, minutes=minutes, seconds=seconds)
# final_time = start_time + timedelta(seconds=68)

queue_products = deque()

while True:
    command = input()
    if command == 'End':
        break
    queue_products.append(command)

while queue_products:
    product = queue_products.popleft()
    current_time += timedelta(seconds=1)
    if free_robots:
        name, work_time = free_robots.popleft()
        work_time = int(work_time)
        if current_time < timedelta(hours=10):
            print(f'{name} - {product} [0{current_time}]')
        else:
            print(f'{name} - {product} [{current_time}]')

        finish_work = current_time + timedelta(seconds=work_time)
        robots_working[name] = [work_time, str(finish_work)]
    else:
        queue_products.append(product)
        best_time_robot = ['', -10000000]
        for name, list_info in robots_working.items():
            work_time, finish_work = list_info
            if int(work_time) < best_time_robot[1]:
                best_time_robot = [name, work_time]
                finis = finish_work
        free_robots.append(best_time_robot)


from transformers import AutoModelForSequenceClassification
from transformers import AutoTokenizer, AutoConfig
from scipy.special import softmax
import os
import pandas as pd
from preprocess import preprocess as pp

class SentimentModel:
    def __init__(self, model_name):
        self.model_name = model_name
        # Check if tokenizer already exists, otherwise create it
        tokenizer_saved_path = "cardiffnlp/tokenizer"
        if os.path.exists(tokenizer_saved_path):
            self.tokenizer = AutoTokenizer.from_pretrained(tokenizer_saved_path)
        else:
            self.tokenizer = AutoTokenizer.from_pretrained(model_name)
            self.tokenizer.save_pretrained(tokenizer_saved_path)
        self.config = AutoConfig.from_pretrained(model_name)
        self.model = AutoModelForSequenceClassification.from_pretrained(model_name)

    def score(self, text):
        encoded_input = self.tokenizer(text, return_tensors="pt")
        output = self.model(**encoded_input)
        scores = output[0][0].detach().numpy()
        scores = softmax(scores)
        return scores

    def score_from_tweets_df(self, df):
        # Create a new DataFrame to store the average sentiment score for each date
        sentiment_df = pd.DataFrame(
            columns=[
                "Date",
                "Text",
                "Negative_Score",
                "Natural_Score",
                "Positive_Score",
            ]
        )

        # Iterate over each date and calculate the average sentiment score for all tweets on that date
        for tweet in df.iterrows():
            text = tweet[1].text
            date = tweet[1].Date
            sentiment_score = self.score(text)
            new_row = pd.DataFrame(
                {
                    "Date": date,
                    "Text": text,
                    "Negative_Score": sentiment_score[0],
                    "Natural_Score": sentiment_score[1],
                    "Positive_Score": sentiment_score[2],
                },
                index=[0],
            )
            sentiment_df = pd.concat([sentiment_df, new_row], ignore_index=True)

        sentiment_df = pp.calculate_avarge_rolling(sentiment_df,'Negative_Score',250)
        return sentiment_df


from django.shortcuts import render

from shop_order.models import Order
from shop_product.models import Product
from shop_setting.models import Setting
from shop_slider.models import Slider

def header(request):
    site_setting = Setting.objects.first()
    active_order: Order = Order.objects.filter(owner_id=request.user.id, is_paid=False).first()
    len_order_detail = 0
    if active_order is not None:
        len_order_detail = len(active_order.orderdetail_set.all())

    context = {
        'setting': site_setting,
        'order_detail': len_order_detail
    }
    return render(request, 'shared/Header.html', context)

def footer(request):
    context = {}
    return render(request, 'shared/Footer.html', context)

def slider(request):
    active_slider = Slider.objects.filter(active=True).all()

    context = {
        'slider': active_slider
    }
    return render(request, 'shared/slider_component.html', context)

def meta_tags(request):
    site_setting = Setting.objects.first()

    context = {
        'setting': site_setting
    }
    return render(request, 'shared/mata_tags_component.html', context)

def home_page(request):
    last_products = Product.objects.get_active_product().order_by('-id').all()[:5]

    context = {
        'title': 'صفحه اصلی | فروشگاه ووگا فودز',
        'slider_title': 'محصولات ارگانیک و طبیعی',
        'slider_text': 'ارسال سریع توسط فروشگاه',
        'last_products': last_products,
    }
    return render(request, 'home_page.html', context)


import logging

import boto3

import config

def obj_last_modified(myobj):
    """
    Gets the last modified date of the file
    :param myobj:
    :return: Last Modified timestamp of file
    """
    return myobj['LastModified']

def fileWithLeastTimestamp():
    """
    Gets the file with the least timestamp
    :return: file with the least timestamp
    """
    s3client = boto3.client('s3')
    try:
        response = s3client.list_objects(Bucket=config.BUCKET_NAME, Prefix=config.PREFIX)
        print('resonpnse is: ', response)
    except Exception as e:
        logging.error(e)
        print(f'Unexpected error while listing the dir {config.BUCKET_NAME}:{config.PREFIX}')
    if ('Contents' in response):
        l = []
        for key in response['Contents']:
            l.append(key)
        sortedObjects = sorted(l, key=obj_last_modified, reverse=False)
        return sortedObjects[0]['Key']
    return None


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
from scipy import signal
import os
import pylab

# make values from -5 to 5, for this example

UNKNOWN_FLOW_THRESH = 0.5

def readFlowFile(file):
    assert type(file) is str, "file is not str %r" % str(file)
    assert os.path.isfile(file) is True, "file does not exist %r" % str(file)
    assert file[-4:] == '.flo', "file ending is not .flo %r" % file[-4:]
    f = open(file, 'rb')
    flo_number = np.fromfile(f, np.float32, count=1)[0]
    w = np.fromfile(f, np.int32, count=1)
    h = np.fromfile(f, np.int32, count=1)
    # if error try: data = np.fromfile(f, np.float32, count=2*w[0]*h[0])
    # data = np.fromfile(f, np.float32, count=2*w*h)
    data = np.fromfile(f, np.float32, count=2*w[0]*h[0])
    # Reshape data into 3D array (columns, rows, bands)
    flow = np.resize(data, (int(h), int(w), 2))
    f.close()

    u = flow[: , : , 0]
    v = flow[: , : , 1]
    smaller_u = np.where(abs(u) < UNKNOWN_FLOW_THRESH)
    smaller_v = np.where(abs(v) < UNKNOWN_FLOW_THRESH)
    u[smaller_u] = 0
    u[smaller_v] = 0
    v[smaller_u] = 0
    v[smaller_v] = 0
    u = signal.medfilt(u, 5)
    v = signal.medfilt(v, 5)

    smaller_u = np.where(abs(u) < UNKNOWN_FLOW_THRESH)
    smaller_v = np.where(abs(v) < UNKNOWN_FLOW_THRESH)
    u[smaller_u] = -100
    u[smaller_v] = -100
    v[smaller_u] = -100
    v[smaller_v] = -100
    flow[: , : , 0] = u
    flow[: , : , 1] = v
    tmp = []
    for row in flow:
      for element in row:
        tmp.append(element)

    return tmp

fig, ax = plt.subplots(tight_layout=True)

for i in range(660, 825):
  print('../flow/flow%d.flo' % i)
  arr = readFlowFile('../flow/flow%d.flo' % i)

  x = []
  y = []
  for element in arr:
    x.append(element[0])
    y.append(element[1])

  hist = ax.hist2d(x, y, bins=100, range=[[-10, 10],[-10, 10]])
  plt.savefig('./plt/plt%d.png' % i)


import geojson
from tqdm import tqdm
import sqlite3
from pathlib import Path

db = Path.cwd().parent / 'data/main.db'

def get_routes():
    """
    Extracts the buses and routes from bus-routes.geojson and saves them
    to the db in the tables 'buses' and 'routes_points'.

    Args:
        None

    Returns:
        None
    """

    conn = sqlite3.connect(db)
    cursor = conn.cursor()

    stmt_delete = 'DELETE FROM buses;'
    cursor.execute(stmt_delete)
    stmt_delete = 'DELETE FROM routes_points;'
    cursor.execute(stmt_delete)

    with open('../data/bus-routes.geojson', 'r') as f:
        gj = geojson.load(f)

    buses = []

    for item in gj['features']:
        try:
            if item['properties']['network'] not in ['Movia', 'Takst Sjælland']:
                continue
            if item['properties']['route'] != 'bus':
                continue
            bus = {}
            bus['name'] = item['properties']['ref']
        except:
            continue
        try:
            bus['from'] = item['properties']['from']
        except:
            bus['from'] = None
        try:
            bus['to'] = item['properties']['to']
        except:
            bus['to'] = None
        bus['route'] = []

        if item['geometry']['type'] == 'LineString':
            segment = []
            for point in item['geometry']['coordinates']:
                segment.append([point[1], point[0]])
            bus['route'].append(segment)
        elif item['geometry']['type'] == 'MultiLineString':
            for subroute in item['geometry']['coordinates']:
                segment = []
                for point in subroute:
                    segment.append(point[::-1])
                bus['route'].append(segment)
        buses.append(bus)

    stmt_buses = """INSERT INTO buses (name, from_station_name, to_station_name)
            VALUES (?, ?, ?);"""

    stmt_routes = """INSERT INTO routes_points (bus_id, segment, coordinates, seq)
            VALUES (?, ?, ?, ?);"""

    for bus in tqdm(buses):
        data = (bus['name'], bus['from'], bus['to'])
        cursor.execute(stmt_buses, data)
        bus_id = cursor.lastrowid
        for segment_index, segment in enumerate(bus['route']):
            for point_index, point in enumerate(segment):
                data = (bus_id, segment_index+1, ','.join(map(str, point)), point_index+1)
                cursor.execute(stmt_routes, data)

    conn.commit()
    cursor.close()
    conn.close()

if __name__ == '__main__':
    get_routes()


import secrets
import canonicaljson
import hashlib
import decimal
import datetime
import logging
import random

from . import apitype

import beeline

STANDARD_SUMMARY_BATCHES = [20, 50]

def traced_function(f):
    name = f.__name__
    return beeline.traced(name=name)(f)

from .models import (
    Fact,
    FactCategory,
    FactType,
    BooleanChallenge,
    NumericChallenge,
    Challenge,
    BooleanResponse,
    NumericResponse,
    Response,
    SummaryScore,
    RESPONSE_MODELS,
    FACT_MODELS,
)

from .stats import (
    calculate_plausibility_of,
)

from .exceptions import (
    BadRequest,
    AlreadyResponded,
    NoFactsAvailable,
    PermissionDenied,
)

logger = logging.getLogger(__name__)

@traced_function
def generate_uid():
    return secrets.token_hex(16)

@traced_function
def select_random_fact():
    cats = [cat for cat in FactCategory.objects.all() if cat.active]
    logger.info(
        "Selecting random facts: categories: %s",
        [(cat.name, float(cat.weight)) for cat in cats],
    )
    cat_name = None
    if not cats:
        qs = Fact.objects.filter(active=True)
        logger.info("No categories -- using legacy random selection.")
    else:
        total_weight = float(sum(cat.weight for cat in cats))
        x = random.random() * total_weight
        for cat in cats:
            x -= float(cat.weight)
            if x < 0:
                break
        cat_name = cat.name
        qs = Fact.objects.filter(active=True, category=cat)
    logger.info("Choosing randomly (from category %s) among %d options", cat_name, qs.count())
    return qs.order_by("?").first()

@traced_function
def _save_and_return(x):
    x.save()
    return x

@traced_function
def create_boolean_challenge(fact):
    return _save_and_return(BooleanChallenge(fact=fact))

@traced_function
def create_numeric_challenge(fact):
    return _save_and_return(NumericChallenge(fact=fact))

@traced_function
def create_challenge_from_fact(user, fact):
    creators = {
        "boolean_fact": create_boolean_challenge,
        "numeric_fact": create_numeric_challenge,
    }
    kw = {
        k.replace("_fact", "_challenge"): f(getattr(fact, k))
        for k, f in creators.items()
        if getattr(fact, k)
    }
    return _save_and_return(Challenge(
        uid = generate_uid(),
        user = user,
        fact = fact,
        challenge_type = fact.fact_type,
        **kw,
    ))

@traced_function
def get_or_create_current_challenge(user):
    challenge = Challenge.objects.filter(
        user = user,
        active = True,
        response__isnull = True,
    ).order_by("-creation_time").first()

    if not challenge:
        fact = select_random_fact()
        if not fact:
            raise NoFactsAvailable()
        challenge = create_challenge_from_fact(user, fact)

    return challenge

@traced_function
def discard_current_challenge(user, challenge_uid=None):
    qs = Challenge.objects.filter(
        user = user,
        active = True,
        response__isnull = True,
    )
    if challenge_uid:
        qs = qs.filter(uid = challenge_uid)
    return qs.update(active = False)

@traced_function
def respond_to_challenge(user, challenge_uid, response):
    challenge = Challenge.objects.get(user = user, uid = challenge_uid)

    try:
        challenge.response
        raise AlreadyResponded(detail = f"Challenge {challenge_uid} has already gotten a response")
    except Challenge.response.RelatedObjectDoesNotExist:
        pass

    k = challenge.challenge_type
    if list(response) != [k]:
        raise BadRequest(detail = f"Challenge is of type {k}; got response of other type ({list(response)})")

    response_cls = RESPONSE_MODELS[k]

    response_core = _save_and_return(response_cls(
        challenge = challenge.challenge,
        **response[k],
    ))
    response_field = k + "_response"

    confidence = response_core.confidence_percent

    is_correct = response_core.get_correctness()

    rv = _save_and_return(Response(
        user = user,
        challenge = challenge,
        confidence_percent = confidence,
        correct = is_correct,
        response_type = k,
        **{response_field: response_core},
    ))

    for batch_size in STANDARD_SUMMARY_BATCHES:
        maybe_summarize_responses(user, batch_size)

    return rv

@traced_function
def get_last_response(user):
    return Response.objects.filter(
        user = user,
    ).order_by("-creation_time").first()

@traced_function
def get_user_responses(user, limit):
    return Response.objects.filter(
        user = user,
    ).order_by("creation_time").reverse()[:limit]

def _maybe_pop(d, k):
    if k in d:
        return d.pop(k)
    return None

@traced_function
def post_fact(fact_data):
    fact_data = dict(fact_data)

    key = fact_data.pop("key")

    category_name = None
    if "category" in fact_data:
        category_name = fact_data.pop("category")

    category = None
    if category_name:
        category, _ = FactCategory.objects.get_or_create(name = category_name)

    logger.info("Attempting to post new fact (with key: %s)", key)

    kwargs = {
        "category": category_name,
        "source_link": _maybe_pop(fact_data, "source_link"),
        "source": _maybe_pop(fact_data, "source"),
        "fine_print": _maybe_pop(fact_data, "fine_print"),
    }

    if len(fact_data) != 1:
        raise BadRequest(f"Invalid fact data (unknown type): {' '.join(fact_data)}")

    fact_type = list(fact_data)[0]
    fact_payload = list(fact_data.values())[0]
    fact_hashable_obj = {
        fact_type: fact_payload,
        **kwargs,
    }
    fact_hashable = canonicaljson.encode_canonical_json(fact_hashable_obj)

    fact_hash = hashlib.sha256(fact_hashable).hexdigest()

    logger.info("Attempting to post new fact (with key: %s, hash: %s)", key, fact_hash)

    old_fact = Fact.objects.filter(
        key = key,
        active = True,
    ).first()
    if old_fact:
        if old_fact.version_hash and old_fact.version_hash == fact_hash:
            logger.info("Attempting to post new fact (with key: %s, hash: %s): rejected, same as active fact", key, fact_hash)
            return old_fact

    field_name = fact_type + "_fact"

    core = FACT_MODELS[fact_type].objects.create(**fact_payload)

    kwargs["category"] = category
    kwargs[field_name] = core

    Fact.objects.filter(key = key).update(active = False)
    return Fact.objects.create(
        key = key,
        active = True,
        version_hash = fact_hash,
        fact_type = fact_type,
        **kwargs,
    )

@traced_function
def get_eval_stats_for_scope(user, limit=None, **kwargs):
    qs = Response.objects.filter(user=user, **kwargs)
    if limit is None:
        objs = list(qs.all())
    else:
        objs = qs.order_by("-creation_time")[:limit]
    correct = [o.correct for o in objs]
    confidences = [o.confidence_percent/100 for o in objs]
    assert len(correct) == len(confidences)
    expected = sum(confidences)
    confidence_correctness = list(zip(confidences, correct))
    plausibility = calculate_plausibility_of(confidence_correctness)
    return {
        "number_of_answers": len(objs),
        "number_of_correct_answers": sum(correct),
        "expected_correct_answers": expected,
        "plausibility": plausibility,
    }

@traced_function
def get_eval_stats(user):
    now = datetime.datetime.now()
    cutoff_24h = now - datetime.timedelta(hours=24)
    rv = {
        "stats": {
            "total": get_eval_stats_for_scope(user),
            "24h": get_eval_stats_for_scope(user, creation_time__gte=cutoff_24h),
            "last50": get_eval_stats_for_scope(user, limit=50),
            "last10": get_eval_stats_for_scope(user, limit=10),
        },
    }
    logger.info("Returning evaluation stats: %s", repr(rv))
    return rv

@traced_function
def get_summarizable_responses_qs(user, batch_size):
    return Response.objects.filter(
        user = user,
        resolved = True,
    ).exclude(
        summary_scores__batch_size = batch_size,
    ).order_by("creation_time")

@traced_function
def get_summarizable_responses(user, batch_size):
    qs = get_summarizable_responses_qs(user, batch_size)
    if qs.count() < batch_size:
        return None
    return qs[:batch_size]

@traced_function
def maybe_summarize_responses(user, batch_size):
    batch = get_summarizable_responses(user, batch_size)
    if not batch:
        return None

    conf_corr = [
        (float(x.confidence_percent/100), x.correct)
        for x in batch
    ]

    actual_correct = sum(corr for _, corr in conf_corr)
    expected_correct = sum(float(conf) for conf, _ in conf_corr)

    resp = calculate_plausibility_of(conf_corr)
    assert resp

    rv = SummaryScore.objects.create(
        user = user,
        batch_size = batch_size,
        actual_correct = actual_correct,
        expected_correct = expected_correct,
        probability_fewer_correct = resp["prob_fewer"],
        probability_same_correct = resp["prob_same"],
        probability_more_correct = resp["prob_more"],
    )
    rv.datapoints.set(batch)
    return rv

@traced_function
def get_last_summary(user, batch_size=None):
    batch_size = batch_size or STANDARD_SUMMARY_BATCHES[0]
    return SummaryScore.objects.filter(
        user = user,
        batch_size = batch_size,
    ).order_by("-creation_time").first()

@traced_function
def get_batch_progress(user, batch_size=None):
    batch_size = batch_size or STANDARD_SUMMARY_BATCHES[0]
    qs = get_summarizable_responses_qs(user, batch_size)
    achieved = min(batch_size, qs.count())
    return achieved, batch_size

@traced_function
def get_largest_standard_summarized_batch_size(user):
    active_batch_sizes = SummaryScore.objects.filter(
        user = user,
    ).values_list("batch_size", flat=True).distinct()
    logger.info("Active batch sizes: %s", repr(active_batch_sizes))

    active_std = set(active_batch_sizes) & set(STANDARD_SUMMARY_BATCHES)

    logger.info("Active standard batch sizes (%s): %s", repr(STANDARD_SUMMARY_BATCHES), repr(active_std))
    if not active_std:
        return None

    return max(active_std)

@traced_function
def get_challenge_by_uid(user, uid):
    return Challenge.objects.get(user = user, uid = uid)

@traced_function
def delete_user_account(user):
    user.delete()

@traced_function
def get_summary_chart_data(user, batch_size = None):
    batch_size = batch_size or get_largest_standard_summarized_batch_size(user)

    if not batch_size:
        return None

    timestamps = []
    lower = []
    upper = []

    scores = SummaryScore.objects.filter(
        user = user,
        batch_size = batch_size,
    ).all()

    if not scores:
        return None

    for score in scores:
        timestamps.append(score.creation_time.strftime("%Y-%m-%d %H:%M"))

    return {
	"type": "line",
	"data": {
                "labels": [str(x) for x in timestamps],
		"datasets": [
                    {
                        "label": "Fewer (underconfident)",
			"data": [x.probability_fewer_correct for x in scores],
                        "borderColor": "#ffaaaa",
                        "backgroundColor": "#ee9999",
                    },
                    {
                        "label": "Same (calibrated)",
			"data": [x.probability_same_correct for x in scores],
                        "borderColor": "#aaffaa",
                        "backgroundColor": "#99ee99",
                    },
                    {
                        "label": "More (overconfident)",
			"data": [x.probability_more_correct for x in scores],
                        "borderColor": "#aaaaff",
                        "backgroundColor": "#9999ee",
                    },
                ],
	},
        "options": {
            "title": {
                "display": True,
                "text": f"Expected correct answers given calibration (batches of {batch_size})",
            },
            "tooltips": {
                "mode": "index",
            },
            "scales": {
                "yAxes": [
                    {
                        "stacked": True,
                    },
                ],
            },
        },
    }

@traced_function
def export_facts(user):
    if not user.is_staff:
        logger.info("User (%s) is not staff user: refusing export", repr(user))
        raise PermissionDenied()

    qs = Fact.objects.filter(
        active = True,
    ).select_related("category")

    logger.info("Exporting %d facts.", qs.count())

    rv = []

    for obj in qs.order_by("pk"):
        attrname = obj.fact_type + "_fact"
        kwargs = getattr(obj, attrname).export()

        logger.info("Exporting fact: %s (cat: %s)", repr(obj), repr(obj.category))

        rv.append(apitype.Fact(
            key = obj.key,
            category = obj.category.name if obj.category else None,
            fine_print = obj.fine_print,
            source = obj.source,
            source_link = obj.source_link,
            **kwargs,
        ))

    return [{k: v for k, v in x.dict().items() if v} for x in rv]

@traced_function
def export_fact_categories(user):
    if not user.is_staff:
        logger.info("User (%s) is not staff user: refusing export", repr(user))
        raise PermissionDenied()

    qs = FactCategory.objects.all()

    logger.info("Exporting %d fact categories.", qs.count())

    rv = []

    for obj in qs.order_by("pk"):
        rv.append(apitype.FactCategory(
            name = obj.name,
            weight = decimal.Decimal(obj.weight),
        ))

    return [{k: v for k, v in x.dict().items() if v} for x in rv]

@traced_function
def post_fact_category(cat_data):
    cat = apitype.FactCategory.parse_obj(cat_data)

    old_cat = FactCategory.objects.filter(
        name = cat.name,
    ).first()

    if old_cat:
        old_cat.weight = cat.weight
        old_cat.save()
        return

    return FactCategory.objects.create(
        name = cat.name,
        weight = cat.weight,
    )


import os
import gzip
import time
import zipfile

from .. import files
from .util import filtered_container_list

# TODO: Should we support tarfiles?
class FileOpener(object):
    """Context manager that will open a (possibly compressed) filesystem file.

    FileOpener will close any open files when the context is exited.
    """
    def __init__(self, file_entry, zip_filter, match_type='first'):
        """Create a new FileOpener

        Arguments:
            file_entry (dict): The file entry as retrieved from the database
            zip_filter (regex): The regular expression to match zip entries, if applicable
            match_type (str): The optional match type if multiple zip entries are matched (default is first)
        """
        self.file_entry = file_entry
        self.zip_filter = zip_filter
        self.match_type = match_type

        # This is the opened file_entry file
        self._system_fd = None

        # This is the optional ZipFile instance
        self._zipfile = None

        # This is the optional set of zipfile entries
        self._zip_entries = []

        # This is the final _fd for reading
        self._fd = None

        # The final filename
        self._name = file_entry['name']

    def is_gzip(self):
        """Check if the file described by file_entry is a gzip file"""
        _, ext = os.path.splitext(self.file_entry['name'])
        return ext == '.gz'

    def __enter__(self):
        # Try to open the file
        open_mode = 'r'
        gz = self.is_gzip()

        if self.zip_filter or gz:
            open_mode = 'rb'
        try:
            # Open the file using file_system
            file_path, file_system = files.get_valid_file(self.file_entry)
            self._system_fd = file_system.open(file_path, open_mode)

            if self.zip_filter:
                # Open zipfile
                self._zipfile = zipfile.ZipFile(self._system_fd)

                # Find zip entry
                zip_entries = []
                for zipinf in self._zipfile.infolist():
                    zip_entries.append({
                        'path': zipinf.filename,
                        'timestamp': time.mktime(zipinf.date_time + (0, 0, -1))
                    })

                self._zip_entries = filtered_container_list(zip_entries, [('path', self.zip_filter)],
                        match_type=self.match_type, date_key='timestamp')

                if not self._zip_entries:
                    raise RuntimeError('Could not find matching zip entry in zip file: {}'.format(self.file_entry['name']))

            elif gz:
                # Open as gzip
                self._fd = gzip.GzipFile(fileobj=self._system_fd, mode='r')
                self._name, _ = os.path.splitext(self._name)
            else:
                # Read file directly
                self._fd = self._system_fd

            return self
        except Exception:
            self.close()
            raise

    def __exit__(self, exception_type, exception_value, traceback):
        self.close()

    def files(self):
        """Iterator for each of the files opened by this file opener"""
        if self._fd:
            yield self._name, self._fd
        elif self._zipfile:
            for entry in self._zip_entries:
                fd = self._zipfile.open(entry['path'], 'r')
                yield entry['path'], fd

    def close(self):
        """Close any open files"""
        # NOTE: This function should be re-entrant
        if self._zipfile:
            self._zipfile.close()
            self._zipfile = None

        if self._system_fd:
            self._system_fd.close()
            self._system_fd = None


import cv2
import subprocess as sp
import pandas as pd

cap = cv2.VideoCapture(0)

_WIDTH = 640
_HEIGHT = 480
_FPS = 30
_FFMPEG_BIN = 'ffmpeg'
file_path = '/home/malov/test_frame.jpg'

# while True:
ret, frame = cap.read()
if ret:
    cv2.imwrite('/home/malov/test_frame.jpg', frame)

    fourcc1 = cv2.VideoWriter_fourcc(*'MJPG')
    fourcc2 = cv2.VideoWriter_fourcc(*'H264')

    stream1 = cv2.VideoWriter('/home/malov/mjpeg_test_frame.jpg', fourcc1, _FPS, (_WIDTH, _HEIGHT))
    stream2 = cv2.VideoWriter('/home/malov/h264_test_frame.avi', fourcc2, _FPS, (_WIDTH, _HEIGHT))

    stream1.write(frame)
    stream2.write(frame)

    command = [_FFMPEG_BIN, '-i', file_path, '-']
    pipe = sp.Popen(command, stdout=sp.PIPE, stderr=sp.PIPE)
    pipe.terminate()
    infos = pipe.stderr.read().decode()

    # duration = int(infos[infos.find('Duration') + 19 : infos.find('Duration') + 21])
    # bitrate = int(infos[infos.find('bitrate') + 8 : infos.find('kb/s')])

print(infos, 'test')
cap.release()


import os
import tempfile
from multiprocessing import Pool
from pathlib import Path

import librosa
import luigi
import pandas as pd
from tqdm import tqdm

from workflows.utils.gcs import single_file_target
from workflows.utils.mixin import DynamicRequiresMixin
from workflows.utils.rsync import GSUtilRsyncTask

def read_path(path: Path) -> dict:
    y, sr = librosa.load(path)
    duration = librosa.get_duration(y=y, sr=sr)
    return dict(filename="/".join(path.parts[-2:]), duration=duration)

class TrainDurations(luigi.Task, DynamicRequiresMixin):
    """Get the duration of each song in the training set into a parquet file."""

    birdclef_root_path = luigi.Parameter()
    output_path = luigi.Parameter()
    parallelism = luigi.IntParameter(default=os.cpu_count())
    capture_output = True

    def output(self):
        return single_file_target(self.output_path)

    def run(self):
        paths = sorted(Path(self.birdclef_root_path).glob("train_audio/**/*.ogg"))
        if not paths:
            raise ValueError("No audio files found", self.birdclef_root_path)
        with Pool(self.parallelism) as pool:
            res = list(tqdm(pool.imap(read_path, paths), total=len(paths)))

        df = pd.DataFrame(res)
        print(df.head())
        # ensure the output directory exists
        Path(self.output_path).parent.mkdir(parents=True, exist_ok=True)
        df.to_parquet(self.output_path)

class TrainDurationsWorkflow(luigi.Task):
    birdclef_root_path = luigi.Parameter()
    output_path = luigi.Parameter()
    local_data_root = luigi.OptionalParameter(default=None)
    parallelism = luigi.IntParameter(default=os.cpu_count())

    def output(self):
        return single_file_target(self.output_path)

    def run(self):
        # create a temporary path to download the data, make it persistent since
        # we're only wrapping the task here
        if self.local_data_root is None:
            self.local_data_root = tempfile.mkdtemp()

        tmp_path = Path(self.local_data_root)
        tmp_birdclef_root_path = tmp_path / "raw" / Path(self.birdclef_root_path).name
        tmp_birdclef_root_path.mkdir(parents=True, exist_ok=True)
        tmp_output_path = tmp_path / "processed" / "train_durations.parquet"
        tmp_output_path.parent.mkdir(parents=True, exist_ok=True)

        download_task = GSUtilRsyncTask(
            input_path=self.birdclef_root_path,
            output_path=tmp_birdclef_root_path.as_posix(),
            is_dir=True,
        )
        yield download_task

        train_durations = TrainDurations(
            birdclef_root_path=tmp_birdclef_root_path.as_posix(),
            output_path=tmp_output_path.as_posix(),
            parallelism=self.parallelism,
            dynamic_requires=[download_task],
        )
        yield train_durations

        upload_task = GSUtilRsyncTask(
            input_path=tmp_output_path.as_posix(),
            output_path=self.output_path,
            is_dir=False,
            dynamic_requires=[download_task, train_durations],
        )
        yield upload_task

if __name__ == "__main__":
    luigi.build(
        [
            TrainDurations(
                birdclef_root_path="data/raw/birdclef-2022",
                output_path="data/processed/birdclef-2022/train_durations.parquet",
            )
        ],
        log_level="INFO",
    )


from sympy import symbols, diff, pprint, factorial, ln, exp, sin, log , cos
import numpy as np

def regla_falsa (f,x0,x1,tol,nmax):
    temp,err,cont,xcentro = 0,0,1,0
    xant = f(x0)
    xact = f(x1)
    if (xant == 0):
        print(x0, "es raiz")
    else:
        if (xact == 0):
            print(x1, "es raiz")
        else:
            if (xant*xact < 0):
                xcentro = x0 - (xant*(x1-x0)/(xact-xant))
                fcentro = f(xcentro)
                err = tol + 1
                print("\n-------------------------------------------------------")
                print("iteracion | xMedio | fcentro | error absoluto")
                #print(cont, "|", x0,"|",x1,"|",xcentro,"|",fcentro,"|",err)
                print(cont, "|",xcentro,"|",fcentro,"|",err)
                while((err > tol) and (fcentro != 0) and cont < nmax):
                    if (xant*fcentro < 0):
                        x1 = xcentro
                        xact = fcentro
                    else:
                        x0 = xcentro
                        xant = fcentro
                    temp = xcentro
                    xcentro = x0 - (xant*(x1-x0)/(xact-xant))
                    fcentro = f(xcentro)
                    err = abs(xcentro - temp)
                    cont += 1
                    #print(cont, "|", x0,"|",x1,"|",xcentro,"|",fcentro,"|",err)
                    print(cont, "|",xcentro,"|",fcentro,"|",err)
                if (fcentro == 0):
                    print(xcentro,"es raiz")
                else:
                    if(err < tol):
                        print('\n')
                        print(xcentro,"es una aproximacion a la raiz")
                        print(err, "con error")
                    else:
                        print("el metodo fracaso")
            else:
                print("el intervalo no sirve")

def f(x):
    return exp(-x+1) - x**2 + 4*x + (7*(cos(x**2 - 4)**2)) -7

#          (f,x0,x1,tol,nmax):
regla_falsa(f,0.0,3.3,1e-7,100)


"""RAFT model
"""
import argparse
import logging
import os
from collections import OrderedDict

import h5py
import numpy as np
import torch
from tqdm import tqdm

from python_libs.image import load_image, show_img
from python_libs.optical_flow.raft import RAFT, flow_viz
from python_libs.video import get_frames

class RaftModel:
    """RaftModel"""

    def __init__(
        self,
        model_path: str,
    ) -> None:
        args = argparse.Namespace(model=model_path, small=False, mixed_precision=False)
        self.model = RAFT(args)
        self.pretrained_weights = torch.load(args.model)
        if torch.cuda.is_available():
            self.device = "cuda"
            self.model = torch.nn.DataParallel(self.model)
            self.model.load_state_dict(self.pretrained_weights)
            self.model.to(self.device)
        else:
            self.device = "cpu"
            self.pretrained_weights = self.get_cpu_model(self.pretrained_weights)
            self.model.load_state_dict(self.pretrained_weights)
        logging.basicConfig(format="%(asctime)s %(message)s")

    def get_cpu_model(self, model):
        """Get cpu model

        Args:
            model (RAFT): model

        Returns:
            OrderedDict: The new model
        """
        new_model = OrderedDict()
        # get all layer's names from model
        for name in model:
            # create new name and update new model
            new_name = name[7:]
            new_model[new_name] = model[name]
        return new_model

    @staticmethod
    def visualize_flow(img, flo):
        """Show flow as image

        Args:
            img (NDArray): original image
            flo (NDArray): The up flow
        """
        # permute the channels and change device is necessary
        img = img[0].permute(1, 2, 0).cpu().numpy()
        flo = flo[0].permute(1, 2, 0).cpu().numpy()

        # map flow to rgb image
        flo = flow_viz.flow_to_image(flo)

        img_flo = np.concatenate([img, flo], axis=0)
        img_flo = load_image(img_flo)
        show_img(img_flo)

    @staticmethod
    def save_flow(flo, name, parent_path):
        """Save flow as image

        Args:
            flo (NDArray): The up flow
            name (str): The name
            parent_path (str): folder
        """
        img = load_image(flow_viz.flow_to_image(flo))
        final_path = os.path.join(parent_path, name)
        img.save(final_path)

    def process_video(
        self, path: str, frame_time: int, width: int, height: int, low=True
    ):
        """Process video

        Args:
            path (str): Video path
            frame_time (int): Time between frames
            width (int): Width
            height (int): Height
            low (bool, optional): Save the original flow. Defaults to True.

        Returns:
            Dict: Flow
        """
        frames = get_frames(path, time=frame_time)
        idx = list(frames.keys())
        counter = 0
        flow = {}
        with torch.no_grad():
            frame_1 = (
                torch.from_numpy(
                    np.array(load_image(frames.get(idx[0])).resize((width, height)))
                )
                .permute(2, 0, 1)
                .float()
                .unsqueeze(0)
                .to(self.device)
            )
            for i in range(1, len(idx) - 1):
                frame_2 = (
                    torch.from_numpy(
                        np.array(load_image(frames.get(idx[i])).resize((width, height)))
                    )
                    .permute(2, 0, 1)
                    .float()
                    .unsqueeze(0)
                    .to(self.device)
                )
                flow_low, flow_up = self.model(
                    frame_1, frame_2, iters=12, test_mode=True
                )
                if low:
                    flow[idx[i]] = flow_low[0].permute(1, 2, 0).cpu().numpy()
                else:
                    flow[idx[i]] = flow_up[0].permute(1, 2, 0).cpu().numpy()
                frame_1 = frame_2
                counter += 1
        return flow

    def process_video_hdf5(
        self,
        path: str,
        frame_time: int,
        width: int,
        height: int,
        hdf5_path: str,
        low=True,
    ) -> str:
        """Process video

        Args:
            path (str): _description_
            frame_time (int): _description_
            width (int): _description_
            height (int): _description_
            low (bool, optional): _description_. Defaults to True.

        Returns:
            str: _description_
        """
        if not os.path.isfile(hdf5_path):
            flow = self.process_video(path, frame_time, width, height, low)
            with h5py.File(hdf5_path, "w") as h_file:
                for index, curr_flow in tqdm(flow.items()):
                    h_file.create_dataset(str(index), data=curr_flow)
            return hdf5_path
        else:
            print(f"{hdf5_path} already processed")
            return None

    def process_dataset(
        self,
        frame_time: int,
        width: int,
        height: int,
        list_file: str,
        root_path: str,
        ext: str = "_flow.hdf5",
        save_file=False,
    ):
        """Process the dataset"""

        self.model.eval()
        logging.info("Opening list file: %s with root path: %s", list_file, root_path)
        with open(list_file, "r") as file:
            video_list = file.read().splitlines()
            for video_name in video_list:
                path = os.path.join(root_path, video_name)
                if os.path.isfile(f"{path}"):
                    if save_file:
                        self.process_video_hdf5(
                            path, frame_time, width, height, f"{path}{ext}"
                        )
                    else:
                        self.process_video(path, frame_time, width, height)


from pubnub.callbacks import SubscribeCallback
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import grovepi
from grove_rgb_lcd import *

pnconf = PNConfiguration()
pnconf.publish_key = "demo"
pnconf.subscribe_key = "demo"
pnconf.enable_subscribe = True

pubnub = PubNub(pnconfig)
channel = "sbd_987654321"
channel2 = "okButton"

buzzer=8
#set led to output
grovepi.pinMode(led,"OUTPUT")
grovepi.pinMode(buzzer,"OUTPUT")
grovepi.digitalWrite(buzzer,0)
setText('Stan is ready')
setRGB(255,215,0)

class MyListener(SubscribeCallback):
    def status(self, pubnub, status):
        print("status changed: %s" % status)

    def message(self, pubnub, message):
        grovepi.digitalWrite(buzzer,1)
        setText(message.message)
        if message.message == "red":
                setRGB(255,0,0)
        elif message.message == "green":
                setRGB(0,255,0)
        elif message.message == "blue":
                setRGB(0,0,255)
        elif message.message == "gold":
                setRGB(255,215,0)

    def presence(self, pubnub, presence):
        pass

my_listener = MyListener()
pubnub.add_listener(my_listener)
pubnub.subscribe().channels(channel).execute()


from flow.petri_net.actions.remove_data import RemoveDataAction
from flow.petri_net.future import FutureAction
from flow.petri_net.success_failure_net import SuccessFailureNet
from flow.shell_command.petri_net import actions

import logging

LOG = logging.getLogger(__name__)

class ShellCommandNet(SuccessFailureNet):
    def __init__(self, name, dispatch_action_class, **action_args):
        SuccessFailureNet.__init__(self, name)

        # state-related places
        self.dispatching_place = self.add_place("dispatching")
        self.pending_place = self.add_place("pending")
        self.running_place = self.add_place("running")

        # messaging places
        self.dispatch_success_place = self.add_place("msg: dispatch_success")
        self.dispatch_failure_place = self.add_place("msg: dispatch_failure")
        self.execute_begin_place = self.add_place("msg: execute_begin")
        self.execute_success_place = self.add_place("msg: execute_success")
        self.execute_failure_place = self.add_place("msg: execute_failure")

        action_args.update({
            "msg: dispatch_success": self.dispatch_success_place,
            "msg: dispatch_failure": self.dispatch_failure_place,
            "msg: execute_begin": self.execute_begin_place,
            "msg: execute_success": self.execute_success_place,
            "msg: execute_failure": self.execute_failure_place,
        })

        primary_action = FutureAction(dispatch_action_class, **action_args)

        self.dispatch_transition = self.add_basic_transition(
                name="dispatch", action=primary_action)

        # messaging transitions
        self.dispatch_success_transition = self.add_basic_transition(
                "dispatch_success")
        self.dispatch_failure_transition = self.add_basic_transition(
                "dispatch_failure")
        self.execute_begin_transition = self.add_basic_transition(
                "execute_begin")

        self.execute_success_transition = self.add_basic_transition(
                "execute_success")
        self.execute_failure_transition = self.add_basic_transition(
                "execute_failure")

        # remove spurious token data
        self.token_cleanup_action = FutureAction(RemoveDataAction,
                fields=['hostname', 'job_id', 'exit_code', 'signal_number'])
        self.success_cleanup_transition = self.add_basic_transition(
                'success_cleanup', action=self.token_cleanup_action)
        self.failure_cleanup_transition = self.add_basic_transition(
                'failure_cleanup', action=self.token_cleanup_action)

        # connecting things together
        self.internal_start_place = self.bridge_transitions(
                self.internal_start_transition, self.dispatch_transition,
                name='start_bridge')
        self.dispatch_transition.add_arc_out(self.dispatching_place)
        self.dispatching_place.add_arc_out(self.dispatch_success_transition)
        self.dispatching_place.add_arc_out(self.dispatch_failure_transition)
        self.dispatch_success_place.add_arc_out(
                self.dispatch_success_transition)
        self.dispatch_failure_place.add_arc_out(
                self.dispatch_failure_transition)

        self.dispatch_success_transition.add_arc_out(self.pending_place)

        self.pending_place.add_arc_out(self.execute_begin_transition)
        self.execute_begin_place.add_arc_out(self.execute_begin_transition)
        self.execute_begin_transition.add_arc_out(self.running_place)

        self.running_place.add_arc_out(self.execute_success_transition)
        self.running_place.add_arc_out(self.execute_failure_transition)
        self.execute_success_place.add_arc_out(self.execute_success_transition)
        self.execute_failure_place.add_arc_out(self.execute_failure_transition)

        self.success_cleanup_place = self.bridge_transitions(
                self.execute_success_transition,
                self.success_cleanup_transition, name='success_cleanup')
        self.failure_cleanup_place = self.join_transitions_as_or(
                destination=self.failure_cleanup_transition,
                sources=[self.execute_failure_transition,
                         self.dispatch_failure_transition])

        self.internal_success_place = self.bridge_transitions(
                self.success_cleanup_transition,
                self.internal_success_transition, 'success_bridge')
        self.internal_failure_place = self.bridge_transitions(
                self.failure_cleanup_transition,
                self.internal_failure_transition, 'failure_bridge')


import os
import sqlite3

import yaml

BASE_DE_DATOS = os.path.join('data', 'database.sqlite')
ARCHIVO_SQL = os.path.join('data', 'declaraciones_sql.yml')

class DatabaseHelper(object):
    def __init__(self):
        self._db_connection = None

    def __enter__(self):
        self._db_connection = sqlite3.connect(BASE_DE_DATOS)
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._db_connection.close()

    def crear_tablas(self):
        """
        Creamos la base de datos con las instrucciones que se
        encuentran en el archivo declaraciones.yml
        """
        with open(ARCHIVO_SQL, 'r+') as f:
            declaraciones = yaml.safe_load(f)

        declaraciones_crear = declaraciones.get('crear', list())

        for s in declaraciones_crear:
            self.insertar(s)

    def eliminar_tablas(self):
        """
        Elimina la base de datos según las instrucciones
        destruir, dentro del archivo declaraciones.yml
        """
        with open(ARCHIVO_SQL, 'r+') as f:
            declaraciones = yaml.safe_load(f)

        declaraciones_eliminar = declaraciones.get('eliminar', list())

        for s in declaraciones_eliminar:
            self.insertar(s)

    @property
    def cursor(self):
        """
        Retorna una conexión (cursor)
        a la base de datos
        """
        if not self._db_connection:
            self._db_connection = sqlite3.connect(BASE_DE_DATOS)
        return self._db_connection.cursor()

    def reiniciar_base_de_datos(self):
        """
        Elimina y crea nuevamente las tablas dentro de
        la base de datos.
        """
        self.eliminar_tablas()
        self.crear_tablas()

        with open(ARCHIVO_SQL, 'r+') as f:
            declaraciones = yaml.safe_load(f)

        reiniciar_base_de_datos_declaraciones = declaraciones.get('reiniciar', list())

        for s in reiniciar_base_de_datos_declaraciones:
            self.insertar(s)

    def select(self, consulta):
        """
        Ejecuta la consulta en la base de datos
        y lo traslada a cadenas (con el método fetchall())
        """
        cursor = self.cursor
        cursor.execute(consulta)
        return cursor.fetchall()

    def insertar(self, consulta):
        """
        Ejecuta la consulta cruda en la bases de datos
        """
        cursor = self.cursor
        cursor.executescript(consulta)
        self._db_connection.commit()

    def select_safe(self, consulta, params):
        """
        Ejecuta la consulta de forma junto a los
        parámetros (esto lo hace resistente a la inyección SQL)
        """
        cursor = self.cursor
        if params:
            cursor.execute(consulta, params)
        else:
            cursor.execute(consulta)
        return cursor.fetchall()