import pandas as pd
import numpy as np

from konlpy.tag import Okt
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.utils import to_categorical
import pickle
from tensorflow.keras.models import load_model

pd.set_option('display.unicode.east_asian_width', True)
# data load
df = pd.read_csv('./crawling/movie_new.csv')
X = df['summary']
Y = df['genre']

# target labeling
with open('./models/movie_encoder_2000.pickle', 'rb') as f:
    encoder = pickle.load(f)
labeled_Y = encoder.transform(Y)
label = encoder.classes_
onehot_Y = to_categorical(labeled_Y)
print(labeled_Y[:5])
print(label)
print(onehot_Y)

# 형태소 분리, 한 글자/불용어 제거
okt = Okt()
stopwords = pd.read_csv('../../PRJ_Movie_for_you-1/crawling_data/stopwords.csv', index_col=0)
for i in range(len(X)):
    X[i] = okt.morphs(X[i], stem=True)
    words = []
    for word in X[i]:
        if len(word) > 1:
            if word not in list(stopwords['stopword']):
                words.append(word)
    X[i] = ' '.join(words)
print(X[:5])

# titles tokenizing
with open('./models/movie_token_500.pickle', 'rb') as f:
    token = pickle.load(f)
tokened_X = token.texts_to_sequences(X)
print(tokened_X[:5])

for i in range(len(tokened_X)):
    if 500 < len(tokened_X[i]):
        tokened_X[i] = tokened_X[i][:500]

# padding
X_pad = pad_sequences(tokened_X, 500)
print(X_pad[:5])

model = load_model('./models/movie_genre_classification_model.h5')
pred = model.predict(X_pad)
sample = 6
print('pred is ', pred[sample])
print('actual is ', onehot_Y[sample])
print('Target :', label[np.argmax(onehot_Y[sample])])
pred = pred[sample].tolist()
acc = 0
ans = []
while acc < 0.99:
    ans.append(label[pred.index(max(pred))])
    acc = acc + max(pred)
    pred[pred.index(max(pred))] = 0
print('Prediction after learning is ', ans)


#!/usr/bin/env python
from __future__ import print_function
# Programmer : zhuxp
# Date:
# Last-modified: 09-09-2014, 13:48:35 EDT
import os,sys,argparse
from bam2x import TableIO,Tools
from bam2x import IO
import sqlite3
import string
from bam2x.DBI.Templates import schema_templates
from bam2x.DBI.Templates import insert_templates

def set_parser(p):
    ''' This Function Parse the Argument '''
    p.add_argument("-D","--database",dest="db",type=str,help="database file name",default="guess")
    p.add_argument("-I","--input_format",dest="input_format",choices=schema_templates.keys(),type=str,help="input format , default: %(default)s",default="bed12")
    p.add_argument("-t","--table_name",dest="table_name",type=str,help="table name, default: %(default)s",default="test")
def help():
    return "read bed12 file into a sqlite3 db. if sqlite3 db is not exists , it will generate one"

def run(args):
    schema_template=schema_templates[args.input_format]
    SQL_template=insert_templates[args.input_format]
    db_filename=args.db
    out=IO.fopen(args.output,"w")
    if db_filename=="guess":
        db_filename=args.input.strip(".gz")+".db"
    db_is_new = not os.path.exists(db_filename)
    print("Database file : %s"%db_filename,file=out)
    with sqlite3.connect(db_filename) as conn:
        cursor=conn.cursor()
        if db_is_new:
            print ('Creating table %s if not exists\n________________________________'%args.table_name,file=out)
            S=schema_template.substitute({"table_name":args.table_name})
            print (S,file=out)
            print ("_______________________________",file=out)
            cursor.execute(S)
        else:
            S=schema_template.substitute({"table_name":args.table_name})
            cursor.execute(S)

        fin=IO.fopen(args.input,"r")
        S1=SQL_template.substitute({"table_name":args.table_name})
        print(S1,file=out)
        s=TableIO.parse(args.input,"simple")
        cursor.executemany(S1,s)
        conn.commit()
        print("loaded",file=out)

if __name__=="__main__":
    from bam2x.IO import parser_factory
    p=parser_factory(description=help())
    set_parser(p)
    if len(sys.argv)==1:
        print(p.print_help())
        exit(0)
    run(p.parse_args())


from time import time
t = time()

def CollatzSequence(x):
    SequenceLength=0
    while x!=1:
        if x%2==0:
            n=x/2
            SequenceLength+=1
        else:
            n=3*x+1
            SequenceLength+=1
        x=n
    return(SequenceLength)

Largest=0
Num=0
for x in range(1,1000000):
    SequenceLength=CollatzSequence(x)
    if SequenceLength>Largest:
        Largest=SequenceLength
        num=x
        print(Largest)
        print(num)

print("Largest number is",num)
tt = time()-t
print(tt)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Last-Updated : <2014/01/04 01:16:29 by samui>
import cgi
import webapp2
import jinja2
import os
import logging

from google.appengine.ext import db
#from model import Comment,Article

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

class Comment(db.Model):
    text = db.StringProperty(required=True)
    created_at = db.DateTimeProperty(auto_now_add=True)

class Article(db.Model):
    title = db.StringProperty(required=True)
    text = db.StringProperty(required=True)
    comment = db.ReferenceProperty(reference_class=Comment)
    created_at = db.DateTimeProperty(auto_now_add=True)

class BaseTemplate:
    @classmethod
    def render(self, template, params):
        baseTemplate = JINJA_ENVIRONMENT.get_template('template/common/base.html')
        headTempate = JINJA_ENVIRONMENT.get_template('template/common/_header.html')
        footTemplate = JINJA_ENVIRONMENT.get_template('template/common/_footer.html')
        params.update({
            'common_base': baseTemplate.render({'title':'SimpleTitle'}),
            'common_head':headTempate.render({'uri_for':webapp2.uri_for}),
            'common_footer': footTemplate.render({'uri_for':webapp2.uri_for}),
        })
        bodyTemplate = JINJA_ENVIRONMENT.get_template(template)
        return bodyTemplate.render(params)

class BaseHandler(webapp2.RequestHandler):
    def auth(self):
        pass

