# Author - Dylan Butterfield, CSE111, 3:15 Class
import csv
from datetime import datetime

def main():
    try:
        products_dict = read_dictionary('products.csv', 0)
        with open('request.csv', newline='') as file:
            reader = csv.reader(file)
            next(reader)  # Skip the first line
            ordered_items = []
            subtotal = 0
            for row in reader:
                product_number = row[0]
                quantity = int(row[1])
                if product_number in products_dict:
                    product = products_dict[product_number]
                    product_name = product[1]
                    product_price = float(product[2])
                    total_price = product_price * quantity

                    ordered_items.append(f"{product_name}: {quantity} @ {product_price}")
                    subtotal += total_price
                else:
                    print(f"Product with number {product_number} not found.")

            sales_tax = subtotal * 0.06
            total = subtotal + sales_tax

            print_receipt(ordered_items, len(ordered_items), subtotal, sales_tax, total)
            print_current_datetime()
            print("Thank you for shopping at the Inkom Emporium.")
    except FileNotFoundError:
        print("Error: missing file")
        print("[Errno 2] No such file or directory: 'products.csv'")
    except PermissionError:
        print("Error: permission denied")
    except KeyError as e:
        print(f"Error: unknown product ID in the request.csv file\n'{e.args[0]}'")

def print_receipt(items, num_items, subtotal, sales_tax, total):
    print("Inkom Emporium\n")
    for item in items:
        print(item)
    print()
    print(f"Number of Items: {num_items}")
    print(f"Subtotal: {subtotal:.2f}")
    print(f"Sales Tax: {sales_tax:.2f}")
    print(f"Total: {total:.2f}\n")

def print_current_datetime():
    current_date_and_time = datetime.now()
    print(f"{current_date_and_time:%a %b %d %H:%M:%S %Y}")

def read_dictionary(products, key_column_index):
    compound_dict = {
        "D150": ["D150", "1 gallon milk", 2.85],
        "D083": ["D083", "1 cup yogurt", 0.75],
        "D215": ["D215", "1 lb cheddar cheese", 3.35],
        "P019": ["P019", "iceberg lettuce", 1.15],
        "P020": ["P020", "green leaf lettuce", 1.79],
        "P021": ["P021", "butterhead lettuce", 1.83],
        "P025": ["P025", "8 oz arugula", 2.19],
        "P143": ["P143", "1 lb baby carrots", 1.39],
        "W231": ["W231", "32 oz granola", 3.21],
        "W112": ["W112", "wheat bread", 2.55],
        "C013": ["C013", "twix candy bar", 0.85],
        "H001": ["H001", "8 rolls toilet tissue", 6.45],
        "H014": ["H014", "facial tissue", 2.49],
        "H020": ["H020", "aluminum foil", 2.39],
        "H021": ["H021", "12 oz dish soap", 3.19],
        "H025": ["H025", "toilet cleaner", 4.50]
    }

    with open(products, newline='') as file:
        reader = csv.reader(file)
        for row in reader:
            key = row[key_column_index]
            compound_dict[key] = row

    return compound_dict

if __name__ == '__main__':
    main()


def binary_search(A, target):
    i = 0
    j = len(A) - 1
    while i < j:
        mid = (i + j)//2
        if A[mid] < target:
            i = mid + 1
        else:
            j = mid
    if A[i] != target: return -1
    return i

print(i)
i = binary_search(A, 12)
print(i)

"""
--- Binary Search ---
In order to analyze the correctness of this algorithm, we want to see
why doing this type of searching always works.

For instance, if we do,
A = [1, 1, 2, 3, 3, 4, 5, 5, 6]
i = binary_search(A, 3)

The loop terminates when i == j, which happens because the search interval
keeps shrinking by half and eventually becomes size 2. When it is size 2,
then mid == i always, and then if we found our target, we will set
j = mid and terminate. If we didn't find our target, then we set j = mid
or i = mid + 1, which forces termination regardless.

Basically, we define our loop invariant as: If our search target is present
in the array A, then it is in the subarray A[i:j+1].

At initialization this is trivially true.
At maintainence, we have two possibilities,
At termination, i == j,
therefore, the element of interest would be at A[i].

"""


import os
import sys

from SCons.Script import ARGUMENTS  # pylint: disable=import-error
from SCons.Script import COMMAND_LINE_TARGETS  # pylint: disable=import-error
from SCons.Script import DefaultEnvironment  # pylint: disable=import-error

from platformio import fs, util
from platformio.compat import IS_MACOS, IS_WINDOWS
from platformio.package.meta import PackageItem
from platformio.package.version import get_original_version
from platformio.platform.exception import UnknownBoard
from platformio.platform.factory import PlatformFactory
from platformio.project.config import ProjectOptions

# pylint: disable=too-many-branches, too-many-locals

@util.memoized()
def _PioPlatform():
    env = DefaultEnvironment()
    return PlatformFactory.from_env(env["PIOENV"], targets=COMMAND_LINE_TARGETS)

def PioPlatform(_):
    return _PioPlatform()

def BoardConfig(env, board=None):
    with fs.cd(env.subst("$PROJECT_DIR")):
        try:
            p = env.PioPlatform()
            board = board or env.get("BOARD")
            assert board, "BoardConfig: Board is not defined"
            return p.board_config(board)
        except (AssertionError, UnknownBoard) as exc:
            sys.stderr.write("Error: %s\n" % str(exc))
            env.Exit(1)
    return None

def GetFrameworkScript(env, framework):
    p = env.PioPlatform()
    assert p.frameworks and framework in p.frameworks
    script_path = env.subst(p.frameworks[framework]["script"])
    if not os.path.isfile(script_path):
        script_path = os.path.join(p.get_dir(), script_path)
    return script_path

def LoadPioPlatform(env):
    p = env.PioPlatform()

    # Ensure real platform name
    env["PIOPLATFORM"] = p.name

    # Add toolchains and uploaders to $PATH and $*_LIBRARY_PATH
    for pkg in p.get_installed_packages():
        type_ = p.get_package_type(pkg.metadata.name)
        if type_ not in ("toolchain", "uploader", "debugger"):
            continue
        env.PrependENVPath(
            "PATH",
            os.path.join(pkg.path, "bin")
            if os.path.isdir(os.path.join(pkg.path, "bin"))
            else pkg.path,
        )
        if (
            not IS_WINDOWS
            and os.path.isdir(os.path.join(pkg.path, "lib"))
            and type_ != "toolchain"
        ):
            env.PrependENVPath(
                "DYLD_LIBRARY_PATH" if IS_MACOS else "LD_LIBRARY_PATH",
                os.path.join(pkg.path, "lib"),
            )

    # Platform specific LD Scripts
    if os.path.isdir(os.path.join(p.get_dir(), "ldscripts")):
        env.Prepend(LIBPATH=[os.path.join(p.get_dir(), "ldscripts")])

    if "BOARD" not in env:
        return

    # update board manifest with overridden data from INI config
    board_config = env.BoardConfig()
    for option, value in env.GetProjectOptions():
        if not option.startswith("board_"):
            continue
        option = option.lower()[6:]
        try:
            if isinstance(board_config.get(option), bool):
                value = str(value).lower() in ("1", "yes", "true")
            elif isinstance(board_config.get(option), int):
                value = int(value)
        except KeyError:
            pass
        board_config.update(option, value)

    # load default variables from board config
    for option_meta in ProjectOptions.values():
        if not option_meta.buildenvvar or option_meta.buildenvvar in env:
            continue
        data_path = (
            option_meta.name[6:]
            if option_meta.name.startswith("board_")
            else option_meta.name.replace("_", ".")
        )
        try:
            env[option_meta.buildenvvar] = board_config.get(data_path)
        except KeyError:
            pass

    if "build.ldscript" in board_config:
        env.Replace(LDSCRIPT_PATH=board_config.get("build.ldscript"))

def PrintConfiguration(env):  # pylint: disable=too-many-statements
    platform = env.PioPlatform()
    pkg_metadata = PackageItem(platform.get_dir()).metadata
    board_config = env.BoardConfig() if "BOARD" in env else None

    def _get_configuration_data():
        return (
            None
            if not board_config
            else [
                "CONFIGURATION:",
                "https://docs.platformio.org/page/boards/%s/%s.html"
                % (platform.name, board_config.id),
            ]
        )

    def _get_plaform_data():
        data = [
            "PLATFORM: %s (%s)"
            % (
                platform.title,
                pkg_metadata.version if pkg_metadata else platform.version,
            )
        ]
        if (
            int(ARGUMENTS.get("PIOVERBOSE", 0))
            and pkg_metadata
            and pkg_metadata.spec.external
        ):
            data.append("(%s)" % pkg_metadata.spec.uri)
        if board_config:
            data.extend([">", board_config.get("name")])
        return data

    def _get_hardware_data():
        data = ["HARDWARE:"]
        mcu = env.subst("$BOARD_MCU")
        f_cpu = env.subst("$BOARD_F_CPU")
        if mcu:
            data.append(mcu.upper())
        if f_cpu:
            f_cpu = int("".join([c for c in str(f_cpu) if c.isdigit()]))
            data.append("%dMHz," % (f_cpu / 1000000))
        if not board_config:
            return data
        ram = board_config.get("upload", {}).get("maximum_ram_size")
        flash = board_config.get("upload", {}).get("maximum_size")
        data.append(
            "%s RAM, %s Flash"
            % (fs.humanize_file_size(ram), fs.humanize_file_size(flash))
        )
        return data

    def _get_debug_data():
        debug_tools = (
            board_config.get("debug", {}).get("tools") if board_config else None
        )
        if not debug_tools:
            return None
        data = [
            "DEBUG:",
            "Current",
            "(%s)"
            % board_config.get_debug_tool_name(env.GetProjectOption("debug_tool")),
        ]
        onboard = []
        external = []
        for key, value in debug_tools.items():
            if value.get("onboard"):
                onboard.append(key)
            else:
                external.append(key)
        if onboard:
            data.extend(["On-board", "(%s)" % ", ".join(sorted(onboard))])
        if external:
            data.extend(["External", "(%s)" % ", ".join(sorted(external))])
        return data

    def _get_packages_data():
        data = []
        for item in platform.dump_used_packages():
            original_version = get_original_version(item["version"])
            info = "%s @ %s" % (item["name"], item["version"])
            extra = []
            if original_version:
                extra.append(original_version)
            if "src_url" in item and int(ARGUMENTS.get("PIOVERBOSE", 0)):
                extra.append(item["src_url"])
            if extra:
                info += " (%s)" % ", ".join(extra)
            data.append(info)
        if not data:
            return None
        return ["PACKAGES:"] + ["\n - %s" % d for d in sorted(data)]

    for data in (
        _get_configuration_data(),
        _get_plaform_data(),
        _get_hardware_data(),
        _get_debug_data(),
        _get_packages_data(),
    ):
        if data and len(data) > 1:
            print(" ".join(data))

