import csv
import datetime
import demographics
import os
import json
from collections import OrderedDict

JSON_FILE = demographics.VARIABLE_FILE
COUNTIES_FILE = ""
CONFIDENCE_99 = float(2.576 / 1.645)
TOTAL_POPULATION = 0
TOTAL_POPULATION_ERROR = 0

def main(is_county_code, zip_codes=[], null_responses=[]):
    global COUNTIES_FILE
    COUNTIES_FILE = demographics.BASE + "/census/ca_counties.csv"
    if is_county_code == "0":
        base_path = demographics.BASE + "/census/simulations/counties"
        base_write = demographics.BASE + "/census/analysis/counties/" + datetime.datetime.now().strftime('%Y-%m-%d-%H:%M') + ".txt"
        with open(base_write, "w") as handle:
            os.chdir(base_path)
            subdirectories = os.popen("ls").read()
            subdirectories = format(subdirectories)
            for sub_dir in subdirectories:
                ch_dir = base_path + "/" + sub_dir
                os.chdir(ch_dir)
                last_simulation = max(os.listdir('.'), key = os.path.getctime)
                write_from_file(handle, last_simulation)
                handle.write("\n\n\n")
    else:
        base_path = demographics.BASE + "/census/simulations/zip_codes"
        base_write = demographics.BASE + "/census/analysis/zip_codes/" + datetime.datetime.now().strftime('%Y-%m-%d-%H:%M') + ".txt"
        with open(base_write, "w") as handle:
            write_null_responses(handle, null_responses)
            os.chdir(base_path)
            subdirectories = os.popen("ls").read()
            subdirectories = format(subdirectories)
            for sub_dir in subdirectories:
                ch_dir = base_path + "/" + sub_dir
                os.chdir(ch_dir)
                last_simulation = max(os.listdir('.'), key = os.path.getctime)
                write_from_file(handle, last_simulation, zip_codes=0)
                handle.write("\n\n\n")

"""
Writes the null responses from NULL_REPONSES into HANDLE.
"""
def write_null_responses(handle, null_responses):
    string = "Could not evaluate information for zip_codes: "
    for zip_code in null_responses:
        string += (zip_code + ", ")
    string = string[:-2]
    handle.write(string + ".\n\n\n")
    return

"""
Writes Appropriate Values into HANDLE.
"""
def write_from_file(handle, f, zip_codes=1):
    code = os.getcwd().split("/")[-1]
    with open(f, "r") as csvfile:
        with open(COUNTIES_FILE, "r") as county_file:
            reader = csv.DictReader(csvfile)
            vals = next(row for row in reader)
            if zip_codes == 1:
                write_county(handle, code, county_file)
            else:
                write_zip_code(handle, code)

            set_total_population(vals)
            write_total_population(handle)
            write_reproductive_males(handle, vals)
            write_reproductive_females(handle, vals)
            write_median_age(handle, vals)
            write_median_income(handle, vals)
            write_educational_attainment(handle, vals)
            write_foreign_born(handle, vals)
            write_races(handle, vals)
    return

"""
Writes the ZIP_CODE into HANDLE.
"""
def write_zip_code(handle, code):
    handle.write("Zip Code: " + code + ".\n")
    return

"""
Writes the appropriate description for CODE from COUNTY_FILE into HANDLE.
"""
def write_county(handle, code, county_file):
    reader = csv.DictReader(county_file)
    description = ""
    for row in reader:
        if row["county_code"] == code:
            description = row["county"]
        else:
            continue
    handle.write("County: " + description + ".\n")
    return

"""
Writes the foreign born population into HANDLES from VALUES.
"""
def write_foreign_born(handle, values):
    us_born_pop = float(values["B06009_001E"])
    us_born_error = float(values["B06009_001M"])
    us_born_upper_bound = us_born_pop + (CONFIDENCE_99 * us_born_error)
    us_born_lower_bound = us_born_pop - (CONFIDENCE_99 * us_born_error)
    foreign_born_pop = TOTAL_POPULATION - us_born_pop
    foreign_born_upper_bound = TOTAL_POPULATION - us_born_lower_bound
    foreign_born_lower_bound = TOTAL_POPULATION - us_born_upper_bound
    handle.write("Foreign Born Population Estimate: " + str(foreign_born_pop) + ".\n")
    handle.write("Foreign Born Population Range: " + str(foreign_born_lower_bound) + "," + str(foreign_born_upper_bound) + ".\n")
    return

"""
Writes the median Age for a county into a HANDLE.
"""
def write_median_age(handle, values):
    median_age = values["B01002_001E"]
    median_age_error = values["B01002_001M"]
    MOE_99 = (CONFIDENCE_99 * float(median_age_error))
    median_age_upper_bound = float(median_age) + MOE_99
    median_age_lower_bound = float(median_age) - MOE_99
    handle.write("Median Age Estimate: " + median_age + ".\n")
    handle.write("Median Age Range: " + str(median_age_lower_bound) + "," + str(median_age_upper_bound) + ".\n")
    return

"""
Writes the number of reproductive males from VALUES into HANDLE.
"""
def write_reproductive_males(handle, values):
    total_reproductive_population = 0.0
    total_reproductive_upper_bound = 0.0
    total_reproductive_lower_bound = 0.0
    prefix = "B01001"
    for key in values.keys():
        try:
            if key[-1] != "E":
                continue
            if key[0:6] == prefix:
                suffix = key[7:10]
                kicker = int(suffix)
                if kicker >= 6 and kicker <= 14:
                    total_var = prefix + "_" + suffix + "E"
                    error_var = prefix + "_" + suffix + "M"
                    total_for_range = float(values[total_var])
                    error_for_range = float(values[error_var])
                    upper_for_range = total_for_range + (CONFIDENCE_99 * error_for_range)
                    lower_for_range = total_for_range - (CONFIDENCE_99 * error_for_range)
                    total_reproductive_population += total_for_range
                    total_reproductive_lower_bound += lower_for_range
                    total_reproductive_upper_bound += upper_for_range
        except ValueError:
            continue
    handle.write("Total Population for Reproductive Males Estimate: " + str(total_reproductive_population) + ".\n")
    handle.write("Total Population of Reproductive Males Range: " + str(total_reproductive_lower_bound) + "," + str(total_reproductive_upper_bound) + ".\n")
    return

"""
Writes the number of reproductive females from VALUES into HANDLE.
"""
def write_reproductive_females(handle, values):
    total_reproductive_population = 0.0
    total_reproductive_upper_bound = 0.0
    total_reproductive_lower_bound = 0.0
    prefix = "B01001"
    for key in values.keys():
        try:
            if key[-1] != "E":
                continue
            if key[0:6] == prefix:
                suffix = key[7:10]
                kicker = int(suffix)
                if kicker >= 30 and kicker <= 38:
                    total_var = prefix + "_" + suffix + "E"
                    error_var = prefix + "_" + suffix + "M"
                    total_for_range = float(values[total_var])
                    error_for_range = float(values[error_var])
                    upper_for_range = total_for_range + (CONFIDENCE_99 * error_for_range)
                    lower_for_range = total_for_range - (CONFIDENCE_99 * error_for_range)
                    total_reproductive_population += total_for_range
                    total_reproductive_lower_bound += lower_for_range
                    total_reproductive_upper_bound += upper_for_range
        except ValueError:
            continue
    handle.write("Total Population for Reproductive Females Estimate: " + str(total_reproductive_population) + ".\n")
    handle.write("Total Population for Reproductive Females Range: " + str(total_reproductive_lower_bound) + "," + str(total_reproductive_upper_bound) + ".\n")
    return

"""
Writes the median household income from VALUES into HANDLE.
"""
def write_median_income(handle, values):
    median_income = float(values["B19013_001E"])
    median_income_error = float(values["B19013_001M"])
    median_income_lower_bound = median_income - (CONFIDENCE_99 * median_income_error)
    median_income_upper_bound = median_income + (CONFIDENCE_99 * median_income_error)
    handle.write("Median Hosuehold Income Estimate: " + str(median_income) + ".\n")
    handle.write("Median Household Income Range: " + str(median_income_lower_bound) + "," + str(median_income_upper_bound) + ".\n")
    return

"""
Sets global variable to total population in VALUES.
"""
def set_total_population(values):
    global TOTAL_POPULATION
    global TOTAL_POPULATION_ERROR
    TOTAL_POPULATION = float(values["B01001_001E"])
    TOTAL_POPULATION_ERROR = float(values["B01001_001M"])
    return

"""
Writes the total population to HANDLE.
"""
def write_total_population(handle):
    total_pop_upper_bound = TOTAL_POPULATION + (CONFIDENCE_99 * TOTAL_POPULATION_ERROR)
    total_pop_lower_bound = TOTAL_POPULATION - (CONFIDENCE_99 * TOTAL_POPULATION_ERROR)
    handle.write("Total Population Estimate: " + str(TOTAL_POPULATION) + ".\n")
    handle.write("Total Population Range: " + str(total_pop_lower_bound) + "," + str(total_pop_upper_bound) + ".\n")
    return

"""
Write the educational attainments of a population into HANDLE.
"""
def write_educational_attainment(handle, values):
    high_school_or_lower_pop = float(values["B06009_002E"])
    high_school_or_lower_pop_error = float(values["B06009_002M"])
    high_school_or_lower_pop_upper_bound = high_school_or_lower_pop + (CONFIDENCE_99 * high_school_or_lower_pop_error)
    high_school_or_lower_pop_lower_bound = high_school_or_lower_pop - (CONFIDENCE_99 * high_school_or_lower_pop_error)
    estimate_for_high_school_or_higher = TOTAL_POPULATION - high_school_or_lower_pop
    estimate_for_high_school_or_higher_upper_bound = TOTAL_POPULATION - high_school_or_lower_pop_lower_bound
    estimate_for_high_school_or_higher_lower_bound = TOTAL_POPULATION - high_school_or_lower_pop_upper_bound
    handle.write("High School Education or Higher Estimate: " + str(estimate_for_high_school_or_higher) + ".\n")
    handle.write("High School Education or Higher Range: " + str(estimate_for_high_school_or_higher_lower_bound) + "," + str(estimate_for_high_school_or_higher_upper_bound) + ".\n")
    return

