import datetime
import random
import re
import time
import warnings
from multiprocessing import Process, Queue
import sdbfuncs

import urllib3
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import config
import SBDdata

warnings.filterwarnings("ignore")

class Item():
    name = ''
    def __init__(self, name , color, size,category):
        self.name=name
        self.color=color
        self.category = category
        self.size=size
        self.sizeid=''
        self.shopid = ''
        self.itemid=''
        self.colid=''
        self.active=False
    def __str__(self):
        return  self.name+':  '+str(self.shopid)+':'+str(self.itemid)+':'+str(self.colid)

def findItems(item,q):
    #Найти товар на странице
    http = urllib3.PoolManager()

    ad=False
    r = http.request('GET', 'https://www.supremenewyork.com/shop/all/'+item.category)
    d = r.data
    soup = BeautifulSoup(d)
    brke=False

    for link in soup.find_all('a'):
        if(brke):
            break

        if (sdbfuncs.iseacval (link.contents[0], item.name )):

            for l in soup.find_all('a'):
                if l.get('href') == link.get('href') and (str(l.contents[0]).lower() == str(item.color).lower() or item.color=='any'):

                    page_url = l.get('href')
                    http = urllib3.PoolManager()
                    r = http.request('GET',
                                     "http://www.supremenewyork.com/" + page_url)
                    d = r.data
                    print(d)
                    parsed_html = BeautifulSoup(d)

                    at = parsed_html.body.find('select', attrs={'id': 'size'})
                    at = at.find_all('option')

                    for sz in at:
                        if (sz.text == item.size or item.size == 'any'):
                            item.sizeid=sz['value']
                            break

                    at = str(parsed_html.body.find('input', attrs={'id': 'style'}))
                    a = str(re.search(r'\d{4,6}', at).group())

                    ct = str(parsed_html.body.find('form', attrs={'id': 'cart-addf'}))
                    c = str(re.search(r'\d{5,6}', ct).group())
                    item.shopid = c
                    item.colid = a
                    if(a!=''):
                        item.active=True

                    print('Найден: ',item.name)
                    ad=True

                    brke=True
                    break

    if (ad==False) :
        print('Товар не найден:',item.name)

    q.put(item)

def wait():
    http = urllib3.PoolManager()
    r = http.request('GET',
                     "https://www.supremenewyork.com/shop/new")
    d = r.data
    d1 = d
    while (d == d1):
        r = http.request('GET',
                         "https://www.supremenewyork.com/shop/new")
        d1 = r.data
        time.sleep(2)

def bot(data,items):

    JsBuy = open('buy.js').read()
    JScode = open('additem.js').read()
    options = Options()
    options.add_argument('test-type')
    options.accept_untrusted_certs = True
    options.assume_untrusted_cert_issuer = True
    options.add_argument("user-data-dir=selenium")
    # options.set_headless(headless=True)

    driver = webdriver.Chrome(options=options)
    driver.set_window_size(1050, 650)
    #print('Ходят легенды, если потренеровать капчу заранее, шанс взять выше:')
    #driver.get('https://patrickhlauke.github.io/recaptcha/')

    print('Ожидание дропа.. ничего не трогай!')
    #sdbfuncs.waittime()
    url = "https://www.supremenewyork.com/shop/all/new"
    driver.get(url)
    #sdbfuncs.waitdrop()

    ti=time.clock()
    print("Бот запущен",datetime.datetime.now())

    q = Queue()
    proc =[]
    for item in items:
        proc.append(Process(target=findItems, args=(item, q)))

    for p in proc:#запускаем все
        p.start()

    for p in proc:#ждем окончание всех процессов
        p.join()

    print('all items detected')

    for i in range(len(items)):
        items[i]=q.get()
    #print('Добавлено в список задач', q.get())

    for i in range(len(items)):
        if(items[i].active==False):
            print('Товар не найден или sold out: ',items[i].name)
            continue

        cd = JScode.format(shopid=items[i].shopid, styleid=items[i].colid, sizeid=items[i].sizeid)
        driver.execute_script(cd)
        print("Товар добавлен в корзину", items[i], time.clock()-ti)
        if(i+1!=len(items)):
            time.sleep(0.3)

    JsBuy=JsBuy.format(name=data['fio'],email=data['email'],tel=data['tel']
                       ,adress=data['adress'],sity=data['sity'],cardnom=data['card_nom']
                       ,zip=data['postcode'],cvv=data['card_cvc'],card_type=data['card_type'],
                       card_month=data['card_month'],card_year=data['card_year'])
    driver.execute_script(JsBuy)
    print("Куплено", time.clock()-ti)
    time.sleep(5)
    driver.save_screenshot('scrin.png')
    time.sleep(360)

def main(data, items):
    bot(data, items)

def run():
    import SBDdata
    try:
        data=SBDdata.getdata()
    except :
        sdbfuncs.setdata()
        data = SBDdata.getdata()

    items = []

    name = 'Box Logo Crewneck Sweatshirt'
    print('name: ',name)
    size=input('Item size: ')
    color = input('Item color: ')

    wt=random.uniform(0.9, 1.8)
    while True:
        #name=input('Item name: ')

        if(name)=='-':
            break
        #size=input('Item size: ')
        #color=input('Item color: ')
        category=input('Item category [low letter]: ')
        if (category) == '-':
            break

        itm = Item(name, color, size, category)
        items.append(itm)
        wt += random.uniform(0.2, 0.5)

    print("--------------------------")
    print("Товар добавлен, рассчетное время работы бота",wt,'c')
    main(data,items)

def testrun():
    import SBDdata
    try:
        data = SBDdata.getdata()
    except:
        sdbfuncs.setdata()
        data = SBDdata.getdata()

    items = []

    name = 'Diamond Faux Fur Jacket'
    color="any"
    size="any"
    category="jackets"
    print('name: ', name)

    wt = random.uniform(0.9, 1.8)

    itm = Item(name, color, size, category)
    items.append(itm)
    wt += random.uniform(0.2, 0.5)

    print("--------------------------")
    print("Товар добавлен, рассчетное время работы бота", wt, 'c')
    main(data, items)

if __name__ == "__main__":
    print(config.avaimg)
    if(sdbfuncs.issetting()==False):
        sdbfuncs.setsetting()
    #boxlogorun()
    testrun()
    #run()


import pygame, pickle, copy, setting
from constant import *
from button import Button
import random
from menu import Menu

# 키 입력을 위한 설정
class Setting_Key_Bundle(Menu):

     # 가능한 메뉴 목록
    avail_menu = ["up", "down", "left", "right", "enter", "pause"]
    display_name = ["위", "아래", "왼쪽", "오른쪽", "선택", "일시정지"]

    # 버튼이 있어야 할 위치 반환
    pos_formula = lambda self, i: (self.size[0] * (i+1)/7, self.size[1] * 0.7)

    # x축 정렬 메뉴? y축 정렬 메뉴?
    axis = "x"

    def __init__(self, pos, size):
        self.name = "keys"
        self.screen = None
        super().__init__(pos, size, scale=(0.6, 1.0))

    def init_draw(self):
        self.pos = self.pos_formula
        super().init_draw()
        for i in range(len(self.avail_menu)):
            self.button[i].ChangeText(
                f"{self.display_name[i]}: {pygame.key.name(setting.options[self.avail_menu[i]])}"
            )

    def draw(self, screen):
        # key_prompt를 위해 screen이 필요하지만, handle_event를 고칠 수는 없으므로.
        if self.screen is None:
            self.screen = screen

    def select_menu(self, index):
        key = self.avail_menu[index]

        # 키 설정 메시지 출력
        font = setting.get_font(70)
        text = font.render("바꿀 키를 입력해주세요.", True, "Black")
        pygame.draw.rect(self.screen, "White", text.get_rect(center=(self.size[0] / 2, self.size[1] / 2)))

        text_rect = text.get_rect(center=(self.size[0] / 2, self.size[1] / 2))
        self.screen.blit(text, text_rect)
        pygame.display.update()

        # 사용자가 키를 입력할 때까지 대기
        key_pressed = False
        while not key_pressed:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    # 입력된 키값 저장
                    try:
                        setting.apply_setting(key, event.key)
                        key_pressed = True
                    except ValueError:
                        text = font.render("중복된 키가 입력되었습니다. 다시 시도해 주세요.", True, "Black")
                        pygame.draw.rect(self.screen, "White", text.get_rect(center=(self.size[0] / 2, self.size[1] / 2)))
                        text_rect = text.get_rect(center=(self.size[0] / 2, self.size[1] / 2))
                        self.screen.blit(text, text_rect)
                        pygame.display.update()
        self.button[index].ChangeText(
            f"{self.display_name[index]}: {pygame.key.name(setting.options[key])}"
        )

# 키 입력을 제외한 일반적인 설정
class Setting_Menu(Menu):
    # 가능한 메뉴 목록
    avail_menu = []

    # 버튼이 있어야 할 위치 반환
    pos_formula = None

    # x축 정렬 메뉴? y축 정렬 메뉴?
    axis = "x"

    def __init__(self, pos, size, name):
        self.name = name
        if name == "resolution":
            self.avail_menu = list(str(value) for value in setting.resolution.values())
            self.pos_formula = lambda i: (
                self.size[0] * (7 + 6 * i) / 31,
                self.size[1] * 0.2,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.2)
            self.display_name = "해상도"
        elif name == "sound":
            self.avail_menu = ["-10%", "+10%"]
            self.pos_formula = lambda i: (
                self.size[0] * (9 + 14 * i) / 31,
                self.size[1] * 0.3,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.3)
            self.display_name = "전체 음량"
        elif name == "bgm":
            self.avail_menu = ["-10%", "+10%"]
            self.pos_formula = lambda i: (
                self.size[0] * (9 + 14 * i) / 31,
                self.size[1] * 0.4,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.4)
            self.display_name = "배경음악"
        elif name == "se":
            self.avail_menu = ["-10%", "+10%"]
            self.pos_formula = lambda i: (
                self.size[0] * (9 + 14 * i) / 31,
                self.size[1] * 0.5,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.5)
            self.display_name = "효과음"
        elif name == "colorblind":
            self.avail_menu = ["켜짐", "꺼짐"]
            self.pos_formula = lambda i: (
                self.size[0] * (9 + 14 * i) / 31,
                self.size[1] * 0.6,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.6)
            self.display_name = "색약 모드"
        elif name == "control":
            self.avail_menu = ["전체 초기화", "돌아가기"]
            self.pos_formula = lambda i: (
                self.size[0] * (9 + 14 * i) / 31,
                self.size[1] * 0.8,
            )
            self.name_formula = lambda: (self.size[0] * 0.1, self.size[1] * 0.8)
            self.display_name = ""

        super().__init__(pos, size, scale=((0.8, 1) if name == 'resolution' else (1, 1)))

    def init_draw(self):
        super().init_draw()

        self.name_pos = self.name_formula()
        self.NAME_TEXT = setting.get_font(45 * setting.get_screen_scale()).render(
            f"{self.display_name}: ", True, "Black"
        )
        self.NAME_RECT = self.NAME_TEXT.get_rect(center=self.name_pos)

    def draw(self, screen):
        if self.display_name != "":
            screen.blit(self.NAME_TEXT, self.NAME_RECT)

    # 메뉴 선택 시 처리
    def select_menu(self, index):
        super().select_menu(index)
        if self.name == "resolution":
            setting.apply_setting("resolution", index)
        if self.name in ("sound", "bgm", "se"):
            volume = int(self.avail_menu[index].split("%")[0])
            setting.apply_setting(self.name, setting.options[self.name]+volume)
        if self.name == "colorblind":
            setting.apply_setting(
                "colorblind", True if self.avail_menu[index] == "켜짐" else False
            )
        if self.name == "control":
            if index == 0:
                setting.reset_setting()
            else:
                pygame.event.post(pygame.event.Event(EVENT_CLOSE_OPTION))