def exists(_):
    return True

def generate(env):
    env.AddMethod(PioPlatform)
    env.AddMethod(BoardConfig)
    env.AddMethod(GetFrameworkScript)
    env.AddMethod(LoadPioPlatform)
    env.AddMethod(PrintConfiguration)
    return env


import io
import sys
import mysql.connector
import binascii
from io import BytesIO
import serial
import codecs
import cv2
import numpy as np
import PIL
from PIL import Image
import base64
ser = serial.Serial('COM3', 9600,timeout=.5)
print ("done conn")
y= b''
y1=b''
y2=b''
y3=b""
yy=b''
z=0
swt=0
iname=""
idata=""

while swt<1:
   incoming = ser.readline().strip()

   if len(incoming)>0:
      y= y +incoming
      z1=len(y)-3
      if y[:-z1]==b"SIN" and y[z1:]==b'OIN' :
         y=y[3:]
         iname=y[0:-3]
         print(iname.decode())
      else :
         y=b""

   if len(incoming)>0:
      y1= y1 +incoming
      z2=len(y1)-4
      if y1[:-z2]==b"SIMG" and y1[z2:]==b"OIMG":
         y1=y1[4:]
         idata=y1[0:-4]
         print(idata.decode())
         decodeit = open(iname.decode(), 'wb')
         decodeit.write(base64.b64decode((idata)))
         decodeit.close()

      else :
         y1=b""

   if len(incoming)>0:
      y2= y2 +incoming
      z1=len(y2)-3
      if y2[:-z1]==b"STN" and y2[z1:]==b"OTN":
         y2=y2[3:]
         tname=y2[0:-3]
         print(tname.decode())
      else :
         y2=b""

   if len(incoming)>0:
      y3= y3 +incoming
      z2=len(y3)-4
      if y3[:-z2]==b"STXT" and y3[z2:]==b"OTXT":
         y3=y3[4:]
         Tdata=y3[0:-4]
         print(Tdata.decode())
         ftxt = open(tname.decode(), 'w')
         ftxt.write(Tdata.decode())
         ftxt.close()
      else :
         y3=b""

print ("done")
ser.close()


# Objetivo: Receber um número N. Calcular e mostrar a série 1 + 1/1! + 1/2! + ... + 1/N!
# Programador: Hugo Leça Ribeiro
# Data de Elaboração: 25.10.19

# Função
def Fserie(num):
    seq = 1
    fat = 1
    ifat = num
    while num >= 1:
        while ifat >= 1:
            fat = fat * ifat
            ifat = ifat - 1
        seq = seq + (1 / fat)
        num = num - 1
        ifat = num
        fat = 1
    return (seq)

# Algoritmo Principal
n = int(input('Digite aqui o número desejado: '))
if n >= 1:
    print(f'A soma dessa sequência será de: {Fserie(n)}')
else:
    print('O número deve ser igual ou maior do que 1')


from sys import stdin

COINS_COUNT, TARGET = map(int, stdin.readline().split())
COINS = sorted(map(int, stdin.read().split()), reverse=True)

# begin_index == COINS_COUNT - 1
CACHE = [
    1 if target % COINS[COINS_COUNT - 1] == 0 else 0
    for target in range(TARGET+1)
]