"""
Writes race and origins into HANDLE.
"""
def write_races(handle, values):
    white_population_total = float(values["B01001A_001E"])
    white_population_error = float(values["B01001A_001M"])
    white_population_total_upper_bound = white_population_total + (CONFIDENCE_99 * white_population_error)
    white_population_total_lower_bound = white_population_total - (CONFIDENCE_99 * white_population_error)
    handle.write("White Population Estimate: " + str(white_population_total) + ".\n")
    handle.write("White Population Range: " + str(white_population_total_lower_bound) + "," + str(white_population_total_upper_bound) + ".\n")
    hispanic_population_total = float(values["B01001I_001E"])
    hispanic_population_error = float(values["B01001I_001M"])
    hispanic_population_total_upper_bound = hispanic_population_total + (CONFIDENCE_99 * hispanic_population_error)
    hispanic_population_total_lower_bound = hispanic_population_total - (CONFIDENCE_99 * hispanic_population_error)
    handle.write("Hispanic Population Estimate: " + str(hispanic_population_total) + ".\n")
    handle.write("Hispanic Population Range: " + str(hispanic_population_total_lower_bound) + "," + str(hispanic_population_total_upper_bound) + ".\n")
    black_population_total = float(values["B01001B_001E"])
    black_population_error = float(values["B01001B_001M"])
    black_population_total_upper_bound = black_population_total + (CONFIDENCE_99 * black_population_error)
    black_population_total_lower_bound = black_population_total - (CONFIDENCE_99 * black_population_error)
    handle.write("African American Population Estimate: " + str(black_population_total) + ".\n")
    handle.write("African American Population Range: " + str(black_population_total_lower_bound) + "," + str(black_population_total_upper_bound) + ".\n")
    native_american_population_total = float(values["B01001C_001E"])
    native_american_population_error = float(values["B01001C_001M"])
    native_american_population_total_upper_bound = native_american_population_total + (CONFIDENCE_99 * native_american_population_error)
    native_american_population_total_lower_bound = native_american_population_total - (CONFIDENCE_99 * native_american_population_error)
    handle.write("Native American Population Estimate: " + str(native_american_population_total) + ".\n")
    handle.write("Native American Population Range: " + str(native_american_population_total_lower_bound) + "," + str(native_american_population_total_upper_bound) + ".\n")
    asian_population_total = float(values["B01001D_001E"])
    asian_population_error = float(values["B01001D_001M"])
    asian_population_total_upper_bound = asian_population_total + (CONFIDENCE_99 * asian_population_error)
    asian_population_total_lower_bound = asian_population_total - (CONFIDENCE_99 * asian_population_error)
    handle.write("Asian American Population Estimate: " + str(asian_population_total) + ".\n")
    handle.write("Asian American Population Range: " + str(asian_population_total_lower_bound) + "," + str(asian_population_total_upper_bound) + ".\n")
    pacific_islander_total = float(values["B01001E_001E"])
    pacific_islander_error = float(values["B01001E_001M"])
    pacific_islander_total_upper_bound = pacific_islander_total + (CONFIDENCE_99 * pacific_islander_error)
    pacific_islander_total_lower_bound = pacific_islander_total - (CONFIDENCE_99 * pacific_islander_error)
    handle.write("Pacific Islander Population Estimate: " + str(pacific_islander_total) + ".\n")
    handle.write("Pacific Islander Population Range: " + str(pacific_islander_total_lower_bound) + "," + str(pacific_islander_total_upper_bound) + ".\n")
    other_total = float(values["B01001F_001E"])
    other_error = float(values["B01001F_001M"])
    other_total_upper_bound = other_total + (CONFIDENCE_99 * other_error)
    other_total_lower_bound = other_total - (CONFIDENCE_99 * other_error)
    handle.write("Other Race Population Estimate: " + str(other_total) + ".\n")
    handle.write("Other Race Population Range: " + str(other_total_lower_bound) + "," + str(other_total_upper_bound) + ".\n")
    two_or_more_races_total = float(values["B01001G_001E"])
    two_or_more_races_error = float(values["B01001G_001M"])
    two_or_more_races_total_upper_bound = two_or_more_races_total + (CONFIDENCE_99 * two_or_more_races_error)
    two_or_more_races_total_lower_bound = two_or_more_races_total - (CONFIDENCE_99 * two_or_more_races_error)
    handle.write("Two or More Races Population Estimate: " + str(two_or_more_races_total) + ".\n")
    handle.write("Two or More Races Population Range: " + str(two_or_more_races_total_lower_bound) + "," + str(two_or_more_races_total_upper_bound) + ".\n")
    return

"""
Loads the Descriptor for a VARIABLE from our JSON_FILE.
"""
def load_descriptor(variable):
    with open(JSON_FILE, "r") as json_file:
        data = json.load(json_file)
    if variable != 'county' and variable != 'state':
        value = data[variable]
    else:
        value = variable
    return value

"""
Format output.
"""
def format(string):
    sub_dirs = []
    next_dir = ""
    for c in string:
        if c != "\n":
            next_dir += str(c)
        else:
            sub_dirs.append(next_dir)
            next_dir = ""
    return sub_dirs


import socket
import sys
# cliente 1
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.56.6', 502)
sock.connect(server_address)
sock.sendall('\x00\x04\x00\x00\x00\x06\x01\x05\x00\x01\xff\x00'.encode())
data = sock.recv(49096)#.decode('hex')
print("RX: ",data)

TCP_UDP_MULTICAST Comms/TCP P1/TCP 1.1/cliente1.py


from blueprints.dataApi.controllers import DataController
from flask import Blueprint, request
from utils.response_tools import (SuccessDataResponse, ArgumentExceptionResponse)
import json
from utils.redis_tools import RedisWrapper
import uuid as u

bp = Blueprint('data_api', __name__, url_prefix='/api/data_api')

# http://localhost:10981/api/data_api/fetch_root
@bp.route('fetch_root', methods=['GET'])
def fetch_root():
    try:
        data = DataController._search_path_file()
        return SuccessDataResponse(data)
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

# http://localhost:10981/api/data_api/fetch_path {path_id:int}
@bp.route('fetch_path/<path_id>/', methods=['GET'])
def fetch_path(path_id):
    try:
        data = DataController._search_path_file(id=path_id)
        return SuccessDataResponse(data)
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

@bp.route('fetch_page/<file_id>/', methods=['GET'])
def fetch_page(file_id):
    try:
        data = DataController._search_file_page(id=file_id)
        return SuccessDataResponse(data)
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

@bp.route('fetch_content', methods=['POST'])
def fetch_content():
    try:
        args = request.json
        image_id = args.get('image_id')
        uuid = args.get('uuid')
        data = DataController._search_content(image_id=image_id, uuid=uuid)
        return SuccessDataResponse(data)
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

@bp.route('update_content', methods=['POST'])
def update_content():
    args = request.json
    content_id = args.get('content_id')
    content = args.get('content')
    content_location = args.get('content_location')

    response = DataController._update_content(
        id = content_id,
        content = content,
        location = content_location
    )

    if response and type(response) == bool:
        return SuccessDataResponse([])
    else:
        return ArgumentExceptionResponse(msg=f'{response}')

@bp.route('add_content', methods=['POST'])
def add_content():
    # arg = （
    # ['name'],
    # ['content_type']
    #  ['father_page'] (id)
    # ['content']
    # ['location']
    try:

        args = request.json

        dic = {
            "name":args.get('name'),
            'content':args.get('content'),
            'content_type':args.get('content_type'),
            'content_location':args.get('content_location'),
            'father_page':args.get('father_page')
        }

        response = DataController._add_content(
            row=dic
        )

        if response and type(response) == bool:
            return SuccessDataResponse([])
        else:
            return ArgumentExceptionResponse(msg=f'{response}')
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

# 悲观锁服务
@bp.route('lock', methods=['POST'])
def lock():
    args = request.json
    try:
        image_id = args.get("image_id")
    except:
        return ArgumentExceptionResponse(msg=f'No Image Provide.')

    try:
        uuid_ = args.get("uuid")
    except:
        uuid_ = None

    redis_cli = RedisWrapper('p_lock')
    value = redis_cli.get(f'predict:lock:{image_id}')

    # 有锁
    if value:
        # 无uuid或uuid不匹配，无法解锁
        if not uuid_ or uuid_ != value:
            return ArgumentExceptionResponse(msg=f'Image locked.')
        # uuid匹配，延续解锁时长3s
        elif uuid_ == value:
            redis_cli.set(key=f'predict:lock:{image_id}', ex=4, value=value)
            return SuccessDataResponse([])

    else:
        uuid_id = u.uuid4()
        redis_cli.set(key=f'predict:lock:{image_id}', ex=4, value=str(uuid_id))
        return SuccessDataResponse(str(uuid_id))

@bp.route('delete_content/<content_id>/', methods=['GET'])
def delete_content(content_id):
    try:
        response = DataController._delete_content(
            id=content_id
        )

        if response and type(response) == bool:
            return SuccessDataResponse([])
        else:
            return ArgumentExceptionResponse(msg=f'{response}')
    except Exception as e:
        return ArgumentExceptionResponse(msg=f'{e}')