class Setting_UI:

    # 가능한 메뉴 목록
    avail_menu = []

    def __init__(self, pos=(0, 0), size=(150, 50)):
        setting.options = setting.default_setting
        setting.load_setting()
        self.pos = pos
        self.size = size
        self.pressed = False

        # 현재 highlight된 위치의 index
        self.highlight = ("None", 0)
        # 현재 선택된 대상, -1일 경우 마우스 조작 중
        self.selected = [0, -1]

        self.init_draw()

    # init에서 draw 부분을 분리
    def init_draw(self,):
        self.OPTIONS_TEXT = setting.get_font(45, True).render(
            "설정", True, "Black"
        )
        self.OPTIONS_RECT = self.OPTIONS_TEXT.get_rect(center=(self.size[0] / 2, 50))

        self.setting_menus = []
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "resolution"))
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "sound"))
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "bgm"))
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "se"))
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "colorblind"))
        self.setting_menus.append(Setting_Key_Bundle(self.pos, self.size))
        self.setting_menus.append(Setting_Menu(self.pos, self.size, "control")) # 초기화, 돌아가기

    # 크기 변경에 맞춰 재조정
    def resize(self, size):
        self.size = size

        self.init_draw()

        for obj in self.setting_menus:
            obj.resize(size)

    # 스크린에 자신을 그리기
    def draw(self, screen: pygame.Surface):
        screen.fill("white")

        self.SOUND_TEXT = setting.get_font(45).render(
            f"{setting.options['sound']}%", True, "Black"
        )
        self.SOUND_RECT = self.SOUND_TEXT.get_rect(center=(self.size[0] / 2, self.size[1] * 0.3))
        self.BGM_TEXT = setting.get_font(45).render(
            f"{setting.options['bgm']}%", True, "Black"
        )
        self.BGM_RECT = self.BGM_TEXT.get_rect(center=(self.size[0] / 2, self.size[1] * 0.4))
        self.SE_TEXT = setting.get_font(45).render(
            f"{setting.options['se']}%", True, "Black"
        )
        self.SE_RECT = self.SE_TEXT.get_rect(center=(self.size[0] / 2, self.size[1] / 2))

        screen.blit(self.OPTIONS_TEXT, self.OPTIONS_RECT)
        screen.blit(self.SOUND_TEXT, self.SOUND_RECT)
        screen.blit(self.BGM_TEXT, self.BGM_RECT)
        screen.blit(self.SE_TEXT, self.SE_RECT)

        for menu in self.setting_menus:
            for i in range(menu.max_menu):
                menu.button[i].update(screen)
                if menu.name == self.highlight[0] and i == self.highlight[1]:
                    menu.button[i].changeHighlight(True, screen)
                else:
                    menu.button[i].changeHighlight(False, screen)

        for obj in self.setting_menus:
            obj.draw(screen)

    # 이벤트 처리
    # 키보드 처리를 해결하기 위해 모든 메뉴를 하나의 객체로 묶어버릴지,
    # 아니면 설정 객체에서 모든 이벤트를 처리할지 꽤 고민했습니다.
    # 일단 후자로 결정했습니다.
    def handle_event(self, event: pygame.event.Event):
        # 마우스 입력 = 모든 메뉴를 순회하여 기존 메뉴처럼 처리
        for menu in self.setting_menus:
            if event.type == pygame.MOUSEBUTTONDOWN:
                 for i in range(menu.max_menu):
                    if menu.rect[i].collidepoint(event.pos):
                        menu.select_menu(i)
                        break  # 한 번에 여러 개의 메뉴가 눌리지 않도록 처리
            elif event.type == pygame.MOUSEMOTION:
                for i in range(menu.max_menu):
                    if menu.rect[i].collidepoint(event.pos):
                        # highlight 대상을 변경
                        self.highlight = (menu.name, i)
                        # 키보드 선택 해제
                        self.selected = [0, -1]
        # 키보드 입력
        if event.type == pygame.KEYDOWN:
            if self.pressed == False:
                self.pressed = True
                # 엔터 키가 눌렸을 때
                if event.key == setting.options["enter"]:
                    # 키보드로 선택한 것이 있다면 그 메뉴를 선택
                    if self.selected != -1:
                        self.setting_menus[self.selected[0]].select_menu(self.selected[1])
                elif (event.key == setting.options["left"]):
                    # 선택을 하나 위로 이동
                    if self.selected[1] > 0:
                        self.selected[1] -= 1
                    else:
                        # 해당 메뉴의 첫 선택으로 가면 이전 메뉴로 넘기기
                        self.selected[0] -= 1
                        if self.selected[0] == -1: self.selected[0] = len(self.setting_menus) - 1
                        self.selected[1] = self.setting_menus[self.selected[0]].max_menu - 1
                    self.highlight = (self.setting_menus[self.selected[0]].name, self.selected[1])
                elif (event.key == setting.options["right"]):
                    # 선택을 하나 아래로 이동
                    if self.selected[1] < self.setting_menus[self.selected[0]].max_menu - 1:
                        self.selected[1] += 1
                    else:
                        # 해당 메뉴의 마지막 선택으로 가면 다음 메뉴로 넘기기
                        self.selected[0] += 1
                        if self.selected[0] == len(self.setting_menus) : self.selected[0] = 0
                        self.selected[1] = 0
                    self.highlight = (self.setting_menus[self.selected[0]].name, self.selected[1])
                elif (event.key == setting.options["up"]):
                    # 메뉴를 하나 위로 이동
                    self.selected[0] -= 1
                    if self.selected[0] == -1: self.selected[0] = len(self.setting_menus) - 1
                    self.selected[1] = self.setting_menus[self.selected[0]].max_menu - 1
                    self.highlight = (self.setting_menus[self.selected[0]].name, self.selected[1])
                elif (event.key == setting.options["down"]):
                    # 메뉴를 하나 아래로 이동
                    self.selected[0] += 1
                    if self.selected[0] == len(self.setting_menus) : self.selected[0] = 0
                    self.selected[1] = 0
                    self.highlight = (self.setting_menus[self.selected[0]].name, self.selected[1])
            # 버튼이 누르고 있어도 계속 동작하지 않게 뗄 때까지는 작동 방지
        elif event.type == pygame.KEYUP:
            self.pressed = False

    # 색맹 기능
    def is_blind(self, blind, ref_deck):
        self.apply_setting("colorblind", blind)
        for card in ref_deck:
            card.colorblind(setting.options["colorblind"])


from django.conf import settings

from .handlers.datasource_processor import DataSourceProcessor
from .models import DataSourceType
# Import all data source types here

from llmstack.common.utils.module_loader import get_all_sub_classes

def get_data_source_type_interface_subclasses():
    subclasses = DataSourceProcessor.__subclasses__()
    allowed_packages = settings.DATASOURCE_TYPE_PROVIDERS

    for package in allowed_packages:
        subclasses.extend(get_all_sub_classes(
            package, DataSourceProcessor))

    return subclasses

class DataSourceTypeFactory:
    """
    Factory class for Data source types
    """
    @staticmethod
    def get_datasource_type_handler(datasource_type: DataSourceType) -> DataSourceProcessor:
        subclasses = get_data_source_type_interface_subclasses()
        for subclass in subclasses:
            # Convert to lowercase to avoid case sensitivity
            if subclass.slug() == datasource_type.slug.lower():
                return subclass
        return None


import tweepy
import sys
import time

# Set variables and tokens
if sys.argv[1:]:
    consumer_key = sys.argv[1]
    consumer_secret = sys.argv[2]
    access_token = sys.argv[3]
    access_token_secret = sys.argv[4]
else:
    # add the secrets and tokens here
    pass

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth)

public_tweets = api.home_timeline()
for tweet in public_tweets:
    print(tweet.text)

def rate_limit_handler(cursor):
    try:
        while True:
            yield cursor.next()
    except tweepy.RateLimitError:
        time.sleep(1000)

# follow-back the followers
for follower in rate_limit_handler(tweepy.Cursor(api.followers).items()):
    print(follower.name)

search_str = 'python'
numOfTweets = 100

for tweet in tweepy.Cursor(api.search, search_str).items(numOfTweets):
    try:
        tweet.favorite()
        print('I liked that tweet!')
    except tweepy.TweepError as e:
        print(e.reason)
    except StopIteration:
        break


import json
import requests
from colorama import init, Fore, Style

def check():
    url = input("Digite a url: ")
    r = requests.get(url)
    if r.status_code == 200:
        json_object = json.loads(r.text)
        json_formatted_str = json.dumps(json_object, indent=2)
        print(Fore.GREEN + "Status da URL: " + str(r.status_code) , Style.RESET_ALL)
        print(Fore.YELLOW + "Message: " + json_formatted_str, Style.RESET_ALL)
    else:
        print(Fore.RED + "Status da URL: " + str(r.status_code) , Style.RESET_ALL)
        print(Fore.YELLOW + "Message: " + r.text, Style.RESET_ALL)


from django.contrib import messages
from django.conf import settings
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import get_object_or_404, render, redirect
from django.template import RequestContext
from django.utils.translation import gettext_lazy as _
from datetime import datetime, timedelta
from django.utils import timezone
from django.core.mail import send_mail

from .forms import AddToCartForm, SetSizesForm, IWantForm
from .models import (
    Photo,
    Categories,
    Fashions,
    Items,
    Sizes,
    Sets,
    Balance,
    SetsPhoto,
    Stocks,
    Artists,
)
from apps.orders.models import Cart, CartItem, CartSet, CartSetItem, IWant
from apps.info.models import Info, Config
from apps.comments.forms import CommentForm, ReplayForm
from apps.comments.models import Comments