def solve(target: int, begin_index: int) -> int:
    # target: [0, TARGET]
    # begin_index: [0, COINS_COUNT - 2]

    current_coin = COINS[begin_index]
    return sum(
        CACHE[target - i*current_coin]
        for i in range(target//current_coin + 1)
    )

for begin_index in range(COINS_COUNT - 2, -1, -1):
    CACHE = [
        solve(target, begin_index)
        for target in range(TARGET+1)
    ]

answer = CACHE[TARGET]
print(answer)


#coding:utf-8
__author__ = 'similarface'

from scrapy.spiders import Spider
from scrapy.selector import Selector
from logging import log
from w3school.items import W3SchoolItem
'''
对www.w3school.com.cn的网站的一些爬取
'''
class W3schoolSpider(Spider):
    name="w3school"
    allowed_domains = ["w3school.com.cn"]
    #访问url的入口
    start_urls = [
        "http://www.w3school.com.cn/xml/xml_syntax.asp"
    ]

    def parse(self, response):
        sel=Selector(response)
        #这儿的ul加了1表示div[navsecond]下的第一个ul标签
        sites=sel.xpath('//div[@id="navsecond"]/div[@id="course"]/ul[1]/li')
        #item的容器
        items=[]
        #选择器结果遍历
        for site in sites:
            item=W3SchoolItem()
            #获取a标签的文本
            title = site.xpath('a/text()').extract()
            #获取a标签的href属性
            link = site.xpath('a/@href').extract()
            #获取a标签的title属性
            desc = site.xpath('a/@title').extract()
            #
            item['title'] = [t.encode('utf-8') for t in title]
            #response.urljoin 会加上访问的domain
            item['link'] = [response.urljoin(l.encode('utf-8')) for l in link]
            item['desc'] = [d.encode('utf-8') for d in desc]
            items.append(item)
            print("Appending item...")
        print("Append done.")
        return items


import socket
import struct
import enum
import datetime
import dataclasses

import os
import json
import zmq
import time

INTERFACE = "0.0.0.0"
PORT = 40868

#bus_endpoint = "tcp://192.168.1.223:7777"
bus_endpoint = os.environ["ITS_GBUS_BSCP_ENDPOINT"]

def generate_logfile_name():
    now = datetime.datetime.utcnow().replace(microsecond=0)
    isostring = now.isoformat()  # строка вида 2021-04-27T23:17:31
    isostring = isostring.replace("-", "")  # Строка вида 20210427T23:17:31
    isostring = isostring.replace(":", "")  # Строка вида 20210427T231731, то что надо
    return "sdr-lora-log-" + isostring + ".bin"

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((INTERFACE, PORT,))

ctx = zmq.Context()
socket = ctx.socket(zmq.PUB)
print("connecting to %s" % bus_endpoint)
socket.connect(bus_endpoint)

log_file = generate_logfile_name()
log_stream = open(log_file, mode="wb")

cookie = 1

while True:
    data, port = sock.recvfrom(4096)
    log_stream.write(struct.pack("<L", len(data)) + data)
    log_stream.flush()

    lora_tap_len = 13 # 13 байт на непонятные нули
    lora_mac_len = 5  # пять байт на что-то, что постоянно меняется
    crc_len = 2 # 2 байта, на что-то типо контрольной суммы?

    tap_bytes = data[:lora_tap_len]
    rssi_bytes = data[lora_tap_len:][:lora_mac_len]
    payload = data[lora_tap_len + lora_mac_len:][:-crc_len]
    crc_bytes = data[-crc_len:]
    print(
        "tap: %s, mac: %s, payload: %s, crc: %s"
        % (tap_bytes.hex(), rssi_bytes.hex(), payload.hex(), crc_bytes.hex())
    )

    frame_no = payload[:2]
    frame_no, = struct.unpack("<H", frame_no)
    payload = payload[2:]

    now = time.time()
    packet = {
        'time_s': int(now),
        'time_us': int((now - int(now)) * 1000_0000),
        'cookie': cookie,
        'snr' : rssi_bytes[0],
        'frame_no': frame_no,

        'tap_bytes': tap_bytes.hex(),
        'rssi_bytes': rssi_bytes.hex(),
        'crc_bytes': crc_bytes.hex(),
    }

    parts = [
        b"sdr.downlink_frame",
        json.dumps(packet).encode("utf-8"),
        payload
    ]

    socket.send_multipart(parts)
    cookie += 1
    cookie &= 0xFFFF_FFFF_FFFF_FFFF
    if cookie == 0:
        cookie = 1


#!FastApi
from fastapi import FastAPI,Header,HTTPException,Request
from fastapi.middleware.cors import CORSMiddleware

#!Python modules and functions
from datetime import datetime,timedelta

#!Redis
from models import redis

# create your views here,and run server =>  uvicorn main:app --reload
app = FastAPI(title="Add to cart")

# Create FastApi object from FastAPI class
app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

#*root
@app.get("/")
async def root():
    return {"message": "Hello add to cart"}

#*add_to_cache
@app.post("/add_to_cache/")
def add_to_cache(user_hashed_id:str):
    user_data = redis.get(user_hashed_id)
    if user_data is None:
        redis.set(user_hashed_id,1,ex=timedelta(days=30))
    elif user_data is not None:
        user = int(user_data)
        user += 1
        redis.set(user_hashed_id,user,ex=timedelta(days=30))
    return {"message": "Value added to cache"}

#*get_from_cache
@app.post("/get_from_cache/")
def get_from_cache(user_hashed_id:str):
    user_data = redis.get(user_hashed_id)
    return {"cart_item_count":user_data}


import os
import cv2
import pickle as pkl
import natsort
from scipy.io import loadmat
import numpy as np
import imageio
import optparse
from moviepy.video.io.ffmpeg_reader import FFMPEG_VideoReader
import moviepy.editor as moviepyeditor
import paramiko

from core import image_utils

def read_frame_pathes(video_name, max_n_frames):
    video_path = '/home/nour/Documents/Datasets/YouTube2Text/YouTubeClips/all_frames/'
    folder_path = video_path + video_name
    frame_names = natsort.natsorted(os.walk(folder_path).next()[2])
    n_frames = len(frame_names)

    if n_frames > max_n_frames:
        frame_names = np.array(np.linspace(0, n_frames - 1, num=max_n_frames), dtype=int)
        frame_pathes = [folder_path + '/' + str(name) + '.jpeg' for name in frame_names]
    else:
        frame_pathes = [folder_path + '/' + name for name in frame_names]

    return frame_pathes

def read_frames_from_desk(video_name, max_n_frames):
    frame_pathes = read_frame_pathes(video_name, max_n_frames)
    frames = [cv2.imread(frame_path) for frame_path in frame_pathes]
    return frames

def video_to_frames(event_name):
    """
    Extract places classes and scores (accumulate scores) from time-samples n frames of the videos
    :return:
    """

    # frames of videos
    videos_root_path = '/home/nour/Documents/Datasets/TRECVID_MED/Events/' + event_name + '/video/'
    frames_root_path = '/home/nour/Documents/Datasets/TRECVID_MED/Events/' + event_name + '/all-frames/'
    video_names = natsort.natsorted(os.walk(videos_root_path).next()[2])
    video_pathes = [videos_root_path + name for name in video_names]

    # read only the first 500 videos, we only want to compare qualitatively the
    # places extracted from key-frames vs. the ones extracted from the sampled-frames
    count = 0

    for video_path, video_name in zip(video_pathes, video_names):

        video_name_no_extn = video_name[:-4]
        frames_save_dir = frames_root_path + video_name_no_extn + '/'

        count += 1
        print(video_name_no_extn)
        print(count)

        # if no folder with video name, create it
        if not os.path.exists(frames_save_dir):
            os.mkdir(frames_save_dir)

        try:
            read_frames_imageio(video_path, frames_save_dir)
        except:
            read_frames_opencv(video_path, frames_save_dir)

def read_frames_opencv(video_fullpath, frames_save_dir):
    '''
    opencv ugly and sluggish way to get frames
    :param video:
    :return:
    '''
    cap = cv2.VideoCapture(video_fullpath)
    i = 0
    while cap.isOpened():
        ret, frame = cap.read()

        frame_file_name = frames_save_dir + str(i) + '.jpeg'
        cv2.imwrite(frame_file_name, frame)
        i += 1

        if not ret:
            break

def read_frames_imageio(video_fullpath, frames_save_dir):
    '''
     much better/faster way to read video frames
    :param video_fullpath:
    :return:
    '''
    vid = imageio.get_reader(video_fullpath, 'ffmpeg')
    for i, frame in enumerate(vid):
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        frame_file_name = frames_save_dir + str(i) + '.jpeg'
        cv2.imwrite(frame_file_name, frame)

def video_uniform_sampling(spf, video_path, resize_type, is_local, verbose=False):
    assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    n_samples = int(duration / float(spf))

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    frame_size = 224
    frames = np.zeros(shape=(n_samples, frame_size, frame_size, 3), dtype='float32')
    for i in range(n_samples):
        num = i + 1
        if num % 100 == 0 and verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf
        frame = cap.get_frame(time_sec)
        # resize frame to fit in the array, it's going to be used by caffe anyway
        frame = resize_function(frame)
        # frame encoded as uint and values are from 0-255
        # but caffe needs float32 and values from 0-1
        frame = frame.astype('float32') / float(255)
        frames[i] = frame

    # very important, or we'd have memory leakage
    cap.__del__()

    return frames, fps, n_frames, duration

def video_uniform_sample_and_save_old(spf, video_path, frames_path, image_name_format, resize_type, verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    n_samples = int(duration / float(spf))

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    for i in range(n_samples):
        num = i + 1
        if verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf
        frame = cap.get_frame(time_sec)

        if resize_type is not None:
            # resize frame to fit in the array, it's going to be used by caffe anyway
            frame = resize_function(frame)

        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        frame_path = image_name_format % (frames_path, num)
        cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.close()

    return fps, n_frames, duration

def video_uniform_sample_and_save(spf, video_path, frames_path, image_name_format, resize_type, verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = moviepyeditor.VideoFileClip(video_path)
    fps = cap.fps
    duration = cap.duration
    n_frames = int(fps * duration)
    n_samples = int(duration / float(spf))

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    for i in range(n_samples):
        num = i + 1
        if verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf
        frame = cap.get_frame(time_sec)

        if resize_type is not None:
            # resize frame to fit in the array, it's going to be used by caffe anyway
            frame = resize_function(frame)

        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        frame_path = image_name_format % (frames_path, num)
        cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.close()

    return fps, n_frames, duration

def video_uniform_sample_and_save_i3d(spf, video_path, frames_path, resize_type, verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = moviepyeditor.VideoFileClip(video_path)
    fps = cap.fps
    duration = cap.duration
    n_frames = int(fps * duration)
    n_samples = int(duration / float(spf))
    n_frames_per_segment = 8
    fps_float = float(fps)

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    for i in range(n_samples):
        num = i + 1
        if verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf

        t_stop = time_sec + n_frames_per_segment - 1
        if t_stop > duration:
            return

        # get 8 successive frames for i3d
        for j in range(n_frames_per_segment):
            t = time_sec + (j / fps_float)
            frame = cap.get_frame(t)

            # resize frame to fit in the array, it's going to be used by caffe anyway
            if resize_type is not None:
                frame = resize_function(frame)

            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            frame_path = '%s/%06d_%d.jpg' % (frames_path, num, j + 1)
            cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.close()

    return fps, n_frames, duration

def video_uniform_sample_n_frames_old(video_path, n_samples, max_dim):
    """
    Sample only n frames from the video.
    """

    raise Exception('Needs to add argument about resizing type')

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    step = duration / (n_samples)

    frames = []
    for i in range(n_samples):
        time_sec = i * step
        frame = cap.get_frame(time_sec)
        # resize frame to fit in the array, it's going to be used by caffe anyway
        frame = image_utils.resize_keep_aspect_ratio_max_dim(frame, max_dim)
        # frame encoded as uint and values are from 0-255
        # but caffe needs float32 and values from 0-1
        frame = frame.astype('float32') / float(255)
        frames.append(frame)

    # very important, or we'd have memory leakage
    cap.__del__()

    return frames

def video_uniform_sample_n_frames_and_save(n_samples, video_path, frames_path, image_name_format, resize_type, verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = moviepyeditor.VideoFileClip(video_path)
    fps = cap.fps
    duration = cap.duration
    step = duration / (n_samples)

    for i in range(n_samples):
        num = i + 1
        if verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))

        time_sec = i * step
        frame = cap.get_frame(time_sec)

        if resize_type is not None:
            # resize frame to fit in the array, it's going to be used by caffe anyway
            frame = resize_function(frame)

        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        frame_path = image_name_format % (frames_path, num)
        cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.reader.close()
    cap.close()
    del cap.reader
    del cap

    return fps, n_samples, duration

def video_save_frames(video_path, frames_path, image_name_format, resize_type=None, verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = moviepyeditor.VideoFileClip(video_path)
    fps = float(cap.fps)
    duration_sec = cap.duration
    n_frames = int(fps * duration_sec)

    index = 0
    while True:
        time_sec = index / fps
        frame = cap.get_frame(time_sec)

        # resize frame to fit in the array, it's going to be used by caffe anyway
        if resize_type is not None:
            frame = resize_function(frame)

        index += 1
        if index > n_frames:
            break

        if verbose and index % 100 == 0:
            print(' ... reading frame %d/%d' % (index, n_frames))
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        frame_path = image_name_format % (frames_path, index)
        cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.reader.close()
    cap.close()
    del cap.reader
    del cap

    return fps, n_frames, duration_sec

def video_save_frames_specific_duration(action_num, video_num, video_path, frames_root_pathes, start_stop_sec, image_name_format, verbose=False):
    assert len(frames_root_pathes) == len(start_stop_sec)

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    duration_sec = cap.duration
    img_dim = 224

    start_stop_sec = np.array(start_stop_sec)

    for i, s_s_sec in enumerate(start_stop_sec):
        start_sec, stop_sec = s_s_sec
        frame_root_path = frames_root_pathes[i]

        # offset of starting/stopping the action
        sec_offset = 0.25

        start_idx = int((start_sec + sec_offset) * fps)
        stop_idx = int((stop_sec + sec_offset) * fps) + 1

        if verbose:
            print('action, video: %d, %d' % (action_num, video_num))
            print('%d/%d' % (start_sec, stop_sec))
            print('%d/%d' % (start_idx, stop_idx))

        for idx_frame in range(start_idx, stop_idx):
            time_sec = idx_frame / fps
            if verbose and idx_frame % 100 == 0:
                print('... time_sec, frame: %d/%d' % (time_sec, idx_frame))

            frame = cap.get_frame(time_sec)
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            frame = resize_crop(frame, target_width=img_dim, target_height=img_dim)
            frame_path = image_name_format % (frame_root_path, idx_frame)
            cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.__del__()

def get_video_info(video_path):
    # video_fps, video_n_frames, video_duration = video_utils.

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    cap.close()
    del cap

    return fps, n_frames, duration

def get_regions(video_path, annot, resize_type, verbose=False):
    """
    Get the frames whose numbers are given in the "annot" dictionary.. Then, for each frame get the regions as specificed in the "annot" dictionary.
    Finally, return these regions.
    """

    assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    n_frames = cap.nframes
    duration = cap.duration
    n_regions = sum([len(v) for k, v in annot.iteritems()])

    frame_size = 224
    bbox_resize_factor = 2
    regions = np.zeros(shape=(n_regions, frame_size, frame_size, 3), dtype='float32')
    region_idx = -1

    frame_nums = annot.keys()
    for frame_num in frame_nums:

        if (region_idx + 1) % 100 == 0 and verbose:
            print(' ... reading region %d/%d' % (region_idx + 1, n_regions))

        # get the frame
        i = frame_num - 1
        time_sec = i / fps
        frame = cap.get_frame(time_sec)

        # get the regions (resized) from the frame
        regions_info = annot[frame_num]
        for region_info in regions_info:
            region_idx += 1
            bbox = region_info[1:5]
            bbox = np.multiply(bbox, bbox_resize_factor).astype(np.int)
            x1, y1, x2, y2 = bbox
            region = frame[y1:y2, x1:x2]
            # resize frame to fit in the array, it's going to be used by caffe anyway
            region = resize_function(region)
            # frame encoded as uint and values are from 0-255, but caffe needs float32 and values from 0-1
            region = region.astype('float32') / float(255)
            regions[region_idx] = region

    # very important, or we'd have memory leakage
    cap.__del__()

    return regions


def valid_credit_card(n):
    n1=[ int( i ) for i in str( n) ][::-1]
    for i in range ( 1, len( n1 ), 2 ): n1[i ]= n1[i ] * 2
    n1=[ n1[i ] % 10 + n1[i ] // 10 if i % 2 else n1[i ] for i in range( len( n1 ) ) ]
    return sum(n1[1:]) * 9 % 10 == n%10

    ######
def valid_credit_card(number):
    new_number_list  =[2*int(val) if idx%2!=0 else int(val) for idx,val in enumerate(str(number)[::-1]) ]
    new_number = "".join(map(str,new_number_list))
    check_list = sum([int(i) for i in new_number])
    return check_list%10==0
    #########
def valid_credit_card(CrdNum):
    CrdNum=str(CrdNum)
    ChDgt=int(CrdNum[-1])
    CrdNum2=list(CrdNum[:-1])
    for i in range(1,len(CrdNum)-1,2):
        if int(CrdNum2[i])>=5:
            CrdNum2.insert(i, str((int(CrdNum2[i])*2)-9))
            CrdNum2.pop(i+1)
        else:
            CrdNum2.insert(i, str(int(CrdNum2[i])*2))
            CrdNum2.pop(i+1)
    print(CrdNum2)
    To=0
    for a in CrdNum2:
        To+=int(a)
    print (To)
    To2=str(To*9)
    print(To2)
    if int(To2[-1])==ChDgt:
        return "Visa Card"
    else:
        return "Not a valid credit card number"
print(valid_credit_card(37562198673))

#########
number = 7777777777777777
A= list(str(number//10))[::-1]
number1= list(map(lambda x : 2*int(x), A[::2]))
number2= list(map(lambda x : x-9 if int(x)>9 else int(x), number1))
K=list(map(lambda x : int(x), A[1::2]))
print(((sum(K)+sum(number2))*9)%10==number%10)

#####################

def valid_credit_card(number):
    sayi = list(str(number)[::-1])
    for i in range(1, len(sayi),2):
        sayi[i] = int(sayi[i])*2
        if sayi[i] > 9: sayi[i] -= 9
    total = 0
    for i in sayi[1:]: total += int(i)
    return (total * 9)%10 == int(sayi[0])

    ############


import os
# tail -n +0 be.id2title.txt > be.id2title_cat.txt
# tail -n +0 be.id2title.category.txt >> be.id2title_cat.txt
from parsoid_helper import load_title_to_id

language = 'uk'
directory = "nlpdocs\\UKWIKI"
t2i = "{}\\{}.id2title_cat.txt".format(directory, language)
title2id = load_title_to_id(t2i)
redirect2title = {}
unresolved = []
resolved = []

with open(os.path.join(directory, "{}.redirects.txt".format(language)), 'r', encoding='utf-8') as file:
    for line in file.read().split('\n'):
        if line != '':
            id_, title, redirect = line.split('\t')
            if title2id.get(redirect, None) == None:
                unresolved.append((title,redirect, []))
            else:
                resolved.append((title2id[redirect], title))
            redirect2title[title] = redirect

def vicious_cirle(title, redirect, prev):
    if title2id.get(redirect, None) != None:
        resolved.append((title2id[redirect], title))
    elif redirect2title.get(redirect, None) != None:
        if redirect2title[redirect] in prev:
            print(title, redirect, prev)
        else:
            unresolved.append((redirect, redirect2title[redirect], prev+[title]))
    else:
        pass
    unresolved.remove((title, redirect, prev))

while len(unresolved)>=1:
    print(len(resolved), len(unresolved), len(resolved)+len(unresolved))
    for title, redirect, prev in unresolved:
        vicious_cirle(title, redirect, prev)

print(len(resolved))

with open(t2i, 'a', encoding='utf-8') as wr:
    for id_, title in resolved:
        wr.write(str(id_)+'\t'+title+'\n')


import numpy as np
import gensim.models as word2vec
import jieba
import re

# 设置卷积核
def set_cnn_filter(n_gram):
    array = np.random.rand(n_gram * 300, 300)

    return array

# 保存卷积核
def save_cnn_filter(path, array, n_gram):
    pathname = path + str(n_gram) + '_gram.npy'
    np.save(pathname, array)

# 获得卷积核
def get_cnn_filter(path, n_gram):
    pathname = path + str(n_gram) + '_gram.npy'
    array = np.load(pathname)

    return array

# 加载模型
def load_word2vec_model(model_path):
    model = word2vec.Word2Vec.load(model_path)
    return model

# 输出词向量
def get_vector(word, model):
    return model.wv.__getitem__(word)

# 增加专业名词
def set_user_dict(car_path):
    jieba.load_userdict(car_path)

# 获取结巴分词
def get_split(sentence):

    # 标点符号
    remove_chars = '[·’!"#$%&\'()*+,-./:;<=>?@，。?★、…【】《》？“”‘’！[\\]^_`{|}~]+'

    # 去除标点符号
    sentence = re.sub(remove_chars, "", sentence)

    # 分词
    words = [w for w in jieba.cut(sentence, cut_all=False)]

    return words

# relu函数
def relu(x):
    return np.where(x < 0, 0, x)

# max-polling函数
def poll(array):
    return array.max(axis=0)

def poll_sum(arrays):
    return arrays[0] + arrays[1] + arrays[2]

# 卷积神经网络
def nbt_cnn(sentence, model, cnn_filter_path, bs):
    # n-gram表征
    poll_arrays = []

    # 设置卷积核
    n_gram = 0
    for j in range(3):
        # n-gram
        n_gram += 1

        # 偏项
        b = bs[n_gram - 1]

        # 获取卷积核
        cnn_filter = get_cnn_filter(cnn_filter_path, n_gram)

        # 分词
        words = get_split(sentence)

        # 获得词向量
        vectors = []
        for k in words:
            vector = get_vector(k, model)
            vectors.append(vector)

        # 词向量
        words_vector = []

        # 1-gram
        if n_gram == 1:
            words_vector = vectors
        elif n_gram == 2:
            for k in range(len(vectors) - 1):
                gram = vectors[k].tolist()
                gram_1 = vectors[k + 1].tolist()
                gram.extend(gram_1)
                words_vector.append(np.asarray(gram))
        else:
            for k in range(len(vectors) - 2):
                gram = vectors[k].tolist()
                gram_1 = vectors[k + 1].tolist()
                gram_2 = vectors[k + 2].tolist()
                gram.extend(gram_1)
                gram.extend(gram_2)
                words_vector.append(np.asarray(gram))

        # 将句子向量转换成矩阵
        words_array = np.asarray(words_vector)

        # 卷积
        cnn_array = words_array.dot(cnn_filter)

        # 线性整流函数relu
        relu_array = relu(cnn_array + b)

        # 池化函数max-polling
        poll_array = poll(relu_array)
        poll_arrays.append(poll_array)

    # 语句表征
    r = poll_sum(poll_arrays)

    return r

if __name__ == '__main__':
    # 保存路径
    my_cnn_filter_path = '../../data/representation_data/'

    # # 设置卷积核
    # my_n_gram = 0
    # for i in range(3):
    #     # n-gram
    #     my_n_gram += 1
    #
    #     # 设置卷积核
    #     my_cnn_filter = set_cnn_filter(my_n_gram)
    #
    #     # 保存卷积核
    #     save_cnn_filter(my_cnn_filter_path, my_cnn_filter, my_n_gram)

    # 模型路径
    my_model_path = r'../../data/result_data/word2vec.model'

    # 加载模型
    my_model = load_word2vec_model(my_model_path)

    # 词向量
    # print_vector('奔驰')

    # 专业名词路径
    my_car_path = '../../data/jieba_data/car_name.txt'
    set_user_dict(my_car_path)

    # 句子
    my_sentence = '车快半年了，车内的味道还是很大。'

    # 偏项
    my_bs = [0.2, 0.3, 0.4]

    # 卷积神经网络
    my_r = nbt_cnn(my_sentence, my_model, my_cnn_filter_path, my_bs)
    print(my_r)


import numpy as np
from layer import *

class FeedForwardNN:
    def __init__(self):
        self.layers = []

    def addLayer(self,layer):
        if (len(self.layers) == 0):
            self.nVis = layer.W.shape[0]
            #check for shape?
        self.layers.append(layer)

    def fprop(self, X):
        modelState = [X]
        lastLayerActivation = X
        for l in self.layers:
            lastLayerActivation = l.fprop(lastLayerActivation)
            modelState.append(lastLayerActivation)
        return modelState

    def predict(self, X):
        state = self.fprop(X)
        return state[-1]

    def calcCost(self, y, modelState, trainParams):
        weightPenalty = float(trainParams["WeightPenalty"])
        hx = modelState[-1]
        m = hx.shape[0]

        cost = 1./m * sum(sum(- y * np.log(hx) - (1-y) * np.log(1 - hx)))
        for l in self.layers:
            cost += weightPenalty / (2*m) * l.getWeightCost()
        return cost

    def bprop(self, y, modelState, trainParams):
        weightPenalty = float(trainParams["WeightPenalty"])
        gradients = []
        numLayers = len(self.layers)

        hx = modelState[-1]
        m = hx.shape[0]

        dLastLayer = hx - y

        for layerNum in range(numLayers - 1, 0, -1):
            gradients.insert(0, self.layers[layerNum].getBackPropGrad(modelState[layerNum], dLastLayer, trainParams))
            dLastLayer = self.layers[layerNum].bprop(modelState[layerNum], dLastLayer)

        gradients.insert(0, self.layers[0].getBackPropGrad(modelState[0], dLastLayer, trainParams))
        return gradients

    def serialize(self):
        return np.concatenate([l.serialize() for l in self.layers])

    @staticmethod
    def deserialize(serialized, modelDef):
        m = FeedForwardNN()
        current = 0
        for layer in modelDef:
            l = None
            if layer["name"] == "softmax":
                nInput = layer["nInput"]
                nOutput = layer["nOutput"]
                numberOfVars = nInput*nOutput + nOutput
                l = SigmoidLayer.deserialize(serialized[current: current + numberOfVars], nInput, nOutput)
                current += numberOfVars
            m.layers.append(l)
        return m


from os import system, name
from typing import List
from .cards import Card, CardTypes
from .player import Player

def get_input_int(user_message: str, min_input: int = 1, max_input: int = 999999) -> int:
    """Asks for an integer input from the user.

    Args:
        user_message (str): Message for the user

    Returns:
        int: Integer that the user puts in.
    """
    val = 0
    while True:
        _input = input(user_message)
        try:
            val = int(_input)
        except:
            print("This was not a valid integer. Please try again.")
            continue

        if min_input <= val <= max_input:
            return val

        if min_input > val:
            print(f"The entered value should exceed {min_input}")
        else:
            print(f"The maximum input should not exceed {max_input}")

def clear_screen() -> int:
    """
    Clears the screen of the user.
    """
    if name == 'nt':
        system('cls')
    else:
        system('clear')
    return 0

def create_card_deck() -> List[Card]:
    """Creates the card deck and returns it

    Returns:
        List[Card]: List with instances of type Card
    """
    cards = []
    for i in range(13):
        for suit in ['Red diamond', 'Black clubs', 'Red heart', 'Black spade']:
            if i < 9:
                cards.append(Card(i + 2, f"{suit} {i + 2}", CardTypes.NUMBER))
            elif i == 9:
                cards.append(Card(10, f'{suit} Jack', CardTypes.PICTURE))
            elif i == 10:
                cards.append(Card(10, f'{suit} Lady', CardTypes.PICTURE))
            elif i == 11:
                cards.append(Card(10, f'{suit} King', CardTypes.PICTURE))
            else:
                cards.append(Card(11, f'{suit} Ass', CardTypes.ASS))
    return cards

def draw_card(player: Player, cards: List[Card]) -> None:
    """Function draws a card and adds it to the card deck
    of the player.

    Args:
        player (Player): Object of class Player
        cards (List[Card]): List of cards
    """
    new_card = cards.pop()
    if player.is_host:
        print(f"The host got a new card:     {new_card}")
    else:
        print(f"You got a new card:          {new_card}")
    player.add(new_card)

def player_plays(player: Player, cards: List[Card]) -> bool:
    """Function asks the user for decisions until the user
    has stopped or is busted.

    Args:
        player (Player): Instance of class Player
        cards (List[Card]): List with elements of class Card

    Returns:
        bool: True, if user has not lost
    """
    decision = "y"
    while decision != 'n':
        print(f"\nYour current score is: {player.score}\nYou have the following cards:")
        for card in player.cards:
            print(f"\t{str(card)}")

        decision = input("Do you want to draw a card or stop (y/n)?").lower()
        if decision == 'y':
            draw_card(player, cards)
            if player.score >= 21:
                print("You lost")
                return False
        else:
            print("You decided to end the game")
            print(f"You have a score of {player.score}")
            return True

def host_plays(host: Player, cards: List[Card]) -> True:
    """Function that plays for the host.

    Args:
        host (Player): Object of class Player
        cards (list): List of cards

    Returns:
        True: True if Host has not lost the game
    """
    done = False
    while not done:
        if host.score < 17:
            draw_card(host, cards)
            for card in host.cards:
                print(f"\t{str(card)}")
        elif host.score >= 17:
            return True

        if host.has_blackjack():
            print("Host has a blackjack! He won!")
            return True

        if host.score >= 21:
            print(f"Host has a score of {host.score}. You won")
            return False


import numpy as np
import pandas as pd
import streamlit as st
#from pathlib import Path
from datetime import datetime
import plotly.express as px

from PIL import Image
#import plotly.graph_objects as go
#import plotly.io as pio

realBonds = ['R197', 'I2025', 'R210', 'I2029', 'I2031', 'I2033', 'R202', 'I2038', 'I2046', 'I2050']

nomBonds = ['R186', 'R2030', 'R213', 'R2032', 'R2035', 'R209', 'R2037', 'R2040', 'R214', 'R2044', 'R2048', 'R2053']

#file = "BondDetails.csv"
file = "BondDetailsv1.csv"
fileprev = 'BondDetailsv0.csv'

@st.cache_data
def data(file):
    #df = pd.read_csv(file, delimiter=";", index_col="Date", parse_dates=True, infer_datetime_format=True)
    #df = pd.read_csv(file, delimiter=";")
    df = pd.read_csv(file, delimiter=",")
    return df

df = data(file)
dfprev =data(fileprev)

#bondData = df[['Bond Code', 'Date', 'ISSUER', 'ISSUER_INDUSTRY', 'PAYMENT_RANK', 'Coupon', 'Companion Bond',
#               'BP Spread', 'MTM', 'Last MTM Change Date', 'DAYS_TO_NEXT_COUPON', 'NXT_CPN_DT', 'Modified Duration']]

bondData = df[['Bond Code', 'Maturity', 'ISSUER', 'ISSUER_INDUSTRY', 'PAYMENT_RANK', 'Coupon', 'Companion Bond',
               'BP Spread', 'MTM', 'Last MTM Change Date', 'DAYS_TO_NEXT_COUPON', 'NXT_CPN_DT', 'Modified Duration']]

change0 = df[['Bond Code', 'ISSUER', 'ISSUER_INDUSTRY', 'PAYMENT_RANK', 'Companion Bond', 'BP Spread']]
change1 = dfprev[['Bond Code', 'ISSUER', 'ISSUER_INDUSTRY', 'PAYMENT_RANK', 'Companion Bond', 'BP Spread']]

#change0['BP Spread'] = change0['BP Spread'].astype(float)
#change1['BP Spread'] = change1['BP Spread'].astype(float)

change = pd.merge(change0, change1, on='Bond Code', how='left')

change = change.drop(['ISSUER_y'], axis=1)
change = change.drop(['ISSUER_INDUSTRY_y'], axis=1)
change = change.drop(['PAYMENT_RANK_y'], axis=1)
change = change.drop(['Companion Bond_y'], axis=1)

#change0['BP Spread'] = change0['BP Spread'].astype(float)
#change1['BP Spread'] = change1['BP Spread'].astype(float)

change['Move'] = change['BP Spread_x'] - change['BP Spread_y']

change = change.dropna()

change = change[(change['Move'] != 0)]

change = change.rename({'ISSUER_x': 'Issuer',
                        'ISSUER_INDUSTRY_x': 'Industry',
                        'PAYMENT_RANK_x': 'Rank',
                        'Companion Bond_x': 'Companion',
                        'BP Spread_x': 'Current Spread',
                        'BP Spread_y': 'Previous Spread',
            }, axis=1)

change = change[['Bond Code', 'Issuer', 'Industry', 'Rank', 'Companion', 'Previous Spread', 'Current Spread', 'Move']]

#st.dataframe(change)

#st.dataframe(bondData)

#bondData = bondData.dropna()
#bondaData = bondData.dropna(subset = ['DAYS_TO_NEXT_COUPON'])
#bondaData = bondaData.loc[bondaData['DAYS_TO_NEXT_COUPON'] != ' #N/A N/A ']

#st.dataframe(bondData)
##bondaData['DAYS_TO_NEXT_COUPON'] = bondaData['DAYS_TO_NEXT_COUPON'].replace(' -  ', 0)
#bondaData = bondData.dropna(subset = ['Date'])

#bondaData = bondData.dropna(subset = ['NXT_CPN_DT'])
#bondaData = bondData.dropna(subset = ['DAYS_TO_NEXT_COUPON'])

today = datetime.today().date()

#bondData['Maturity'] = bondData.apply(lambda x: datetime.strptime(x['Date'], "%Y/%m/%d").date(), axis=1)
bondData['Maturity'] = bondData.apply(lambda x: datetime.strptime(x['Maturity'], "%d-%b-%y").date(), axis=1)
bondData['Last_MTM_Change'] = bondData.apply(lambda x: datetime.strptime(x['Last MTM Change Date'], "%d-%b-%y").date(), axis=1)

#bondData['NXT_CPN_DT'] = bondData.apply(lambda x: datetime.strptime(x['NXT_CPN_DT'], "%Y/%m/%d").date(), axis=1)

bondData['Term'] = bondData.apply(lambda x: ((x['Maturity'] - today).days)/365, axis=1)

#bondData['MD'] = bondData.apply(lambda x: ((x['DAYS_TO_NEXT_COUPON'] - today).days)/365, axis=1)
bondData['MD'] = bondData.apply(lambda x: (float(x['DAYS_TO_NEXT_COUPON']))/365 if (x['Companion Bond'] == 'JIBAR') else x['Modified Duration'] , axis=1)

#bondData = bondData.drop(['Date'], axis=1)
bondData = bondData.drop(['Last MTM Change Date'], axis=1)

bondData = bondData.sort_values(by='Maturity')

issuerData = bondData['ISSUER'].unique()

industryData = bondData['ISSUER_INDUSTRY'].unique()

rankData = bondData['PAYMENT_RANK'].unique()

benchmarkData = bondData['Companion Bond'].unique()

codes = bondData['Bond Code'].unique()

options = ['Issuer', 'Industry', 'Rank']

issuers = sorted(issuerData)

industry = sorted(industryData)

rank = sorted(rankData)

benchmark = benchmarkData

####benchmark = sorted(benchmarkData)#####

@st.cache_data
def MTMRegression(data):

    fig = px.scatter(data, x='Term', y='Companion_Spread', text='Bond Code', trendline='ols', trendline_color_override='red')

    fig.update_traces(textposition='top center')

    results = px.get_trendline_results(fig)
    results0 = results.iloc[0]["px_fit_results"].summary()
    results1 = results.iloc[0]["px_fit_results"].params

    r_squared = px.get_trendline_results(fig).px_fit_results.iloc[0].rsquared

    return fig, results0, results1, r_squared

@st.cache_data
def MTMRegressionJIBAR(data):

    fig = px.scatter(data, x='Term', y='JIBAR_Spread', text='Bond Code', trendline='ols', trendline_color_override='red')

    fig.update_traces(textposition='top center')

    results = px.get_trendline_results(fig)
    results0 = results.iloc[0]["px_fit_results"].summary()
    results1 = results.iloc[0]["px_fit_results"].params

    r_squared = px.get_trendline_results(fig).px_fit_results.iloc[0].rsquared

    return fig, results0, results1, r_squared

@st.cache_data
def MTMHistogram(data, metric, attribute):

    fig = px.histogram(data, x=metric, color=attribute, text_auto = True)

    fig.update_layout(legend=dict(
    orientation="h",
    yanchor="bottom",
    y=-0.3,
    xanchor="left",
    x=0.0
))

    return fig

#st.markdown("
Credit Analysis
", unsafe_allow_html=True)

st.header('Credit Analysis')

st.markdown(" ")
banner2 = Image.open('background1.jpg')
st.image(banner2)
st.markdown(" ")

#st.header('Spread Moves')

#st.dataframe(change)

st.sidebar.header('Pricing Inputs')

st.markdown(" ")
banner1 = Image.open('sidebarBackground2.jpg')
st.sidebar.image(banner1)
st.markdown(" ")

refRate = st.sidebar.number_input('3M JIBAR', value=8.492)

inflation = st.sidebar.number_input('12M YOY CPI', value=6.300)

####Need to fix this, include or incorporate inflation#############
####Also need to think about spread - it should be spread over Companion not JIBAR?########

#bondData['YTM'] = bondData.apply(lambda x: 200*((1+((refRate + (x['BP Spread'])/100))/400)**(2)-1) if (x['Companion Bond'] == 'JIBAR') else x['MTM'], axis =1)

#bondData['Spread'] = bondData.apply(lambda x: round(100*((400*(((1+((x['YTM'])/200))**(0.5))-1))-refRate),2), axis =1)

@st.cache_data
def ytm(data):

    lenth = data.shape[0]

    yieldToMaturity = []

    for i in range(0,lenth):

        #if (data['Companion Bond'].iloc[i].isin(realBonds)):
        if(data['Companion Bond'].iloc[i] == 'R197'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2025'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'R210'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2029'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2029'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'R2031'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'R2033'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'R202'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2038'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2046'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'I2050'):
            ytm =  data['MTM'].iloc[i] + (inflation)
            yieldToMaturity.append(ytm)

        elif(data['Companion Bond'].iloc[i] == 'JIBAR'):
            ytm = (data['BP Spread'].iloc[i]/100) + refRate
            yieldToMaturity.append(ytm)

        else:
            ytm = data['MTM'].iloc[i]

            yieldToMaturity.append(ytm)

    return yieldToMaturity

@st.cache_data
def jibarSpread(data):

    lenth = data.shape[0]

    jibarSpread = []

    for i in range(0,lenth):

        if(data['Companion Bond'].iloc[i] == 'JIBAR'):
            spread = round((data['YTM'].iloc[i] - refRate)*100,2)
            jibarSpread.append(spread)

        else:
            spread = round((((((1+((data['YTM'].iloc[i])/200))**(2/4)) - 1)*400) - refRate)*100,2)
            jibarSpread.append(spread)

    return jibarSpread

#bondData['Spread'] = bondData['BP Spread']

#bondData['YTM'] = bondData.apply(lambda x: x['MTM'] if (x['MTM'] > 0) else ((x['Spread']/100) + refRate), axis=1)

bondData['YTM'] = ytm(bondData)

bondData['Companion_Spread'] = bondData['BP Spread']

#bondData['JIBAR_Spread'] = (bondData['YTM'] - refRate)*100

bondData['JIBAR_Spread'] = jibarSpread(bondData)

#########
#########

#bondData['MD'] = bondData.apply(lambda x: (float(x['DAYS_TO_NEXT_COUPON'])/365) if (x['Companion Bond'] == 'JIBAR') else x['Modified Duration'], axis =1)

bondData = bondData.drop(['BP Spread'], axis=1)
bondData = bondData.drop(['MTM'], axis=1)
bondData = bondData.drop(['DAYS_TO_NEXT_COUPON'], axis=1)
bondData = bondData.drop(['NXT_CPN_DT'], axis=1)
bondData = bondData.drop(['Modified Duration'], axis=1)

st.header('BESA MTM')

st.write('', unsafe_allow_html=True)

showDF = st.radio("Details",("Spread Change", "All Bonds"))

if (showDF == 'Spread Change'):
    st.dataframe(change)
else:
    st.dataframe(bondData)

selection = st.sidebar.selectbox('Criteria', options, index=0)

###################################################################################################################################################
################################### Code within if statements based on selection ##################################################################

st.markdown(" ")
st.markdown(" ")
st.header('Filtered Bond')

if (selection == 'Issuer'):

    issuer1 = st.multiselect('Issuers', issuers, default = 'ABSA BANK LTD')

    emptyDf = []

    for issuer in issuer1:
        container = bondData.loc[(bondData['ISSUER'] == issuer)]
        emptyDf.append(container)

    issuerFilter = pd.concat(emptyDf)

    issuerIndustry = st.sidebar.checkbox("Industry")
    if issuerIndustry:
        industryIssuer = st.sidebar.selectbox('Industry', industry, index=0)
        issuerFilter = issuerFilter.loc[(issuerFilter['ISSUER_INDUSTRY'] == industryIssuer)]

    issuerRank = st.sidebar.checkbox("Rank")
    if issuerRank:
        rankIssuer = st.sidebar.selectbox('Rank', rank, index=0)
        issuerFilter = issuerFilter.loc[(issuerFilter['PAYMENT_RANK'] == rankIssuer)]

    issuerBenchmark = st.sidebar.checkbox("Benchmark")
    if issuerBenchmark:
        benchmarkIssuer = st.sidebar.selectbox('Rank', benchmark, index=0)
        issuerFilter = issuerFilter.loc[(issuerFilter['Companion Bond'] == benchmarkIssuer)]

    issuerDate = st.sidebar.checkbox("Date")
    if issuerDate:
        dateIssuer1 = st.sidebar.date_input("Start Date")
        dateIssuer2 = st.sidebar.date_input("End Date")

        issuerFilter = issuerFilter.loc[(issuerFilter['Maturity'] >= dateIssuer1) & (issuerFilter['Maturity'] <= dateIssuer2)]

    st.write('', unsafe_allow_html=True)

    bondCode = st.radio("Filter on Bond Code",("No", "Yes"))

    #bondCode = st.checkbox("Filter on Bond Code")

    if(bondCode == "Yes"):

        identifier = issuerFilter['Bond Code'].unique()

        codeBonds = st.multiselect('Bond Codes', identifier)

        issuerFilter = issuerFilter[issuerFilter['Bond Code'].isin(codeBonds)]
    else:
        pass

    #st.header('Filtered Bond')
    st.dataframe(issuerFilter, use_container_width=True)

#############
    #showMoves = st.checkbox("Show Spread Changes")

    #if showMoves:
    #    st.header('Spread Moves')

    #    st.dataframe(change)

#############
    showStats = st.checkbox("Show Statistics")

    if showStats:

        #descriptiveDF = issuerFilter[['Spread', 'Term']]
        descriptiveDF = issuerFilter[['Companion_Spread', 'JIBAR_Spread']]

        df1, df2, df3= st.columns([0.6,1,1])

        df1.header('Statistics')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.dataframe(descriptiveDF.describe())

        histSpOJ = MTMHistogram(issuerFilter, 'Companion_Spread', 'ISSUER')
        df2.header('Companion_Spread Histogram')
        df2.plotly_chart(histSpOJ, use_container_width=True)

        #histTerm = MTMHistogram(issuerFilter, 'Term', 'ISSUER')
        #df3.header('Term Histogram')
        #df3.plotly_chart(histTerm, use_container_width=True)

        histJIBARSpread = MTMHistogram(issuerFilter, 'JIBAR_Spread', 'ISSUER')
        df3.header('JIBAR_Spread Histogram')
        df3.plotly_chart(histJIBARSpread, use_container_width=True)

    showGraph = st.checkbox("Spread Over Companion Bond Regression")

    if showGraph:

        yieldGraph, summary, param, rSquared = MTMRegression(issuerFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS Comapanion Bond Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('Companion Bond Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread over Companion Bond = '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')

        summaryCol.markdown('R-Squared = '+str(round(rSquared,2)))

        inputTerm = summaryCol.number_input('Term', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        averageCompanionYield = round(issuerFilter['YTM'].mean() - (issuerFilter['Companion_Spread'].mean())/100,2)

        YTM = round(averageCompanionYield + (Spread/100), 2)

        YTMQuarterly = round(400*(((1+(YTM/200))**(2/4))-1),2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        summaryCol.markdown('Ref: Average Companion Bond Yield = '+str(averageCompanionYield))

        summaryCol.markdown('Spread over Companion Bond = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTMQuarterly))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTM))

        #showSummary= st.checkbox("Companion Bond Regression Results")
        #if showSummary:
        #
        #    st.header('OLS Results Summary')
        #    summary

    showGraph = st.checkbox("Spread Over JIBAR Regression")

    if showGraph:

        yieldGraph, summary, param, rSquaredJibar = MTMRegressionJIBAR(issuerFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS JIBAR Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('JIBAR Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread Over 3M JIBAR = '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')
        summaryCol.markdown('R-Squared = '+str(round(rSquaredJibar,2)))

        inputTerm = summaryCol.number_input('Tenor', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        YTM = round((Spread/100) + refRate,2)

        YTMSemi = round(200*(((1+(YTM/400))**(2))-1),2)

        summaryCol.markdown('Ref: 3M JIBAR = '+str(refRate))

        summaryCol.markdown('Spread over 3M JIBAR = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTM))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTMSemi))

        #showSummary= st.checkbox("JIBAR Spread Regression Results")
        #if showSummary:
        #
        #    st.header('OLS Results Summary')
        #    summary
######

elif(selection == 'Industry'):

    industry1 = st.multiselect('Industries', industry, default = 'BANK')

    emptyDf = []

    for industry in industry1:
        container = bondData.loc[(bondData['ISSUER_INDUSTRY'] == industry)]
        emptyDf.append(container)

    industryFilter = pd.concat(emptyDf)

    industryIssuer = st.sidebar.checkbox("Issuer")
    if industryIssuer:
        issuerIndustry = st.sidebar.selectbox('Issuer', issuers, index=0)
        industryFilter = industryFilter.loc[(industryFilter['ISSUER'] == issuerIndustry)]

    rankIndustry = st.sidebar.checkbox("Rank")
    if rankIndustry:
        industryRank = st.sidebar.selectbox('Rank', rank, index=0)
        industryFilter = industryFilter.loc[(industryFilter['PAYMENT_RANK'] == industryRank)]

    industryBenchmark = st.sidebar.checkbox("Benchmark")
    if industryBenchmark:
        benchmarkIndustry = st.sidebar.selectbox('Rank', benchmark, index=0)
        industryFilter = industryFilter.loc[(industryFilter['Companion Bond'] == benchmarkIndustry)]

    industryDate = st.sidebar.checkbox("Date")
    if industryDate:
        dateIssuer1 = st.sidebar.date_input("Start Date")
        dateIssuer2 = st.sidebar.date_input("End Date")

        industryFilter = industryFilter.loc[(industryFilter['Maturity'] >= dateIssuer1) & (industryFilter['Maturity'] <= dateIssuer2)]

    bondCode = st.checkbox("Filter on Bond Code")

    if bondCode:

        identifier = industryFilter['Bond Code'].unique()

        codeBonds = st.multiselect('Bond Codes', identifier)

        industryFilter = industryFilter[industryFilter['Bond Code'].isin(codeBonds)]

    st.dataframe(industryFilter)

#############
    showStats = st.checkbox("Show Statistics")

    if showStats:

        #descriptiveDF = industryFilter[['Spread', 'Term']]
        descriptiveDF = industryFilter[['Companion_Spread', 'JIBAR_Spread']]

        df1, df2, df3= st.columns([0.6,1,1])

        df1.header('Statistics')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.dataframe(descriptiveDF.describe())

        histSpOJ = MTMHistogram(industryFilter, 'Companion_Spread', 'ISSUER')
        df2.header('Companion_Spread Histogram')
        df2.plotly_chart(histSpOJ, use_container_width=True)

        #histTerm = MTMHistogram(industryFilter, 'Term', 'ISSUER')
        #df3.header('Term Histogram')
        #df3.plotly_chart(histTerm, use_container_width=True)

        histJIBARSpread = MTMHistogram(industryFilter, 'JIBAR_Spread', 'ISSUER')
        df3.header('JIBAR_Spread Histogram')
        df3.plotly_chart(histJIBARSpread, use_container_width=True)

    showGraph = st.checkbox("Spread Over Companion Bond Regression")

    if showGraph:

        yieldGraph, summary, param = MTMRegression(industryFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS Comapanion Bond Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('Companion Bond Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread over Companion Bond= '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')

        inputTerm = summaryCol.number_input('Term', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        averageCompanionYield = round(industryFilter['YTM'].mean() - (industryFilter['Companion_Spread'].mean())/100,2)

        YTM = round(averageCompanionYield + (Spread/100), 2)

        YTMQuarterly = round(400*(((1+(YTM/200))**(2/4))-1),2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        summaryCol.markdown('Ref: Average Companion Bond Yield = '+str(averageCompanionYield))

        summaryCol.markdown('Spread over Companion Bond = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTMQuarterly))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTM))

        showSummary= st.checkbox("Companion Bond Regression Results")
        if showSummary:

            st.header('OLS Results Summary')

            summary

    showGraph = st.checkbox("Spread Over JIBAR Regression")

    if showGraph:

        yieldGraph, summary, param = MTMRegressionJIBAR(industryFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS JIBAR Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('JIBAR Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread Over 3M JIBAR = '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')

        inputTerm = summaryCol.number_input('Tenor', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        YTM = round((Spread/100) + refRate,2)

        YTMSemi = round(200*(((1+(YTM/400))**(2))-1),2)

        summaryCol.markdown('Ref: 3M JIBAR = '+str(refRate))

        summaryCol.markdown('Spread over 3M JIBAR = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTM))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTMSemi))

        showSummary= st.checkbox("JIBAR Spread Regression Results")
        if showSummary:

            st.header('OLS Results Summary')

            summary
######

elif (selection == 'Rank'):

    rank1 = st.multiselect('Rank', rank, default = 'Sr Unsecured')

    emptyDf = []

    for rank in rank1:
        container = bondData.loc[(bondData['PAYMENT_RANK'] == rank)]
        emptyDf.append(container)

    rankFilter = pd.concat(emptyDf)

    rankIssuer = st.sidebar.checkbox("Issuer")
    if rankIssuer:
        issuerRank = st.sidebar.selectbox('Issuer', issuers, index=0)
        rankFilter = rankFilter.loc[(rankFilter['ISSUER'] == issuerRank)]

    rankIndustry = st.sidebar.checkbox("Industry")
    if rankIndustry:
        industryRank = st.sidebar.selectbox('Industry', industry, index=0)
        rankFilter = rankFilter.loc[(rankFilter['ISSUER_INDUSTRY'] == industryRank)]

    rankBenchmark = st.sidebar.checkbox("Benchmark")
    if rankBenchmark:
        benchmarkRank = st.sidebar.selectbox('Rank', benchmark, index=0)
        rankFilter = rankFilter.loc[(rankFilter['Companion Bond'] == benchmarkRank)]

    industryDate = st.sidebar.checkbox("Date")
    if industryDate:
        dateIssuer1 = st.sidebar.date_input("Start Date")
        dateIssuer2 = st.sidebar.date_input("End Date")

        rankFilter = rankFilter.loc[(rankFilter['Maturity'] >= dateIssuer1) & (rankFilter['Maturity'] <= dateIssuer2)]

    bondCode = st.checkbox("Filter on Bond Code")

    if bondCode:

        identifier = rankFilter['Bond Code'].unique()

        codeBonds = st.multiselect('Bond Codes', identifier)

        rankFilter = rankFilter[rankFilter['Bond Code'].isin(codeBonds)]

    st.dataframe(rankFilter)

#############
    showStats = st.checkbox("Show Statistics")

    if showStats:

        #descriptiveDF = rankFilter[['Spread', 'Term']]
        descriptiveDF = rankFilter[['Companion_Spread', 'JIBAR_Spread']]

        df1, df2, df3= st.columns([0.6,1,1])

        df1.header('Statistics')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.markdown(' ')
        df1.dataframe(descriptiveDF.describe())

        histSpOJ = MTMHistogram(rankFilter, 'Companion_Spread', 'ISSUER')
        df2.header('Companion_Spread Histogram')
        df2.plotly_chart(histSpOJ, use_container_width=True)

        #histTerm = MTMHistogram(rankFilter, 'Term', 'ISSUER')
        #df3.header('Term Histogram')
        #df3.plotly_chart(histTerm, use_container_width=True)

        histJIBARSpread = MTMHistogram(rankFilter, 'JIBAR_Spread', 'ISSUER')
        df3.header('JIBAR_Spread Histogram')
        df3.plotly_chart(histJIBARSpread, use_container_width=True)

    showGraph = st.checkbox("Spread Over Companion Bond Regression")

    if showGraph:

        yieldGraph, summary, param = MTMRegression(rankFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS Comapanion Bond Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('Companion Bond Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread over Companion Bond= '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')

        inputTerm = summaryCol.number_input('Term', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        averageCompanionYield = round(rankFilter['YTM'].mean() - (rankFilter['Companion_Spread'].mean())/100,2)

        YTM = round(averageCompanionYield + (Spread/100), 2)

        YTMQuarterly = round(400*(((1+(YTM/200))**(2/4))-1),2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        summaryCol.markdown('Ref: Average Companion Bond Yield = '+str(averageCompanionYield))

        summaryCol.markdown('Spread over Companion Bond = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTMQuarterly))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTM))

        showSummary= st.checkbox("Companion Bond Regression Results")
        if showSummary:

            st.header('OLS Results Summary')

            summary

    showGraph = st.checkbox("Spread Over JIBAR Regression")

    if showGraph:

        yieldGraph, summary, param = MTMRegressionJIBAR(rankFilter)

        graphCol, summaryCol = st.columns([1.1,0.9])

        graphCol.header('OLS JIBAR Spread')

        graphCol.plotly_chart(yieldGraph)

        summaryCol.header('JIBAR Model Based Spread')

        constant = round(param[0],5)
        gradient = round(param[1],5)

        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')
        summaryCol.markdown(' ')

        summaryCol.markdown('Spread Over 3M JIBAR = '+str(round(param[0],2))+' + ' + str(round(param[1],2)) + ' x Term')

        inputTerm = summaryCol.number_input('Tenor', value=1.00)

        Spread = round(constant + gradient*inputTerm,2)

        #YTM = round(((200*(((1+(((Spread/100)+refRate)/400))**(2))-1))),2)

        YTM = round((Spread/100) + refRate,2)

        YTMSemi = round(200*(((1+(YTM/400))**(2))-1),2)

        summaryCol.markdown('Ref: 3M JIBAR = '+str(refRate))

        summaryCol.markdown('Spread over 3M JIBAR = '+str(Spread))
        summaryCol.markdown('Quarterly YTM = ' + str(YTM))
        summaryCol.markdown('Semi-Annual YTM = ' + str(YTMSemi))

        showSummary= st.checkbox("JIBAR Spread Regression Results")
        if showSummary:

            st.header('OLS Results Summary')

            summary

################################################################################
################################################################################


from ui import qtx

class SettingsPresenter:

    def __init__(self, mainView, settings):
        self._mainView = mainView
        self._settings = settings

        self._mainView.closing.connect(self._onClosing)

        state = self._settings.get('mainState')
        if state:
            self._mainView.restoreState(qtx.QByteArray(state))
        geom = self._settings.get('mainGeometry')
        if geom:
            self._mainView.restoreGeometry(qtx.QByteArray(geom))

    def _onClosing(self):
        self._settings['mainState'] = self._mainView.saveState().data()
        self._settings['mainGeometry'] = self._mainView.saveGeometry().data()
        self._settings.sync()


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        queue, temp, res, rev = [root], [], [], True
        while queue:
            r = []
            for node in queue:
                r.append(node.val)
                if node.left:
                    temp.append(node.left)
                if node.right:
                    temp.append(node.right)

            res.append(r if rev else r[::-1])
            rev = not rev
            queue = temp
            temp = []
        return res

103. Binary Tree Zigzag Level Order Traversal.py


# Importando bibliotecas importantes da FastAPI

from email.policy import default
from typing import Union
from fastapi import FastAPI, Body, HTTPException, Path, Form
from pydantic import BaseModel,Field
from fastapi.responses import HTMLResponse
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import (
    http_exception_handler,
    request_validation_exception_handler,
)
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
from fastapi.encoders import jsonable_encoder

app = FastAPI()

mock_database = [{'id' : 1, 'name' : "banana", 'qtd' : 4},
                 {'id': 2, 'name' : "pêra", 'qtd' : 7},
                 {'id': 3, 'name' : "manga", 'qtd' : 1}]

# --------------------------------------- Declarando a classe do produto -------------------------------------------------------
class ProductUpdate(BaseModel):
    name: str = Field(default = "Placeholder", title="O nome do produto", max_length=300, example="Maçã")
    qtd : int = Field(default = 0,  title = "A quantidade do produto", ge=0, description="A quantidade não pode ser negativa", example=4)

class ProductBase(ProductUpdate):
    id : int = Field(title = "Id do produto", description = "Identificador do produto", ge = 1)
    # name: str = Field(default = "Placeholder", title="O nome do produto", max_length=300, example="Maçã")
    # qtd : int = Field(default = 0,  title = "A quantidade do produto", ge=0, description="A quantidade não pode ser negativa", example=4)

# ----------------- Declarando função importante para mostrar erros em caso de dado não encontrado -----------------------------
def product_not_in_db(product_id):
    if product_id not in [product['id'] for product in mock_database]:
        raise HTTPException(status_code=404, detail="Produto não encontrado!")

#  -----------------------------------  Handlers que enviam erros --------------------------------------------------------------
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
    return await http_exception_handler(request, exc)

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return await request_validation_exception_handler(request, exc)

# --------------------------------------- Implementando o CRUD ------------------------------------------------------------------

@app.get("/", tags=["home page"])
async def main():
    """
    Apenas uma home page com gosto de macarrão
    """
    content = """

Buon giorno mondo!

    """
    return HTMLResponse(content=content)

@app.get("/products/{product_id}", status_code=200, response_model = ProductBase, tags=["product"])
async def read_item(product_id: int = Path(title="O id do produto que você quer consultar", ge=0)):
    """
    Procura o produto baseado em seu id de identificação e retorna desse forma:

    {"name":"manga",

    "price_unit":3.5,

    "qtd":1,

    "is_available":false}

    """
    product_not_in_db(product_id)
    for product in mock_database:
        if product['id'] == product_id:
            produto = product

    return produto

@app.get("/products/", status_code=200, response_model = list[ProductBase], tags=["product"])
async def read_item():
    """
    Lista todos os produtos e os retorna dessa forma:

    {"name":"manga",

    "qtd":1}
    """
    return mock_database

@app.post("/products/", status_code=201, response_model=ProductBase, tags=["product"])
async def create_item(*, product: ProductBase = Body(
        examples = {
            "normal": {
                "summary": "Um exemplo normal de sucesso",
                "description": "Um exemplo normal de produto que funciona corretamente",
                "value": {
                    "id": 1,
                    "name": "banana",
                    "qtd": 4,
                }
            },
            "convertido": {
                "summary": "Um exemplo com conversão de dados",
                "description": "A FastAPI converte string de quantidade para números automaticamente e vice-versa",
                "value": {
                    "id": "1",
                    "name" : "banana",
                    "qtd" : "4"
                }
            },
            "incorreto" : {
                "summary" : "Um exemplo de dado incorreto",
                "description" : "Nessa situação, quando a tipagem é errada um erro é retornado",
                "value":{
                    "id" : "um",
                    "name" : "banana",
                    "qtd" : "quatro"
                }
            },

        })):
    """
    Crie um produto com as seguintes informações abaixo:

    - **id**: id de cada produto
    - **name**: nome de cada produto
    - **qtd**: quantidade do produto no inventário
    """
    product = product.dict()
    mock_database.append(product)
    return product

@app.put("/products/{product_id}", tags=["product"])
async def overwrite_item(
    product_id: int = Path(title="O id do produto que você quer editar", ge=0),
    product: ProductUpdate = Body(
        examples = {
            "normal": {
                "summary": "Um exemplo normal de sucesso",
                "description": "Um exemplo normal de produto que funciona corretamente",
                "value": {
                    "name": "banana",
                    "qtd": 4,
                }
            },
            "convertido": {
                "summary": "Um exemplo com conversão de dados",
                "description": "A FastAPI converte string de quantidade para números automaticamente e vice-versa",
                "value": {
                    "name" : "banana",
                    "qtd" : "4"
                }
            },
            "incorreto" : {
                "summary" : "Um exemplo de dado incorreto",
                "description" : "Nessa situação, quando a tipagem é errada um erro é retornado",
                "value":{
                    "name" : "banana",
                    "qtd" : "quatro"
                }
            },

        })):

    """
    Atualize totalmente as informações de um produto com as seguintes informações abaixo:

    - **id**: id de cada produto (mas você não pode atualizá-lo. O id a ser considerado é o que
    escreve no campo product_id separadamente)
    - **name**: nome de cada produto
    - **qtd**: quantidade do produto no inventário
    """
    product_not_in_db(product_id)
    for produto in mock_database:
        if produto['id'] == product_id:
            produto['name'] = product.name
            produto['qtd'] = product.qtd

    return {'product_id': product_id, 'product': product}

@app.patch("/products/{product_id}", response_model=ProductBase, tags=["product"])
async def update_item(
    product_id: int,
    product: ProductUpdate = Body(examples = {
        "nome": {
            "summary" : "Um exemplo modificando apenas o nome",
            "value" :{
                "name" : "maçã"
            }
        },
        "quantidade" : {
            "summary" : "Um exemplo modificando apenas a quantidade",
            "value" : {
                "qtd" : 0
            }
        }
        })):
    """
    Atualize parcialmente as informações de um produto com as seguintes informações abaixo:

    - **id**: id de cada produto
    - **name**: nome de cada produto
    - **qtd**: quantidade do produto no inventário
    """

    for produto in mock_database:
        if produto['id'] == product_id:
            produto_escolhido = produto

    stored_product_data = produto_escolhido
    stored_product_model = ProductUpdate(**stored_product_data)
    update_data = product.dict(exclude_unset=True)
    update_data['id'] = product_id
    updated_product = stored_product_model.copy(update=update_data)
    temp_product =  ProductBase(id=product_id, name= updated_product.name, qtd = updated_product.qtd)

    for i in range(len(mock_database)):
        if mock_database[i]['id'] == product_id:
            mock_database[i] = temp_product.dict()

    return temp_product

@app.delete("/products/{product_id}", tags=["product"])
async def delete_item(product_id: int = Path(title="O id do produto que você quer deletar", ge=0)):
    """
    Apaga um produto da base de dados.
    """
    product_not_in_db(product_id)

    for produto in mock_database:
        if produto['id'] == product_id:
            mock_database.remove(produto)

    return {'Produto removido com sucesso. Antigo id': product_id}


import sqlite3
import csv
import os.path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
db_path = os.path.join(BASE_DIR, "db.sqlite3")
conn = sqlite3.connect(db_path)
c = conn.cursor()
c.execute("SELECT rowid, * FROM inventory")
columns = [column[0] for column in c.description]
results = []
for row in c.fetchall():
    results.append(dict(zip(columns, row)))
with open("output.csv", "w", newline='') as new_file:
    fieldnames = columns
    writer = csv.DictWriter(new_file,fieldnames=fieldnames)
    writer.writeheader()
    for line in results:
        writer.writerow(line)
conn.close()


"""
demo14_vc.py　视频捕捉
"""
import cv2 as cv

# 报错，因为没有摄像头
# 获取视频捕捉设备
vc = cv.VideoCapture(0)
while True:
    # 读取一帧
    frame = vc.read()[1]
    cv.imshow('VideoCapture', frame)
    # 每个33毫秒，会截图，并且即使不摁键盘方法也会自动退出，
    # 退出键esc的值27，当cv.waitKey()的返回值为27时退出white循环
    if cv.waitKey(33) == 27:
        break
# 释放视频捕捉设备
vc.release()
# 销毁cv的所有窗口
cv.destroyAllWindows()


import time
import requests
import urllib.parse
import datetime
import xlwt
import write_excel

def decrypt(t: str, e: str) -> str:
    n, i, a, result = list(t), list(e), {}, []
    ln = int(len(n)/2)
    start, end = n[ln:], n[:ln]
    a = dict(zip(end, start))
    return ''.join([a[j] for j in e])

COOKIES = 'BAIDUID=8759768F974CE3E6C2884260097331A4:FG=1; PSTM=1574683224; H_PS_PSSID=1445_21116_29567_29220; BIDUPSID=43233656E2011B10D268D7B02D7A956A; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=2; Hm_lvt_d101ea4d2a5c67dab98251f0b5de24dc=1574939615; BDUSS=hWWDJ0Z01VOWZINGdPaWRkTUotYmR4WlRhcEhJNTVDQzA3SUpDNzBSWHRPQWRlRVFBQUFBJCQAAAAAAAAAAAEAAAA3VXuxu6rPxNPQxMzGpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO2r313tq99daE; CHKFORREG=f47c79690c889b9fe3bb335ced026f76; bdindexid=j4g6p93elqe6o7phocmmfn53o2; Hm_lpvt_d101ea4d2a5c67dab98251f0b5de24dc=1574940479'
headers = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Cookie': COOKIES,
    'DNT': '1',
    'Host': 'zhishu.baidu.com',
    'Pragma': 'no-cache',
    'Proxy-Connection': 'keep-alive',
    'Referer': 'zhishu.baidu.com',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
}
session = requests.Session()
session.headers.update(headers)

def get_ptbk(uniqid: str) -> str:
    with session.get(
        url=f"http://index.baidu.com/Interface/ptbk?uniqid={uniqid}"
    ) as response:
        ptbk = response.json()["data"]
        return ptbk

def get_index_data(keyword: str, start: str, end: str) -> str:
    keyword = urllib.parse.quote(keyword)
    with session.get(
        url=f"http://index.baidu.com/api/SearchApi/index?area=0&word=[[%7B%22name%22:%22{keyword}%22,%22wordType%22:1%7D]]&startDate={start}&endDate={end}"
    ) as response:
        data = response.json()["data"]
        all_data = data["userIndexes"][0]["all"]["data"]

        uniqid = data["uniqid"]
        ptbk = get_ptbk(uniqid)
        result = decrypt(ptbk, all_data).split(',')
        return result

def GetDesktopPath():
    import os
    return os.path.join(os.path.expanduser("~"), 'Desktop')

# 获取从开始日期 start 到截止日期 end 中的所有日期
def get_date_list(start:str, end: str):
    # 也可以是%Y%m%d
    datestart = datetime.datetime.strptime(start,'%Y-%m-%d')
    dateend = datetime.datetime.strptime(end,'%Y-%m-%d')

    data_list = []
    while datestart<dateend:
        datestart+=datetime.timedelta(days=1)
        data_list.append(datestart.strftime('%Y-%m-%d'))
    return data_list

start = "2020-7-01"
end = "2020-9-30"

d_name = []
d_name.append("名称")
d_name += get_date_list(start, end)

myExcel = write_excel.Excel()

myExcel.write_title(d_name)

line = 1
with open('./百度指数修改名单.txt',"r",encoding='UTF-8') as lines:  # 一次性读入txt文件，并把内容放在变量lines中
    array = lines.readlines()  # 返回的是一个列表，该列表每一个元素是txt文件的每一行
    for name in array:
        temp = []
        arr_name = name.split(" ")
        if len(arr_name) == 2:
            name = arr_name[1].replace("\n","")
        else:
            name = arr_name[0].replace("\n","")
        try:
            data = get_index_data(
                keyword=name,
                start=start,
                end=end
            )
            temp.append(name)
            temp += data
            time.sleep(1)

            myExcel.write_content_line(temp)

            break
        except Exception as e:
            print(name)
            continue
myExcel.save_excel("123")


import os
from PIL import Image

if __name__ == '__main__':
    # 获取目录下文件名
    file_full_path = os.path.dirname(os.path.abspath(__file__))
    files = os.listdir(file_full_path)
    # 图标大小
    size = (256, 256)

    for inName in files:
        # 分离文件名与扩展名
        tmp = os.path.splitext(inName)
        # 因为python文件跟图片在同目录，所以需要判断一下
        if tmp[1] == '.png':
            outName = tmp[0] + '.ico'
            # 打开图片并设置大小
            im = Image.open(os.path.join(file_full_path, inName)).resize(size)
            try:
                # 图标文件保存
                im.save(os.path.join(file_full_path, outName))
                print('{} --> {}'.format(inName, outName))
            except IOError:
                print('connot convert :', inName)


from fcm_django.models import FCMDevice
from services.firebase.firebase_cloud_messaging.templates import notification

def send_notification(user_ids, title, template, data, *args):
    message = getattr(notification, template)(args)
    default_data = {
        "click_action": "FLUTTER_NOTIFICATION_CLICK",
        "android": {
            "notification": {
                "channel_id": "high_importance_channel"
            }
        }
    }
    if data:
        default_data.update(data)
    try:
        devices = FCMDevice.objects.filter(user__in=user_ids)
        result = devices.send_message(
            title=title,
            body=message,
            data=default_data,
            sound=True
        )
        return result
    except Exception as e:
        print(e)


# Programa Python para embaralhar um baralho de cartas

# importando módulos
import itertools, random

# montando um baralho de cartas
deck = list(itertools.product(range(1,14),['Spade','Heart','Diamond','Club']))

# shuffle the cards
random.shuffle(deck)

# draw five cards
print("Você tem:")
for i in range(5):
   print(deck[i][0], " de ", deck[i][1])