@bp.route('test', methods=['GET'])
def test():
    return SuccessDataResponse([])


from telegram.ext import Updater, InlineQueryHandler, CommandHandler
import requests
# import re
import sqlite3
from scraping import get_product_info_flipkart
import telegram.ext
from datetime import timedelta
import logging
from time import sleep

def gather_name_list(chat_id):
    logging.info("Gathering list of items for "+str(chat_id))
    conn = sqlite3.connect("telegram_database.db")
    c = conn.cursor()

    table_name = "_" + str(chat_id)

    c.execute(
        'create table if not exists ' + table_name + ' (link text,name text,price_with_currency text,price real,in_stock text)')
    c.execute('SELECT * FROM ' + table_name)
    lis = c.fetchall()
    product_names = []
    for j in lis:
        product_names.append(j[1])
    # print(product_names)
    product_names.sort()
    list_message = "You are tracking the following products:\n\n"
    for i in enumerate(product_names):
        list_message += str(i[0] + 1) + ". " + i[1] + "\n\n"
    list_message = list_message.strip() + ""
    conn.commit()
    conn.close()
    return (list_message, product_names)

def add(bot, update):
    chat_id = update.message.chat_id
    logging.info(str(chat_id)+" is trying add a product.")
    # print(chat_id)
    try:
        link = str(update.message.text).strip().split()[1]
        # print(link)
    except IndexError:
        logging.info(str(chat_id)+" didn't enter any product link.")
        bot.send_message(
            chat_id=chat_id, text="Please enter a flipkart product link.", parse_mode="html")
        return
    if "flipkart.com" not in link:
        logging.info(str(chat_id)+" didn't enter a valid product link")
        bot.send_message(chat_id=chat_id, text=""+link +
                         " Doesn't seem to be a valid flipkart link.", parse_mode="html")
        return
    conn = sqlite3.connect("telegram_database.db")
    c = conn.cursor()
    table_name = "_"+str(chat_id)
    c.execute(
        'create table if not exists ' + table_name + ' (link text,name text,price_with_currency text,price real,in_stock text)')
    conn.commit()
    conn.close()
    try:
        product_info = get_product_info_flipkart(link)
    except IndexError:
        logging.info(str(chat_id)+" didn't enter a valid product link")
        bot.send_message(chat_id=chat_id, text=link +
                         " is not a link to product on flipkart.\nEnter / help commands to view all commands and their formats")
    if product_info:
        conn = sqlite3.connect("telegram_database.db")
        c = conn.cursor()
        c.execute('SELECT * FROM ' + table_name +
              ' WHERE name=?', (product_info["name"],))
        match = c.fetchone()
        if match:
            logging.info(str(chat_id)+" entered an already present link.")
            bot.send_message(chat_id=chat_id, text='You are already tracking '+match[1]+'')
        else:
            logging.info("Product addition was a success")
            c.execute('INSERT INTO ' + table_name + ' values (?,?,?,?,?)', (link,product_info['name'], product_info["price_with_currency"], product_info["price_in_num"], product_info['availability']))
            bot.send_message(chat_id=chat_id, text="You just added " + product_info["name"] + " for tracking.\nCurrently:\n   Price:" +product_info["price_with_currency"].rjust(10) + "\nIn Stock:" + product_info["availability"].rjust(10), parse_mode='html')

        conn.commit()
        conn.close()
    else:
        bot.send_message(chat_id=chat_id,text="Something didn't work there!! Try again after a minute or so.")

def list_names(bot, update):
    chat_id = update.message.chat_id
    logging.info("Listing "+str(chat_id)+"'s Products")
    list_message, product_names = gather_name_list(chat_id)
    if len(product_names) == 0:
        bot.send_message(
            chat_id=chat_id, text="You are not tracking any items.", parse_mode='html')
        return
    bot.send_message(chat_id=chat_id, text=list_message, parse_mode='html')

def remove(bot, update):
    chat_id = update.message.chat_id
    logging.info(str(chat_id)+" is trying to remove a product.")
    # print(chat_id)
    list_message, product_names = gather_name_list(chat_id)
    try:
        num = int(str(update.message.text).strip().split()[1])
        # print(num)
    except IndexError:
        num = 0
    except ValueError:
        num = 0

    if len(product_names) == 0:
        bot.send_message(
            chat_id=chat_id, text="You are not tracking any items.", parse_mode='html')
        return
    if not num:
        bot.send_message(chat_id=chat_id, text=list_message, parse_mode='html')
        bot.send_message(
            chat_id=chat_id, text="\nSelect the product to remove. \nEnter /remove --no. corresponding to the product--  to remove the product", parse_mode='html')
        return
    if num > len(product_names) or num < 0:
        bot.send_message(
            chat_id=chat_id, text="No Product with that number.", parse_mode='html')
        return

    conn = sqlite3.connect("telegram_database.db")
    c = conn.cursor()
    table_name = "_"+str(chat_id)
    c.execute("DELETE FROM "+table_name +
              " WHERE name=?", (product_names[num-1],))
    conn.commit()
    conn.close()
    bot.send_message(chat_id=chat_id, text="You removed " +
                     product_names[num-1]+" from tracking.", parse_mode='html')
    logging.info(str(chat_id)+" removed a product.")

def daily_checker(bot, job):
    conn = sqlite3.connect("telegram_database.db")
    c = conn.cursor()
    c.execute('SELECT name from sqlite_master where type= "table"')
    all_users = c.fetchall()
    conn.close()
    logging.info("There are currently "+str(len(all_users)) +
                 " accounts using the bot.")
    total_products = 0
    for j in all_users:

        conn = sqlite3.connect("telegram_database.db")
        c = conn.cursor()

        c.execute("SELECT * FROM "+j[0])

        all_items = c.fetchall()
        conn.close()

        chat_id = int(j[0][1:])
        # print("Doing "+str(chat_id)+"'s Tracking.")
        # print(dic)
        logging.info("Tracking "+str(chat_id)+"'s products.")
        for i in all_items:
            sleep(2)
            total_products += 1
            dic = get_product_info_flipkart(i[0])
            # print(dic)
            if not dic:
                continue
            current_price = dic['price_in_num']
            current_in_stock = dic['availability']
            price_change = current_price - i[3]
            # price_change= -1000
            # print(dic['name'])
            if price_change > 0:
                bot.send_message(chat_id=chat_id, text="**"+dic['name']+"**:\n\n"+"*6 hours back*:\n```   Price:"+i[2].rjust(10)+"\nIn Stock:"+i[4].rjust(
                    10)+"```\n*Now*:\n```   Price:"+dic["price_with_currency"].rjust(10)+"\nIn Stock:"+dic["availability"].rjust(10)+"```", parse_mode='markdown')

                bot.send_message(chat_id=chat_id, text="```diff\n-Price has increased by " +
                                 dic["price_with_currency"][0]+str(price_change)+"```", parse_mode='markdown')
                logging.info("Price of "+dic['name']+" increased.")

            elif price_change < 0:
                bot.send_message(chat_id=chat_id, text="**"+dic['name']+"**:\n\n"+"*6 hours back*:\n```   Price:"+i[2].rjust(10)+"\nIn Stock:"+i[4].rjust(
                    10)+"```\n*Now*:\n```   Price:"+dic["price_with_currency"].rjust(10)+"\nIn Stock:"+dic["availability"].rjust(10)+"```", parse_mode='markdown')

                bot.send_message(chat_id=chat_id, text="```yaml\nPrice has decreased by " +
                                 dic["price_with_currency"][0]+str(abs(price_change))+"```", parse_mode='markdown')
                logging.info("Price of "+dic['name']+" decreased.")

            else:
                logging.info("No change in price for "+dic['name'])

            if dic['availability'] == 'Yes' and i[4] == 'No':
                if price_change != 0:
                    bot.send_message(
                        chat_id=chat_id, text="```yaml\nProduct is in stock.```", parse_mode='markdown')
                else:
                    bot.send_message(chat_id=chat_id, text="**"+dic['name']+"**:\n"+"*6 hours back*:\n```   Price:"+i[2].rjust(10)+"\nIn Stock:"+i[4].rjust(
                        10)+"```\n*Now*:\n```   Price:"+dic["price_with_currency"].rjust(10)+"\nIn Stock:"+dic["availability"].rjust(10)+"```", parse_mode='markdown')
                    bot.send_message(
                        chat_id=chat_id, text="```yaml\nProduct is in stock.```", parse_mode='markdown')
                    logging.info("Product just came in to stock.")

            if price_change < 0 and dic['availability'] == "No":
                bot.send_message(
                    chat_id=chat_id, text="```diff\n-But the product is out of stock.```", parse_mode='markdown')
                logging.info("Product went out of stock.")
            if price_change != 0:
                bot.send_message(chat_id=chat_id,
                                 text="Link:\n"+i[0])
            # Updating the database with the current values.
            conn = sqlite3.connect("telegram_database.db")
            c = conn.cursor()
            c.execute("UPDATE "+j[0]+" SET price_with_currency='" +
                      dic['price_with_currency']+"' WHERE link=?", (i[0],))
            c.execute("UPDATE "+j[0]+" SET price=" +
                      str(dic["price_in_num"])+" WHERE link=?", (i[0],))
            c.execute("UPDATE "+j[0]+" SET in_stock='" +
                      dic["availability"]+"' WHERE link=?", (i[0],))
            conn.commit()
            conn.close()

    logging.info("Total number of products tracked : "+str(total_products))