def showcase(request, category_id=None, fashion_id=None, artist_id=None):
    # print(request.LANGUAGE_CODE)
    category = None
    fashion = None
    items = None

    if category_id:
        category = get_object_or_404(Categories, id=category_id)

    if fashion_id:
        fashion = get_object_or_404(Fashions, id=fashion_id)

    categories = Categories.objects.all()

    if fashion:
        title_tag = fashion.title_tag
        description_tag = fashion.description_tag
    elif category:
        title_tag = category.title_tag
        description_tag = category.description_tag
    else:
        title_tag = _("main pae title_tag")
        description_tag = _("main pae description_tag")

    fashions = None
    artist = None

    if category and fashion:
        fashions = Fashions.objects.filter(categories=category, displayed=True)
        items = Items.objects.filter(
            fashions=fashion, showcase_displayed=True
        ).order_by("-showcase_avail", "-showcase_new", "-views")
        # sets = []

    elif category:
        if category.set:
            items = Sets.objects.filter(categories=category).order_by(
                "-showcase_avail", "-showcase_new", "-views"
            )
            # sets = Sets.objects.filter(categories=category)
            # items = []
        else:
            items = Items.objects.filter(
                fashions__categories=category, showcase_displayed=True
            ).order_by("-showcase_avail", "-showcase_new", "-views")
            # sets = []
        fashions = Fashions.objects.filter(categories=category, displayed=True)

    elif artist_id:
        try:
            artist = Artists.objects.get(pk=artist_id)
            items = Items.objects.filter(
                artist=artist, showcase_displayed=True
            ).order_by("-showcase_avail", "-showcase_new", "-views")
        except Artists.DoesNotExist:
            items = Items.objects.all()
        # sets = []

    else:
        items = Items.objects.filter(showcase_displayed=True).order_by(
            "-showcase_avail", "-showcase_new", "-views"
        )
        # sets = Sets.objects.all()

    # avail_items = []
    # not_avail_items = []
    # new_items = []
    #
    # for item in items:
    #     for balance in item.balance_set.all():
    #         if balance.amount > 0:
    #             item.is_set = False
    #             if datetime(item.added.year, item.added.month, item.added.day) < datetime.today()-timedelta(days=15):
    #                 avail_items.append(item)
    #             else:
    #                 new_items.append(item)
    #             break
    #
    # for item in items:
    #     amount = []
    #
    #     for balance in item.balance_set.all():
    #         if balance.amount == 0:
    #             amount.append(balance)
    #
    #     if len(amount) == item.balance_set.count():
    #         item.is_set = False
    #         not_avail_items.append(item)
    #
    # if sets:
    #     for set in sets:
    #         i = Items.objects.filter(sets=set)
    #         res = False
    #         if i:
    #             res = True
    #         for item in i:
    #             balances = Balance.objects.filter(item=item)
    #             am = False
    #             for balance in balances:
    #                 if balance.amount > 0:
    #                     am = True
    #             res = res and am
    #         if res:
    #             set.is_set = True
    #             avail_items.append(set)
    #         else:
    #             set.is_set = True
    #             not_avail_items.append(set)
    #
    # avail_items.sort(key=lambda x: x.views, reverse=True)
    #
    # not_avail_items.sort(key=lambda x: x.views, reverse=True)
    #
    # items = new_items + avail_items + not_avail_items

    paginator = Paginator(items, 12)

    page = request.GET.get("page")

    try:
        itm = paginator.page(page)
    except PageNotAnInteger:
        itm = paginator.page(1)
    except EmptyPage:
        itm = paginator.page(paginator.num_pages)

    for it in itm:
        it.d_t = it.description_tag.split(".")[0] + ". " + str(_("Foto."))
        it.d_a = it.description_tag.split(".")[0] + ". " + str(_("Image."))

    return render(
        request,
        "elephants/showcase.html",
        {
            "category": category,
            "categories": categories,
            "fashion": fashion,
            "fashions": fashions,
            "items": items,
            "itm": itm,
            "artist": artist,
            "title_tag": title_tag,
            "description_tag": description_tag,
        },
    )

def artists(request):
    artists = Artists.objects.all()
    categories = Categories.objects.all()
    return render(
        request,
        "elephants/artists.html",
        {"artists": artists, "categories": categories},
    )

def item_details(request, id):
    item = get_object_or_404(Items, id=id)

    photos = Photo.objects.filter(item=item).order_by("added")
    media = Config.objects.get()

    sizes = (
        Sizes.objects.select_related()
        .filter(balance__item=item, balance__amount__gt=0)
        .count()
    )

    comments = Comments.objects.filter(items=item).order_by("-added")

    comment_form = CommentForm()
    replay_form = ReplayForm()

    if sizes > 0:
        form = AddToCartForm(item=item)
    else:
        form = None

    if request.method == "POST":
        form = AddToCartForm(request.POST, item=item)
        if form.is_valid():
            cart, cart_created = Cart.objects.get_or_create(
                session_key=request.session.session_key
            )
            cart.session = request.session.session_key
            cart.save()

            cart_item = CartItem.objects.filter(
                cart=cart, item=item, size=form.cleaned_data["size"]
            )
            if cart_item:
                cart_item = cart_item[0]
                cart_item.amount += form.cleaned_data["quantity"]
            else:
                cart_item = CartItem(
                    cart=cart,
                    item=item,
                    size=form.cleaned_data["size"],
                    amount=form.cleaned_data["quantity"],
                )
            cart_item.save()

            action = cart.get_items_count()
            if action:
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    _("%(name)s was added to your cart. %(count)s")
                    % {"name": item.name, "count": action},
                )
            else:
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    _("%(name)s was added to your cart.") % {"name": item.name},
                )

            request.cart_amount += cart_item.amount

            return redirect("item_details", id=item.id)
    else:
        item.views_today = item.views_today + 1
        item.save()

    d_t = item.name.split(".")[0] + ". " + str(_("Foto."))
    d_a = item.name.split(".")[0] + ". " + str(_("Image."))

    return render(
        request,
        "elephants/item_details.html",
        {
            "photos": photos,
            "item": item,
            "form": form,
            "d_t": d_t,
            "d_a": d_a,
            "replay_form": replay_form,
            "comment_form": comment_form,
            "comments": comments,
            "media": media.media,
        },
    )

def item_set_details(request, id):
    set = get_object_or_404(Sets, id=id)

    comments = Comments.objects.filter(sets=set).order_by("-added")

    photos = SetsPhoto.objects.filter(set=set).order_by("added")

    items = Items.objects.filter(sets=set)

    comment_form = CommentForm()
    replay_form = ReplayForm()

    res = False
    if items:
        res = True

    for item in items:
        balances = Balance.objects.filter(item=item)
        am = False
        for balance in balances:
            if balance.amount > 0:
                am = True
        res = res and am

    if res:
        form = SetSizesForm(set=set)
    else:
        form = None

    if request.method == "POST":
        form = SetSizesForm(request.POST, set=set)
        if form.is_valid():
            cart, cart_created = Cart.objects.get_or_create(
                session_key=request.session.session_key
            )
            cart.session = request.session.session_key
            cart.save()

            cartset = CartSet()
            cartset.cart = cart
            cartset.set = set
            cartset.amount = form.cleaned_data["quantity"]
            cartset.save()

            for name, value in form.cleaned_data.items():
                if name.startswith("item_"):
                    cart_item = CartItem.objects.filter(
                        cart=cart,
                        item=form.fields[name].item,
                        size=form.cleaned_data[name],
                    )
                    if cart_item:
                        cart_item = cart_item[0]
                        cart_item.amount += form.cleaned_data["quantity"]
                        cart_item.amount_set += form.cleaned_data["quantity"]
                    else:
                        cart_item = CartItem(
                            cart=cart,
                            item=form.fields[name].item,
                            size=form.cleaned_data[name],
                            amount=form.cleaned_data["quantity"],
                            amount_set=form.cleaned_data["quantity"],
                        )
                    cart_item.save()

                    cartsetitem = CartSetItem()
                    cartsetitem.cartset = cartset
                    cartsetitem.item = form.fields[name].item
                    cartsetitem.size = form.cleaned_data[name]
                    cartsetitem.save()

            messages.add_message(
                request,
                messages.SUCCESS,
                _("%(name)s was added to your cart. %(count)s")
                % {"name": set.name, "count": cart.get_items_count()},
            )

            request.cart_amount += form.cleaned_data["quantity"]

            return redirect("item_set_details", id=set.id)
    else:
        set.views_today = set.views_today + 1
        set.save()

    d_t = set.name.split(".")[0] + ". " + str(_("Foto."))
    d_a = set.name.split(".")[0] + ". " + str(_("Image."))

    return render(
        request,
        "elephants/item_set_details.html",
        {
            "photos": photos,
            "set": set,
            "form": form,
            "comment_form": comment_form,
            "replay_form": replay_form,
            "d_t": d_t,
            "d_a": d_a,
            "comments": comments,
        },
    )

def stocks(request):
    stocks = Stocks.objects.filter(
        action_end__gte=timezone.datetime.today() - timedelta(days=365)
    ).order_by("-id")

    topic = get_object_or_404(Info, topic="stocks")

    return render(request, "elephants/stocks.html", {"topic": topic, "stocks": stocks})

def i_want(request, id):
    topic = get_object_or_404(Info, topic="i_want")
    item = get_object_or_404(Items, id=id)

    form = IWantForm(
        initial={
            "message": _("Hello! I wantto bay this item")
            + "\n"
            + item.name
            + " "
            + item.fashions.name
        }
    )

    if request.method == "POST":
        form = IWantForm(request.POST)
        if form.is_valid():
            subject = _("[Contact form] New message")
            message = (
                form.cleaned_data.get("name")
                + "\n\n"
                + form.cleaned_data.get("email")
                + "\n\n"
                + form.cleaned_data.get("phone")
                + "\n\n"
                + form.cleaned_data.get("message")
            )
            from_email = settings.DEFAULT_FROM_EMAIL
            recipient_list = [settings.INFO_EMAIL]
            fail_silently = True

            try:
                send_mail(subject, message, from_email, recipient_list, fail_silently)
            except:
                pass

            messages.add_message(
                request, messages.SUCCESS, _("The message was successfully sent.")
            )

            i_want = IWant(
                name=form.cleaned_data.get("name"),
                phone=form.cleaned_data.get("phone"),
                email=form.cleaned_data.get("email"),
                comment=form.cleaned_data.get("message"),
                lang_code=request.LANGUAGE_CODE,
                item=item,
            )
            i_want.save()

            return redirect("item_details", id)

    return render(request, "info/feedback.html", {"form": form, "topic": topic})


"""
A common part for many test, a standard test
"""

from members.models import Role
from shifts.models import *
import pytz

FUNNY_SHIFT_LEADER = "FunnyShiftLeader"
GRUMPY_SHIFT_LEADER = 'GrumpyShiftLeader'
POOR_SHIFT_LEADER= 'PoorShiftLeaderGuy'