class HelloWebApp2(BaseHandler):
    def get(self):
        """
        p1 = Article(title="SampleTitle0",text="SampleTEXT")
        p1.put()
        """
        #articles = db.GqlQuery("SELECT * FROM Article ORDER BY date DESC LIMIT 10")
        articles = db.GqlQuery("SELECT * FROM Article ORDER BY created_at DESC")
        for blog in articles:
            self.response.write(blog.title+"
")
            self.response.write(blog.created_at)
            self.response.write("
")

        template_values = {
            'test':'HelloWorld,WebApp2!',
            #'debug': self.uri_for('home'),
            'debug':'t',
        }
        view = BaseTemplate.render('template/index.html',template_values)
        self.response.write(view)


import subprocess
import os
import sys

# TO find the correct Catagory, check REST API to see what main header this API lives under

CATAGORYS = {
    'application': [],
    'cloud': [],
    'cluster': [
        "cluster_data_source.md",
        "cluster_schedule_data_source.md",
        "cluster_schedule_resource.md",
        "cluster_licensing_license_resource.md"],
    'nas': [
        "protocols_cifs_local_group_data_source.md",
        "protocols_cifs_local_user_data_source.md",
        "protocols_nfs_service_data_source.md",
        "protocols_nfs_service_resource.md",
        "protocols_nfs_export_policy_resource.md",
        "protocols_nfs_export_policy_rule_data_source.md",
        "protocols_nfs_export_policy_rule_resource.md"],
    'name-services': [
        "name_services_dns_data_source.md",
        "name_services_dns_resource.md"
    ],

    'ndmp': [],
    'networking': [
        "networking_ip_interfaces_data_source.md",
        "networking_ip_interface_data_source.md",
        "networking_ip_interface_resource.md",
        "networking_ip_route_data_source.md",
        "networking_ip_route_resource.md"],
    'nvme': [],
    'object-store': [],
    'san': [],
    'security': [],
    'snaplock': [],
    'snapmirror': ["snapmirror_policy_resource.md"],
    'storage': [
        "storage_aggregate_resource.md",
        "storage_snapshot_policy_resource.md",
        "storage_volume_snapshot_data_source.md",
        "storage_volume_resource.md",
        "storage_volume_data_source.md",
        "storage_volume_snapshot_resource.md"],
    'support': [],
    'svm': ["svm_resource.md"],
}

def main():
    print("===== Generating docs =====")
    generate_doc()
    remove_example()
    print("===== Adding Catagories =====")
    add_catagories()
    print("===== Validate =====")
    validate()
    print("===== Errors =====")
    issue = warn_missing_catagory(["docs/data-sources/", "docs/resources/"])
    if issue:
        sys.exit(1)

def generate_doc():
    cmd_str = "go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate"
    subprocess.run(cmd_str, shell=True)

def validate():
    cmd_str = "go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs validate"
    subprocess.run(cmd_str, shell=True)

def remove_example():
    files = ['docs/data-sources/example.md', 'docs/resources/example.md']
    for file_path in files:
        if os.path.exists(file_path):
            os.remove(file_path)

def add_catagories():
    for catagory in CATAGORYS:
        for page in CATAGORYS[catagory]:
            if 'data_source' in page:
                update_datasource(page, catagory)
            if 'resource' in page:
                update_resouces(page, catagory)

def update_datasource(page, catagory):
    path = "docs/data-sources/" + page
    update_md_file(path, catagory)

def update_resouces(page, catagory):
    path = "docs/resources/" + page
    update_md_file(path, catagory)

def update_md_file(path, catagory):
    print("Updating %s" % path)
    try:
        with open(path) as f:
            lines = f.readlines()
        for i, line in enumerate(lines):
            if line.startswith('subcategory: "'):
                split_line = line.split('subcategory: "')
                new_line = split_line[0] + 'subcategory: "' + catagory + split_line[1]
                lines[i] = new_line
                break
        with open(path, 'w') as f:
            f.writelines(lines)
    except:
        return

def warn_missing_catagory(directory_paths):
    issue = False
    for directory_path in directory_paths:
        full_path = os.path.join(os.getcwd(), directory_path)
        for filename in os.listdir(full_path):
            if os.path.isfile(os.path.join(full_path, filename)):
                with open(os.path.join(full_path, filename), 'r') as f:
                    file_content = f.read()
                    if 'subcategory: ""' in file_content:
                        print('%s is missing a catagory' % filename)
                        issue = True
    return issue

if __name__ == "__main__":
    main()


# Examples of Python Keywords
# False
# True
# None
# and
# or
# not
# if
# else
# elif
# while
# for
# in
# break
# continue
# def
# return
# class
# try
# except
# finally
# import
# from
# as
# with
# raise
# assert
# lambda

# False, True, and None:
# False and True are Boolean values representing the logical values of false and true, respectively.
# # None represents the absence of a value and is often used to indicate the absence of a return value in functions.

is_active = False
is_valid = True
result = None

# and, or, and not:
# and, or, and not are logical operators used for combining and negating conditions.
a = True
b = False

if a and b:
    print("Both a and b are true")

if a or b:
    print("Either a or b is true")

if not b:
    print("b is false")

# if, else, and elif:
# if, else, and elif are used for conditional statements and control the flow of the program based on specific conditions.
num = 10

if num > 0:
    print("Number is positive")
elif num < 0:
    print("Number is negative")
else:
    print("Number is zero")

# while and for:
# while and for are used for loop statements to iterate over a sequence of values until a certain condition is met.
count = 0
while count < 5:
    print("Count:", count)
    count += 1

numbers = [1, 2, 3]
for num in numbers:
    print("Using for", num)

# break and continue:
# break is used to exit a loop prematurely, while continue is used to skip the remaining code in the current iteration and move to the next one.
for num in range(5):
    if num == 3:
        break
    print("Using break", num)

for num in range(5):
    if num == 3:
        continue
    print("Using continue", num)

# def and return:
# def is used to define user-defined functions.
# return is used to specify the value that a function should return.
def add_numbers(a, b):
    return a + b

result = add_numbers(2, 3)
print(result)

# class:
# class is used to define a class, which is a blueprint for creating objects.
class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

circle = Circle(5)
print("Area is: ", circle.area())

# try, except, and finally:
# try, except, and finally are used for exception handling to catch and handle potential errors in code execution.
try:
    num = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero")
finally:
    print("Execution complete")

# import and from:
# import and from are used to include modules or specific functions from modules into the current program.
import math
print(math.sqrt(25))

from datetime import datetime
current_time = datetime.now()
print(current_time)

# as:
# as is used for aliasing, allowing you to give an alternate name to a module or object.
import numpy as np
array = np.array([1, 2, 3])
total = np.sum(array)
print(total)

# with:
# with is used in the context manager construct to ensure proper acquisition and release of resources.
with open("file.txt", "r") as file:
    content = file.read()
    print(content)

# assert:
# assert is used for debugging purposes to check if a condition is true. If it's false, an AssertionError is raised.
num = 10

assert num > 0, "Number should be positive"
print("Assertion passed")

# lambda:
# lambda is used to define anonymous functions, also known as lambda functions.
multiply = lambda x, y: x * y
result = multiply(3, 4)
print(result)

# raise:
# raise is used to raise an exception explicitly.
age = -5
if age < 0:
    raise ValueError("Age cannot be negative")


from transformers import AutoModelForCausalLM, AutoTokenizer

checkpoint = "bigscience/bloomz-7b1"  # "bigscience/bloom"

tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(
    checkpoint, torch_dtype="auto", device_map="auto", load_in_8bit=True
)

inputs = tokenizer.encode(
    "Question: What is Prompt engineering?\n Answer: Let's think step by step.",
    return_tensors="pt",
).to("cuda")
outputs = model.generate(inputs, max_new_tokens=100, min_new_tokens=30)

for out in outputs:
    print(tokenizer.decode(out))


import matplotlib.pyplot as plt

from EixampleEnergy.tool import load_shapefile
from EixampleEnergy.drawers.drawer import Drawer
from EixampleEnergy.drawers.drawer_map import DrawerMap
from EixampleEnergy.drawers.drawer_stacked_bar import DrawerStackedBar

def clean_data(df):
    df = df[df['build_date'] > 1900]
    df['build_date_10'] = df['build_date'].apply(lambda date: date - (date % 10))
    return df

def main():
    df = load_shapefile('../data/BCN_Private_communities/BCN_Private_communities_4326.shp')
    df = clean_data(df)
    cmap = plt.cm.RdYlGn.reversed()
    drawer_map = DrawerMap(full_df=df,
                           color_col="E_certific",
                           xlim=(2.05, 2.23),
                           # ylim=(41.313, 41.47),
                           bg_img='../out/background_greyscale.tif',
                           cmap=cmap)
    drawer_stacked = DrawerStackedBar(full_df=df,
                                      xcol='build_date_10',
                                      group_col='E_certific',
                                      xlabel="Build year",
                                      ylabel="Energy Certificate",
                                      cmap=cmap)

    drawer_map.download_bg('../out/bg.tif')
    exit()

    drawer = Drawer(full_df=df,
                    drawers=[drawer_map],
                    # drawers=[drawer_map, drawer_stacked],
                    time_col='build_date_10',
                    dpi=600,
                    # dpi=72,
                    save_dir_path='../out/building_cert2/map/')

    # drawer.draw_anime(save_anim_imgs=True, show=False)
    drawer.draw_static()

if __name__ == '__main__':
    main()


import random

from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.views import View

class FormView(View):
    def get(self, request):
        return HttpResponse('Jesteśmy w metodzie GET')
    def post(selfself, request):
        return HttpResponse('Jesteśmy w metodzie POST')

class PizzaView(View):
    def get(self, request):
        return render(request, 'firstApp/pizza.html')
    def post(selfself, request):
        products = request.POST.getlist('skladnik', '')
        return HttpResponse(" ".join(products))
class CarView(View):
    def get(self, request):
        return render(request, 'firstApp/car.html')
    def post(selfself, request):
        car = request.POST.get('car', '')
        return HttpResponse(car)

class LoginView(View):
    def get(self, request):
        return render(request, 'firstApp/login.html')
    def post(selfself, request):
        login = request.POST.get('login', '')
        haslo = request.POST.get('haslo', '')
        if login == 'Admin' and haslo == 'Tajne123':
            return HttpResponse("Witaj admin!", 'brak parametru')
        else:
            return HttpResponse("Zły login lub hasło!", 'brak parametru')

def hello(request):
    return HttpResponse('Hello')
def adding(req):
    l1 = float(req.GET.get('l1', 0))
    l2 = float(req.GET.get('l2', 0))
    w = l1+l2
    return HttpResponse("Wynik: "+str(w))

def multiply(req):
    l = req.GET.get('l',0)
    wynik = "
"
    for i in range(1, int(l)+1):
        wynik += "
"
        for j in range(1,int(l)+1):
            wynik+=""
            wynik+=str(i*j)
            wynik+="	"
            j+=1
        wynik += "
"
        i+=1
    wynik += "
"
    return HttpResponse(wynik)

def brothers(req):
    names=[]
    wynik = ""
    names = req.GET.getlist('names','0')
    for i in names:
        wynik+="
"
        wynik+=i
        wynik+="
"
    return HttpResponse(wynik)

def fibonacci(req):
    l = int(req.GET.get('l', 0))
    w = [1,1]
    wynik = "
"
    wynik+="

1

1
"
    for i in range(2,l):
        temp = w[i-2]+w[i-1]
        wynik+="
"+str(temp)+"
"
        w.append(temp)
        i+=1
    wynik+="
"
    return HttpResponse(wynik)

def genFibo(n):
    a = 0
    b = 1
    for i in range(n):
        a , b = b , a + b
        yield a

def showSimpleFibo(req):
    l = int(req.GET.get('l', 0))
    wynik=""
    for i in genFibo(l):
        wynik+=str(i)
    return HttpResponse(wynik)

number = random.randint(1,100)
def game(req):
    global number
    message=""
    guess=-1
    try:
        guess = int(req.GET.get('guess', 0))
        if guess==0:
            odp = "<form><input name='guess' placeholder='podaj liczbę(1-100)'></form>"
        else:
            if(guess>number): message = "Twoja liczba jest za duża"
            elif(guess<number): message = "Twoja liczba jest za mała"
            else:
                message="zgadłeś/aś"
                number = random.randint(1, 100)
            odp = "<form><input name='guess' placeholder='podaj liczbę(1-100)'></form>" + message
        return HttpResponse(odp)
    except:
        pass

def helloPath(req,name):
    return HttpResponse(name)

def article(req, id):
    wynik=""
    if(id<4):
        wynik="Id to "+str(id)
    else:
        wynik= "brak artykułu o podanym id"
    return HttpResponse(wynik)

def greetings(req,name,repeat):
    wynik="Witaj "
    for i in range(0,repeat):
        wynik+=name
        wynik+=" "
        i+=1
    return HttpResponse(wynik)

def calc(req, nA, o, nB):
    try:
        if o == 'plus':
            return HttpResponse(str(nA+nB))
        elif o == 'minus':
            return HttpResponse(str(nA - nB))
        elif o == 'multiply':
            return HttpResponse(str(nA * nB))
        elif o == 'divide':
            if nB == 0:
                return HttpResponse('Nieprawidłowe dane')
            return HttpResponse(str(nA / nB))
    except:
        return HttpResponse('Nieprawidłowe dane')

def randomGenerator(req,min,max,throw=1):
    wynik=0
    while(throw):
        wynik+=random.randint(min, max)
        throw-=1
    return HttpResponse(str(wynik))

def index(request):
    return render(request,
                  'firstApp/index.html',
                  context={
          'msg':'wiadomość',
          'names':['Maja','Ala','Maria','Ewa'],
      })

def form(request):
    if request.method=='GET':
        return render(request, 'firstApp/form.html')
    if request.method == 'POST':
        return HttpResponse(request.POST.get("message",'brak parametru'))

def fizzBuzz(request):
    wynik=[]
    n = int(request.GET.get('n', 0))
    for i in range(1,n):
        if(i%3==0):
            if (i % 5 == 0):
                wynik.append("Fizz Buzz")
            else:
                wynik.append("Fizz")
        elif(i%5==0):
            wynik.append("Buzz")
        else:
            wynik.append(i)
    return render(request, 'firstApp/fizz_buzz.html',
                  context={'data':wynik})

def multiplyT(request, n):
    return render(request,'firstApp/multiply.html',context={'data':range(1,n+1)})

def rpg_game(request):
    player_hp = random.randint(100, 200)
    enemy_hp = random.randint(100, 500)

    stats=[]
    winner=[]
    player_hp_info = [player_hp]
    enemy_hp_info = [enemy_hp]

    for i in range(1,100):
        if enemy_hp<1 or player_hp<1:
            if enemy_hp<1: winner.append('player')
            elif player_hp<1: winner.append('enemy')
            break
        player_attack = random.randint(1, 100)
        enemy_hp -= player_attack

        enemy_attack = random.randint(10, 20)
        player_hp -= enemy_attack

        stats.append("Runda: "+str(i))
        stats.append("enemy lost: "+str(player_attack))
        stats.append("enemy life: "+str(enemy_hp))
        stats.append("player lost: " + str(enemy_attack))
        stats.append("player life: " + str(player_hp))

    return render(request, 'firstApp/rpg_game.html',
                  context={
                      'stats': stats,
                      'winner':winner,
                  })
def main(request):
    return render(request, 'firstApp/main.html')
def login_user(request, message="ok"):
    login = request.POST.get('login', '')
    haslo = request.POST.get('haslo', '')
    if request.method=='GET':
        return render(request, 'firstApp/login.html')
    if request.method == 'POST':
        if login=='Admin' and haslo=='Tajne123':
            return HttpResponse("Witaj admin!", 'brak parametru')
        else: return redirect('/login/?message="zły login lub hasło"')

products = {}

def add_product(request):
    product = request.POST.get('product', '')
    price = request.POST.get('price', '')
    if request.method=='GET':
        return render(request, 'firstApp/add_product_form.html')
    if request.method == 'POST':
        products[product] = price
        return redirect('/product/show')

def show_products(request):
    return render(request, 'firstApp/product_show.html',
                  context={'products':products})


from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

import debug_toolbar

from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="Movie Database API",
      default_version='v1',
      description="A sample Movie Database API",
      terms_of_service="http://localhost:8000",
      contact=openapi.Contact(email="vipin6673@gmail.com"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include('api.urls')),

    # for openapi
    path('api-auth/',include('rest_framework.urls')),
    path('', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

# for serving static files
urlpatterns+=static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns+=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()

if settings.DEBUG:
   urlpatterns+=[
      path('__debug__/', include(debug_toolbar.urls)),
   ]


from queue_client import (
    QueueConfig,
    AbstractQueueInitializer,
    AbstractQueueConsumer,
    AbstractQueueProducer,
)
from kafka_client import (
    KafkaQueueInitializer,
    KafkaQueueConsumer,
    KafkaQueueProducer,
)

import sys
import os

sys.path.append(os.path.join(os.path.dirname(__file__), "..", "log"))
from custom_log import AbstractLogger

class QueueInitializerCreator:
    @staticmethod
    def create_initializer(
        initializer_type: str, config: QueueConfig, logger: AbstractLogger
    ) -> AbstractQueueInitializer:
        if initializer_type == "kafka":
            return KafkaQueueInitializer(config=config, logger=logger)
        else:
            raise NotImplementedError(
                "{} type is not implemented!".format(initializer_type)
            )

class QueueProducerCreator:
    @staticmethod
    def create_producer(
        producer_type: str, config: QueueConfig, logger: AbstractLogger
    ) -> AbstractQueueProducer:
        if producer_type == "kafka":
            return KafkaQueueProducer(config=config, logger=logger)
        else:
            raise NotImplementedError(
                "{} type is not implemented!".format(producer_type)
            )

class QueueConsumerCreator:
    @staticmethod
    def create_consumer(
        consumer_type: str, config: QueueConfig, logger: AbstractLogger
    ) -> AbstractQueueConsumer:
        if consumer_type == "kafka":
            return KafkaQueueConsumer(config=config, logger=logger)
        else:
            raise NotImplementedError(
                "{} type is not implemented!".format(consumer_type)
            )


import functools, os, sys
import flask
from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from flask import current_app

from cislovky.db import get_db

bp = Blueprint('home', __name__, url_prefix='/')

@bp.route('/', methods=('GET',))
def home():
    instance_path = current_app.instance_path
    cfg = current_app.config
    dirs = os.listdir( current_app.instance_path )
    pyversion = sys.version
    flaskversion = flask.__version__
    return render_template('home/home.html', in_path=instance_path, cfg=cfg, dirs=dirs, pyversion=pyversion, flaskversion=flaskversion)

@bp.route('/all', methods=('GET',))
def all():
    db = get_db()
    cislovky = db.execute(
        "SELECT id, rome, cs, en"
        " FROM cislovky"
        " ORDER BY id ASC"
    ).fetchall()
    return render_template('home/all.html', cislovky=cislovky)

@bp.route('/en', methods=('GET',))
def en():
    db = get_db()
    cislovky = db.execute(
        "SELECT id, en"
        " FROM cislovky"
        " ORDER BY id ASC"
    ).fetchall()
    return render_template('home/en.html', cislovky=cislovky)

@bp.route('/cs', methods=('GET',))
def cs():
    db = get_db()
    cislovky = db.execute(
        "SELECT id, cs"
        " FROM cislovky"
        " ORDER BY id ASC"
    ).fetchall()
    return render_template('home/cs.html', cislovky=cislovky)


from tkinter import *

WIDTH = 400
HEIGHT = 300

root = Tk()
cnv = Canvas(root, width=WIDTH, height=HEIGHT, bg='ivory')
cnv.pack()

ellipse = cnv.create_oval(200,250,350,100)

print(cnv.coords(ellipse))

root.mainloop()

Tkinter/IV - Les canevas/34 - Contour d'un item/ovale.py


'''
A module to build Logistic regression and decision tree classifiers to predict churn
for credit card customers.
Data taken from  https://www.kaggle.com/sakshigoyal7/credit-card-customers/code

Author: Chris Bonham
Date: 7th January 2023
'''
import pickle
from sklearn.utils import resample
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import RocCurveDisplay, classification_report
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

pd.set_option('display.max_columns', 99)

def import_data(pth):
    '''Returns dataframe for the csv found at pth

    input:
        pth: a string containing a path to the csv
    output:
        df: pandas dataframe. Imported development data
    '''
    df = pd.read_csv(pth, index_col=0)
    # df = pd.read_csv(pth, index_col=0, nrows = 5)
    return df

def derive_label(df, response='Churn'):
    '''Derive the target field. NB This assumes a binary classifier

    input:
        df: pandas dataframe. Development data
        response: string of response name [optional argument that could be used
                  for naming variables or index y column]
    output:
        df: pandas dataframe with new target field
    '''
    df[response] = df['Attrition_Flag'].apply(
        lambda val: 0 if val == "Existing Customer" else 1)
    return df

def perform_eda(df):
    '''Perform eda on df and save figures to images folder

    input:
        df: pandas dataframe. Development data
    output:
        None
    '''
    # Get high level stats
    # print("\nDataframe has {0} rows and {1} columns".format(df.shape[0], df.shape[1]))
    # print("\nView 10 random records\n", resample(df, n_samples=10, random_state=1234,
    #                                              replace=False))
    # print("\nProportion of missing values in each column\n", df.isnull().sum() / df.shape[0])

    # Get a list of the numeric and caregorical feature names
    num_feature_names = df.select_dtypes(include='number').columns.tolist()
    num_feature_names.remove('CLIENTNUM')   # Remove the URN from the list
    cat_field_names = df.select_dtypes(
        include=['object', 'category']).columns.tolist()

    # Get distributions of numeric fields
    for feature in num_feature_names:
        sns.displot(df[feature], kde=True)
        plt.title("Distribution of {0}".format(feature))
        plt.xlabel(feature)
        plt.ylabel('Count')
        plt.savefig(r".\images\eda\{0}_distribution.png".format(feature))

    # Get distributions of categorical fields
    for feature in cat_field_names:
        sns.displot(df[feature])
        plt.title("Distribution of {0}".format(feature))
        plt.xlabel(feature)
        plt.ylabel('Count')
        plt.savefig(r".\images\eda\{0}_distribution.png".format(feature))

    # Get correlations of the numeric fields
    plt.figure(figsize=(20, 10))
    sns.heatmap(
        df[num_feature_names].corr(),
        annot=False,
        cmap='Dark2_r',
        linewidths=2)
    plt.title("Numeric feature correlations")
    plt.savefig(r".\images\eda\Numeric_feature_correlations.png")

def encoder_helper(df, cat_recode_lst, response='Churn'):
    '''
    helper function to turn each categorical column into a new column with
    proportion of churn for each category - associated with cell 16 from the notebook

    input:
        df: pandas dataframe
        cat_recode_lst: list of columns that contain categorical features to recode
        response: string of response name [optional argument that could be used for
                  naming variables or index y column]
    output:
        df: pandas dataframe with new columns for
    '''
    for feature in cat_recode_lst:
        recode_map = df.groupby(feature).mean()[response]
        df["{0}_Churn".format(feature)] = df[feature].replace(recode_map)
    return df

def perform_feature_engineering(
        df,
        cat_recode_lst,
        features_lst,
        response='Churn'):
    '''Recode the categorical features and split data into train and test datasets

    input:
        df: pandas dataframe. Development data
        cat_recode_lst: list of columns that contain categorical features to recode
        features_lst: list of columns to include as model features
        response: string of response name [optional argument that could be used for
                  naming variables or index y column]
    output:
        X_train: pandas dataframe. training data features
        X_test: pandas dataframe. testing data features
        y_train: pandas series. training data labels
        y_test: pandas series. testing data labels
    '''
    # Recode the categorical fields
    df = encoder_helper(df, cat_recode_lst)

    # Split into train and test datasets
    y = df[response]
    X = df[features_lst]
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=42)

    return X_train, X_test, y_train, y_test

def classification_report_image(y_train, y_test,
                                y_train_preds_lr, y_train_preds_rf,
                                y_test_preds_lr, y_test_preds_rf,
                                y_train_probs_lr, y_train_probs_rf,
                                y_test_probs_lr, y_test_probs_rf):
    '''Produce classification report and ROC curves for training and test data and store in
    images folder
    NB The probabilities are need to generate the ROC curves. I could pass the model object
    but as the predictions have already been calculated it seems inefficient to regenrate

    input:
        y_train: training response values
        y_test:  test response values
        y_train_preds_lr: training predictions (classification) from logistic regression
        y_train_preds_rf: training predictions (classification) from random forest
        y_test_preds_lr: test predictions (classification) from logistic regression
        y_test_preds_rf: test predictions (classification) from random forest
        y_train_probs_lr: training predictions (probability) from logistic regression
        y_train_prob_rf: training predictions (probability) from random forest
        y_test_prob_lr: test predictions (probability) from logistic regression
        y_test_prob_rf: test predictions (probability) from random forest
    output:
        None
    '''
    # Classification report as text
    file = open(r".\images\results\classification_report.txt", "w")
    file.write('Random forest results')
    file.write('\nTest results\n')
    file.write(classification_report(y_test, y_test_preds_rf))
    file.write('\nTrain results\n')
    file.write(classification_report(y_train, y_train_preds_rf))
    file.write('\n\nLogistic regression results')
    file.write('\nTest results\n')
    file.write(classification_report(y_test, y_test_preds_lr))
    file.write('\nTrain results\n')
    file.write(classification_report(y_train, y_train_preds_lr))
    file.close()

    # Train data ROC curve
    plt.figure(figsize=(15, 8))
    ax = plt.gca()
    RocCurveDisplay.from_predictions(
        y_train, y_train_probs_lr, name='LogReg', ax=ax)
    RocCurveDisplay.from_predictions(
        y_train, y_train_probs_rf, name='RandForest', ax=ax)
    plt.title("Train ROC")
    plt.xlabel("True positive rate")
    plt.ylabel("False positive rate")
    plt.savefig(r".\images\results\Train ROC curve.png")

    # Test data ROC curve
    plt.figure(figsize=(15, 8))
    ax = plt.gca()
    RocCurveDisplay.from_predictions(
        y_test, y_test_probs_lr, name='LogReg', ax=ax)
    RocCurveDisplay.from_predictions(
        y_test, y_test_probs_rf, name='RandForest', ax=ax)
    plt.title("Test ROC")
    plt.xlabel("True positive rate")
    plt.ylabel("False positive rate")
    plt.savefig(r".\images\results\Test ROC curve.png")

def feature_importance_plot(model, features_lst, output_pth):
    '''creates feature importance chart and store in output_pth

    input:
        model: model object containing feature_importances_
        features_lst: list of columns to include as model features
        output_pth: path to store the figure
    output:
        None
    '''
    # Get feature importance
    importances = model.feature_importances_

    # Sort the features list to match the order
    indices = np.argsort(importances)[::-1]
    sorted_features_lst = [features_lst[i] for i in indices]

    # Plot the feature importance
    plt.figure(figsize=(15, 15))
    plt.bar(
        range(
            len(sorted_features_lst)),
        importances[indices],
        tick_label=sorted_features_lst)
    plt.title("Feature Importance")
    plt.ylabel('Importance')
    plt.xticks(rotation=45)
    plt.savefig(output_pth)

def train_models(X_train, X_test, y_train, y_test, features_lst):
    '''Train, assess and save models

    input:
        X_train: pandas dataframe. training data features
        X_test: pandas dataframe. testing data features
        y_train: pandas series. training data labels
        y_test: pandas series. testing data labels
        features_lst: list of columns to include as model features
    output:
        None
    '''
    # Initialise the models
    rfc = RandomForestClassifier(random_state=42)
    lrc = LogisticRegression(solver='lbfgs', max_iter=3000)

    # Define the random forest hyperparameter search space
    param_grid = {
        'n_estimators': [200, 500],
        'max_features': ['log2', 'sqrt'],       # Auto has been depreciated
        'max_depth': [4, 5, 100],
        'criterion': ['gini', 'entropy']
    }
    cv_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv=5)

    # Train the models
    cv_rfc.fit(X_train, y_train)
    lrc.fit(X_train, y_train)

    # Get train and test scores (probability and classification)
    # Probability is needed for the RocCurveDisplay.from_predictions() call
    y_train_preds_rf = cv_rfc.best_estimator_.predict(X_train)
    y_train_probs_rf = cv_rfc.best_estimator_.predict_proba(X_train)[:, 1]
    y_train_preds_lr = lrc.predict(X_train)
    y_train_probs_lr = lrc.predict_proba(X_train)[:, 1]
    y_test_preds_rf = cv_rfc.best_estimator_.predict(X_test)
    y_test_probs_rf = cv_rfc.best_estimator_.predict_proba(X_test)[:, 1]
    y_test_preds_lr = lrc.predict(X_test)
    y_test_probs_lr = lrc.predict_proba(X_test)[:, 1]

    # Get classification_reports and ROC curves
    classification_report_image(y_train, y_test,
                                y_train_preds_lr, y_train_preds_rf,
                                y_test_preds_lr, y_test_preds_rf,
                                y_train_probs_lr, y_train_probs_rf,
                                y_test_probs_lr, y_test_probs_rf)

    # Get feature importances for random forest
    feature_importance_plot(cv_rfc.best_estimator_, features_lst,
                            r".\images\results\RF feature importance.png")

    # Save models
    with open(r".\models\rfc_model.pkl", "wb") as file:
        pickle.dump(cv_rfc, file)
    with open(r".\models\logistic_model.pkl", "wb") as file:
        pickle.dump(lrc, file)

def main():
    '''
    Main call for all model build functionality
    The function contains three parameters
    1) "raw_data_path".  String containing the path and name of the development data
    2) "cat_recode_list".  list of categorial feature names to recode
    3) "feature_list".  List of feature names to include in training

    input
        None
    output:
        None
    '''
    # Define parameters
    raw_data_path = r".\data\bank_data.csv"
    cat_recode_lst = [
        'Gender',
        'Education_Level',
        'Marital_Status',
        'Income_Category',
        'Card_Category']
    features_lst = [
        'Customer_Age', 'Dependent_count', 'Months_on_book',
        'Total_Relationship_Count', 'Months_Inactive_12_mon',
        'Contacts_Count_12_mon', 'Credit_Limit', 'Total_Revolving_Bal',
        'Avg_Open_To_Buy', 'Total_Amt_Chng_Q4_Q1', 'Total_Trans_Amt',
        'Total_Trans_Ct', 'Total_Ct_Chng_Q4_Q1', 'Avg_Utilization_Ratio',
        'Gender_Churn', 'Education_Level_Churn', 'Marital_Status_Churn',
        'Income_Category_Churn', 'Card_Category_Churn'
    ]

    custs = import_data(raw_data_path)
    custs = derive_label(custs)
    perform_eda(custs)
    X_train, X_test, y_train, y_test = perform_feature_engineering(
        custs, cat_recode_lst, features_lst)
    train_models(X_train, X_test, y_train, y_test, features_lst)

# Top level script entry point
if __name__ == "__main__":
    main()


import pyautogui
import webbrowser
import time
from datetime import datetime

while True:
    now =datetime.now()

    if now.strftime("%H%M%S") == "184730":
        webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open_new(
        "https://zoom.us")

        time.sleep(7)
        pyautogui.click(1435, 150)
        time.sleep(6)
        pyautogui.click(945, 750)
        time.sleep(6)
        pyautogui.click(916, 590)

    if now.strftime("%H%M%S") == "184800":
        webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open_new(
        "https://zoom.us")

    break

        # pyautogui.hotkey('alt', 'v')
        # pyautogui.hotkey('alt', 'a')


"""
An Atom feed.
"""

from xml.etree import ElementTree
from datetime import datetime

# A puppy dies every time Fredrik Lundh serializes XML.
NS = "http://www.w3.org/2005/Atom"
ElementTree._namespace_map[NS] = "atom"

def qname(name):
    """
    Return a node name qualified with the Atom namespace.
    """
    return unicode(ElementTree.QName(NS, name))

class Atom(object):
    """
    An Atom feed.
    """

    # The maximum number of <entry> nodes.
    ENTRIES = 15

    def __init__(self, pathname, title, alternate, id, author):
        """
        Setup to manage an Atom feed.
        """
        self.pathname = pathname
        self.title = title
        self.alternate = alternate
        self.author = author
        try:
            self.etree = ElementTree.parse(self.pathname)
        except IOError:
            feed = ElementTree.Element(qname("feed"))
            ElementTree.SubElement(feed, qname("title"), {
                "type": "html"
            }).text = self.title
            ElementTree.SubElement(feed, qname("link"), {
                "href": id,
                "rel": "self"
            })
            ElementTree.SubElement(feed, qname("link"), {
                "href": alternate,
                "rel": "alternate"
            })
            ElementTree.SubElement(feed, "id").text = id
            ElementTree.SubElement(feed, qname("updated"))
            ElementTree.SubElement(ElementTree.SubElement(feed,
                qname("author")), qname("name")).text = self.author
            self.etree = ElementTree.ElementTree(feed)
            self.etree.write(self.pathname)
            self.etree = ElementTree.parse(self.pathname)

    def __del__(self):
        """
        Write the Atom feed back to disk with an updated timestamp.
        """
        self.etree.find(qname("updated")).text \
            = datetime.today().strftime("%Y-%m-%dT%H:%M:%SZ")
        self.etree.write(self.pathname)

    def entry(self,
        title=None,
        alternate=None,
        id=None,
        author=None,
        content=""
    ):
        """
        Create a new <entry>, bumping an old one out of the Atom feed if
        necessary.  Fill the new <entry> with the parameters or sensible
        defaults.
        """

        # Find sensible defaults for omitted arguments.
        if title is None:
            title = self.title
        if alternate is None:
            alternate = self.alternate
        if author is None:
            author = self.author

        # Setup the new <entry>.
        entry = self.etree.find(qname("entry"))
        if entry is None:
            entry = ElementTree.SubElement(self.etree.getroot(),
                qname("entry"))
        else:
            i = 0
            for e in self.etree.getroot().getchildren():
                if qname("entry") == e.tag:
                    break
                i += 1
            self.etree.getroot()[i+1:i+self.ENTRIES] \
                = self.etree.getroot()[i:i+self.ENTRIES-1]
            entry = self.etree.getroot()[i] = ElementTree.Element(
                qname("entry"))

        # Place the new article in the <entry>.
        ElementTree.SubElement(entry, qname("title"), {
            "type": "html"
        }).text = title
        ElementTree.SubElement(entry, qname("link"), {
            "href": alternate,
            "rel": "alternate"
        })
        ElementTree.SubElement(entry, qname("id")).text = id
        ElementTree.SubElement(entry, qname("published")).text \
            = datetime.today().strftime("%Y-%m-%dT%H:%M:%SZ")
        ElementTree.SubElement(entry, qname("updated")).text \
            = datetime.today().strftime("%Y-%m-%dT%H:%M:%SZ")
        ElementTree.SubElement(ElementTree.SubElement(entry,
            qname("author")), qname("name")).text = author
        ElementTree.SubElement(entry, qname("content"), {
            "type": "html"
        }).text = content


import numpy as np
import networkx as nx
from matplotlib import pyplot as plt

class Graph:
    def __init__(self, bansko) -> None:
        self.graph = self._init_graph(bansko)
        self.component_population = np.zeros(self.encode_slope(self.graph.number_of_nodes(), self.graph.number_of_nodes()) + 1)
        self.lift_indices = self._get_lift_inices()
        self.slope_indices = self._get_slope_inices()

    def _init_graph(self, bansko):
        graph = nx.DiGraph()
        if not bansko:
            graph.add_edge(1, 2, lift = True, queue = 0, capacity=53, time=3.5)
            graph.add_edge(1, 4, lift = True, queue = 0, capacity=23, time=5)
            graph.add_edge(3, 4, lift = True, queue = 0, capacity=20, time=3.5)
            graph.add_edge(5, 4, lift = True, queue = 0, capacity=17, time=1)

            #slope = nx.DiGraph()
            graph.add_edge(2, 1, lift = False, difficulty = 1, time = 3)
            graph.add_edge(2, 3, lift = False, difficulty = 0.25, time = 3)
            graph.add_edge(4, 1, lift = False, difficulty = 0.5, time = 3)
            graph.add_edge(4, 5, lift = False, difficulty = 0.75, time = 3)
            graph.add_edge(5, 3, lift = False, difficulty = 0.75, time = 3)
        else:
            graph.add_edge(1, 2, lift = True, queue = 0, time=10,capacity=33.3) #capacity=33.3)    #bansko
            graph.add_edge(3, 2, lift = True, queue = 0, time=4, capacity=32.75)    #chalin valog
            graph.add_edge(2, 4, lift = True, queue = 0, time=11, capacity=33.3)    #bansko
            graph.add_edge(4, 5, lift = True, queue = 0, time=6.3, capacity=33.33)  #Banderitza 1
            graph.add_edge(4, 6, lift = True, queue = 0, time=2.5, capacity=50)     #Kolarski
            graph.add_edge(7, 6, lift = True, queue = 0, time=7.2, capacity=15.9)   #stara kotva
            graph.add_edge(8, 6, lift = True, queue = 0, time=6.5, capacity=15.9)   #detska kotva
            graph.add_edge(8, 9, lift = True, queue = 0, time=7, capacity=33.3)     #todorka
            graph.add_edge(5, 10, lift = True, queue = 0, time=3.5, capacity=33.33)  #Banderitza 2
            graph.add_edge(8, 11, lift = True, queue = 0, time=7.5, capacity=33.33)  #shiligarnik
            graph.add_edge(11, 10, lift = True, queue = 0, time=5.5, capacity=36.67) #Plato
            graph.add_edge(12, 11, lift = True, queue = 0, time=9.5, capacity=32.33) #mosta

            graph.add_edge(1, 11, lift = True, queue = 0, time=9.5, capacity=32.33) #miproved lift
            #kan också förbättra genom att dubbla capaciteten av lift 1-2
            #lift.add_edge(13, 12, lift = True, queue = 0, time=9.5, pph=32.33) #miproved lift

            graph.add_edge(2, 3,difficulty=0.75, lift = False, time = 1)
            graph.add_edge(2, 3,difficulty=0.5, lift = False, time = 3)    # 2 Backar
            graph.add_edge(4, 1,difficulty=0.5, lift = False, time = 20)
            graph.add_edge(4, 3,difficulty=0.5, lift = False, time = 14)
            graph.add_edge(3, 1,difficulty=0.5, lift = False, time = 6)
            graph.add_edge(5, 4,difficulty=1, lift = False, time = 3)
            graph.add_edge(6, 7,difficulty=0.75, lift = False, time = 3)
            graph.add_edge(6, 8,difficulty=0.5, lift = False, time = 7)
            graph.add_edge(6, 8,difficulty=0.75, lift = False, time = 4)    #2 stycken
            graph.add_edge(8, 7,difficulty=0.5, lift = False, time = 6)
            graph.add_edge(7, 4,difficulty=0.5, lift = False, time = 8)
            graph.add_edge(8, 12,difficulty=0.5, lift = False, time = 6)
            graph.add_edge(9, 8,difficulty=0.75, lift = False, time = 6)
            graph.add_edge(9, 5,difficulty=0.75, lift = False, time = 4)
            graph.add_edge(5, 6,difficulty=0.75, lift = False, time = 3)
            graph.add_edge(10, 9,difficulty=0.75, lift = False, time = 3)
            graph.add_edge(10, 5,difficulty=0.75, lift = False, time = 10)
            graph.add_edge(10, 11,difficulty=0.5, lift = False, time = 14)
            graph.add_edge(9, 11,difficulty=0.5, lift = False, time = 8)
            graph.add_edge(11, 8,difficulty=0.5, lift = False, time = 8)
            graph.add_edge(11, 12,difficulty=0.5, lift = False, time = 7)
            graph.add_edge(12, 2,difficulty=0.25, lift = False, time = 4)
        return graph

    def _set_edge_attribute(self, edge, attribute, value):
        start, end = self.decode_slope(edge)
        self.graph[start][end][attribute] = value

    def get_neighbors(self, position):
        return self.graph[position]

    def encode_slope(self, start_node, end_node):
        # Cantor pairing function
        slope_index = ((start_node + end_node) * (start_node + end_node + 1))/2 + end_node + self.graph.number_of_nodes()
        return int(slope_index)

    def decode_slope(self, slope_index):
        # inverted Cantor pairing function
        d = slope_index - self.graph.number_of_nodes()
        w = np.floor((np.sqrt(8*d + 1) -1)/2)
        t = (np.square(w) + w)/2
        end_node = d - t
        start_node = w - end_node
        return int(start_node), int(end_node)

    def reposition_agent(self, current_position, new_position):
        self.component_population[current_position] -= 1
        self.component_population[new_position] += 1

    def get_edge_attribute(self, edge, attribute):
        start, end = self.decode_slope(edge)
        return self.graph[start][end][attribute]

    def enter_queue(self, edge):
        start, end = self.decode_slope(edge)
        self.graph[start][end]['queue'] += 1

    def _get_lift_inices(self):
        lifts = []
        for edge in self.graph.edges.data():
            if edge[2]['lift']:
                lifts.append(self.encode_slope(edge[0], edge[1]))
        return lifts

    def _get_slope_inices(self):
        slopes = []
        for edge in self.graph.edges.data():
            if not edge[2]['lift']:
                slopes.append(self.encode_slope(edge[0], edge[1]))
        return slopes

    def leave_queue(self, edge):
        start, end = self.decode_slope(edge)
        self.graph[start][end]['queue'] -= 1

    def get_queues(self):
        queues = [
            self.graph[1][2]['queue'],
            self.graph[3][2]['queue'],
            self.graph[2][4]['queue'],
            self.graph[4][5]['queue'],
            self.graph[4][6]['queue'],
            self.graph[7][6]['queue'],
            self.graph[8][6]['queue'],
            self.graph[8][9]['queue'],
            self.graph[5][10]['queue'],
            self.graph[8][11]['queue'],
            self.graph[11][10]['queue'],
            self.graph[12][11]['queue'],
            self.graph[1][11]['queue']
            ]
        return queues

    def get_capacities(self):
        capacities = [
            self.graph[1][2]['capacity'],
            self.graph[3][2]['capacity'],
            self.graph[2][4]['capacity'],
            self.graph[4][5]['capacity'],
            self.graph[4][6]['capacity'],
            self.graph[7][6]['capacity'],
            self.graph[8][6]['capacity'],
            self.graph[8][9]['capacity'],
            self.graph[5][10]['capacity'],
            self.graph[8][11]['capacity'],
            self.graph[11][10]['capacity'],
            self.graph[12][11]['capacity'],
            self.graph[1][11]['capacity']
        ]
        return capacities

def main():
    g = Graph(bansko=True)
    lift_indices = g.lift_indices
    #start_node, end_node = g.decode_slope(4)
    for lift in lift_indices:
        print(g.decode_slope(lift))
    #print(start_node, end_node)

if __name__ == '__main__':
    main()


# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
    def __repr__(self):
        return 'value of listnode is %d' %(self.val)

class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def deleteDuplicates(self, head):
        #length of list is 0
        if head == None:
            return None
        #length of list is 1
        elif head.next == None:
            return head
        #length of list is 2
        else:
            tmp = head
            next_nod = head.next
            while 1:
                if tmp.val == next_nod.val:
                    tmp.next = next_nod.next
                    next_nod = tmp.next
                else:
                    tmp = next_nod
                    next_nod = next_nod.next
                if next_nod == None:
                    break
            return head


import json

from tqdm import tqdm

def build_and_save_data(
    abstract_file="ChemProt_Corpus/chemprot_training/chemprot_training_abstracts.tsv",
    entity_file="ChemProt_Corpus/chemprot_training/chemprot_training_entities.tsv",
    relation_file="ChemProt_Corpus/chemprot_training/chemprot_training_relations.tsv",
    target_file="chemprot_train.json",
):
    data = open(abstract_file).read().split("\n")
    id2text = {
        sent.split("\t", 1)[0]: sent.split("\t", 1)[1] for sent in data if len(sent) > 0
    }

    data = open(entity_file).read().split("\n")
    entities = {}
    for line in tqdm(data):
        items = line.split("\t", 5)
        if len(items) < 6:
            print(items)
            continue
        entities[f"{items[0]}.{items[1]}"] = items[-1]
    print(list(entities.items())[:10])

    ds = []

    data = open(relation_file).read().split("\n")
    for line in tqdm(data):
        items = line.split("\t", 5)
        if len(items) < 6:
            print(items)
            continue

        id = items[0]
        e1 = items[4].split(":", 1)[1]
        e2 = items[5].split(":", 1)[1]

        e1 = entities[f"{id}.{e1}"]
        e2 = entities[f"{id}.{e2}"]

        text = id2text[id]
        relation = items[3]

        sample = f"find relation between entities - {e1} and {e2} in {text}"
        target = relation

        ds.append({"sample": sample, "target": target})

    with open(target_file, "w") as f:
        json.dump(ds, f)

build_and_save_data(
    abstract_file="ChemProt_Corpus/chemprot_training/chemprot_training_abstracts.tsv",
    entity_file="ChemProt_Corpus/chemprot_training/chemprot_training_entities.tsv",
    relation_file="ChemProt_Corpus/chemprot_training/chemprot_training_relations.tsv",
    target_file="chemprot_train.json",
)
build_and_save_data(
    abstract_file="ChemProt_Corpus/chemprot_development/chemprot_development_abstracts.tsv",
    entity_file="ChemProt_Corpus/chemprot_development/chemprot_development_entities.tsv",
    relation_file="ChemProt_Corpus/chemprot_development/chemprot_development_relations.tsv",
    target_file="chemprot_valid.json",
)

from datasets import DatasetDict, load_dataset

ds = DatasetDict(
    {
        "train": load_dataset("json", data_files="chemprot_train.json", split="train"),
        "valid": load_dataset("json", data_files="chemprot_valid.json", split="train"),
    }
)

print(ds)

push_to_hub = False

if push_to_hub:
    ds.push_to_hub("ddp-iitm/chemprot", private=True)


# coding=utf-8
# ======================================
# File:     blender.py
# Author:   Jackie PENG
# Contact:  jackie.pengzhao@gmail.com
# Created:  2021-08-29
# Desc:
#   Strategy blending functions and
#   blender string parsers.
# ======================================

import numpy as np
from numba import njit
from .utilfuncs import is_number_like, BLENDER_STRATEGY_INDEX_IDENTIFIER

# 这里定义可用的交易信号混合函数
@njit()  # 实测njit版本运行速度是python版本的2倍左右
def op_sum(*args):
    """ 在combo模式下，所有的信号被加总合并，这样每个所有的信号都会被保留，
        虽然并不是所有的信号都有效。在这种模式下，本意是原样保存所有单个输入
        多空模板产生的交易信号，但是由于正常多空模板在生成卖出信号的时候，会
        运用"比例机制"生成卖出证券占持有份额的比例。这种比例机制会在针对
        combo模式的信号组合进行计算的过程中产生问题。
        例如：在将两组信号A和B合并到一起之后，如果A在某一天产生了一个股票
        100%卖出的信号，紧接着B在接下来的一天又产生了一次股票100%卖出的信号，
        两个信号叠加的结果，就是产生超出持有股票总数的卖出数量。将导致信号问题
        因此combo后的数据需要用clip处理

    :param args:
    :return:
    """
    # 计算所有交易信号之和
    signal_sum = np.zeros_like(args[0])
    for signal in args:
        signal_sum += signal
    return signal_sum

# 这个函数本身速度比较快，而且njit版本的运行速度没有任何提升
def op_avg(*args):
    """ 通常用于PT持仓目标信号。
        组合后的持仓取决于看多的蒙板的数量，看多蒙板越多，持仓越高，
        只有所有蒙板均看空时，最终结果才看空所有蒙板的权重相同，因此，如
        果一共五个蒙板三个看多两个看空时，持仓为60%。更简单的解释是，混
        合后的多空仓位是所有蒙版仓位的平均值.

    :param args: 以tuple形式传入的所有交易信号
    :return:
    """
    # 计算所有交易信号之和
    signal_sum = op_sum(*args)
    # 交易信号的个数
    signal_count = len(args)
    return signal_sum / signal_count

# 这个函数本身速度不快，但njit版本更慢，njit()后运行时间增加40%
def op_pos(n, t, *args):
    """ 择时策略混合器，将各个择时策略生成的多空蒙板按规则混合成一个蒙板

    最终的多空信号强度取决于蒙板集合中各个蒙板的信号值，只有满足N个以
    上的蒙板信号值为多(>0)或者为空(<0)时，最终蒙板的多空信号才为多或
    为空。某组信号看多/看空的判断依据是信号强度绝对值是否大于t。例如，
    当T为0.25的时候，0.35会被接受为多头，但是0.15不会被接受为多头，因
    此尽管有两个策略在这个时间点判断为多头，但是实际上只有一个策略会被
    接受.
    最终信号的强度始终为-1或1，如果希望最终信号强度为输入信号的
    平均值，应该使用avg_pos-N方式混合

    Parameters
    ---------
    n: int
    t: float
    args: ndarray

    Returns
    -------
    ndarray
    """
    signal_sign = np.zeros_like(args[0])
    for msk in args:
        signal_sign += np.sign(np.where(np.abs(msk) < t, 0, msk))
    res = np.where(np.abs(signal_sign) >= n, 1., 0)
    return res

# 这个函数本身速度不快，但njit版本更慢，njit()后运行时间增加33%
def op_avg_pos(n, t, *args):
    """择时策略混合器，将各个择时策略生成的多空蒙板按规则混合成一个蒙板

    持仓目标取决于看多的蒙板的数量，只有满足N个或更多蒙板看多时，最终结果
    看多，否则看空，在看多/空情况下，最终的多空信号强度=平均多空信号强度
    。某组信号看多/看空的判断依据是信号强度绝对值是否大于t。例如，
    当T为0.25的时候，0.35会被接受为多头，但是0.15不会被接受为多头，因
    此尽管有两个策略在这个时间点判断为多头，但是实际上只有一个策略会被
    接受.
    当然，avg_pos-1与avg等价，如avg_pos-2方式下，至少两个蒙板看多
    则最终看多，否则看空

    Parameters
    ---------
    n: int
    t: float
    args: ndarray

    Returns
    -------
    ndarray
    """
    # 计算所有交易信号之和
    signal_sum = op_sum(*args)
    # 交易信号的个数
    signal_count = len(args)
    signal_sign = np.zeros_like(args[0])
    for msk in args:
        signal_sign += np.sign(np.where(np.abs(msk) < t, 0, msk))
    res = np.where(np.abs(signal_sign) >= n, signal_sum, 0) / signal_count
    return res

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增加25%
def op_str(t, *args):
    """ str-T模式下，持仓只能为0或+1，只有当所有多空模版的输出的总和大于
        某一个阈值T的时候，最终结果才会是多头，否则就是空头

    Parameters
    ----------
    t: float
    args: ndarray

    Returns
    -------
    ndarray
    """
    # 计算所有交易信号之和
    signal_sum = op_sum(*args)
    return np.where(np.abs(signal_sum) >= t, 1, 0) * np.sign(signal_sum)

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增加4倍
def op_clip(lbound, ubound, *args):
    """ 剪切掉信号中小于lbound，或大于ubound的值，替换为lbound或ubound

    Parameters
    ----------
    lbound: float
    ubound: float
    args: ndarray

    Returns
    -------
    ndarray
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count > 1:
        raise ValueError(f'only one array of signals can be passed to blend function "clip", please check '
                         f'your input')
    signal_res = args[0]
    signal_res = np.where(signal_res < lbound, lbound, signal_res)
    signal_res = np.where(signal_res > ubound, ubound, signal_res)
    return signal_res

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增加90%
def op_unify(*args):
    """ 调整输入矩阵每一行的元素，通过等比例缩小（或放大）后使得所有元素的和为1
    用于调整

    Parameters
    ----------
    args: ndarray

    Returns
    -------
    ndarray

    examples
    --------
    >>> op_unify([[3.0, 2.0, 5.0], [2.0, 3.0, 5.0]])
    >>> [[0.3, 0.2, 0.5], [0.2, 0.3, 0.5]]
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count > 1:
        raise ValueError(f'only one array of signals can be passed to blend function "unify", please check '
                         f'your input')
    signal_arr = args[0]
    s = signal_arr.sum(1)
    shape = (s.shape[0], 1)
    signal_res = signal_arr / s.reshape(shape)
    # 如果原信号中有全0的情况，会导致NaN出现，下面将所有NaN填充为0
    signal_res = np.where(np.isnan(signal_res), 0., signal_res)
    return signal_res

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增加80%
def op_max(*args):
    """ 信号混合器，将各个择时策略生成的信号取最大值后生成新的交易信号

    生成的交易信号为所有交易信号中的最大值

    Parameters
    ----------
    args: ndarray

    Returns
    -------
    ndarray
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count < 1:
        return
    elif signal_count == 1:
        return args[0]
    elif signal_count == 2:
        return np.fmax(args[0], args[1])
    else:  # signal_count > 2
        signal_max = np.fmax(args[0], args[1])
        for signal in args[2:]:
            signal_max = np.fmax(signal_max, signal)
        return signal_max

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增加50%
def op_min(*args):
    """ 信号混合器，将各个择时策略生成的信号取最小值后生成新的交易信号

    生成的交易信号为所有交易信号中的最小值

    Parameters
    ----------
    args: ndarray

    Returns
    -------
    ndarray
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count < 1:
        raise KeyError('at least one signal array should be passed to min()')
    elif signal_count == 1:
        return args[0]
    elif signal_count == 2:
        return np.fmin(args[0], args[1])
    else:  # signal_count > 2
        signal_min = np.fmin(args[0], args[1])
        for signal in args[2:]:
            signal_min = np.fmin(signal_min, signal)
        return signal_min

# 这个函数本身速度不够快，但是njit版本的运行速度没有任何提升
def op_power(*args):
    """ ，逐个元素操作生成first的second次幂，功能等同于np.power

    np.power()函数可以接受第三个ndarray作为结果，这种操作方式
    是这里不需要的，因此创建op_power函数实现np.power的功能，但
    同时避免超过两个参数出现时导致的问题

    另外，在生成blender表达式的逆波兰式的时候，power函数的两个
    参数次序会颠倒，因此这里实际需要生成的是second的first次幂

    :param args: args中有且只能有两个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 2:
        raise ValueError('only two signal arrays are allowed in power()/pow()')
        # return  # 本函数允许且仅允许两个参数传入

    # blender表达式的逆波兰式导致两个参数次序颠倒，这里再颠倒回来
    signal_res = np.power(args[1], args[0])
    return signal_res

@njit()  # 这个函数本身速度不够快，njit版本的运行速度稍快，实测大约快5%
def op_exp(*args):
    """ ，逐个元素操作生成e的signal次幂，效果与np.exp()一致

        np.exp()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_exp函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in exp()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.exp(args[0])
    return signal_res

# 这个函数本身速度不够快，但是njit版本的运行速度更慢，实测大约慢5%
def op_log(*args):
    """ ，逐个元素操作生成signal的自然对数，效果与np.log()一致

        np.log()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_log函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in log()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.log(args[0])
    return signal_res

# 这个函数本身速度不够快，但是njit版本的运行速度更慢，实测大约慢20%
def op_log10(*args):
    """ ，逐个元素操作生成signal的以10为底的对数，效果与np.log10()一致

        np.log10()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_log10函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in log10()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.log10(args[0])
    return signal_res

@njit()  # 实测njit版本运行速度是python版本的10倍以上
def op_floor(*args):
    """ 逐个元素操作生成signal的floor，效果与np.floor()一致

        np.floor()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_floor函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in floor()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.floor(args[0])
    return signal_res

@njit()  # 实测njit版本运行速度是python版本的10倍以上
def op_ceil(*args):
    """ 逐个元素操作生成signal的ceil，效果与np.cail()一致

        np.ceil()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_ceil函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in ceil()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.ceil(args[0])
    return signal_res

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间增倍（因为overhead）
def op_sqrt(*args):
    """ ，逐个元素操作生成signal的平方根，效果与np.sqrt()一致

        np.sqrt()函数可以接受一个ndarray作为结果，这种操作方式
        是这里不需要的，因此创建op_sqrt函数避免第二个参数被传入

    :param args: args中有且只能有一个参数
    :return:
    """
    # 交易信号的个数
    signal_count = len(args)
    if signal_count != 1:
        raise ValueError('only one signal array is allowed in sqrt()')
        # return  # 本函数允许且仅允许一个参数传入

    signal_res = np.sqrt(args[0])
    return signal_res

# TODO: 增加下列函数支持：
#  product()
_AVAILABLE_FUNCTIONS = {'abs':      abs,
                        'avg':      op_avg,
                        'avgpos':   op_avg_pos,
                        'ceil':     op_ceil,
                        'clip':     op_clip,
                        'combo':    op_sum,
                        'exp':      op_exp,
                        'floor':    op_floor,
                        'log':      op_log,
                        'log10':    op_log10,
                        'max':      op_max,
                        'min':      op_min,
                        'pos':      op_pos,
                        'position': op_pos,
                        'pow':      op_power,
                        'power':    op_power,
                        'sqrt':     op_sqrt,
                        'strength': op_str,
                        'str':      op_str,
                        'sum':      op_sum,
                        'unify':    op_unify,
                        'uni':      op_unify
                        }

def run_blend_func(func_str, *args):
    """ 根据func_str（一个代表混合函数的字符串解析出正确的函，并返回正确结果

    :param func_str:
        交易信号混合函数名，额外的交易参数直接包含在函数名中
        含有此类附加参数的函数必须特殊解析后才能使用，即将函数名中的特殊参数
        分离出来后作为参数传入函数。
        例如：
        avg_pos-3-0.5(*args)
        解析后的实际执行效果为：
        avg_pos(3, 0.5, *args)

    :param args:
        作为函数func的参数传入的交易信号

    :return:
        函数的运行结果
    """
    if not isinstance(func_str, str):
        raise TypeError(f'func_str should be a string, got {type(func_str)} instead')

    # 分离函数名和附加参数（附加参数的个数不限，受实际定义的函数限制）
    func_name_args = func_str.split('_')
    func_name, *additional_args = func_name_args
    func = _AVAILABLE_FUNCTIONS.get(func_name)
    if func is None:
        raise KeyError(f'function ({func_name}) is not available')
    # 将所有的附加参数处理为float类型，便于传入func处理
    additional_args = tuple(float(item) for item in additional_args)
    try:
        res = func(*additional_args, *args)
    except Exception as e:
        raise Exception(f'Error raised while executing blending function {func_name}({additional_args}, {args}), '
                        f'error message: \n{e}')
    return res

def blender_parser(blender_string):
    """选股策略混合表达式解析程序，将通常的中缀表达式解析为前缀运算队列，从而便于混合程序直接调用

    系统接受的合法表达式为包含 '*' 与 '+' 的中缀表达式，符合人类的思维习惯，使用括号来实现强制
    优先计算，如 '0 + (1 + 2) * 3'; 表达式中的数字0～3代表选股策略列表中的不同策略的索引号
    上述表达式虽然便于人类理解，但是不利于快速计算，因此需要转化为前缀表达式，其优势是没有括号
    按照顺序读取并直接计算，便于程序的运行。为了节省系统运行开销，在给出混合表达式的时候直接将它
    转化为前缀表达式的形式并直接存储在blender列表中，在混合时直接调用并计算即可
    input： =====
        no input parameter
    return：===== s2: 前缀表达式
        :rtype: list: 前缀表达式
    """

    prio = {'|':    0,
            'or':   0,
            '&':    1,
            'and':  1,
            '~':    1,
            'not':  1,
            '+':    0,
            '-':    0,
            '*':    1,
            '/':    1,
            '^':    2}

    # 定义两个队列作为操作堆栈
    op_stack = []  # 运算符栈
    arg_count_stack = []  # 函数的参数个数栈
    output = []  # 结果队列
    exp_list = _exp_to_token(blender_string)[::-1]
    while exp_list:
        token = exp_list.pop()
        # 从右至左逐个读取表达式中的元素（数字/操作符/函数/括号/逗号）
        # 并按照以下算法处理
        if is_number_like(token):
            # 1，如果元素是数字则进入结果队列
            output.append(token)
        elif token == '(':
            # 2，如果元素是反括号则压入运算符栈
            op_stack.append(token)
        elif token == ')':
            # 3，扫描到")"时，依次弹出所有运算符直到遇到"("或一个函数，并根据遇到的token类型（函数/右括号）来确定下一步
            while op_stack[-1][-1] != '(':
                try:
                    output.append(op_stack.pop())
                except:  # 如果右括号没有与之配对的左括号，则报错
                    raise ValueError(f'Invalid expression, missing opening parenthesis!')
            if op_stack[-1] == '(':  # 如果剩余右括号，则弹出右括号，并丢弃这对括号
                op_stack.pop()
            else:  # 如果剩余一个函数，则将函数的参数+1，并弹出函数，设置函数的参数个数
                arg_count = arg_count_stack.pop() + 1
                func = op_stack.pop() + str(arg_count) + ")"
                output.append(func)
        elif token in prio.keys():
            # 4，扫描到运算符时
            if len(op_stack) > 0:
                if (op_stack[-1] in '+-*/&|^~andnotor') and (prio[token] <= prio[op_stack[-1]]):
                    output.append(op_stack.pop())
                    exp_list.append(token)
                else:
                    op_stack.append(token)
            else:
                # 如果op栈为空，直接将token压入op栈
                op_stack.append(token)
        elif (token[0].isalpha) and (token[-1] == '('):
            # 5，扫描到字母开头，且'('结尾的字符串时，说明扫描到函数，将函数压入op栈，并将数字0压入arc_count栈
            op_stack.append(token)
            arg_count_stack.append(0)
        elif token == ',':
            # 6, 扫描到逗号时，说明函数有参数，该函数的参数数量+1，同时弹出op栈中所有非函数的op
            try:
                arg_count_stack[-1] += 1
            except:
                raise ValueError(f'Invalid expression: miss-placed comma!')
            while op_stack[-1][-1] != '(':  # 弹出所有的操作符，直到下一个函数或括号
                try:
                    output.append(op_stack.pop())
                except:
                    raise ValueError(f'Invalid expression, missing opening parenthesis!')
        elif BLENDER_STRATEGY_INDEX_IDENTIFIER.match(token):
            # 7, 扫描到策略序号index时，将其送入结果队列
            output.append(token)

        else:  # 扫描到不合法输入
            raise ValueError(f'Blender token can not be parsed"{token}"')
    while op_stack:
        output.append(op_stack.pop())
    output.reverse()  # 表达式解析完成，生成前缀表达式
    return output

def signal_blend(op_signals, blender):
    """ 选股策略混合器，将各个选股策略生成的选股蒙板按规则混合成一个蒙板

    input:
        :param op_signals:
        :param blender:
    :return:
        ndarray, 混合完成的选股蒙板
    """
    exp = blender[:]  # 混合表达式的逆波兰式，可以直接读取后计算
    s = []  # 信号栈，用来存储所有需要操作的交易信号
    while exp:
        token = exp[-1]
        if token[-1] == ')':
            # 如果碰到函数，解析函数的参数数量，并弹出信号栈内的适当个交易信号，应用函数得到结果，压入信号栈
            token = exp.pop()
            arg_count = int(token[-2])
            func_name = token[0:-3]
            args = tuple(s.pop() for i in range(arg_count))
            res = run_blend_func(func_name, *args)
            s.append(res)
        elif token in '~not':
            # 如果碰到一元运算符，弹出信号栈内的交易信号，得到结果，再压入信号栈
            s.append(_operate(s.pop(), None, exp.pop()))
        elif token in '+-*/^&|andor':
            # 如果碰到二元运算符，弹出信号栈内两个交易信号，得到结果，再压入信号栈
            s.append(_operate(s.pop(), s.pop(), exp.pop()))
        elif BLENDER_STRATEGY_INDEX_IDENTIFIER.match(token):
            # 如果是index，直接读取交易信号并压入信号栈
            sig_index = int(exp.pop()[1:])
            s.append(op_signals[sig_index])
        else:  # exp[-1].isnum():
            # 如果是数字，直接作为数字压入信号栈
            s.append(float(exp.pop()))

    return s[0]

def _exp_to_token(string):
    """ 将输入的blender-exp裁切成不同的元素(token)，包括数字、符号、函数等

    :return:
    """
    if not isinstance(string, str):
        raise TypeError()
    function_like_operators = ['or',
                               'and',
                               'not']
    token_types = {
        'operator':          0,
        'number':            1,
        'function':          2,
        'open_parenthesis':  3,
        'close_parenthesis': 4,
        'comma':             5
    }
    tokens = []
    string = string.replace(' ', '')
    string = string.replace('\t', '')
    string = string.replace('\n', '')
    string = string.replace('\r', '')
    cur_token = ''
    next_token = False  # 如果需要强行分开两个相同类型的token，则将next_token设置为True
    prev_token_type = None
    cur_token_type = None
    # 逐个扫描字符，判断每个字符代表的token类型，当token类型发生变化时，将当前token压入tokens栈
    for ch in string:
        if ch in '+*/^&|~':
            cur_token_type = token_types['operator']
        elif ch in '-':
            # '-'号出现在function中作为参数存在时，应被识别为function的一部分，此时'-'前只能是'_'
            if (cur_token_type == token_types['function']) and (cur_token[-1] == '_'):
                cur_token_type = token_types['function']
            # '-'号在下面四种情况下应被识别为负号，成为数字的一部分：
            #   1，在表达式第一位
            #   2，紧接在左括号后面
            #   3，紧接在另一个符号后面
            #   4，紧接在一个完整结尾的function之后
            elif (prev_token_type == token_types['operator']) or \
                    (prev_token_type == token_types['open_parenthesis']) or \
                    (prev_token_type == token_types['function']) and (cur_token[-1] == '(') or \
                    (prev_token_type is None):

                cur_token_type = token_types['number']
            # 其余情况下被识别为一个操作符
            else:
                cur_token_type = token_types['operator']
        elif ch in '0123456789':
            if cur_token == '':
                cur_token_type = token_types['number']
            else:
                # 如果数字跟在function的后面，则被识别为字母（function）的一部分，否则被识别为数字
                # 但数字被识别为function一部分的前提是function还没有以左括号结尾
                # 以及前一个function不在"function_like_operator"中
                if (prev_token_type == token_types['function']) and \
                        (cur_token[-1] != '(') and \
                        (cur_token not in function_like_operators):
                    cur_token_type = token_types['function']
                else:
                    cur_token_type = token_types['number']
        elif ch in '.':
            # 小数点应被识别为数字，除非小数点是跟在一个function中的且function未结束（不以"("结尾）
            if (cur_token_type == token_types['function']) and (cur_token[-1] != '('):
                cur_token_type = token_types['function']
            # 其他情况下小数点应该被识别为数字（允许出现小数点打头的数字，如".15"
            else:
                cur_token_type = token_types['number']
        elif ch.upper() in '_ABCDEFGHIJKLMNOPQRSTUVWXYZ':
            # 字母和下划线应被识别为变量或函数名,
            if cur_token == '':
                cur_token_type = token_types['function']
            else:
                # 如果当前token为function且已经完整，则强行分割token
                if (cur_token_type == token_types['function']) and (cur_token[-1] == '('):
                    next_token = True
                # 如果当前token为function，且属于function_like_operator，也强行分割token
                if (cur_token_type == token_types['function']) and (cur_token in function_like_operators):
                    next_token = True
                # 如果当前token为function，但发现当前token是index，以s打头且后接若干数，也强行分割token
                if (cur_token_type == token_types['function']) and \
                        (BLENDER_STRATEGY_INDEX_IDENTIFIER.match(cur_token)):
                    next_token = True
                cur_token_type = token_types['function']
        elif ch in '(':
            # 如果左括号是单独出现的，则应被识别为左括号
            if cur_token == '':
                cur_token_type = token_types['open_parenthesis']
            # 如果左括号出现在function的后面，且该function尚未以左括号结束，则应被识别为function
            # 的一部分，且被包含在function内作为function的结束符
            else:
                if (prev_token_type == token_types['function']) and (cur_token[-1] != '('):
                    cur_token_type = token_types['function']
                else:
                    cur_token_type = token_types['open_parenthesis']
        elif ch in ')':
            cur_token_type = token_types['close_parenthesis']
        elif ch in ',':
            # ','逗号被用来分割函数的参数，实际应被忽略
            cur_token_type = token_types['comma']
        else:
            # 某种没有预料到的字符出现在表达式中：
            raise TypeError(f'character in expression "{ch}" is not valid!')

        # 四种常规情况下判断当前token已经完整，将该token压入tokens栈，完成一个token的识别：
        # 1，当前字符被判定为新的token类型;
        # 2，当前token类型为左括号;
        # 3，当前token类型为右括号;
        # 4，出现强行分割token的标识next_token
        # 一种特殊情况下，将token压入tokens栈时，需要修改该token：
        # 1，当前token类型为数字，且token仅包含一个字符"-"时，将token改为'-1'，并压入一个额外token'*'
        # 此时重置token类型、重置当前token，将当前字符赋予当前token
        if cur_token_type != prev_token_type or \
                cur_token_type == token_types['open_parenthesis'] or \
                cur_token_type == token_types['close_parenthesis'] or \
                next_token:
            if cur_token != '':
                if (cur_token == '-') and (prev_token_type == token_types['number']):
                    tokens.append('-1')
                    tokens.append('*')
                else:
                    tokens.append(cur_token)
            prev_token_type = cur_token_type
            cur_token = ''
            next_token = False
        if cur_token_type is not None:
            cur_token += ch
    tokens.append(cur_token)
    return tokens

# 这个简单函数本身速度已经很快，不需要@njit()，njit()后运行时间大大增加（因为overhead）
def _operate(n1, n2, op):
    """混合操作符函数，将两个选股、多空蒙板混合为一个

    input:
        :param n1: np.ndarray: 第一个输入矩阵
        :param n2: np.ndarray: 第二个输入矩阵
        :param op: np.ndarray: 运算符
    return:
        :return: np.ndarray

    """
    if op == '+':
        return n2 + n1
    elif op in ['and', '&', '*']:
        return n2 * n1
    elif op == '-':
        return n2 - n1
    elif op == '/':
        return n2 / n1
    elif op in ['or', '|']:
        return 1 - (1 - n2) * (1 - n1)
    elif op in ['not', '~']:
        return -1 * n1
    else:
        raise ValueError(f'Unknown operand: ({op})!')


def add(x, y):
    """Сложение"""
    return x + y

def subtract(x, y):
    """Вычитание"""
    return x - y

def multiply(x, y):
    """Умножение"""
    return x * y

def divide(x, y):
    """Деление"""
    return x / y

print("Выберите операцию.")
print("1. Сложение")
print("2. Вычитание")
print("3. Умножение")
print("4. Деление")

# Запросить ввод пользователя
choice = input("Введите номер операции (1/2/3/4): ")

num1 = float(input("Введите первое число: "))
num2 = float(input("Введите второе число: "))

if choice == '1':
    print(num1, "+", num2, "=", add(num1, num2))

elif choice == '2':
    print(num1, "-", num2, "=", subtract(num1, num2))

elif choice == '3':
    print(num1, "*", num2, "=", multiply(num1, num2))

elif choice == '4':
    print(num1, "/", num2, "=", divide(num1, num2))
else:
    print("Некорректный ввод")


"""
COMS 4733: Computational Aspects of Robotics
HW1 Problem 5.2
Bug Algorithm
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
import math

def plot(start: tuple, end: tuple, c_obs: list, movements: list) -> None:
    c_obs.append(c_obs[0])
    x, y = np.array(c_obs).T
    plt.scatter(x, y)
    plt.plot(x, y)
    plt.fill_between(x, y)
    x_values = [start[0], end[0]]
    y_values = [start[1], end[1]]
    plt.scatter(x_values, y_values)
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.annotate("Start", (x_values[0], y_values[0]))
    plt.annotate("Goal", (x_values[1], y_values[1]))
    plt.plot(x_values, y_values, "--", linewidth=6)
    x_moves = []
    y_moves = []
    for a, b in movements:
        x_moves.append(a)
        y_moves.append(b)
    plt.scatter(x_moves, y_moves, zorder=5)
    plt.plot(x_moves, y_moves)
    plt.show()

def hit_m_line(movements: list, m_line: Path) -> bool:
    last_move = Path([movements[-2], movements[-1]])
    if last_move.intersects_path(m_line):
        return True
    return False

def bug(start: tuple, end: tuple, c_obs: list, d: float, delt: float) -> list:
    m_line = Path([start, end])
    movements = [list(start)]
    obs = Path(c_obs)
    if start[0] < end[0]:
        sign = 1
    if start[0] > end[0]:
        sign = -1
    slope = float(end[1] - start[1]) / float(end[0] - start[0])
    starting_angle = math.atan(slope)
    current_angle = starting_angle
    next_move = (
        movements[-1][0] + sign * d * np.cos(starting_angle),
        movements[-1][1] + sign * d * np.sin(starting_angle),
    )
    # move toward goal before the obstacle
    while not obs.contains_point(next_move):
        if start[0] < end[0]:
            if movements[-1][0] > end[0]:
                movements.pop()
                movements.append(end)
                plot(start, end, c_obs, movements)
                print(movements)
                return movements
        if start[0] > end[0]:
            if movements[-1][0] < end[0]:
                movements.pop()
                movements.append(end)
                plot(start, end, c_obs, movements)
                print(movements)
                return movements
        movements.append(list(next_move))
        next_move = (
            movements[-1][0] + sign * d * np.cos(current_angle),
            movements[-1][1] + sign * d * np.sin(current_angle),
        )
    # hit obstacle, turn and get out of the m-line's way
    while obs.contains_point(next_move):
        next_move = (
            movements[-1][0] + sign * d * np.cos(current_angle + delt),
            movements[-1][1] + sign * d * np.sin(current_angle + delt),
        )
        current_angle = current_angle + delt
    movements.append(list(next_move))
    next_move = (
        movements[-1][0] + sign * d * np.cos(current_angle),
        movements[-1][1] + sign * d * np.sin(current_angle),
    )
    while obs.contains_point(next_move):
        next_move = (
            movements[-1][0] + sign * d * np.cos(current_angle + delt),
            movements[-1][1] + sign * d * np.sin(current_angle + delt),
        )
        current_angle = current_angle + delt
    movements.append(list(next_move))
    # follow the boundary
    while not hit_m_line(movements, m_line):
        next_move = (
            movements[-1][0] + sign * d * np.cos(current_angle - delt),
            movements[-1][1] + sign * d * np.sin(current_angle - delt),
        )
        if obs.contains_point(next_move):
            next_move = (
                movements[-1][0] + sign * d * np.cos(current_angle),
                movements[-1][1] + sign * d * np.sin(current_angle),
            )

        else:
            prev_angle = current_angle + delt
            current_angle = current_angle - delt
            while not obs.contains_point(next_move):
                next_move = (
                    movements[-1][0] + sign * d * np.cos(current_angle - delt),
                    movements[-1][1] + sign * d * np.sin(current_angle - delt),
                )
                current_angle = current_angle - delt
            next_move = (
                movements[-1][0] + sign * d * np.cos(current_angle + delt),
                movements[-1][1] + sign * d * np.sin(current_angle + delt),
            )
            current_angle = current_angle + delt
        while obs.contains_point(next_move):
            next_move = (
                movements[-1][0] + sign * d * np.cos(current_angle + delt),
                movements[-1][1] + sign * d * np.sin(current_angle + delt),
            )
            current_angle = current_angle + delt
        new_path = Path([movements[-1], list(next_move)])
        if obs.intersects_path(new_path):
            next_move = (
                movements[-1][0] + sign * d * np.cos(prev_angle),
                movements[-1][1] + sign * d * np.sin(prev_angle),
            )
        movements.append(list(next_move))
    # clear sight to the goal --> delete the last move,
    # turn towards the direction of the m-line, then Go go go!
    movements.pop()
    last_obs_point = movements[-1]
    goal_slope = float(end[1] - last_obs_point[1]) / float(end[0] - last_obs_point[0])
    goal_angle = math.atan(goal_slope)
    turns = (goal_angle - current_angle) / delt
    next_move = (
        movements[-1][0] + sign * d * np.cos(current_angle + turns * delt),
        movements[-1][1] + sign * d * np.sin(current_angle + turns * delt),
    )
    if start[0] < end[0]:
        while movements[-1][0] < end[0]:
            movements.append(list(next_move))
            next_move = (
                movements[-1][0] + sign * d * np.cos(current_angle + turns * delt),
                movements[-1][1] + sign * d * np.sin(current_angle + turns * delt),
            )
    if start[0] > end[0]:
        while movements[-1][0] > end[0]:
            movements.append(list(next_move))
            next_move = (
                movements[-1][0] + sign * d * np.cos(current_angle + turns * delt),
                movements[-1][1] + sign * d * np.sin(current_angle + turns * delt),
            )
    movements.pop()
    movements.append(end)
    plot(start, end, c_obs, movements)
    print(movements)
    return movements

if __name__ == "__main__":
    start_1 = [1, 1]
    end_1 = [10, 19]
    c_obs_1 = [[6, 18], [3, 3], [9, 3]]
    d_1 = 0.5
    delt_1 = np.radians(5)
    bug(start_1, end_1, c_obs_1, d_1, delt_1)

    start_2 = [10, 1]
    end_2 = [1, 19]
    c_obs_2 = [[4, 12], [4, 6], [8, 6], [8, 12]]
    d_2 = 0.5
    delt_2 = np.radians(5)
    bug(start_2, end_2, c_obs_2, d_2, delt_2)

    start_3 = [2, 3]
    end_3 = [11, 3]
    c_obs_3 = [[4, 12], [4, 6], [8, 6], [8, 12]]
    d_3 = 0.5
    delt_3 = np.radians(5)
    bug(start_3, end_3, c_obs_3, d_3, delt_3)


import pytest

from simplerestapi.api import GetUpdateDeleteAPI, ListCreateAPI
from simplerestapi.exception import ConfigEndpointError
from simplerestapi.main import SimpleApi
from tests import models

from .conftest import ERROR_TEMPLATE

class TestMain:
    @pytest.fixture(autouse=True)
    def setup(self, db_url_test):
        self.simple_api = SimpleApi(models, db_url_test)

    def test_get_models(self):
        assert len(self.simple_api.models) == 2
        assert models.Car in self.simple_api.models
        assert models.CustomUser in self.simple_api.models

    def test_construct_routes(self):
        expect_routes = [
            {'path': '/car', 'endpoint': ListCreateAPI, 'model': models.Car},
            {'path': '/car/{id}', 'endpoint': GetUpdateDeleteAPI, 'model': models.Car},
            {
                'path': '/customuser',
                'endpoint': ListCreateAPI,
                'model': models.CustomUser,
            },
            {
                'path': '/customuser/{id}',
                'endpoint': GetUpdateDeleteAPI,
                'model': models.CustomUser,
            },
        ]
        assert len(self.simple_api.routes) == 4
        result = [{'path': r.path, 'endpoint': r.endpoint, 'model': r.model} for r in self.simple_api.routes]
        for expect in expect_routes:
            assert expect in result

def test_raise_exceptions_by_errors(db_url_test):
    models.Car.ConfigEndpoint.pagination = 'not int'
    models.CustomUser.ConfigEndpoint.denied_methods = ['not_exist_method']
    with pytest.raises(ConfigEndpointError) as exc:
        SimpleApi(models, db_url_test)
    expected_errors = [
        ERROR_TEMPLATE.format('Car', 'pagination', 'value is not a valid integer'),
        ERROR_TEMPLATE.format(
            'CustomUser',
            'denied_methods',
            'methods must be from list (\'get\', \'post\', \'delete\', \'put\', \'patch\')',
        ),
    ]
    assert exc.value.args[0] == 'Your models have errors:\n' + '\n'.join(expected_errors)
    assert exc.value.errors == expected_errors


def aBinario(oct):
    res = []
    while oct > 0:
        res.append(oct % 2)
        oct //= 2
    return list(
        reversed(
            (res + [0 for i in range(8 - len(res))])))

oct = input().split('.')

print(''.join([''.join([str(d) for d in aBinario(int(o))]) for o in oct]))


#!/usr/bin/env python3
"""Geometry module contains Polygon. Adopt `shapely` library and clean up unnecessary parts."""
from __future__ import annotations

from copy import deepcopy
from math import floor
from typing import TypedDict

import pyproj
from shapely.geometry import Polygon as ShapelyPolygon
from shapely.ops import transform

CRS_WGS84 = pyproj.CRS("EPSG:4326")
CRS_UTM = pyproj.CRS("EPSG:32618")

class GeoJSON(TypedDict):

    type: str
    """Geometry type. Should be polygon."""
    coordinates: list[list[list[float]]]
    """Coordinates extracted from open street map."""

class Polygon:
    """polygon geometry class to manipulate `shapely.geometry.Polygon`."""

    def __init__(self, geojson: GeoJSON):
        """Initialize Polygon class.

        Args:
            geojson (dict): GeoJSON of the polygon. It includes types and coordinates.
        """

        self.crs = CRS_WGS84
        self.geojson: GeoJSON = geojson
        # Initial geometry
        self._geo: ShapelyPolygon = ShapelyPolygon(
            self.geojson["coordinates"][0].copy()
        )

    def __repr__(self) -> str:

        return f"{self.__class__.__name__}(bounds={self.geometry.bounds}, area={self.geometry.area})"

    @property
    def geometry(self) -> ShapelyPolygon:
        """Return `shapely.geometry.Polygon`"""
        return self._geo

    @geometry.setter
    def geometry(self, other: ShapelyPolygon) -> None:
        """Set geometry from other."""
        self._geo = other

    @property
    def coord(self):
        if self._geo.exterior is not None:
            return self._geo.exterior.xy
        else:
            raise ValueError(
                "Graph: There is no exterior coordinate information!"
            )

    @property
    def utm_zone(self) -> int:
        """Calculate UTM zone from avg longitude to define CRS to project to"""
        avg_lng = self.geometry.representative_point().x  # type: ignore

        return int(floor((avg_lng + 180) / 6) + 1)

    @property
    def utm_crs(self) -> str:
        """Coordinate Reference System of the polygon in UTM"""
        return f"+proj=utm +zone={self.utm_zone} +ellps=WGS84 +datum=WGS84 +units=m +no_defs"

    @property
    def osm_coord(self) -> str:
        """Convert coordinates to OSM format. Partially copied from `osmnx` package."""
        s = ""
        separator = " "
        for coord in self.geojson["coordinates"][0].copy():
            # round floating point lats and longs to 6 decimals (ie, ~100 mm)
            # so we can hash and cache strings consistently
            s = f"{s}{separator}{coord[1]:.6f}{separator}{coord[0]:.6f}"
        return s

    @property
    def swap_coord(self) -> list[list[float]]:
        latlng = []
        for coord in self.geojson["coordinates"][0].copy():
            latlng.append([coord[1], coord[0]])
        return latlng

    def to_utm(self) -> Polygon:
        """Convert latitude and longitude to UTM coordinates.

        Note:
            - `pyproj` uses lat-lng order for `CRS_UTM`. Therefore, we need to swap the coordinate. (On the other hand, openstreet map returns coordinates in lng-lat order.)
        """

        if self.crs == CRS_UTM:
            return self
        else:
            project = pyproj.Transformer.from_crs(
                CRS_WGS84, CRS_UTM, always_xy=True
            ).transform

            geo = transform(project, ShapelyPolygon(self.swap_coord))
            self.geojson["coordinates"][0] = [
                [coord[1], coord[0]] for coord in geo.exterior.coords
            ]
            # Reconstruction of polygon using swapped coordinates.
            self._geo = ShapelyPolygon(self.geojson["coordinates"][0].copy())
            self.crs = CRS_UTM
            return self

    def to_lnglat(self) -> Polygon:
        """Convert UTM coordinates to latitude and longitude."""

        if self.crs == CRS_WGS84:
            return self
        else:
            project = pyproj.Transformer.from_crs(
                CRS_UTM, CRS_WGS84, always_xy=True
            ).transform
            geo = transform(project, ShapelyPolygon(self.swap_coord))

            # Bring back to long-lat order
            self.geojson["coordinates"][0] = [
                [coord[1], coord[0]] for coord in geo.exterior.coords
            ]
            self._geo = ShapelyPolygon(self.geojson["coordinates"][0].copy())

            self.crs = CRS_WGS84

            return self

    def buffered(self, buffer: float) -> Polygon:
        """Buffer the polygon by a given distance.

        Args:
            buffer (float): Distance to buffer the polygon by.
        """

        # Somehow, buffer function returns BaseGeometry. Therefore ignore type.
        self._geo = self._geo.buffer(buffer)  # type: ignore
        self.geojson["coordinates"][0] = [
            [coord[0], coord[1]] for coord in self._geo.exterior.coords  # type: ignore
        ]

        return self

    def copy(self) -> Polygon:
        return deepcopy(self)


N,M = map(int,input().split()) # 사람의 수, 파티의 수 입력
number = set(map(int,input().split()[1:])) # 진실을 아는 사람 번호
party = [] # 각 파티의 집합
cnt = 0

for i in range(M): # 각 파티에 참가하는 사람의 집합
    party.append(set(map(int,input().split()[1:])))

for i in range(M): # 파티의 수 만큼 반복
    for x in party: # 각 파티의 참가하는 사람 중 진실을 아는 사람이 포함되어 있는지 비교
        if x.isdisjoint(number) == False:
            number = number.union(x)

for i in range(M): # 각 파티의 참가하는 사람 중 진실을 아는 사람이 없는 경우 cnt 증가
    if party[i].isdisjoint(number) == True:
        cnt += 1

print(cnt)