def check_now(bot, update):
    chat_id = update.message.chat_id
    # print(chat_id)
    list_message, product_names = gather_name_list(chat_id)
    try:
        num = int(str(update.message.text).strip().split()[1])
        print(num)
    except IndexError:
        num = 0
    except ValueError:
        num = 0
    conn = sqlite3.connect("telegram_database.db")
    c = conn.cursor()
    table_name = "_"+str(chat_id)
    c.execute('create table if not exists ' + table_name +
              ' (link text,name text,price_with_currency text,price real,in_stock text)')
    c.execute("SELECT * FROM "+table_name)
    all_items = c.fetchall()
    logging.info("Doing "+str(chat_id)+"'s Tracking.")
    if len(all_items) == 0:
        bot.send_message(
            chat_id=chat_id, text="You are not tracking any items.", parse_mode='html')
        return
    if num == 0:
        message = "__**You are tracking the following items.**__\n"
        for j in enumerate(all_items):
            message += str(j[0]+1)+". "+j[1][1]+"\n\n"
        message += "-1. All Items\n" + \
            "Enter `/check <no. corresponding to product>` to check that product."
        bot.send_message(chat_id=chat_id, text=message, parse_mode='markdown')
    else:
        if num > len(all_items) or num < -2:
            bot.send_message(
                chat_id=chat_id, text="No Product with that number.", parse_mode='html')
            return
        else:
            if num == -1:
                for i in all_items:
                    sleep(2)
                    dic = get_product_info_flipkart(i[0])
                    if not dic:
                        bot.send_message(chat_id=chat_id,text=i[1]+" wasn't tracked due to some error. Try again after a while.")
                        continue
                    current_price = dic['price_in_num']
                    current_in_stock = dic['availability']
                    bot.send_message(chat_id=chat_id, text=""+dic['name']+":\n"+"Last Time Checked:\n   Price:"+i[2].rjust(10)+"\nIn Stock:"+i[4].rjust(
                        10)+"\nNow:\n   Price:"+dic["price_with_currency"].rjust(10)+"\nIn Stock:"+dic["availability"].rjust(10)+"\nLink:\n"+i[0], parse_mode='html')
                    # await user.send()
            else:
                dic = get_product_info_flipkart(all_items[num-1][0])
                if not dic:
                    bot.send_message(chat_id=chat_id,text=all_items[num-1][0]+" wasn't tracked due to some error. Try again after a while.")
                    return
                current_price = dic['price_in_num']
                current_in_stock = dic['availability']
                bot.send_message(chat_id=chat_id, text=""+dic['name']+":\n"+"Last Time Checked:\n   Price:"+all_items[num-1][2].rjust(10)+"\nIn Stock:"+all_items[num-1][4].rjust(
                    10)+"\nNow:\n   Price:"+dic["price_with_currency"].rjust(10)+"\nIn Stock:"+dic["availability"].rjust(10)+"\nLink:\n"+all_items[num-1][0], parse_mode='html')

def start(bot, update):
    chat_id = update.message.chat_id
    bot.send_message(chat_id=chat_id, text="This is a bot to track price and stock status of a product on flipkart.\nCommands:\n\n  /add --link to product--\n  /remove\n  /check: (To check current price and stock.)\n  /list\nThe bot will check the product price and stock every 6 hours.\nIf some command doesn't work, wait a minute or two and try again. ", parse_mode='html')
    logging.info(str(chat_id)+" started using the bot.")

def main():
    for handler in logging.root.handlers[:]:
        logging.root.removeHandler(handler)
    logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s",
                        datefmt='%m/%d/%Y %I:%M:%S %p', handlers=[logging.FileHandler("output.log"), logging.StreamHandler()])

    updater = Updater("***TOKEN TO YOUR BOT***")
    dp = updater.dispatcher
    dp.add_handler(CommandHandler('add', add))
    dp.add_handler(CommandHandler('list', list_names))
    dp.add_handler(CommandHandler('remove', remove))
    dp.add_handler(CommandHandler('check', check_now))
    dp.add_handler(CommandHandler('start', start))
    dp.add_handler(CommandHandler('help', start))
    j = updater.job_queue
    j.run_repeating(daily_checker, interval=timedelta(hours=6), first=0)
    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()


from __future__ import absolute_import
from __future__ import unicode_literals

import logging
import os
import signal
import time
import traceback
from multiprocessing import Event
from multiprocessing import Lock
from multiprocessing import Process

import six
from kafka import KafkaConsumer
from kafka.common import ConsumerTimeout
from retrying import retry

from yelp_kafka import metrics
from yelp_kafka.consumer import KafkaSimpleConsumer
from yelp_kafka.error import ConsumerGroupError
from yelp_kafka.error import PartitionerError
from yelp_kafka.error import PartitionerZookeeperError
from yelp_kafka.error import ProcessMessageError
from yelp_kafka.metrics_responder import MetricsResponder
from yelp_kafka.partitioner import Partitioner
from yelp_kafka.utils import get_default_responder_if_available
from yelp_kafka.utils import retry_if_kafka_unavailable_error

DEFAULT_REFRESH_TIMEOUT_IN_SEC = 0.5
CONSUMER_GROUP_INTERNAL_TIMEOUT = 100  # milliseconds

class ConsumerGroup(object):
    """Single process consumer group.
    Support partitions distribution for a single topic
    between many consumer instances.

    If the topic consists of only one partition, only one consumer belonging
    to the group will be able to consume messages. The other consumers will
    stay idle, ready to take over the active consumer in case of failures.
    If the topic consists of many partitions and only one consumer has
    joined the group, the consumer will consume messages
    from all the partitions. Finally if the topic consists of many
    partitions and there are many consumers, each consumer will pick up
    a subset of partitions and consume from them.

    .. warning::
        Messages will be named tuples with fields "partition",
        "offset", "key", "value". This message format is different from those
        yielded by :py:class:`yelp_kafka.consumer_group.KafkaConsumerGroup`.

    .. warning:: This class is considered deprecated in favor of :py:class:`yelp_kafka.consumer_group.KafkaConsumerGroup`.

    Example:

    .. code-block:: python

       from yelp_kafka import discovery
       from yelp_kafka.config import KafkaConsumerConfig
       from yelp_kafka.consumer_group import ConsumerGroup

       cluster = discovery.get_local_cluster('standard')
       config = KafkaConsumerConfig('my_group', cluster)

       def my_process_function(message):
           partition, offset, key, value = message
           print partition, offset, key, value

       consumer = ConsumerGroup('test_topic', config, my_process_function)
       consumer.run()

    :param topics: topics to consume from
    :type topics: list
    :param config: yelp_kakfa config. See :py:mod:`yelp_kafka.config`
    :type config: dict
    :param process_func: function used to process the message.
        This function should accept a :py:data:`yelp_kafka.consumer.Message`
        as parameter.
    """

    def __init__(self, topic, config, process_func):
        self.log = logging.getLogger(self.__class__.__name__)
        self.config = config
        self.topic = topic
        self.partitioner = Partitioner(
            config,
            topic if isinstance(topic, list) else [topic],
            self._acquire,
            self._release
        )
        self.consumer = None
        self.process = process_func

    def run(self, refresh_timeout=DEFAULT_REFRESH_TIMEOUT_IN_SEC):
        """Create the group, instantiate a consumer and consume message
        from kafka. The refresh timeout shouldn't be too high in order to
        allow the consumers to stay updated with the group changes.

        :param refresh_timeout: waiting timeout in secs to refresh
            the consumer group. It should never be greater than
            'zk_partitioner_cooldown' to avoid wasting time resetting
            the partitioner many times upon changes.
            See :py:mod:`yelp_kafka.config`
            Default: 5 seconds.
        """
        with self.partitioner:
            while True:
                self.consume(refresh_timeout)

    def consume(self, refresh_timeout):
        """Consume messages from kafka and refresh the group
        upon timeout expiration.

        :param refresh_timeout: refresh period for consumer group
        """
        timeout = time.time() + refresh_timeout
        if self.consumer:
            for message in self.consumer:
                try:
                    self.process(message)
                except:
                    trace = traceback.format_exc()
                    self.log.exception(
                        "Error processing message: %s",
                        message,
                    )
                    raise ProcessMessageError(
                        "Error processing message: {0}\n\nException "
                        "caught inside processing message function:\n{1}"
                        .format(
                            message,
                            trace,
                        )
                    )
                if time.time() > timeout:
                    break
        try:
            self.partitioner.refresh()
        except (PartitionerZookeeperError, PartitionerError):
            self.log.exception("Encountered a partitioner error")
            raise

    def _acquire(self, partitions):
        """Create a consumer ready to consume from kafka.

        .. note: This function should only by called by the partitioner.
           The partitioner executes _acquire when the partition group
           changes and the partitions have been acquired.
        """
        if partitions.get(self.topic):
            self.consumer = KafkaSimpleConsumer(
                self.topic,
                self.config,
                partitions[self.topic]
            )
            try:
                # We explicitly catch and log the exception.
                self.consumer.connect()
            except:
                self.log.exception(
                    "Consumer topic %s, partition %s, config %s:"
                    " failed connecting to kafka",
                    self.topic,
                    partitions,
                    self.config,
                )
                raise

    def _release(self, partitions):
        """Release the consumer.

        .. note: This function should only by called by the partitioner.
           The partitioner executes _release when it has to release the
           acquired partitions.
        """
        if self.consumer:
            self.consumer.close()
            self.consumer = None