def setup_schedule():
    # Minimum object setup needed for the tests
    # example of a full 24h cycle
    # AM 7-15, PM 14-22, NG 22-06(day after)

    roleSL, roleOP = create_two_test_roles()
    member1 = create_test_member('Morning member', FUNNY_SHIFT_LEADER, roleSL)
    member2 = create_test_member('Afternoon member', GRUMPY_SHIFT_LEADER, roleSL)
    member3 = create_test_member('Night member', POOR_SHIFT_LEADER, roleSL)
    member1op = create_test_member('Morning OP', 'SomePoorOperator', roleOP)
    member2op = create_test_member('Afternoon OP', 'AnotherPoorOperator', roleOP)
    member3op = create_test_member('Night OP', 'UnknownPoorOperator', roleOP)
    memberOffice = create_test_member('Office Hours member', 'OfficeHoursEmployee', roleSL)
    # prepare some simple schedule
    shiftID0, shiftID1, shiftID2 = create_test_shiftIDs()
    AM, PM, NG, NWH = create_four_test_slots()
    campaign, revision = create_test_campaign_revision()
    a10, b10, c10, a11, b11, c11, a12 = create_test_shiftIDs_multiple()
    testShifts = (  # The TEST schedule
        # standalone correct NWH shift
        (member1, NWH, datetime.date(2022, 4, 30), shiftID0),
        # 24h coverage with NWH overlapping
        (member1, AM, datetime.date(2022, 5, 1), shiftID1),
        (member1op, AM, datetime.date(2022, 5, 1), shiftID1),
        (member2, PM, datetime.date(2022, 5, 1), shiftID2),
        (member2op, PM, datetime.date(2022, 5, 1), shiftID2),
        (member3, NG, datetime.date(2022, 5, 1), None),
        (member3op, NG, datetime.date(2022, 5, 1), None),
        (memberOffice, NWH, datetime.date(2022, 5, 1), None),
        # AM/PM with NWH overlapping
        (member1, AM, datetime.date(2022, 5, 3), None),
        (member2, PM, datetime.date(2022, 5, 3), None),
        (memberOffice, NWH, datetime.date(2022, 5, 3), None),
        # just NWH
        (memberOffice, NWH, datetime.date(2022, 5, 4), None),
        # more than one 24h round with some ppl scheduled NWH
        (member1, AM, datetime.date(2022, 5, 10), a10),
        (member2, PM, datetime.date(2022, 5, 10), b10),
        (member3, NG, datetime.date(2022, 5, 10), c10),
        (memberOffice, NWH, datetime.date(2022, 5, 10), None),
        (member1, AM, datetime.date(2022, 5, 11), a11),
        (member2, PM, datetime.date(2022, 5, 11), b11),
        (member3, NG, datetime.date(2022, 5, 11), c11),
        (memberOffice, NWH, datetime.date(2022, 5, 11), None),
        (member1, AM, datetime.date(2022, 5, 12), a12),
        (member2, PM, datetime.date(2022, 5, 12), None),
        (member3, NG, datetime.date(2022, 5, 12), None),
        (memberOffice, NWH, datetime.date(2022, 5, 12), None),
        (member2, AM, datetime.date(2022, 5, 13), None),
        (member3, NWH, datetime.date(2022, 5, 13), None),

        (member2, AM, datetime.date(2022, 5, 14), None),
        (member2, AM, datetime.date(2022, 5, 15), None),
        (member2, AM, datetime.date(2022, 5, 16), None),
    )
    return testShifts, campaign, revision

def create_test_shifts(slotsMembersDates=None, campaign=None, revision=None):
    for one in slotsMembersDates:
        shift = Shift()
        shift.member = one[0]  # member1
        shift.slot = one[1]  # AM
        shift.campaign = campaign
        shift.revision = revision
        shift.date = one[2]  # datetime.date(2022, 5, 1)
        if one[3] is not None:
            shift.shiftID = one[3]
        shift.save()

def create_test_member(username, firstname, role):
    member1 = Member(username=username)
    member1.first_name = firstname
    member1.role = role
    member1.save()
    return member1

def create_test_campaign_revision():
    revision = Revision(date_start=datetime.datetime(2020, 12, 30, 12, 00, 00, tzinfo=pytz.UTC), valid=True)
    revision.save()
    campaign = Campaign(name='test', date_start=datetime.datetime(2020, 12, 31, 12, 00, 00, tzinfo=pytz.UTC),
                        date_end=datetime.datetime(2020, 12, 31, 23, 00, 00, tzinfo=pytz.UTC))
    campaign.save()
    return campaign, revision

def create_test_shiftIDs():
    shiftID0 = ShiftID(label='20220430A', date_created=datetime.datetime(2022, 4, 30, 7, 00, 00, tzinfo=pytz.UTC))
    shiftID0.save()
    shiftID1 = ShiftID(label='20220501A', date_created=datetime.datetime(2022, 5, 1, 7, 00, 00, tzinfo=pytz.UTC))
    shiftID1.save()
    shiftID2 = ShiftID(label='20220501B', date_created=datetime.datetime(2022, 5, 1, 14, 14, 00, tzinfo=pytz.UTC))
    shiftID2.save()
    return shiftID0, shiftID1, shiftID2

def create_test_shiftIDs_multiple():
    a10 = ShiftID(label='20220510A', date_created=datetime.datetime(2022, 5, 10, 7, 00, 00, tzinfo=pytz.UTC))
    a10.save()
    b10 = ShiftID(label='20220510B', date_created=datetime.datetime(2022, 5, 10, 14, 30, 00, tzinfo=pytz.UTC))
    b10.save()
    c10 = ShiftID(label='20220510C', date_created=datetime.datetime(2022, 5, 10, 22, 14, 00, tzinfo=pytz.UTC))
    c10.save()
    a11 = ShiftID(label='20220511A', date_created=datetime.datetime(2022, 5, 11, 7, 00, 00, tzinfo=pytz.UTC))
    a11.save()
    b11 = ShiftID(label='20220511B', date_created=datetime.datetime(2022, 5, 11, 14, 30, 00, tzinfo=pytz.UTC))
    b11.save()
    c11 = ShiftID(label='20220511C', date_created=datetime.datetime(2022, 5, 11, 22, 14, 00, tzinfo=pytz.UTC))
    c11.save()
    a12 = ShiftID(label='20220512A', date_created=datetime.datetime(2022, 5, 12, 7, 00, 00, tzinfo=pytz.UTC))
    a12.save()
    return a10, b10, c10, a11, b11, c11, a12,

def create_two_test_roles():
    roleSL = Role(name="ShiftLeader", abbreviation="SL")
    roleSL.save()
    roleOP = Role(name="Operator", abbreviation="OP")
    roleOP.save()
    return roleSL, roleOP

def create_four_test_slots():
    AM = Slot(name='Morning',
              hour_start=datetime.time(7, 0, 0), hour_end=datetime.time(15, 00, 0),
              abbreviation='AM')
    AM.save()
    PM = Slot(name='Evening',
              hour_start=datetime.time(14, 0, 0), hour_end=datetime.time(22, 00, 00),
              abbreviation='PM', id_code='B')
    PM.save()
    NG = Slot(name='Night',
              hour_start=datetime.time(22, 0, 0), hour_end=datetime.time(6, 0, 0),
              abbreviation='NG', id_code='C')
    NG.save()
    NWH = Slot(name='NormalWH',
               hour_start=datetime.time(8, 0, 0), hour_end=datetime.time(16, 30, 0),
               abbreviation='NWH')
    NWH.save()
    return AM, PM, NG, NWH


from flask import Flask, request, render_template
import paymentwall
app = Flask(__name__)
# Initialize Paymentwall API keys

paymentwall.Paymentwall.configure(
    paymentwall.PublicKey('YOUR_PUBLIC_KEY'),
    paymentwall.PrivateKey('YOUR_PRIVATE_KEY')
)

@app.route('/checkout', methods=['POST', 'GET'])
def checkout():
    if request.method == 'POST':
        product_id = 'your_product_id'  #actual product ID
        amount = 50.0  #$
        #paymentwall widget
        widget = paymentwall.Widget(
            product_id,
            'user_email@example.com',  #user's email
            {
                'amount': amount,
                'currency_code': 'USD',
                'description': 'Product Description',
                'custom': 'Custom Parameter'  # Optional custom parameter
            }
        )
        return render_template('checkout.html', widget=widget.get_html_code())
    return 'Invalid request'

@app.route('/payment_success', methods=['POST'])
def payment_success():
    widget = paymentwall.Widget(request.form['widget'])
    if widget.verify_signature(request.form):
        transaction_id = request.form['id']
        return 'Payment Success! Transaction ID: {}'.format(transaction_id)
    else:
        return 'Payment Verification Failed'

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


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

filelist=[]

liimited_filelist = []

x = np.linspace(-1, 1, 200)
j = 1
for i in range(1,100):
    filelist.append("FVM_1S_B&W_{}.txt".format(i))
    liimited_filelist.append("BeamW_Limited_{}.txt".format(i))

for fname, fname1 in zip(filelist, liimited_filelist):
    plt.figure(figsize=(12,6))
    data=np.loadtxt(fname)
    data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    plt.plot(x, data, color = 'orange', linewidth = 0.7, label = 'B&W unlimited')
    plt.plot(x, data1, marker = 'o', markersize = 4, linewidth = 1.3, color = 'blue', label = 'B&W Method 2nd Order')
    #plt.plot(x, data, marker = 'o', markersize = 4, linewidth = 2, color = 'darkorange', label = 'B&W method Van\nAlbada Slope Limited')
    plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
    plt.title('1D Linear Convection 2nd Order Beam & Warming FVM Analysis ', fontsize=15)
    plt.xlabel('u (m/s)', fontsize=15)
    plt.ylabel('time t(s)', fontsize=15)
    plt.ylim(-0.4, 1.4)
    plt.xlim(-1.1, 1.1)
    #plt.title("1D Linear Convection FVM")
    plt.legend(loc = 'upper right')
    plt.savefig('B&W{}.png'.format(j))
    plt.clf()
    plt.close()
    j += 1

#plt.legend()
plt.show()

'''

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
filelist=[]

#liimited_filelist = []
#iC_square=np.loadtxt('Data.txt')

#d1 = np.loadtxt('sol_10.txt')
x = np.linspace(0, 1, 100)
j = 1
for i in range(1,200):
    #if i % 5 == 0:
    filelist.append("Burgers_{}.txt".format(i))
    #liimited_filelist.append("FROMM_UNLIMITED_{}.txt".format(i))

#colour=iter(cm.rainbow(np.linspace(0,20,860)))
#plt.plot(x, d1, marker = 'o', markersize = 1, linewidth = 2, color = 'blue', label = 't = 0.0 s')
#plt.plot(x, iC_square, marker = 'o', markersize = 1.6, linewidth = 2, color = 'darkblue', label = 'CFL = 0.5')

for fname  in filelist:
    plt.figure(figsize=(8,8))
    #c=next(colour)
    data=np.loadtxt(fname)
    #data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    plt.plot(x, data, marker = 'o', markersize = 5, linewidth = 2, color = 'blue', label = 'CFL = 0.5')

    #plt.plot(x1, initial_data, color = 'orange', linewidth = 0.7, label = 'Initial Condition')
    #plt.plot(x, data, marker = 'o', markersize = 2.1, linewidth = 1.3, color = 'blue', label = 'FROMM Method 2nd Order')
    #plt.plot(x, data, marker = 'o', markersize = 4, linewidth = 2, color = 'darkorange', label = 'Fromm method Van\nAlbada Slope Limited')
    #plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
    #plt.title('1D Inviscid Burgers Sine wave ICs ', fontsize=15)
    plt.ylabel('u (m/s)', fontsize=15)
    plt.xlabel('u (m)', fontsize=15)
    plt.ylim(-0.25, 1.25)
    plt.xlim(0, 1)
    plt.title("1D Advection equation")
    plt.legend(loc = 'upper right')
    plt.savefig('A{}.png'.format(j))
    plt.clf()
    plt.close()

    j += 1

#plt.legend()
plt.show()

'''

import numpy as np
import matplotlib.pyplot as plt

filelist=[]

liimited_filelist = []

x = np.linspace(0, 2 * np.pi, 100)
x1 = np.linspace(0, 2 * np.pi, 100)
x2 = np.linspace(-1, 1, 100)
x4 = np.linspace(-1, 1, 200)
x_ICs = np.linspace(-1, 1, 206)

j = 1

#for i in range(1,5):
#    filelist.append("laxwendroff_limited_step{}.txt".format(i))

plt.figure(figsize = (10,8))
data1=np.loadtxt('Data.txt')
#data2=np.loadtxt('sol_9.txt')