class KafkaConsumerGroup(object):
    """KafkaConsumerGroup allows you to efficiently consume from all the
    partitions of a topic without having to manually use the
    :py:class:`yelp_kafka.partitioner.Partitioner` class. You can spin up
    multiple KafkaConsumerGroups, and they will co-ordinate via the Partitioner
    to divvy up the available partitions between each other.

    This class works by attempting to rebalance before each call to `next()`. In
    the event that rebalancing does occur and that you have enabled
    auto-committing, any messages marked as done using `task_done()` will be
    committed before repartitioning. To commit messages immediately, you can
    call `commit()`.

    If metrics_reporter is enabled in config, the metrics prefix in
    will be: "yelp_kafka.KafkaConsumerGroup."

    .. warning::
        Do not create multiple KafkaConsumerGroups in the same process;
        the Partitioner class does not work if there are multiple instances of it in
        the same process.

    .. warning::
        Messages will be instances of kafka-python KafkaMessage, which is
        a named tuple with the fields "topic", "partition", "offset", "key",
        "value". This message format is different from those yielded by
        :py:class:`yelp_kafka.consumer_group.ConsumerGroup`.

    :param topics: a list of topics to consume from.
    :type topics: list
    :param config: yelp_kakfa consumer config.
    :type config: :py:class:`yelp_kafka.config.KafkaConsumerConfig`
    :param metrics_responder: A metric responder to report metrics, defaults to
        use :py:class:`yelp_kafka.yelp_metrics_responder.MeteoriteMetricsResponder`, if
        the import of yelp_meteorite is successful.
    :type metrics_responder: class which implements metric_responder.MetricsResponder
    """

    METRIC_PREFIX = 'yelp_kafka.KafkaConsumerGroup'

    def __init__(self, topics, config, metrics_responder=None):
        assert isinstance(topics, list), "Topics must be a list"

        self.log = logging.getLogger(self.__class__.__name__)
        self.topics = topics
        self.partitioner = Partitioner(
            config,
            topics,
            self._acquire,
            self._release
        )
        self.consumer = None

        consumer_config = config.get_kafka_consumer_config()
        self.log.debug(
            "Using config: %s",
            consumer_config,
        )

        self.metrics_responder = metrics_responder or get_default_responder_if_available()
        assert not metrics_responder or isinstance(metrics_responder, MetricsResponder), \
            "Metric Reporter is not of type yelp_kafka.metrics_responder.MetricsResponder"

        if self.metrics_responder:
            self._setup_metrics_responder(config)
            consumer_config['metrics_responder'] = self._send_to_metrics_responder

        self.pre_rebalance_callback = config.pre_rebalance_callback
        self.post_rebalance_callback = config.post_rebalance_callback

        # Intercept the user's timeout and pass in our own instead. We do this
        # in order to periodically refresh the partitioner when calling next()
        self.iter_timeout = consumer_config['consumer_timeout_ms']
        consumer_config['consumer_timeout_ms'] = CONSUMER_GROUP_INTERNAL_TIMEOUT
        self.config = consumer_config

    def _setup_metrics_responder(self, config):
        extra_dimensions = config.metrics_dimensions
        self.timers = {}
        for name in metrics.TIME_METRIC_NAMES:
            topic_name = self.METRIC_PREFIX + '.' + name
            timer = self.metrics_responder.get_timer_emitter(topic_name, extra_dimensions)
            self.timers[name] = timer

        self.counters = {}
        for name in metrics.FAILURE_COUNT_METRIC_NAMES:
            topic_name = self.METRIC_PREFIX + '.' + name
            counter = self.metrics_responder.get_counter_emitter(topic_name, extra_dimensions)
            self.counters[name] = counter

    def _send_to_metrics_responder(self, key, value):
        if key in self.timers:
            # kafka-python emits time in seconds, but yelp_meteorite wants
            # milliseconds
            time_in_ms = value * 1000
            self.metrics_responder.record(self.timers[key], time_in_ms)
        elif key in self.counters:
            self.metrics_responder.record(self.counters[key], 1)
        else:
            self.log.warn("Unknown metric: {0}".format(key))

    def start(self):
        self.partitioner.start()

    def stop(self):
        self.partitioner.stop()
        self.consumer.close()

    def next(self):
        start_time = time.time()
        while self._should_keep_trying(start_time):
            self.partitioner.refresh()
            try:
                return self.consumer.next()
            except ConsumerTimeout:
                # This is due to the internal timeout, not the user's provided
                # one.
                pass
        error_msg = "KafkaConsumerGroup timed out after {0} ms"
        raise ConsumerTimeout(error_msg.format(self.iter_timeout))

    def _should_keep_trying(self, start_time):
        if self.iter_timeout < 0:
            return True
        elapsed_seconds = time.time() - start_time
        return elapsed_seconds * 1000 < self.iter_timeout

    def task_done(self, message):
        return self.consumer.task_done(message)

    def commit(self):
        return self.consumer.commit()

    def _acquire(self, partitions):
        if not self.consumer:
            self.consumer = KafkaConsumer(partitions, **self.config)
        else:
            self.consumer.set_topic_partitions(partitions)
        if self.post_rebalance_callback:
            self.post_rebalance_callback(partitions)

    # set_topic_partitions causes a metadata request, which may fail on the
    # first try.
    @retry(stop_max_attempt_number=2, retry_on_exception=retry_if_kafka_unavailable_error)
    def _release(self, partitions):
        if self.pre_rebalance_callback:
            self.pre_rebalance_callback(partitions)
        if self._auto_commit_enabled():
            self.consumer.commit()
        self.consumer.set_topic_partitions({})

    def _auto_commit_enabled(self):
        return self.config['auto_commit_enable']

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, type, value, traceback):
        self.stop()

    def __iter__(self):
        return self

    def __next__(self):
        return self.next()

class MultiprocessingConsumerGroup(object):
    """Multiprocessing consumer group allows to consume
    from multiple topics at once. It spawns a python process
    for each assigned partition.
    It also implements monitoring for the running consumers and
    is able to restart restart these upon failures.

    .. note: This class is thread safe.

    Example:

    .. code-block:: python

       from threading import Thread
       from yelp_kafka import discovery
       from yelp_kafka.config import KafkaConsumerConfig
       from yelp_kafka.consumer import KafkaConsumer
       from yelp_kafka.consumer_group import MultiprocessingConsumerGroup

       class MyConsumer(KafkaConsumerBase):

           def __init__(topic, config, partitions):
               super(MyConsumer, self).__init__(topic, config, partitions)

           def initialize(self):
               print "Initializing.. Usually you want to set the logger here"

           def dispose(self):
               print "Dying..."

           def process(self, message):
               partition, offset, key, value = message
               print partition, offset, key, value

       cluster = discovery.get_local_cluster('standard')
       config = KafkaConsumerConfig('my_group', cluster)

       group = MultiprocessingConsumerGroup(
           ['topic1', 'topic2'],
           config,
           MyConsumer,
       )
       group_thread = Thread(target=group.start_group)
       group_thread.start()
       # Do some other cool stuff here like sleep
       time.sleep(600)
       group.stop_group()

    :param topics: a list of topics to consume from.
    :type topics: list
    :param config: yelp_kakfa config. See :py:mod:`yelp_kafka.config`
    :type config: dict
    :param consumer_factory: the function used to instantiate the consumer.
        the consumer_factory must have the same argument list of
        :py:class:`yelp_kafka.consumer.KafkaConsumerBase`. It has to return
        an instance of a subclass of
        :py:class:`yelp_kafka.consumer.KafkaConsumerBase`.
    """

    def __init__(self, topics, config, consumer_factory):
        self.config = config
        self.termination_flag = None
        self.partitioner = Partitioner(
            config,
            topics,
            self.acquire,
            self.release,
        )
        self.consumers = None
        self.consumers_lock = Lock()
        self.consumer_procs = {}
        self.consumer_factory = consumer_factory
        self.log = logging.getLogger(self.__class__.__name__)
        self.pre_rebalance_callback = config.pre_rebalance_callback
        self.post_rebalance_callback = config.post_rebalance_callback

    def start_group(self, refresh_timeout=DEFAULT_REFRESH_TIMEOUT_IN_SEC):
        """Start the consumer group.

        :param refresh_timeout: waiting timeout in secs to refresh
            the consumer group. It should never be greater than
            'zk_partitioner_cooldown' to avoid wasting time resetting
            the partitioner many times upon changes.
            See :py:mod:`yelp_kafka.config`
            Default: 5 seconds.

        .. note: this function does not return. You may want to run it into
            a separate thread.

        """
        # Create the termination flag
        self.termination_flag = Event()

        with self.partitioner:
            while not self.termination_flag.is_set():
                self.termination_flag.wait(refresh_timeout)
                self.monitor()
                try:
                    self.partitioner.refresh()
                except (PartitionerZookeeperError, PartitionerError):
                    self.log.exception("Encountered a partitioner error")
                    raise

    def stop_group(self):
        """Set the termination flag to stop the group.

        :raises: ConsumerGroupError is the group has not been started, yet.
        """
        if not self.termination_flag:
            raise ConsumerGroupError("Group not running")
        self.termination_flag.set()

    def acquire(self, partitions):
        """Acquire kafka topics-[partitions] and start the
        consumers for them.
        """
        self.log.debug("Acquired partitions: %s", partitions)
        with self.consumers_lock:
            self.consumers = list(self.start(
                partitions
            ))
            self.log.debug("Allocated consumers %s", self.consumers)
        if self.post_rebalance_callback:
            self.post_rebalance_callback(partitions)

    def start(self, acquired_partitions):
        """Start a consumer process for each acquired partition.
        Use consumer_factory to create a consumer instance. Then
        start a new process on the method run.

        :param acquired_partitions: acquired topics partitions
        :type: dict {<topic>: <[partitions]>}
        """
        # TODO KAFKA-72: We create a consumer process for each partition.
        # There can be too many consumers in case we have a lot of
        # partitions and just a worker instance.
        # We should make this smarter and allow the user to decide
        # how many processes/partitions allocate.
        for topic, partitions in six.iteritems(acquired_partitions):
            for p in partitions:
                self.log.info(
                    "Creating consumer topic = %s, config = %s,"
                    " partition = %s", topic, self.config, p
                )
                consumer = self.consumer_factory(topic, self.config, [p])
                self.consumer_procs[self.start_consumer(consumer)] = consumer
        return self.consumer_procs.values()

    def start_consumer(self, consumer):
        """Create a new consumer process"""
        try:
            proc = Process(
                target=consumer.run,
                name='Consumer-{0}-{1}'.format(
                    consumer.topic,
                    consumer.partitions,
                ),
            )
            proc.daemon = True
            proc.start()
        except Exception:
            self.log.error(
                "Impossible to start a new consumer."
                "Topic: %s. Partition: %s.",
                consumer.topic,
                consumer.partitions,
            )
            raise ConsumerGroupError(
                "Error starting a new consumer."
                "Topic: {topic}. Partition: {partitions}.".format(
                    topic=consumer.topic,
                    partitions=consumer.partitions,
                ),
            )
        return proc

    def release(self, partitions):
        """Terminate all the consumer processes"""
        if self.pre_rebalance_callback:
            self.pre_rebalance_callback(partitions)
        self.log.info("Terminating consumer group")
        for consumer in six.itervalues(self.consumer_procs):
            consumer.terminate()

        timeout = time.time() + self.config.max_termination_timeout_secs
        while (
            time.time() <= timeout and any(
                [proc.is_alive() for proc in six.iterkeys(self.consumer_procs)]
            )
        ):
            continue

        for proc, consumer in six.iteritems(self.consumer_procs):
            if proc.is_alive():
                os.kill(proc.pid, signal.SIGKILL)
                self.log.error(
                    "Process %s, topic %s, partitions %s:"
                    "killed due to timeout",
                    proc.name,
                    consumer.topic,
                    consumer.partitions,
                )
        self.consumer_procs.clear()
        with self.consumers_lock:
            self.consumers = None

    def monitor(self):
        """Respawn consumer processes upon failures."""
        # We don't use the iterator because the dict may change during the loop
        for proc, consumer in self.consumer_procs.items():
            if not proc.is_alive():
                self.log.error(
                    "consumer process %s topic %s partitions %s: "
                    "died exit status %s",
                    proc.name,
                    consumer.topic,
                    consumer.partitions, proc.exitcode,
                )
                # Restart consumer process
                self.consumer_procs[self.start_consumer(consumer)] = consumer
                # Remove dead process
                del self.consumer_procs[proc]

    def get_consumers(self):
        """Get a copy of the allocated consumers.

        :returns: A copy of allocated consumers
        :rtype: list
        """
        with self.consumers_lock:
            if self.consumers is not None:
                return self.consumers[:]
            return None


# https://leetcode.com/problems/permutations-ii/
from typing import List

class Solution:
    def __init__(self):
        self.results = []
        self.permutation = []

    def backtracking(self, remain):
        if not remain:
            self.results.append(self.permutation[:])
        for i in range(0, len(remain)):
            if i > 0 and remain[i] == remain[i - 1]:
                continue
            self.permutation.append(remain[i])
            self.backtracking(remain[0:i] + remain[i + 1:])
            self.permutation.pop()

    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        self.backtracking(nums)
        return self.results


import torch

import numpy as np

from scipy.io import wavfile
from tqdm import trange

from model.demucsv2.model import Demucs, center_trim
from utils.audio import get_clean_n_noisy
from utils.operation import get_args, prepare_repetition_directory, update_state, \
    get_logger, save_repetition_results, save_experiment_results, \
    prepare_experiment_directory, get_paths, get_crit
from utils.metrics import MetricsTracker

MAX_EXPERIMENT_REPETITION = 1000

def main(args, logger):
    logger.info(args)
    if args.device == "cuda" and not torch.cuda.is_available():
        logger.info("CUDA not available switching to CPU")
        args.device = "cpu"
    paths = get_paths(args.source)
    experiment_dir = prepare_experiment_directory(args)
    for repetition_i in range(MAX_EXPERIMENT_REPETITION):
        wavs = get_clean_n_noisy(paths[repetition_i % len(paths)], args, logger)
        if wavs is None:
            continue
        clean, noisy, clean_path = wavs
        args.clean_path = clean_path
        repetition_directory = prepare_repetition_directory(experiment_dir, args)
        if repetition_directory is None:  # already finished all required repetitions
            logger.info("Finished required repetitions")
            break
        net_input = (torch.rand(size=clean.size(), device=clean.device) - 0.5) * 2
        net = Demucs(sources=1, audio_channels=1, samplerate=args.samplerate, depth=args.depth,
                     skip=args.skip, lstm_layers=args.lstm_layers, glu=args.glu, attention_layers=args.attention_layers,
                     attention_heads=args.attention_heads, resample=args.resample).to(args.device)
        crit = get_crit(args)
        optimizer = torch.optim.Adam(net.parameters(), lr=args.lr)
        wavfile.write(str(repetition_directory / "noisy.wav"), rate=args.samplerate,
                      data=noisy.squeeze().detach().cpu().numpy())
        wavfile.write(str(repetition_directory / "clean.wav"), rate=args.samplerate,
                      data=clean.squeeze().detach().cpu().numpy())
        losses = []
        with torch.no_grad():
            out = net(net_input).squeeze(0)
            clean = center_trim(clean, out)
            noisy = center_trim(noisy, out)

        epochs_range = trange(1, args.epochs + 1)
        metrics_tracker = MetricsTracker(clean, noisy)

        for epoch in epochs_range:
            optimizer.zero_grad()
            out = net(net_input).squeeze(0)
            total_loss = crit(out.squeeze(), noisy.squeeze())
            total_loss.backward()
            loss = total_loss.item()
            losses.append(loss)
            epochs_range.set_description('Epoch %05d Loss=%f' % (epoch, loss))
            optimizer.step()
            update_state(clean, noisy, repetition_directory, epoch, losses, metrics_tracker, out, args)
        save_repetition_results(metrics_tracker, np.array(losses), args.samplerate, repetition_directory)
        try:
            torch.save(net.state_dict(), str(repetition_directory / "state.th"))
        except Exception as e:
            logger.exception(e)
    save_experiment_results(experiment_dir, logger)

if __name__ == "__main__":
    logger = get_logger()
    args = get_args()
    main(args, logger)


from flask import render_template, url_for, flash, redirect,request,Blueprint,Response
from neuro import app
from neuro.Hog.camera import VideoCamera
import os
import os.path
Hog = Blueprint('Hog',__name__)

@Hog.route('/hog')
def index():
    x =os.path.exists('neuro/static/assets/video/Hog.mp4')
    if x == False:
        return render_template('hog.html')
    else:
        os.remove('neuro/static/assets/video/Hog.mp4')
    return render_template('hog.html')

def gen(camera):
    while True:
        #get camera frame
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@Hog.route('/video_feed_hog')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@Hog.route('/uploader_hog', methods = ['GET', 'POST'])
def upload_file():
   success = None
   if request.method == 'POST':
      f = request.files['file']
      f.save("neuro/static/assets/video/"+f.filename)
      os.rename("neuro/static/assets/video/"+f.filename,r"neuro/static/assets/video/Hog.mp4")
      success = "File uploaded successfully"
      return render_template('hog.html',success=success)


"""
This module contains custom filter backends for Django REST Framework.

The backends included in this module are:

- TodaySeanceFilterBackend: A filter backend that filters seances by the ones that occur today.
- DateRangeFilterBackend: A filter backend that filters seances by a date range.

"""

from datetime import datetime, date, time, timedelta
from django_filters import rest_framework as filters
from rest_framework.filters import BaseFilterBackend

class TodaySeanceFilterBackend(BaseFilterBackend):
    """
    A filter backend that filters seances by the ones that occur today.

    This filter backend retrieves the seances that occur on the current date. It does this by
    comparing the date of the seance with the current date. If a seance's date is equal to the current
    date, then it is included in the queryset.

    Attributes:
        None

    Methods:
        filter_queryset(request, queryset, view): Filters the queryset based on the query parameters
            provided in the request object. Returns the filtered queryset.
    """

    def filter_queryset(self, request, queryset, view):
        """
            Filters the queryset based on the query parameters provided in the request object.
            Returns the filtered queryset.

            Args:
                request (Request): The request object containing the query parameters.
                queryset (QuerySet): The queryset to filter.
                view (APIView): The view class that called the filter.

            Returns:
                QuerySet: The filtered queryset.
            """

        today = date.today()
        start_time__gte = datetime.combine(today, datetime.min.time())
        start_time__lte = datetime.combine(today, datetime.max.time())

        hall = request.query_params.get('hall')
        start_time = request.query_params.get('start_time')
        end_time = request.query_params.get('end_time')

        if hall:
            queryset = queryset.filter(hall=hall)

        if start_time and end_time:
            start_time = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S')
            end_time = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S')
            queryset = queryset.filter(start_time__range=(start_time, end_time))

        if start_time and not end_time:
            start_time_exact = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S')
            queryset = queryset.filter(
                start_time__gte=start_time__gte,
                start_time__lte=start_time__lte,
                start_time__time__gte=start_time_exact.time()
            )

        return queryset