#iC_square=np.loadtxt('Square_Initial_conditions.txt')
#iC_sine=np.loadtxt('Sine_Initial_Conditions.txt')
#data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    #plt.plot(x1, initial_data, color = 'orange', linewidth = 0.7, label = 'Initial Condition')
#plt.plot(x, data1, marker = 'o', markersize = 4, linewidth = 1.3, color = 'blue', label = 'Lax Fromm Method 2nd Order')
#plt.plot(x_ICs, iC_square, linewidth = 2, linestyle = 'dashed', color = 'red', label = 'Initial Conditions')
plt.plot(x, data1, marker = 'o', markersize = 2, linewidth = 2, color = 'blue', label = 'limited')
#plt.plot(x1, data2, marker = 'o', markersize = 2, linewidth = 2, color = 'red', label = 'limited')

#plt.plot(x, data2, marker = 'o', markersize = 2, linewidth = 2.5, color = 'green', label = 'limited')
#plt.plot(x_ICs, iC_square,  linewidth = 1.6, color = 'red', linestyle='dashed', label = 'limited')

#plt.plot(x2, data3, marker = 'o', markersize = 2, linewidth = 1.7, color = 'red', label = 'NX = 100')

#plt.plot(x4, data4, marker = 'o', markersize = 2, linewidth = 1.7, color = 'darkturquoise', label = 'NX = 100')

#plt.plot(x_ICs, iC_sine, linewidth = 2, color = 'red', linestyle = 'dashed', label = 'Initial Conditions')
#plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
#plt.title('2nd Order Lax Wendroff Slope Limiter Comparison T = 2.0 s', fontsize=15)
#plt.xlabel('u (m/s)', fontsize=15)
#plt.ylabel('time t(s)', fontsize=15)
#plt.xlabel('u (m/s)', fontsize=15)
#plt.ylabel('time t(s)', fontsize=15)
#plt.ylim(-0.1, 1.2)
#plt.xlim(-0.1, 1.1)
#plt.xticks([-1, -0.5, 0, 0.5, 1])
#lt.yticks([0, 0.2, 0.4, 0.6, 0.8, 1])
#plt.title("F.O Lax Fredrichs:  Time = 2.0 s", fontsize = 20)
plt.legend(loc = 'upper right')

j += 1

#plt.legend()
plt.savefig("F.0.png")
plt.show()

'''
'''
import numpy as np
import matplotlib.pyplot as plt
import math

x = np.linspace(1,180, 180)
for i in range(len(x)):
    x[i] *= 0.0174533
print(x)
y = []
y1 = []
y2 = []

z = []
z1 = []
z2 = []

for i in range(len(x)):
    y.append(   (math.cos(x[i])**2 + (0.25 * 0.25) * math.sin(x[i])**2)**0.5  )
    y1.append(   (math.cos(x[i])**2 + (0.5 * 0.5) * math.sin(x[i])**2)**0.5  )
    y2.append(   (math.cos(x[i])**2 + (0.8 * 0.8) * math.sin(x[i])**2)**0.5  )
    z.append(   (math.atan(.25 * math.tan(x[i])) / (.25 * x[i])))
    z1.append(   (math.atan(.5 * math.tan(x[i])) / (.5 * x[i])))
    z2.append(   (math.atan(.8 * math.tan(x[i])) / (.8 * x[i])))

fig, (ax,ax2) = plt.subplots(1,2, figsize=(13,5))
plt.title("Lax Fredrichs Diffusion Error")
ax.grid(b=True, which='major', color='#666666', linestyle='-')
ax.minorticks_on()
ax.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)

ax2.grid(b=True, which='major', color='#666666', linestyle='-')
ax2.minorticks_on()
ax2.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)

ax2.plot(x, z, label = 'Sigma = 0.25', linewidth = 2)
ax2.plot(x, z1, label = 'Sigma = 0.5', linestyle = 'dashdot', linewidth = 2)
ax2.plot(x, z2,label = 'Sigma = 0.8', linestyle = 'dashed', linewidth = 2)

ax.plot(x, y, label = 'Sigma = 0.25', linewidth = 2)
ax.plot(x, y1, label = 'Sigma = 0.5', linestyle = 'dashdot', linewidth = 2)
ax.plot(x, y2,label = 'Sigma = 0.8', linestyle = 'dashed', linewidth = 2)

ax.set_xlabel("Phase angle radians")
ax.set_ylabel("Sigma")
ax2.set_xlabel("Phase angle radians")
ax2.set_ylabel("Sigma")

#ax.set_ylim(0, 6)
ax.set_xlim(0, np.pi)

ax2.set_ylim(0, 6)
ax2.set_xlim(0, np.pi/2.1)

plt.legend()
plt.show()