class DateRangeFilterBackend(BaseFilterBackend):
    """
    A filter backend that filters seances by a date range.

    This filter backend retrieves the seances that occur between two dates. It does this by
    filtering the queryset by the start_time that is greater than or equal to the start_time__gte
    parameter and less than or equal to the start_time__lte parameter.

    Attributes:
        None

    Methods:
        filter_queryset(request, queryset, view): Filters the queryset based on the query parameters
            provided in the request object. Returns the filtered queryset.
    """

    def filter_queryset(self, request, queryset, view):
        """
        Filters the queryset based on the query parameters provided in the request object.
        Returns the filtered queryset.

        Args:
            request (Request): The request object containing the query parameters.
            queryset (QuerySet): The queryset to filter.
            view (APIView): The view class that called the filter.

        Returns:
            QuerySet: The filtered queryset.
        """

        start_time__gte = request.query_params.get('start_time__gte')
        start_time__lte = request.query_params.get('start_time__lte')

        if start_time__gte and start_time__lte:
            start_time__gte = datetime.strptime(start_time__gte, '%Y-%m-%dT%H:%M:%S')
            start_time__lte = datetime.strptime(start_time__lte, '%Y-%m-%dT%H:%M:%S')
            queryset = queryset.filter(start_time__gte=start_time__gte, start_time__lte=start_time__lte)

        return queryset


import unittest

if __name__ == '__main__':
    case_path = "test"
    load = unittest.TestLoader()
    all_case = load.discover(case_path, pattern="test*.py", top_level_dir=None)

    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(all_case)


# 写出每个月的天数
day=0
year=int(input('请输入任意年份'))
month=int(input('请输入任意月份'))
if month in [1,3,5,7,8,10,12]:
    print(f'{month}月有31天。')
elif month in [4,6,9,11]:
    print(f'{month}月有30天')
elif month==2 and year%4==0 and year%100!=0 or year%400==0:
    print(f'{month}月有29天')
else:
    print(f'{year}年{month}月有28天')
# 自动跳出星期
# # #
# # # while 1:
# #     num=int(input('请输入数字1-7（输入0结束）'))
# #     if num ==1:
# #         print('MON')
# #
# #     elif num==2:
# #         print('TUE')
# #
# #     elif num==3:
# #         print('WED')
# #
# #     elif num==4:
# #         print('THUR')
# #
# #     elif num==5:
# #         print('FRI')
# #
# #     elif num == 6:
# #         print('SAT')
# #
# #     elif num==7:
# #         print('SUN')
# #
# #     elif num>7:
# #         print('请重新输入：')
# #
# #     else:
# #         print('程序结束！')
# #         break
# #简化版 in
# num1=[1,2,3,4,5,6,7]
# weekday=['MON','TUE','WED','THER','FRI','SAT','SUN']
# # for i,j,in zip(num1,weekday):
#     num=int(input('请输入数字1-7（输入0结束）'))
#     if num ==i:
#         print(j)
#     elif num>7:
#         print('请重新输入：')
#     else:
#         print('程序结束！')
#         break
#
#     # elif num==2:
#     #     print('TUE')
#     #
#     # elif num==3:
#     #     print('WED')
#     #
#     # elif num==4:
#     #     print('THUR')
#     #
#     # elif num==5:
#     #     print('FRI')
#     #
#     # elif num == 6:
#     #     print('SAT')
#     #
#     # elif num==7:
#     #     print('SUN')
#     #
#     # elif num>7:
#     #     print('请重新输入：')
#     #
#     # else:
#     #     print('程序结束！')
#     #     break
# #翻转
# # i='6830575629474'
# # print(i[::-1])
# # print(''.join(reversed('6830575629474')))


from rest_framework import serializers

from pipeline.models.location_assets import (FirstResponder, DiagnosticFacility, TimberFacility,
                                             CivicFacility, Hospital, Project, ServiceBCLocation,
                                             School, Clinic, Court, PostSecondaryInstitution,
                                              ResearchCentre, Airport, Location)

class LocationSerializer(serializers.ModelSerializer):
    community_id = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = Location
        fields = ("id", "name", "community_id", "location_type", "get_latitude", "get_longitude",
                  "location_fuzzy")

class FirstResponderSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = FirstResponder
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "location_website",
            "location_email",
            "category",
            "subcategory",
        )

class DiagnosticFacilitySerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = DiagnosticFacility
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "ser_cd_dsc",
        )

class TimberFacilitySerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = TimberFacility
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "bus_cat_ds",
        )

class CivicFacilitySerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = CivicFacility
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_website",
            "category",
            "subcategory",
            "bus_cat_cl",
            "bus_cat_ds",
        )

class HospitalSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = Hospital
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "location_website",
            "location_email",
            "rg_name",
            "sv_description",
            "hours",
            "num_communities_within_50km",
        )

class ProjectSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")
    provincial_funding = serializers.IntegerField(source="provinvial_funding")
    standardized_start_date = serializers.DateField(source='get_standardized_start_date_as_date')
    standardized_completion_date = serializers.DateField(
        source='get_standardized_completion_date_as_date')
    standardized_start_date_quarter = serializers.CharField(
        source='get_standardized_start_date_as_quarter')
    standardized_completion_date_quarter = serializers.CharField(
        source='get_standardized_completion_date_as_quarter')

    class Meta:
        model = Project
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "location_website",
            "project_id",
            "project_name",
            "project_description",
            "estimated_cost",
            "update_activity",
            "environmental_assessment_stage",
            "construction_type",
            "project_type",
            "region",
            "municipality",
            "developer",
            "architect",
            "project_status",
            "project_stage",
            "project_category_name",
            "public_funding_ind",
            "provincial_funding",
            "green_building_ind",
            "clean_energy_ind",
            "first_nation_ind",
            "first_nation_names",
            "first_nation_agreement",
            "construction_jobs",
            "operating_jobs",
            "start_date",
            "completion_date",
            "standardized_start_date",
            "standardized_completion_date",
            "standardized_start_date_quarter",
            "standardized_completion_date_quarter",
            "first_entry_date",
            "last_update",
            "source_date",
            "source_website",
            "updated_fields",
            "is_earliest_entry",
            "is_latest_entry",
        )

class ServiceBCLocationSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = ServiceBCLocation
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "location_website",
        )

class SchoolSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    school_district = serializers.SerializerMethodField()
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = School
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "district_number",
            "public_or_independent",
            "school_education_level",
            "school_district",
        )

    def get_school_district(self, obj):
        return obj.school_district.name if obj.school_district else None

class PostSecondaryInstitutionSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = PostSecondaryInstitution
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "institution_type",
            "economic_development_region",
        )

class ClinicSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = Clinic
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "location_website",
            "location_email",
            "sv_description",
            "hours",
        )

class CourtSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = Court
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_phone",
            "hours_of_operation",
            "court_level",
        )

class ResearchCentreSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = ResearchCentre
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_website",
            "research_specialties",
            "research_centre_affiliation",
            "institution",
            "inst_acrnm",
            "research_sector",
            "cntr_type",
        )

class AirportSerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField(source="get_latitude")
    longitude = serializers.FloatField(source="get_longitude")
    community = serializers.IntegerField(source="closest_community_id")

    class Meta:
        model = Airport
        fields = (
            "id",
            "name",
            "latitude",
            "longitude",
            "location_fuzzy",
            "community",
            "location_website",
            "location_phone",
            "description",
            "keywords",
            "aerodrome_status",
            "aircraft_access_ind",
            "data_source",
            "data_source_year",
            "elevation",
            "fuel_availability_ind",
            "helicopter_access_ind",
            "iata_code",
            "max_runway_length",
            "number_of_runways",
            "runway_surface",
            "oil_availability_ind",
            "seaplane_access_ind",
        )


#coding=utf-8
#print a string
print("Mary had a little lamb.")
#print a format string with a string in it.
print("Its fleece was white as {}".format('snow'))
#print a string
print("And everywhere that Mary went.")
#print a dot mark and repeat this print for ten times.
print("." * 10) #what'd that do？

#set a value to each variable
end1 = "C"
end2 = "H"
end3 = "E"
end4 = "E"
end5 = "S"
end6 = "E"
end7 = "B"
end8 = "U"
end9 = "R"
end10 = "G"
end11 = "E"
end12 = "R"

#what that comma at the end. try removing it to see what happens
#print several variables and end with a string
print(end1 + end2 + end3 + end4 + end5 + end6, end=' ~~  ')
#print several variables.
#you can add any string in this concatenate str but not int.
print(end7 + end8 + end9 + end10 + end11 +end12 + "123")


"""Bagels, by Al Sweigart al@inventwithpython.com
A deductive logic game where you must guess a number based on clues.
View the original code at https://nostarch.com/big-book-small-python-projects
A version of this game is featured in the book "Invent Your Own
Computer Games with Python" https://nostarch.com/inventwithpython
Tags: short, game, puzzle"""

import random

def main():
    print("""Bagels, a deductive logic game.
By Al Sweigart al@inventwithpython.com""")

    # Sets difficulty level.
    num_digits, max_guesses = set_difficulty()

    print(f"""I am thinking of a {num_digits} digit-number with no repeated digits.
Try to guess what it is. Here are some clues:
When I say:     That means:
    Pico        One digit is correct but in the wrong position.
    Fermi       One digit is correct and in the right position.
    Bagels      No digit is correct.

For example, if the secret number was 248 and your guess was 843, the
clues would be Fermi Pico.""")  # TODO: Try to create a version with letters as well as digits.

    while True:  # Main game loop.
        # This stores the secret number the player needs to guess.
        secret_num = get_secret_num(num_digits)
        print("I have thought up a number.")
        print(f"You have {max_guesses} guesses to get it.")

        num_guesses = 1
        while num_guesses <= max_guesses:
            guess = ''
            # Keep looping until they enter a valid guess:
            while len(guess) != num_digits or not guess.isdecimal():
                print(f"Guess #{num_guesses}: ")
                guess = input("> ")

            clues = get_clues(guess, secret_num)
            print(clues)
            num_guesses += 1

            if guess == secret_num:
                break  # They're correct so break out of this loop.
            if num_guesses > max_guesses:
                print("You ran out of guesses.")
                print(f"The answer was {secret_num}.")

        # Ask the player if they want to play again.  TODO: Allow for changing difficulty at the end of each game.
        print("Do you want to play again? (yes or no)")
        if not input("> ").lower().startswith('y'):
            break
    print("Thanks for playing!")