plt.savefig("Lax-Fredrichs-Diffusion-Error-Plot.png")
'''


import pyshark
cap = pyshark.FileCapture('dump_input/http.pcap')

field_names = [
'date', 'user_agent', 'server', 'request_uri', 'time',
'accept_encoding', 'request_uri_query_parameter',
'response_phrase', 'request_version', 'request_method',
'response_for_uri', 'request_uri_query', 'request_full_uri',
'chat', 'host', 'response_line', 'connection',
'response_version', 'accept_language', 'response_code_desc',
'response_code', 'request_line', 'accept', 'request_uri_path']

def to_http_arr(a):
    smtp_arr = []
    for pac in a:
        if hasattr(pac,'http'):
            smtp_arr.append(pac)
    return smtp_arr

def get_http_info(cap):
    cap = to_http_arr(cap)
    date                        = [[],[]]
    user_agent                  = [[],[]]
    server                      = [[],[]]
    #request                    = [[],[]]
    request_uri                 = [[],[]]
    time                        = [[],[]]
    accept_encoding             = [[],[]]
    #request_number             = [[],[]]
    request_uri_query_parameter = [[],[]]
    response_phrase             = [[],[]]
    request_version             = [[],[]]
    request_method              = [[],[]]
    #response                   = [[],[]]
    #response_number            = [[],[]]
    #request_in                 = [[],[]]
    response_for_uri            = [[],[]]
    request_uri_query           = [[],[]]
    request_full_uri            = [[],[]]
    chat                        = [[],[]]
    host                        = [[],[]]
    response_line               = [[],[]]
    #location                   = [[],[]]
    connection                  = [[],[]]
    response_version            = [[],[]]
    accept_language             = [[],[]]
    response_code_desc          = [[],[]]
    response_code               = [[],[]]
    request_line                = [[],[]]
    accept                      = [[],[]]
    request_uri_path            = [[],[]]
    for pac in cap:
        if hasattr(pac,'http'):
            # print(pac['http'])
            if hasattr(pac.http,'date'):
                date[0].append(pac.frame_info.number)
                date[1].append(pac.http.date)
            if hasattr(pac.http,'user_agent'):
                user_agent[0].append(pac.frame_info.number)
                user_agent[1].append(pac.http.user_agent)
            if hasattr(pac.http,'server'):
                server[0].append(pac.frame_info.number)
                server[1].append(pac.http.server)
            #if hasattr(pac.http,'request'):
            #    request[0].append(pac.frame_info.number)
            #    request[1].append(pac.http.request)
            if hasattr(pac.http,'request_uri'):
                request_uri[0].append(pac.frame_info.number)
                request_uri[1].append(pac.http.request_uri)
            if hasattr(pac.http,'time'):
                time[0].append(pac.frame_info.number)
                time[1].append(pac.http.time)
            if hasattr(pac.http,'accept_encoding'):
                accept_encoding[0].append(pac.frame_info.number)
                accept_encoding[1].append(pac.http.accept_encoding)
            #if hasattr(pac.http,'request_number'):
            #    request_number[0].append(pac.frame_info.number)
            #    request_number[1].append(pac.http.request_number)
            if hasattr(pac.http,'request_uri_query_parameter'):
                request_uri_query_parameter[0].append(pac.frame_info.number)
                request_uri_query_parameter[1].append(pac.http.request_uri_query_parameter)
            if hasattr(pac.http,'response_phrase'):
                response_phrase[0].append(pac.frame_info.number)
                response_phrase[1].append(pac.http.response_phrase)
            if hasattr(pac.http,'request_version'):
                request_version[0].append(pac.frame_info.number)
                request_version[1].append(pac.http.request_version)
            if hasattr(pac.http,'request_method'):
                request_method[0].append(pac.frame_info.number)
                request_method[1].append(pac.http.request_method)
            #if hasattr(pac.http,'response'):
            #    response[0].append(pac.frame_info.number)
            #    response[1].append(pac.http.response)
            #if hasattr(pac.http,'response_number'):
            #    response_number[0].append(pac.frame_info.number)
            #    response_number[1].append(pac.http.response_number)
            #if hasattr(pac.http,'request_in'):
            #    request_in[0].append(pac.frame_info.number)
            #    request_in[1].append(pac.http.request_in)
            if hasattr(pac.http,'response_for_uri'):
                response_for_uri[0].append(pac.frame_info.number)
                response_for_uri[1].append(pac.http.response_for_uri)
            if hasattr(pac.http,'request_uri_query'):
                request_uri_query[0].append(pac.frame_info.number)
                request_uri_query[1].append(pac.http.request_uri_query)
            if hasattr(pac.http,'request_full_uri'):
                request_full_uri[0].append(pac.frame_info.number)
                request_full_uri[1].append(pac.http.request_full_uri)
            if hasattr(pac.http,'chat'):
                chat[0].append(pac.frame_info.number)
                chat[1].append(pac.http.chat)
            if hasattr(pac.http,'host'):
                host[0].append(pac.frame_info.number)
                host[1].append(pac.http.host)
            if hasattr(pac.http,'response_line'):
                response_line[0].append(pac.frame_info.number)
                response_line[1].append(pac.http.response_line)
            #if hasattr(pac.http,'location'):
            #    location[0].append(pac.frame_info.number)
            #    location[1].append(pac.http.location)
            if hasattr(pac.http,'connection'):
                connection[0].append(pac.frame_info.number)
                connection[1].append(pac.http.connection)
            if hasattr(pac.http,'response_version'):
                response_version[0].append(pac.frame_info.number)
                response_version[1].append(pac.http.response_version)
            if hasattr(pac.http,'accept_language'):
                accept_language[0].append(pac.frame_info.number)
                accept_language[1].append(pac.http.accept_language)
            if hasattr(pac.http,'response_code_desc'):
                response_code_desc[0].append(pac.frame_info.number)
                response_code_desc[1].append(pac.http.response_code_desc)
            if hasattr(pac.http,'response_code'):
                response_code[0].append(pac.frame_info.number)
                response_code[1].append(pac.http.response_code)
            if hasattr(pac.http,'request_line'):
                request_line[0].append(pac.frame_info.number)
                request_line[1].append(pac.http.request_line)
            if hasattr(pac.http,'accept'):
                accept[0].append(pac.frame_info.number)
                accept[1].append(pac.http.accept)
            if hasattr(pac.http,'request_uri_path'):
                request_uri_path[0].append(pac.frame_info.number)
                request_uri_path[1].append(pac.http.request_uri_path)
            else:
                pass
    return [date,  #'Wed, 28 Mar 2018 02:37:41 GMT', 'Wed, 28 Mar 2018 02:37:51 GMT'
            user_agent, #'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113'
            server, #'SimpleHTTP/0.6 Python/2.7.14', 'CAFE/1.0', 'Apache'
            #request, # 1
            request_uri, #'/', '/?path=foo', '/foo', '/download.html', '/pagead/ads?client=ca-pub-2309191948673629&random=1084443430285&
            time, #'0.000407565', '0.000491123'
            accept_encoding, #'gzip, deflate'
            #request_number, #'1'
            request_uri_query_parameter, #'path=foo', 'path=foobar', 'client=ca-pub-2309191948673629'
            response_phrase, #'OK', 'Found', 'Found', 'OK'
            request_version, #'HTTP/1.1', 'HTTP/1.1'
            request_method, #'GET', 'GET'
            #response, #'1', '1'
            #response_number, #'1', '1'
            #request_in, #'1', '6', '12'
            response_for_uri, #'http://127.0.0.1/', 'http://127.0.0.1/?path=foo' 'http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-2309191948673629&random
            request_uri_query, #'path=foo', 'path=foobar' 'client=ca-pub-2309191948673629&random=1084443430285
            request_full_uri, #'http://127.0.0.1/', 'http://www.ethereal.com/download.html'
            chat, #'GET / HTTP/1.1\\r\\n', 'HTTP/1.0 200 OK\\r\\n' 'GET /download.html HTTP/1.1\\r\\n'
            host, #'127.0.0.1', 'www.ethereal.com', 'pagead2.googlesyndication.com'
            response_line, #Server: SimpleHTTP/0.6 Python/2.7.14\\xd\\xa 'P3P: policyref="http://www.googleadservices.com/pagead/p3p.xml
            #location, #'foo', '/', 'foobar'
            connection, #'keep-alive', 'keep-alive'
            response_version, #'HTTP/1.0', 'HTTP/1.0'
            accept_language, #'en-US,en;q=0.5'
            response_code_desc, #'OK', 'Found'
            response_code, #'200', '302', '302'
            request_line, #'Host: 127.0.0.1\\xd\\xa' 'Host: www.ethereal.com\\xd\\xa', 'Host: pagead2.googlesyndication.com\\xd\\xa'
            accept, #'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' 'text/xml,application/xml,application/xhtml+xml
            request_uri_path] #'/', '/my/path', '/my/path', '/', '/b/c/d;p', '/pagead/ads'

def compare_code_http(arr,clist):
    out_arr = []
    # from httpf.http_codes import code_http_dict
    for i in arr:
        for j in clist:
            if i == j:
                out_arr.append(clist[j])
    return out_arr

import sys
PROJECT_PATH = '/home/ubuntu18/diploma-1/dpl' #Для HP
# PROJECT_PATH = '/home/ubuntu18/Desktop/dpl' #Для Aquarius
if PROJECT_PATH not in sys.path:
    sys.path.append(PROJECT_PATH)
print(get_http_info(cap)[20])
from httpf.http_codes import code_http_dict
print(compare_code_http(get_http_info(cap)[20][1],code_http_dict))


#standard imports
from datetime import datetime as dt
import utils
import Rooms.Room as Room
#room specific imports
import Rooms.Hallway as Hallway
import Rooms.Armory as Armory
import Rooms.Guards_Room as Guards_Room
import Puzzles.hangman as hangman
import win_lose as win_lose

class Main_Chamber(Room.Room):

    def __init__(self, player, starttime):
        super().__init__(
            "Main_Chamber",
            "You find yourself in a large chamber, in each wall there is a door. In the far wall is the door to the armory, in the wall to the left is the door to the guards room, in the wall to your right is the door to the outside world. Various machines rest haphazerdly about the room, some glow with heat others lay dormant. In one corner is a gallows, presumably for prisoners like you. Besides the gallows, with their back to you, stands the excecutioner.",
            [{
                "name": "hallway door",
                "actions": ["open"]
            }, {
                "name": "armory door",
                "actions": ["open"]
            }, {
                "name": "guard's room door",
                "actions": ["open"]
            }, {
                "name": "door to outside",
                "actions": ["open"]
            }, {
                "name": "gallows",
                "actions": ["inspect"]
            }, {
                "name": "executioner",
                "actions": ["inspect", "talk"]
            }, {
                "name": "mysterious spiky machine",
                "actions": ["inspect", "pull lever"]
            }], player, starttime)

    def start_room(self):
        utils.print_line_of_char("#")
        utils.print_centered_text(self.name)
        utils.print_line_of_char("#")
        print(f"Gametime elapsed: {dt.now() - self.starttime}")
        print(self.description)
        leave = False
        while leave == False:
            [current_item, current_action, item_index] = self.listItems()
            if current_item == "hallway door":
                if current_action == "open":
                    start = Hallway.Hallway(self.player, self.starttime)
                    start.start_room()
            if current_item == "armory door":
                if current_action == "open":
                    start = Armory.Armory(self.player, self.starttime)
                    start.start_room()
            if current_item == "guard's room door":
                if current_action == "open":
                    if self.player.isInItems("guard's uniform"):
                        start = Guards_Room.Guards_Room(
                            self.player, self.starttime)
                        start.start_room()
                    else:
                        win_lose.end(
                            'Upon seeing a free prisoner entering the guards room, the guard captain orders you be incarcerated in a maximum security cell. YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                            self.starttime)
            if current_item == "door to outside":
                if current_action == "open":
                    if self.player.isInItems("master key"):
                        print("YOU HAVE ESCAPED!")
                        win_lose.end(
                            'You emerge from the dungeons to breath the smoky air on the slopes of mount doom, YOU HAVE ESCAPED THE DUNGEONS OF MORDOR!',
                            self.starttime)
                    else:
                        print(
                            "The door is locked, you didn't think it would be that easy did you..."
                        )
            if current_item == "gallows":
                if current_action == "inspect":
                    print(
                        "Just your ordinary gallows, they look quite well cared for though..."
                    )
            if current_item == "executioner":
                if current_action == "inspect":
                    print(
                        "The excecutioner appears to not have noticed your entrance, they are standing with their back to you, mending a noose from the gallows."
                    )
                if current_action == "talk":
                    if self.player.isInItems("guard's uniform"):
                        print(
                            "Excecutioner: 'Hello there, have you heard of the new security protocol? (Cackles) If you don't know the password you hang! Don't remember? Care to guess? Of course you do!'"
                        )
                        win = hangman.play_game()
                        if win == True:
                            utils.print_centered_text(
                                "*** You got the password ***")
                            self.player.insertItem("password")
                        else:
                            win_lose.end(
                                'You are hanged by the excecutioner, YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                                self.starttime)
                    else:
                        print(
                            "Excecutioner: 'You're an escaped prisoner! GUARDS! GUARDS!'"
                        )
                        win_lose.win(
                            'You are captured by the Guards and taken to a maximum security cell, YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                            self.starttime)
            if current_item == "mysterious spiky machine":
                if current_action == "inspect":
                    print(
                        "Just your average every day spiky machine, for...spiking things?"
                    )
                if current_action == "pull lever":
                    print("Nothing happened...wait...yeah nothing happend...")


# Inner_Emerging_Markets_Analyzer

# Co-Programmed by Preston Hodsman, Thomas Leahy and Abhishika Fatehpuria
# The program outputs a Streamlit dashboard containing analysis of all the US states based on their personal income from year 2017 to 2021 and
# percentage gdp growth and identifying 8 target states to focus on investing

# This is the main deliverable code file for our project. We have also included the Jupyter lab file inner_emerging_markets_analyzer.ipynb, in the project folder for anybody who wants to work on it and take our work further.

#import required libraries

import os
import requests
import json
import pandas as pd
from dotenv import load_dotenv
from pathlib import Path

from bokeh.palettes import Oranges256 as oranges
from bokeh.sampledata.us_states import data as us_states
from bokeh.plotting import figure
from bokeh.io import output_notebook, show

import streamlit as st
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from analyzer.plot_industry_analysis import plot_industry_analysis

st.set_page_config(
    layout="wide",
)
st.title("Identifying Emerging markets in the US")

@st.cache

def get_api_key():
    #load the API keys stored in .env file
    load_dotenv()

    # https://apps.bea.gov/api/signup/index.cfm to signup for API key for Bureau of Economic Analysis

    # https://apps.bea.gov/api/_pdf/bea_web_service_api_user_guide.pdf for user guide

    #get BEA API key from .env file
    bea_api_key=os.getenv("BEA_API_KEY")
    return bea_api_key

@st.cache
def get_Data_List(bea_api_key):
    # set up query URL
    bea_url = "http://apps.bea.gov/api/data?UserID=" + bea_api_key + "&method=GETDATASETLIST&ResultFormat=JSON"

    #send request to BEA
    bea_response = requests.get(bea_url).json()["BEAAPI"]["Results"]
    return bea_response

@st.cache
def get_Data(bea_api_key):
    # this query will get the data for all states for the last five years for personal income per capita.
    bea_states_personal_income_linecode_query_url = "http://apps.bea.gov/api/data?UserID=" + bea_api_key + "&method=GetData&datasetname=Regional&TableName=SQINC1&GeoFIPS=STATE&LineCode=3&Year=LAST5&ResultFormat=JSON"

    #query for last five years personal income by state.
    personal_income_by_state_5year = pd.DataFrame(requests.get(bea_states_personal_income_linecode_query_url).json()["BEAAPI"]["Results"]["Data"])
    return personal_income_by_state_5year

# Read the API KEY
bea_api_key = get_api_key()

# get data list from bea
bea_response = get_Data_List(bea_api_key)

# get the regional table dataframe
personal_income_by_state_5year = get_Data(bea_api_key)

# clip out the unnecessary columns
personal_income_by_state_5year=personal_income_by_state_5year[["GeoName", "TimePeriod", "DataValue"]]

# Used str.replace() to remove the ',' from the Income datavalue and convert to float from string
personal_income_by_state_5year['DataValue'] = personal_income_by_state_5year['DataValue'].str.replace(',', '').astype('float')

# Filter the dataframe to get just the states

list_of_states = [ 'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia',
                  'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts',
                  'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey',
                   'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
                   'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia',
                  'Wisconsin', 'Wyoming']

personal_income_state_filter = personal_income_by_state_5year['GeoName'].isin(list_of_states)
personal_income_filter_by_state = personal_income_by_state_5year[personal_income_state_filter]

# Setting the time period to be the index and converting the datatype from string to dateTime
personal_income_filter_by_state_2 = personal_income_filter_by_state
personal_income_filter_by_state = personal_income_filter_by_state.set_index('TimePeriod')
personal_income_filter_by_state.index = pd.to_datetime(personal_income_filter_by_state.index)

# Group the data by state and calculate the average personal income for every year from 2017 to current year

personal_income_filter_annual = personal_income_filter_by_state.groupby('GeoName').resample('A').mean()
personal_income_filter_annual = personal_income_filter_annual.reset_index()
personal_income_filter_annual['TimePeriod'] = personal_income_filter_annual['TimePeriod'].dt.date
personal_income_filter_annual = personal_income_filter_annual.set_index('TimePeriod')

st.header(" Annual Personal Income ranked in ascending order")
# Bar chart for states with an interactive slider
# SelectBox for selecting the timeperiod to view the percapita Personal Income
time = st.selectbox("Choose a Time Period:", personal_income_filter_annual.index.unique())

# Generating plotly express graphs based on the user selected year
fig = px.bar(personal_income_filter_annual.loc[time].sort_values('DataValue'),
             x = 'GeoName',
             y = 'DataValue' ,
             width = 1000,
             title = f'Annual Personal Income for all states in ascending order -{time}',
             labels = { 'GeoName': 'State', 'DataValue': 'Personal Income($)'}, # Axis labels to be displayed on the chart and while hovering
             color_discrete_sequence = ['pink']*len(personal_income_filter_annual))

# Extracting the data to display the limiting line
df = personal_income_filter_annual.loc[time].sort_values('DataValue')

# Adding the line onto the plot
fig.add_shape(type = 'line',
                x0 = df['GeoName'][20], # Place the line at the 21st element to seperate the last 20 states
                y0 = -5000,
                x1 = df['GeoName'][20],
                y1 = max(df['DataValue']),
                line = dict(color = 'Red', width = 3, dash = 'dashdot'))
st.plotly_chart(fig)

#Plots for data pivoted by states

st.header("Personal Income for Fiscal Quarters from 2017 Q1 - 2021 Q2")
# Convert TimePeriod to datetime to get results in a sorted time manner
personal_income_filter_by_state_2['TimePeriod'] = pd.to_datetime(personal_income_filter_by_state_2['TimePeriod']).dt.date

# Pivoting the dataframe around GeoName and TimePeriod
personal_income_melt = personal_income_filter_by_state_2.melt(id_vars = ['GeoName', 'TimePeriod'])

# Line plot for percapita personal income for all the states for all the fiscal quarters.
layout_plots_line = px.line(personal_income_melt,
                        x='TimePeriod',
                        y='value',
                        color = 'GeoName',
                        width = 1000,
                        height = 800,
                        labels = { 'TimePeriod': 'Fiscal Quarter', 'value': 'Personal Income($)', 'GeoName':'State'},
                        title = "5 year Personal Income for all states")

st.plotly_chart(layout_plots_line)

#Sort the States by Personal Income
personal_income_sorted = personal_income_filter_by_state_2.sort_values(by = 'DataValue')

#Pivoting the table around Geoname and Timeperiod
personal_income_melt_2 = personal_income_sorted.melt(id_vars = ['GeoName', 'TimePeriod'])

st.header('US Map with Personal Income for Q2 of 2021')

# Dataframe grouped by state and extracted the last element from each group which is the personal income value for 2021Q2

personal_income_2021Q4 = personal_income_sorted.sort_values('TimePeriod').groupby('GeoName').last()

# loading US states boundary data which is available in bokeh as a part of bokeh.sampledata.us_states
us_states_df = pd.DataFrame(us_states).T

# reset index for merging
personal_income_2021Q4 = personal_income_2021Q4.reset_index()

# deleting states of Alaska, Hawaii and District of Columbia
us_states_df = us_states_df[~us_states_df["name"].isin(['Alaska', "Hawaii", "District of Columbia"])]

# Merge the two dataframes
us_states_df = us_states_df.merge(personal_income_2021Q4[["GeoName", "DataValue"]], how="left", left_on="name", right_on="GeoName")

# Sort the resulting dataframe by geoname to add the state codes for generating the choropleth graph
us_states_df = us_states_df.sort_values('GeoName')

# Add the state code column to the dataframe
us_states_df['code'] = ['AL','AZ','AR','CA','CO','CT','DE','FL','GA','ID',
                        'IL','IN','IA','KS','KY','LA','ME','MD','MA','MI',
                        'MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY',
                        'NC','ND','OH','OK','OR','PA','RI','SC','SD','TN',
                        'TX','UT','VT','VA','WA','WV','WI','WY']

# Hover text
us_states_df['text'] = us_states_df["GeoName"] + '<br>' + 'Per Capita PI = $' + us_states_df['DataValue'].astype(str)

# Generate the choropleth map
fig1 = go.Figure(data=go.Choropleth(
    locations=us_states_df['code'], # Spatial coordinates
    z = us_states_df['DataValue'], # Data to be color-coded
    locationmode = 'USA-states', # set of locations match entries in `locations`
    colorscale = 'blackbody' ,
    colorbar_title = "USD",
    autocolorscale=False,
    text=us_states_df['text'], # hover text
    marker_line_color='white'# line markers between states

))

fig1.update_layout(
        geo_scope='usa', # limite map scope to USA,
        title_text = " Map of US with Personal Income in Q2 of 2021",
         height = 800
         )#margin={"r":0,"t":0,"l":0,"b":0}

st.plotly_chart(fig1, use_container_width = True)

#begin process to filter states to focus analysis on. filter bottom 20 by personal income in 2020Q4.
lowest_20_states_df = us_states_df.nsmallest(20, "DataValue")

# unstack dataframe
personal_income_filter_by_state = personal_income_filter_by_state.reset_index()
unstacked_personal_income_by_state = personal_income_filter_by_state.set_index(['GeoName', 'TimePeriod']).unstack(level=0)

# make new dataframe with the increase in personal income per state for this time period

personal_income_growth_2017to2021Q2 = ((unstacked_personal_income_by_state.transpose()["2021-04-01"] / unstacked_personal_income_by_state.transpose()["2017-01-01"]) - 1) * 100
personal_income_growth_2017to2021Q2_temp = personal_income_growth_2017to2021Q2.reset_index().sort_values(by = 0)

st.header("Percent growth personal income 2017Q1 to 2021Q2")

fig2 = px.bar(personal_income_growth_2017to2021Q2_temp,
              x = 'GeoName',
              y = 0,
             width = 1000,
             title = "Percent growth personal income 2017Q1 to 2021Q2 sorted in ascending order",
             labels = { 'GeoName': 'State', '0' : 'Percent Personal Income Growth(%)'}, # Axis labels to be displayed on the chart and while hovering
             color_discrete_sequence = ['pink']*len(personal_income_filter_annual))

personal_income_growth_2017to2021Q2_temp = personal_income_growth_2017to2021Q2_temp.reset_index(drop = True)
# Adding the line onto the plot
fig2.add_shape(type = 'line',
                x0 = personal_income_growth_2017to2021Q2_temp['GeoName'][20], # Place the line at the 21st element to seperate the last 20 states
                y0 = -2,
                x1 = personal_income_growth_2017to2021Q2_temp['GeoName'][20],
                y1 = 30,
                line = dict(color = 'Red', width = 3, dash = 'dashdot'))
st.plotly_chart(fig2)

st.header(" Personal Income with Percent Growth")

# Creating a new Dataframe to plot the two metrics
personal_income_vs_percentage_growth = pd.DataFrame()
personal_income_vs_percentage_growth['GeoName'] = personal_income_growth_2017to2021Q2_temp['GeoName']
personal_income_vs_percentage_growth['Percent_Growth'] = personal_income_growth_2017to2021Q2_temp[0]
personal_income_vs_percentage_growth = personal_income_vs_percentage_growth.merge(us_states_df[['GeoName', 'DataValue']], how = 'inner', on = 'GeoName')
personal_income_vs_percentage_growth = personal_income_vs_percentage_growth.sort_values(by = 'DataValue')

# Define a subplot figure to plot both the graphs together
sub_fig = make_subplots(specs = [[{"secondary_y": True}]])

# First generate the line figure for percentage growth
fig3 = px.line(x = personal_income_vs_percentage_growth['GeoName'],
               y = personal_income_vs_percentage_growth['Percent_Growth'],
               color_discrete_sequence = ['red']*len(personal_income_vs_percentage_growth)
               )

# Define a figure for plotting the bar graph for Per Capita Personal Income
fig4 = px.bar(x = personal_income_vs_percentage_growth['GeoName'],
              y = personal_income_vs_percentage_growth['DataValue'] ,
              color_discrete_sequence = ['pink']*len(personal_income_vs_percentage_growth),
              width = 1000
            )

# Define second axis for percent growth and define mode to plot markers alongwith the line graph
fig3.update_traces(yaxis = "y2",mode='markers+lines')

# Add both the figures on the sub plot figure
sub_fig.add_traces(fig4.data + fig3.data)
sub_fig.update_layout(width = 1000, height = 500, title_text = " Personal Income with Percentage Growth")
sub_fig.layout.xaxis.title = "State"
sub_fig.layout.yaxis.title = " Personal Income for 2021Q2"
sub_fig.layout.yaxis2.title = "Percentage Growth from 2017Q1 to 2021Q2"

st.plotly_chart(sub_fig)

# filter the rates of personal income growth list by states that are in the bottom 20 states on personal income

keys = list(lowest_20_states_df['name'])

#sort lowest to highest in rates of growth
personal_income_growth_2017to2021Q2_lower_end=personal_income_growth_2017to2021Q2["DataValue"][keys].sort_values()

#plot growth in the 5 year timeframe in personal incomes for bottom 20 states in personal income
fig5 = px.bar(personal_income_growth_2017to2021Q2_lower_end,
              labels = {'GeoName' : 'State', 'value': 'Percent Growth Personal Incomes 2017-2021Q2' },
              color_discrete_sequence = ['pink']*len(personal_income_growth_2017to2021Q2_lower_end),
              width = 1000,
               )
fig5.update_layout(title_text = "Percent Growth in Personal Income 2017-2021Q2 for 20 States with lowest Personal Income", showlegend = False )

st.plotly_chart(fig5)

#create keys for the 8 states with highest personal income growth out of the bottom 20 states in personal income
states_filter_2_keys = list(personal_income_growth_2017to2021Q2_lower_end.iloc[-8:].index)
states_filter_keys_code = ['MS', 'KY','MT', 'IN', 'GA', 'LA','NM','UT']

st.header("Target States")
fig6 = go.Figure(data=go.Choropleth(
    locations=states_filter_keys_code, # Spatial coordinates
    z = personal_income_growth_2017to2021Q2["DataValue"][states_filter_2_keys].sort_values(), # Data to be color-coded
    locationmode = 'USA-states', # set of locations match entries in `locations`
    colorscale = 'viridis' ,
    colorbar_title = "Percentage",
    autocolorscale=False,
    #text=us_states_df['text'], # hover text
    marker_line_color='white'# line markers between states

 ))

fig6.update_layout(
        geo_scope='usa', # limite map scope to USA,
        title_text = " Map of US with target states and their percent growth from 2017Q1 - 2021Q2",
         height = 800
         #margin={"r":0,"t":0,"l":0,"b":0}
         )

st.plotly_chart(fig6,use_container_width = True)

st.write("These are the top 8 states chosen by growth out of the lower income states to focus on ")

#read csv file from kaggle
population_by_state_df = pd.read_csv(Path('Resources/pop_2010_2020.csv'))

#filter csv file to target years, set index to the state
population_by_state = population_by_state_df[['GeoName',
                                             '2016','2017','2018','2019','2020']]
population_by_state = population_by_state.set_index('GeoName')

#Inserted GDP by state & industy csv file
gdp_country_state = pd.read_csv(Path('Resources/GDP_ALL_AREAS_1997_2020.csv'))

# filter by the target 8 states
gdp_country_state=gdp_country_state[gdp_country_state["GeoName"].isin(states_filter_2_keys)]

# extract list of industries
industry_list=gdp_country_state["Description"].drop_duplicates().sort_values()

#Filtered the data to only include GeoName, Description, Years
gdp_state_5year = gdp_country_state[[
    'GeoName',
    'Description',
    '2016','2017','2018','2019','2020']]

# Replacing NA's to 0
gdp_state_5year = gdp_state_5year.replace(["(NA)", "(L)"], 0)
gdp_state_5year=gdp_state_5year.fillna(0)

#changing strings to floats
gdp_state_5year['2016'] = gdp_state_5year['2016'].astype('float')
gdp_state_5year['2017'] = gdp_state_5year['2017'].astype('float')
gdp_state_5year['2019'] = gdp_state_5year['2019'].astype('float')
gdp_state_5year['2020'] = gdp_state_5year['2020'].astype('float')

#grouped by Description to pick out All industry total
gdp_state_5year_filter = gdp_state_5year.groupby('Description')

#Filtering All Industry df
unstacked_gdp_capita_industry = plot_industry_analysis(gdp_state_5year_filter,population_by_state,'All industry total')

# filtering Agriculture

unstacked_gdp_capita_agriculture = plot_industry_analysis(gdp_state_5year_filter,population_by_state,"  Agriculture, forestry, fishing and hunting")

#filtering out Healthcare df
unstacked_gdp_capita_healthcare = plot_industry_analysis(gdp_state_5year_filter,population_by_state,"   Health care and social assistance")

#filtering a df out for manufacturing
unstacked_gdp_capita_manufacturing = plot_industry_analysis(gdp_state_5year_filter,population_by_state,"  Manufacturing")

#filtering df for private gdp by state
unstacked_gdp_capita_private = plot_industry_analysis(gdp_state_5year_filter,population_by_state,' Private industries')

#filteting out df for Finance gdp by state
unstacked_gdp_capita_finance = plot_industry_analysis(gdp_state_5year_filter,population_by_state,'  Finance, insurance, real estate, rental, and leasing')

#filtering df for transportation gdp by state
unstacked_gdp_capita_transportation = plot_industry_analysis(gdp_state_5year_filter,population_by_state,'  Transportation and warehousing')

# Selectbox to input a user specified industry
industry = st.selectbox("Choose a Industry to analyze:", gdp_country_state["Description"].drop_duplicates().sort_values())

unstacked_gdp_capita_generic = plot_industry_analysis(gdp_state_5year_filter,population_by_state,industry)

# Pie graphs to determine the slice of industry in the state
# This is still under construction!!!!

# Our thought here was to visualize the slice of each sector in a particular state, to analyze which sector provides the largest growth in the target state
# Currently, it takes into account the sectors that we have identified to be analyzed. Since Private sector covers a lot of industries under its umbrella,
# we should exclude that and maybe include some more sectors like Education, infrasrtucture etc. in the analysis

# st.header(" Industry Distribution by GDP in Target states")
# listoflists = []

# listoflists.append(unstacked_gdp_capita_agriculture["Value"].loc["2019"])
# listoflists.append(unstacked_gdp_capita_healthcare["Value"].loc["2019"])
# listoflists.append(unstacked_gdp_capita_manufacturing["Value"].loc["2019"])
# listoflists.append(unstacked_gdp_capita_private["Value"].loc["2019"])
# listoflists.append(unstacked_gdp_capita_finance["Value"].loc["2019"])
# listoflists.append(unstacked_gdp_capita_transportation["Value"].loc["2019"])

# pie_chart_data = pd.DataFrame(listoflists,
#                                columns = ['Georgia', 'Indiana', 'Kentucky', 'Louisiana', 'Mississippi', 'Montana', 'New Mexico', 'Utah'])
# pie_chart_data['Industry'] = ['Agriculture', 'Healthcare', 'Manufacturing', 'Private Industries', 'Finance', 'Transportation']
# pie_chart_data.set_index('Industry')

# pie_fig1 = px.pie(pie_chart_data, values = 'Georgia', names = 'Industry', title = 'Geogia')
# st.plotly_chart(pie_fig1,use_container_width = True)

# pie_fig2 = px.pie(pie_chart_data, values = 'Indiana', names = 'Industry', title = 'Indiana')
# st.plotly_chart(pie_fig2,use_container_width = True)

# pie_fig3 = px.pie(pie_chart_data, values = 'Kentucky', names = 'Industry', title = ' Kentucky')
# st.plotly_chart(pie_fig3,use_container_width = True)

# pie_fig4 = px.pie(pie_chart_data, values = 'Louisiana', names = 'Industry', title = 'Louisiana')
# st.plotly_chart(pie_fig4,use_container_width = True)

# pie_fig5 = px.pie(pie_chart_data, values = 'Mississippi', names = 'Industry', title = ' Mississippi')
# st.plotly_chart(pie_fig5,use_container_width = True)

# pie_fig6 = px.pie(pie_chart_data, values = 'Montana', names = 'Industry', title = ' Montana')
# st.plotly_chart(pie_fig6,use_container_width = True)

# pie_fig7 = px.pie(pie_chart_data, values = 'New Mexico', names = 'Industry', title = 'New Mexico')
# st.plotly_chart(pie_fig7,use_container_width = True)

# pie_fig8 = px.pie(pie_chart_data, values = 'Utah', names = 'Industry', title = 'Utah')
# st.plotly_chart(pie_fig8,use_container_width = True)


from .ga_logic import *
from rest_framework import viewsets, permissions, status
from rest_framework.views import APIView
from rest_framework.response import Response
from .algorithm import GeneticAlgorithmService
from .models import *
from .serializers import *
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authentication import TokenAuthentication
from django.contrib.auth.models import User

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

class Individuals(APIView):
    def get(self, request):
        individual = Individual.objects.all()
        serializer = IndividualSerializer(individual, many=True)
        return Response(serializer.data)

    def post(self, request):
        population_size = int(request.data.get('population_size'))
        num_generations = int(request.data.get('num_generations'))
        num_selected = int(request.data.get('num_selected'))
        mutation_rate = float(request.data.get('mutation_rate'))
        gene_length = int(request.data.get('gene_length'))

        algorithm = GeneticAlgorithmService(population_size, gene_length)
        population = algorithm.initialize_population()

        for generation in range(num_generations):
            for individual in population:
                individual.fitness_score = algorithm.calculate_fitness(
                    individual)
                individual.generation = generation

                individual.save()

            population = algorithm.evolve_population(
                population, num_selected, mutation_rate)

        individuals = Individual.objects.all().values('has_albinism')

        return Response({'message': 'Genetic algorithm completed successfully.', 'individuals': individuals})

class Optimize(APIView):
    def get(self, request):
        optimization_result = OptimizationResult.objects.all()
        serializer = OptimizationResultSerializer(
            optimization_result, many=True)
        return Response(serializer.data)

    def post(self, request):
        population_size = int(request.data.get('populationSize'))
        mutation_rate = float(request.data.get('mutationRate',))
        generations = int(request.data.get('generations'))

        # Load the dataset
        dataset = load_dataset()
        dataset_size = len(dataset)

        # Initialize the population
        population = initialize_population(population_size, dataset_size)

        # Genetic Algorithm optimization
        for _ in range(generations):
            fitness_scores = [fitness_function(
                ind, dataset) for ind in population]

            parents = [population[i]
                       for i in np.argsort(fitness_scores)[:2]]

            child = crossover(parents[0], parents[1])

            child = mutate(child, mutation_rate)

            replace_index = np.argmin(fitness_scores)
            population[replace_index] = child

        # Store the optimization result in the database
            best_solution = min(
                population, key=lambda ind: fitness_function(ind, dataset))
            fitness = fitness_function(best_solution, dataset)
            optimization_result = OptimizationResult.objects.create(
                best_solution=best_solution.tolist(),
                fitness=fitness
            )

            # Serialize and return the result
            serializer = OptimizationResultSerializer(optimization_result)
            return Response(serializer.data, status=status.HTTP_201_CREATED)


import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from tornado.web import (
    RequestHandler,
    Application,
    url as unnamed_url)

import logging
from logging.handlers import SysLogHandler, SMTPHandler
from uuid import uuid4
from tornado.options import options
from logging import getLogger
from pystil.db import metadata, Visit
from threading import Thread
from queue import Queue

MESSAGE_QUEUE = Queue()

log = getLogger("pystil")

class Tracking(Thread):
    daemon = True

    def __init__(self, db, log, *args, **kwargs):
        super(Tracking, self).__init__(*args, **kwargs)
        self.log = log
        self.db = db

    def run(self):
        from pystil.websocket import broadcast
        from pystil.utils import visit_to_table_line
        while True:
            try:
                self.log.debug('Blocking for messages')
                message = MESSAGE_QUEUE.get(True)
                self.log.debug('Message got %r' % message)
                try:
                    visit_or_uuid, opening = message.process(self.db)

                    if opening:
                        visit = Visit(**visit_or_uuid)
                        broadcast(
                            'VISIT|' + visit.host + '|' +
                            visit_to_table_line(visit))
                    else:
                        visit_or_uuid and broadcast('EXIT|%s' % visit_or_uuid)
                except:
                    self.log.exception('Error processing visit')
            except:
                self.log.exception('Exception in loop')

class Pystil(Application):
    def listen(self, *args, **kwargs):
        super(Pystil, self).listen(*args, **kwargs)
        db_url = 'postgresql+psycopg2://%s:%s@%s:%d/%s' % (
            options.db_user,
            options.db_password,
            options.db_host,
            options.db_port,
            options.db_name)

        self.db_engine = create_engine(db_url, echo=False)
        metadata.reflect(bind=self.db_engine, schema='agg')
        self.db_metadata = metadata
        self.db = scoped_session(sessionmaker(bind=self.db_engine))
        Tracking(self.db_engine.connect(), self.log).start()
        if not options.debug:
            handler = SysLogHandler(
                address='/dev/log', facility=SysLogHandler.LOG_LOCAL1)
            handler.setLevel(logging.INFO)
            handler.setFormatter(
                logging.Formatter(
                    'PYSTIL: %(name)s: %(levelname)s %(message)s'))

            smtp_handler = SMTPHandler(
                'smtp.keleos.fr',
                'no-reply@pystil.org',
                'pystil-errors@kozea.fr',
                'Pystil Exception')
            smtp_handler.setLevel(logging.ERROR)

            log.addHandler(smtp_handler)
            for logger in (
                    'tornado.access',
                    'tornado.application',
                    'tornado.general',
                    'sqlalchemy'):
                getLogger(logger).addHandler(handler)
                getLogger(logger).addHandler(smtp_handler)
        else:
            self.log.setLevel(logging.DEBUG)
            try:
                from wdb.ext import wdb_tornado, add_w_builtin
            except ImportError:
                pass
            else:
                wdb_tornado(self, start_disabled=True)
                add_w_builtin()

            #getLogger('sqlalchemy').setLevel(logging.DEBUG)

    @property
    def log(self):
        return log

pystil = Pystil(
    debug=options.debug,
    protocol=options.protocol,
    cookie_secret=options.secret,
    static_path=os.path.join(os.path.dirname(__file__), "static"),
    template_path=os.path.join(os.path.dirname(__file__), "templates")
)

class Hdr(RequestHandler):
    @property
    def db(self):
        return self.application.db

    @property
    def log(self):
        return log

    def prepare(self):
        if not self.get_secure_cookie('_pystil_site'):
            self.log.info('Setting secure cookie')
            self.set_secure_cookie('_pystil_site', 'local|' + str(uuid4()))

    def on_finish(self):
        self.db.rollback()

class url(object):
    def __init__(self, url):
        self.url = url

    def __call__(self, cls):
        pystil.add_handlers(
            r'.*$',
            (unnamed_url(self.url, cls, name=cls.__name__),)
        )
        return cls

{'broadcast': 'pystil.websocket.broadcast', 'visit_to_table_line': 'pystil.utils.visit_to_table_line'}

{'wdb_tornado': 'wdb.ext.wdb_tornado', 'add_w_builtin': 'wdb.ext.add_w_builtin'}