def get_secret_num(num_digits):
    """Returns a string made up of num_digits unique random digits."""
    numbers = list('0123456789')  # Create a list of digits 0 to 9.
    random.shuffle(numbers)  # Shuffle them into a random order.

    # Get the first NUM_DIGITS digits in the list for the secret number:
    secret_num = ''
    for i in range(num_digits):
        secret_num += str(numbers[i])
    return secret_num

def get_clues(guess, secret_num):
    """Returns a string with the pico, fermi, bagel clues for a guess
    and secret number pair."""
    if guess == secret_num:
        return "You got it!"

    clues = []

    for i in range(len(guess)):
        if guess[i] == secret_num[i]:
            # A correct digit is in the correct place.
            clues.append('Fermi')
        elif guess[i] in secret_num:
            # A correct digit is in the incorrect place.
            clues.append('Pico')
    if len(clues) == 0:
        return 'Bagels'  # There are no correct digits at all.
    else:
        # Sort the clues into alphabetical order so their original order
        # doesn't give information away.
        clues.sort()
        # Make a single string from the list of string clues.
        return ' '.join(clues)

def set_difficulty():
    """Returns num_digits and max_guesses depending on difficulty as set by user."""

    num_digits, max_guesses = 3, 10  # Default values

    difficulty = ''

    while not difficulty.lower().startswith(("e", "m", "h")):
        print("Please select a difficulty level: (easy/medium/hard)")
        difficulty = input("> ")

    if difficulty.lower().startswith('e'):
        num_digits, max_guesses = 2, 5
    elif difficulty.lower().startswith('h'):
        num_digits, max_guesses = 4, 8

    return num_digits, max_guesses

if __name__ == '__main__':
    main()


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from pandas_profiling import ProfileReport

df = pd.read_csv("../../data/raw/meteors.csv")
df

def data(path):
    df2 = (
    df.rename(columns={"name":"Name given","nametype":"Classification of state","recclass": "Class","mass": "Mass", "fall": "Fall Type"})
    .dropna()
    .drop(['reclat', 'reclong'], axis=1)
      )
    return df2

def DataMass(path):
    df3= (
    df.rename(columns={"name":"Name given","nametype":"Classification of state","recclass": "Class","mass": "Mass", "fall": "Fall Type"})
    .sort_values('Mass', ascending = True)
    .drop(['reclat', 'reclong'], axis=1)
    .dropna()
        )
    return df3

def DataYear(path):
    df4 = (
    df.rename(columns={"name":"Name given","nametype":"Classification of state","recclass": "Class","mass": "Mass", "fall": "Fall Type"})
    .sort_values("year", ascending=True)
    .drop(['reclat', 'reclong'], axis=1)
    .dropna()
)
    return df4


def string_to_int(s):
    """
    >>> string_to_int("123")
    123

    Complexity : O(n) with n length of the string
    """
    tab_conversion = {"0":0, "1":1, "2":2, "3": 3, "4": 4, "5":5, "6":6, "7":7, "8":8, "9":9}
    val = 0
    lenght = len(s)
    for num, letter in enumerate(s):
        val += tab_conversion[letter] * 10 ** (lenght-num-1)
    return val

def string_to_int_more_efficient(s):
    """
    >>> string_to_int_more_efficient("1")
    1
    >>> string_to_int_more_efficient("108")
    108

    Complexity : O(n) with n length of the string
    """
    tab_conversion = {"0":0, "1":1, "2":2, "3": 3, "4": 4, "5":5, "6":6, "7":7, "8":8, "9":9}
    val = 0
    sign = 1
    for num, letter in enumerate(s):
        if letter == '-':
            sign = -1
            continue
        val = (val * 10 + tab_conversion[letter])
    val = sign * val
    return val

def int_to_string(val):
    """
    >>> int_to_string(8120830)
    '8120830'
    """
    res = []
    if val < 0 :
        res.append("-")

    while val !=0:
        res.append('%s' % (val % 10))
        val /= 10
    return "".join(reversed(res))


### TEST ENV ###

# global duality import.
import duality

# makes multiple instances of the object available.
from logistics.plugins.metaclass import Meta

# set type of numpy array and pandas particles.
import numpy as np
import pandas as pd

# for CLI functionality.
import os
from colorama import (
    Fore,
    Back,
    Style,
    init,
)

init()

# imports all data types.
from logistics.plugins.types import *

# imports coloring.
from logistics.plugins.coloring import *

app = duality.DualityApp()

# package.
class MonteCarlo:

    @app.entry('init')
    def __init__(
        self,
        list_of_values : NumberVectorAlike = app.store('list_of_values', 'numlist', 'VALUES'),
        time_seq : IntegerType = app.store('time_seq', 'int'),
        num_sims : IntegerType = app.store('num_sims', 'int'),
        ref_col : IntegerType = 0,
        ref_row : IntegerType = 0,
        ) -> ReturnType:

        '''
        * initial launch.
        '''

        self.list_of_values = list_of_values
        self.time_seq = time_seq
        self.num_sims = num_sims
        self.ref_col = ref_col
        self.ref_row = ref_row

        return

    @app.entry('execute', print_val = True)
    def execute(
        self,
        filtered : BooleanType = True,
        ) -> NumberArrayAlike:

        '''
        * executes a Monte Carlo simulation on a defined data set.
        - filtered (True/False) - filters the data setup print and warnings.
        # DEFAULT: MonteCarlo.execute(filtered : BooleanType = True.)
        '''

        if filtered == False:
            print(Fore.GREEN + f'Monte Carlo has been set up for {self.num_sims} simulations in a period of {self.time_seq} time measurement units and executed.' + Fore.RESET)
            print(Fore.RED + 'NOTE: Use data with reasonable standard deviation in order to prevent exponential growth of the function that cannot be plotted properly, recognize such abnormal values by a + sign anywhere in the data executed below.' + Fore.RESET)

        import numpy as np
        import pandas as pd

        # this removes pandas warning of highly fragmented DataFrame for newer pandas versions.
        from warnings import simplefilter
        simplefilter(action = 'ignore', category = pd.errors.PerformanceWarning)
        # end of pandas warning removal block.

        try:
            self.list_of_values = pd.DataFrame(self.list_of_values)
            self.list_of_values = self.list_of_values.iloc[:, self.ref_col]
        except:
            raise KeyError('Impossible to reach a defined key, value pair. Data types supported: dictionary, list, numpy array, pandas DataFrame. Make sure to set index row_col on an existing field. Must be of type: int.')

        today_value = self.list_of_values.iloc[self.ref_col]
        data = pd.DataFrame()
        loading = 0

        for num_sim in range(self.num_sims):
            rand_change = self.list_of_values.pct_change().std()
            count = 0
            index_array = []
            index_array += [today_value + (today_value * np.random.normal(0, rand_change))]

            for num_day in range(self.time_seq):
                rand_change = self.list_of_values.pct_change().std()
                if count == self.time_seq:
                    break
                index_array += [index_array[count] + (today_value * np.random.normal(0, rand_change))]
                count += 1

            loading += 1
            print(end = '\r')
            print(loading, 'iterations out of', self.num_sims, 'executed so far', end = '')

            data[num_sim] = index_array
        print(end = '\r')
        print(Fore.GREEN + 'Monte Carlo simulation set up and ready to plot.' + Fore.RESET)
        self.results = data

        return data

    @app.entry('change', print_val = True)
    def get_change(
        self,
        ) -> NumberArrayAlike:

        '''
        * shows the percentage of Monte Carlo simulation value change for every iteration.
        '''

        return self.results.pct_change()

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


# -*- coding: utf-8 -*-
"""This module creates the network commands from the network option within services.

.. _Google Python Style Guide:
    http://google.github.io/styleguide/pyguide.html

"""

from ..parser import Parser

class ServiceNetworkParser(Parser):
    """This class converts network in docker-compose services into `docker network` connect commands.
    For example given the below yaml definition (docker-compose.yml).

    ::

        services:
            app:
                image: nginx:alpine
                networks:
                    app_net:
                        ipv4_address: 172.16.238.10

    Once parsed it will look something like:

    ::

        {
            "app_net": {
                "ipv4_address": "172.16.238.10",
            }
        },

    We generate the following command:

    ::

        docker network connect --ip 172.16.238.10 app_net example_app

    Args:
        service_name (str): The name of the container to attach the network to.
        network_name (str): The name of the network (from config).
        network_config (dict): The network option in the service (see example above).

    Attributes:
        service_name (str): The name of the container to attach the network to.

    """

    def __init__(self, service_name: str, network_name: str, network_config: dict):
        self.service_name = service_name
        args = {
            "aliases": {"type": [list], "name": "--alias"},
            "driver": {"type": [str], "name": "--driver-opt"},
            "ipv4_address": {"type": [str], "name": "--ip"},
            "ipv6_address": {"type": [str], "name": "--ip6"},
        }
        super().__init__(args=args, config_name=network_name, config_options=network_config)

    def get_command(self) -> list:
        """Converts the docker compose syntax to normal docker commands. For each network defined in the services
        we generate one `docker network connect` command.

        Returns:
            list: A list of `docker network connect` commands to connect a network to the container.

        """
        args = self._get_args()
        network_command = f"docker network connect {args} {self.config_name} {self.service_name}"
        return network_command