from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold
from sklearn.preprocessing import StandardScaler
from xgboost import XGBClassifier
from AdvancedModels_XGBoost1 import *
from comet_ml import Experiment
import joblib

# Data Preprocessing
def preprocess_data(df):
    # Convert rebound to 0 and 1 instead of True and False
    df['rebound'] = df['rebound'].astype(int)
    # Rearranging columns to make it easier to process data
    df=df[['game_id','period','period_time','coordinates_x','coordinates_y','shot_distance','shot_angle','secondary_type','last_event_type','time_from_last_event(s)','distance_from_last_event','rebound','angle_change','speed','last_event_coordinates_x','last_event_coordinates_y','goal']]
    # Convert period_time to seconds
    df['period_time'] = df['period_time'].apply(lambda x: int(x.split(':')[0])*60 + int(x.split(':')[1]))
    # Convert secondary_type and last_event_type to numeric
    # df['secondary_type'] = df['secondary_type'].astype('category').cat.codes
    # df['last_event_type'] = df['last_event_type'].astype('category').cat.codes
    # Convert secondary_type and last_event_type to dummy variables
    df = pd.get_dummies(df, columns=['secondary_type','last_event_type'], drop_first=True)
    return df

# XGBoost on all features except goal
def XGBoost2(X_train, X_test, y_train, y_test):
    # Feature Scaling
    sc = StandardScaler()
    X_train = sc.fit_transform(X_train)
    X_test = sc.transform(X_test)

    # Hyper parameter tuning
    # Create the parameter grid based on the results of random search
    param_grid = {
        'max_depth': [3, 4, 5, 7],
        'learning_rate': [0.01, 0.05, 0.1],
        'min_child_weight': [1, 5, 10],
        'gamma': [0.5,1,1.5,2,5],
        'subsample': [0.6, 0.8, 1.0],
        'colsample_bytree': [0.6, 0.8, 1.0],
        'n_estimators': [100, 500, 1000],

    }

    # Create a based model
    xgb = XGBClassifier(n_estimators=1000, objective='binary:logistic', silent=True, nthread=1)
    stratifiedSearch = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)
    randomSearch = RandomizedSearchCV(estimator = xgb, param_distributions = param_grid, n_iter = 3, cv = stratifiedSearch, verbose=3, random_state=42, n_jobs = 4)

    # Fit the random search model
    randomSearch.fit(X_train, y_train)

    # Print best parameters and best score from random search
    # print("Best parameters from random search: ", randomSearch.best_params_)
    # print("Best score from random search: ", randomSearch.best_score_)
    # print("Best estimator from random search: ", randomSearch.best_estimator_)
    # print("Best index from random search: ", randomSearch.best_index_)
    # Store best parameters in a variable
    best_params = randomSearch.best_params_
    best_score = randomSearch.best_score_
    best_estimator = randomSearch.best_estimator_
    best_index = randomSearch.best_index_
    return best_params, best_score, best_estimator, best_index

def XGB_with_best_estimator_all_feature(X_train, X_test, y_train, y_test):
    # Training the XGBoost model on the Training set with best parameters from random search

    # Fit the model on the trainng data
    xgb = XGBClassifier(base_score=0.5, booster='gbtree', callbacks=None,
              colsample_bylevel=1, colsample_bynode=1, colsample_bytree=0.6,
              early_stopping_rounds=None, enable_categorical=False,
              eval_metric=None, feature_types=None, gamma=1.5, gpu_id=-1,
              grow_policy='depthwise', importance_type=None,
              interaction_constraints='', learning_rate=0.05, max_bin=256,
              max_cat_threshold=64, max_cat_to_onehot=4, max_delta_step=0,
              max_depth=7, max_leaves=0, min_child_weight=10,
              monotone_constraints='()', n_estimators=500, n_jobs=1, nthread=1,
              num_parallel_tree=1, predictor='auto')

    xgb.fit(X_train, y_train)

    # Predicting the Test set results
    y_pred = xgb.predict(X_test)

    # Making the Confusion Matrix
    from sklearn.metrics import confusion_matrix, accuracy_score
    # cm = confusion_matrix(y_test, y_pred)
    # print("The confusion matrix is : ",cm)

    # Accuracy
    print("The accuracy score is: ",accuracy_score(y_test, y_pred))

    # Making classification report
    from sklearn.metrics import classification_report
    print("The classification report: ",classification_report(y_test, y_pred))

    # save the model to joblib
    joblib.dump(xgb, 'xgb2.joblib')
    return xgb, X_test, y_test

def plot_roc_curve1(model,x_val,y_val, model_name):
    # ROC curve
    y_pred_proba = model.predict_proba(x_val)[:,1]
    xgb_dist_angle_roc_auc = roc_auc_score(y_val, y_pred_proba)
    fpr, tpr, thresholds = roc_curve(y_val, y_pred_proba)
    plt.figure()
    plt.plot(fpr, tpr, label=model_name+' (area = %0.2f)' % xgb_dist_angle_roc_auc)
    plt.plot([0, 1], [0, 1],'r--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver operating characteristic')
    plt.legend(loc="lower right")
    # plt.savefig('Log_ROC')
    plt.show()

def comet(path):
    df = load_data(path)
    df = preprocess_data(df)
    X_train, X_test, y_train, y_test = train_test_split(df.drop('goal', axis=1), df['goal'], test_size=0.2, random_state=42)
    params, score,estimator,index = XGBoost2(X_train, X_test, y_train, y_test)
    xgb2, X_test2, y_test2 = XGB_with_best_estimator_all_feature(X_train, X_test, y_train, y_test)
    plot_roc_curve1(xgb2,X_test2,y_test2,"XGBoost_all_features")
    shot_probability(xgb2, X_test2)
    cumulative_probability(xgb2, X_test2)
    calibration_plot(xgb2, X_test2, y_test2)

    # Log the experiment and the parameters to comet.ml
    experiment = Experiment(
        api_key=os.environ.get('COMET_API_KEY'),
        project_name='ift-6758-team-8',
        workspace="Rachel98",
    )
    xgb2 = joblib.load('xgb2.joblib')
    experiment.log_parameters(params)
    experiment.log_metric("best_score", score)
    experiment.log_metric("best_index", index)
    experiment.log_metric("best_estimator", estimator)
    # Log the metrics
    experiment.log_metric("accuracy", accuracy_score(y_test2, xgb2.predict(X_test2)))
    experiment.log_metric("precision", precision_score(y_test2, xgb2.predict(X_test2)))
    experiment.log_metric("recall", recall_score(y_test2, xgb2.predict(X_test2)))
    experiment.log_metric("f1", f1_score(y_test2, xgb2.predict(X_test2)))
    experiment.log_metric("roc_auc", roc_auc_score(y_test2, xgb2.predict(X_test2)))
    # experiment.log_metric("confusion_matrix", confusion_matrix(y_test2, xgb2.predict(X_test2)))
    experiment.log_metric("classification_report", classification_report(y_test2, xgb2.predict(X_test2)))
    # Log the model
    experiment.log_model(xgb2,'xgb2.joblib')
    experiment.end()

if __name__ == "__main__":
    comet("D:/NHlPro/data/M2_added_features_all.csv")


from odoo.tests import common, tagged
from odoo import fields
from dateutil.relativedelta import relativedelta

@tagged("post_install", "-at_install")
class TestEventPriceShared(common.SavepointCase):
    @classmethod
    def setUpClass(cls):
        super(TestEventPriceShared, cls).setUpClass()
        cls.registration_obj = cls.env['event.registration']
        cls.track_obj = cls.env['event.track']
        cls.customer = cls.env.ref('base.res_partner_12')
        cls.student1 = cls.env.ref('base.res_partner_18')
        cls.student2 = cls.env.ref('base.res_partner_10')
        cls.resource_calendar = cls.env.ref('resource.resource_calendar_std')
        cls.amounced_stage = cls.env.ref('event.event_stage_announced')
        cls.uom_unit = cls.env.ref('uom.product_uom_unit')
        vals = {'name': 'User event price shared',
                'login': 'ueps@avanzosc.es'}
        cls.user = cls.env['res.users'].create(vals)
        vals = {'name': 'employee event price shared',
                'user_id': cls.user.id}
        cls.env['hr.employee'].create(vals)
        cls.product = cls.env['product.product'].create({
            'name': 'product event price sahred',
            'default_code': 'PEPS',
            'uom_id': cls.uom_unit.id,
            'uom_po_id': cls.uom_unit.id,
            'type': 'service',
            'service_tracking': 'task_in_project',
            'invoice_policy': 'order',
            'service_policy': 'delivered_timesheet',
            'event_ok': True})
        cls.event = cls.env['event.event'].create({
            'name': 'Event event_price_shared',
            'date_begin': fields.Date.today(),
            'date_end': fields.Date.today() + relativedelta(days=+7),
            'shared_price_event': True,
            'organizer_id': cls.customer.id,
            'customer_id': cls.customer.id,
            'resource_calendar_id': cls.resource_calendar.id,
            'main_responsible_id': cls.user.id,
            'event_ticket_ids': [(0, 0, {'product_id': cls.product.id,
                                         'name': cls.product.name,
                                         'price': 50})]
            })

    def test_event_price_shared(self):
        self.event.stage_id = self.amounced_stage.id
        self.assertIsNot(self.event.project_id, False)
        track_vals = {'event_id': self.event.id,
                      'name': 'Session 1',
                      'date': fields.Date.today(),
                      'partner_id': self.user.partner_id.id}
        track = self.track_obj.create(track_vals)
        registration_vals = {
            'event_id': self.event.id,
            'partner_id': self.student1.id,
            'student_id': self.student1.id,
            'event_ticket_id': self.event.event_ticket_ids[0].id,
            'real_date_start': fields.Date.today()}
        registration1 = self.registration_obj.create(registration_vals)
        registration1.action_confirm()
        registration_vals = {
            'event_id': self.event.id,
            'partner_id': self.student2.id,
            'student_id': self.student2.id,
            'event_ticket_id': self.event.event_ticket_ids[0].id,
            'real_date_start': fields.Date.today()}
        registration2 = self.registration_obj.create(registration_vals)
        registration2.action_confirm()
        self.assertEqual(self.event.count_sale_orders, 2)
        sales = self.event.sale_order_lines_ids.mapped('order_id')
        for sale in sales:
            sale.action_confirm()
        self.assertIsNot(registration1.task_id, False)
        self.assertIsNot(registration2.task_id, False)
        self.assertNotEqual(registration1.task_id, registration2.task_id)
        track.button_session_done()
        self.assertEqual(len(track.account_analytic_line_ids), 2)


# Напишите программу, удаляющую из текста все слова, содержащие "абв".

from colorama import init, Fore

init(autoreset=True)

text = 'абв зеленый абвход три хр тр трабвбр пр учитьабв'

print(Fore.BLUE + f'Исходный текст:\n--> {text}')

final_text = ' '.join(
    list(filter(lambda x: not 'абв' in x, list(text.split()))))

print(Fore.GREEN +
      f'Текст после удаления слов, содержащих "абв":\n--> {final_text}')


import torch.nn as nn
import torch.nn.functional as F

# 构建网络
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.model1 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024, 64),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x


import os

import geopandas as gpd
import pandas as pd

def main(regions_file_path: str, municipalities_file_path: str) -> None:
    os.makedirs('./output/kommuner', exist_ok=True)

    data_reg = gpd.read_file(regions_file_path)
    print(data_reg.head())
    print(len(data_reg.index))
    data_reg.to_file('./output/kommuner/lan.geojson', driver="GeoJSON", encoding='utf-8')

    data_mun = gpd.read_file(municipalities_file_path)
    data_mun["LnKod"] = data_mun["KnKod"].apply(lambda kn_kod: kn_kod[:2])
    data_mun["LnNamn"] = data_mun["LnKod"].apply(lambda ln_kod: data_reg.loc[data_reg['LnKod'] == ln_kod, 'LnNamn'].iloc[0])
    print(data_mun.head())
    print(len(data_mun.index))
    for index, lan_namn in data_reg['LnNamn'].items():
        data_mun_reg = data_mun[data_mun['LnNamn'] == lan_namn]
        data_mun_reg.to_file('./output/kommuner/{}.geojson'.format(lan_namn), driver="GeoJSON", encoding='utf-8')

if __name__ == '__main__':
    pd.set_option('display.max_columns', None)
    main(
        "../data-collected/sverige-geodata/LanSweref99TM/Lan_Sweref99TM_region.shp",
        "../data-collected/sverige-geodata/KommunSweref99TM/Kommun_Sweref99TM_region.shp"
    )


import os, random, subprocess, sys
from methods import methods
from colorama import Fore, init
os.system ("clear")
try:
    list_files = subprocess.run(["adb"], stdout=subprocess.DEVNULL)
    if 1 == list_files.returncode:
        print (Fore.GREEN+"adb is installed!\n"+Fore.WHITE)
except:
    print(Fore.RED+"adb is not installed!")
    input = input("{0}install adb{1}[{2}y{1}/{2}n{1}]: ".format(Fore.BLUE, Fore.WHITE, Fore.GREEN))
    if input == "y":
        try:
            os.system("pkg install adbapt update && apt install wget && wget https://github.com/MasterDevX/Termux-ADB/raw/master/InstallTools.sh &")
            os.system("apt install adb")
            os.system("apt-get install adb")
        except:
            print(Fore.RED+"Failed to install")
            sys.exit(0)
    elif input == "n":
        print (Fore.RED+"without adb will not work"+Fore.WHITE)
        sys.exit()
    else:
        print("error")
        sys.exit()
#=====================================
banner = '''
\033[92m
          +hydNNNNdyh+
        +mMMMMMMMMMMMMm+
      `dMMm\033[0m:\033[92mNMMMMMMN\033[0m:\033[92mmMMd`
      hMMMMMMMMMMMMMMMMMMh
  \033[92m..  yyyyyyyyyyyyyyyyyyyy  ..
\033[92m.mMMm`MMMMMMMMMMMMMMMMMMMM`mMMm.            \033[0m Created by Deiwan\033[92m
\033[92m:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:
 MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM
 +yy+ MMMMMMMMMMMMMMMMMMMM +yy+
      mMMMMMMMMMMMMMMMMMMm
      `\++MMMMh++hMMMM++/`
          MMMMo  oMMMM
          MMMMo  oMMMM
          oNMm-  -mMИs\n'''
os.system("adb tcpip 5555")
print(Fore.BLUE+"           ZEROSPLOIT")
print(banner)
data = '''
{0}[{1}1{0}]  {2}Show Connected Devices
{0}[{1}2{0}]  {2}Restart Server
{0}[{1}3{0}]  {2}Connect / Disconnect
{0}[{1}4{0}]  {2}Access Shell on a phone
{0}[{1}5{0}]  {2}APK management
{0}[{1}6{0}]  {2}Screenshot/record
{0}[{1}7{0}]  {2}Show real time log of device
{0}[{1}8{0}]  {2}Reboots menu
{0}[{1}9{0}]  {2}Storage manager
{0}[{1}10{0}] {2}Dump System Info
{0}[{1}11{0}] {2}Get Battery Status
{0}[{1}12{0}] {2}Internet manager
{0}[{1}13{0}] {2}Remove Password
{0}[{1}14{0}] {2}Use Keycode
{0}[{1}15{0}] {2}Get Current Activity
{0}[{1}16{0}] {2}use custom adb command\n
{0}[{1}99{0}] {2}Exit   {0}[{1}0{0}] {2}Clear
'''.format(Fore.CYAN, Fore.RED, Fore.GREEN)
print (Fore.RED+"""list script commands""")
print (data)
md = methods
try:
    while True:
        option = input(Fore.GREEN + "zerosploit"+Fore.RED + "(menu) "+Fore.WHITE + "> ")
        if option == "0":
            os.system("clear")
            print (banner)
            print (data)
        elif option == "1":
            md.print_devices(md)
        elif option == "2":
            os.system("adb kill-server && adb start-server")
        elif option == "3":
            md.connect(md)
        elif option == "4":
            md.shell(md)
        elif option == "5":
            md.APK_management(md)
        elif option == "6":
            md.screens(md)
        elif option == "7":
            md.log(md)
        elif option == "8":
            md.reboots_menu(md)
        elif option == "9":
            md.storage_meneger(md)
        elif option == "10":
            md.dumpsys(md)
        elif option == "11":
            md.battery(md)
        elif option == "12":
    	    md.inter_manager(md)
        elif option == "13":
    	    md.rm_pass(md)
        elif option == "14":
            md.keycode(md)
        elif option == "15":
    	    md.activity(md)
        elif option =="16":
    	    md.custom_command(md)
        elif option == "99":
            os.system("adb disconnect")
            print (Fore.GREEN+"\nThank you for using ZeroSploit!\n\n"+Fore.BLUE+"sucessfully exit...\n"+Fore.WHITE)
            sys.exit()
        else:
            print (Fore.RED+" invalid option")
except KeyboardInterrupt:
    os.system("echo && adb disconnect")
    print (Fore.GREEN+"\nThank you for using ZeroSploit!\n\n"+Fore.BLUE+"sucessfully exit...\n"+Fore.WHITE)
    sys.exit()


# 만들 수 없는 금액
# 1,2,3 -> 1 ~ 6 까지
# 1,2,3,5 -> 1 ~ 11 까지
# 1,2,3,5,10 -> 1 ~ 21 까지
# 특정 target 이 동전 보다 작으면 -> answer
# target은 계속 업데이트 됨

n = int(input())
data = list(map(int, input().split()))
data.sort()

target = 1
for x in data:
  if target < x:
    break
  target += x

print(target)

algorithm with python/chapter 11. 실전_그리디/04.py


class CMyClass:

    __name = ""
    __id = 0;

    def __init__(self):
        self.__id = 0;
        self.__name = "inited name";

        self.a = 0;
        self.b = 1;

    def __str__(self):
        return "fuck yourself";

    @property
    def ID(self):
        return self.__id;

    @ID.setter
    def ID(self,num):
        if num < 0:
            print("暂不支持设置ID为负值");
            return
        self.__id = num;

    # 以下两个函数写了可以让类的对象可以在范型for里进行迭代
    def __iter__(self):
        return self;

    def __next__(self):
        self.a,self.b = self.b, self.a + self.b;
        if self.a > 1000: # 退出条件
            raise StopIteration;

        return self.a;

if __name__ == "__main__":
    aaa = CMyClass();
    aaa.ID = -123;
    print(aaa.ID);
    aaa.ID = 321;
    print(aaa.ID);

    print("Fib Starting");
    for i in aaa:
        print(i);


from tkinter import *
def btnclick(numbers):
    global operator
    operator=operator+str(numbers)
    text_input.set(operator)

def btncleardisplay():
    global operator
    operator=""
    text_input.set("")

def btnequalsinput():
    global operator
    sumup=str(eval(operator))
    text_input.set(sumup)
    operator=""

n=Tk()
text_input=StringVar()
operator=""
b1=Button(n,padx=9,bd=5,text="+",bg='blue',command=lambda:btnclick('+'),fg='yellow',font=('Arial',10,'bold'))
b1.place(x=220,y=250)
b2=Button(n,padx=10,bd=5,text="0",bg='grey',command=lambda:btnclick(0),fg='blue',font=('Arial',10,'bold'))
b2.place(x=15,y=250)

b20=Button(n,padx=10,bd=5,text=".",bg='grey',command=lambda:btnclick("."),fg='blue',font=('Arial',10,'bold'))
b20.place(x=85,y=250)

b3=Button(n,padx=11,bd=5,text="/",bg="blue",command=lambda:btnclick('/'),fg="yellow",font=('Arial',10,'bold'))
b3.place(x=220,y=100)

b5=Button(n,padx=9,bd=5,text="x",bg='blue',command=lambda:btnclick('*'),fg='yellow',font=('Arial',10,'bold'))
b5.place(x=220,y=150)
#===============================================================
b6=Button(n,padx=10,bd=5,text="7",bg='grey',command=lambda:btnclick(7),fg='blue',font=('Arial',10,'bold'))
b6.place(x=15,y=200)
b7=Button(n,padx=10,bd=5,text="8",bg='grey',command=lambda:btnclick(8),fg='blue',font=('Arial',10,'bold'))
b7.place(x=85,y=200)
b8=Button(n,padx=10,bd=5,text="9",bg="grey",command=lambda:btnclick(9),fg="blue",font=('Arial',10,'bold'))
b8.place(x=155,y=200)

#===============================================================
b10=Button(n,padx=10,bd=5,text="4",bg='grey',command=lambda:btnclick(4),fg='blue',font=('Arial',10,'bold'))
b10.place(x=15,y=150)
b11=Button(n,padx=10,bd=5,text="5",bg='grey',command=lambda:btnclick(5),fg='blue',font=('Arial',10,'bold'))
b11.place(x=85,y=150)
b12=Button(n,padx=10,bd=5,text="6",bg="grey",command=lambda:btnclick(6),fg="blue",font=('Arial',10,'bold'))
b12.place(x=155,y=150)
#==================================================================
b10=Button(n,padx=10,bd=5,text="1",bg='grey',command=lambda:btnclick(1),fg='blue',font=('Arial',10,'bold'))
b10.place(x=15,y=100)
b11=Button(n,padx=10,bd=5,text="2",bg='grey',command=lambda:btnclick(2),fg='blue',font=('Arial',10,'bold'))
b11.place(x=85,y=100)
b12=Button(n,padx=10,bd=5,text="3",bg="grey",command=lambda:btnclick(3),fg="blue",font=('Arial',10,'bold'))
b12.place(x=155,y=100)
b5=Button(n,padx=11,bd=5,text="-",bg='blue',command=lambda:btnclick('-'),fg='yellow',font=('Arial',10,'bold'))
b5.place(x=220,y=200)
b14=Button(n,padx=10,bd=5,text="=",bg='blue',fg='yellow',font=('Arial',10,'bold'),command=btnequalsinput)
b14.place(x=155,y=250)
b15=Button(n,padx=110,bd=4,text="Ac",bg='red',fg='yellow',font=('Arial',10,'bold'),command=btncleardisplay)
b15.place(x=15,y=65)

e1=Entry(n,font=('Arial',16,'bold'),textvariable=text_input,bd=20,insertwidth=0,bg="grey",justify='right').grid(columnspan=2)

n.title("Calculator_P&H")
n.geometry("280x300")
n.mainloop()


import sys
input = sys.stdin.readline
while True:
    nl = list(map(int,input().split()))
    if nl[0] == 0 and nl[1] == 0 and nl[2] == 0:
        break
    nl.sort()
    if nl[0] + nl[1] <= nl[2]:
        print("Invalid")
    elif nl[0] == nl[1] and nl[1] == nl[2]:
        print("Equilateral")
    elif nl[0] != nl[1] and nl[1] != nl[2] and nl[2] != nl[0]:
        print("Scalene")
    elif nl[0] == nl[1] or nl[1] == nl[2] or nl[2] == nl[0]:
        print("Isosceles")

백준/Bronze/5073. 삼각형과 세 변/삼각형과 세 변.py


# https://leetcode.com/problems/kth-missing-positive-number/
import pytest

class Solution:
    def findKthPositive(self, arr: list[int], k: int) -> int:
        first = arr[0]
        result = []
        i = 1
        l = 0
        while l < len(arr):
            first = arr[l]
            while i < first:
                result.append(i)
                i += 1
            i = first + 1
            l += 1

        if len(result) < k:
            i = arr[len(arr) - 1] + 1
            p = k
            while p >= 0:
                result.append(i)
                i += 1
                p -= 1

        return result[k - 1]

@pytest.mark.parametrize(
    ("arr", "k", "result"), [([2, 3, 4, 7, 11], 5, 9), ([1, 2, 3, 4], 2, 6)]
)
def test_missingpositive(arr: list[int], k: int, result: int) -> None:
    assert result == Solution().findKthPositive(arr, k)


"""
217. Contains Duplicate
Difficulty:Easy

Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

Example 1:

Input: nums = [1,2,3,1]
Output: true
Example 2:

Input: nums = [1,2,3,4]
Output: false
Example 3:

Input: nums = [1,1,1,3,3,4,3,2,4,2]
Output: true

Constraints:

1 <= nums.length <= 105
-109 <= nums[i] <= 109
"""

from typing import List

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        hash_table = {}
        for n in nums:
            if n not in hash_table:
                hash_table[n] = True
            else:
                return True
        return False

if __name__ == "__main__":
    solution = Solution()
    # print(solution.containsDuplicate(nums=[1, 2, 3, 1]))  # true
    print(solution.containsDuplicate(nums=[1, 2, 3, 4]))  # false
    # print(solution.containsDuplicate(nums=[1, 1, 1, 3, 3, 4, 3, 2, 4, 2]))  # true


"""
The TF-IDF scorer assigns a score the candidate participants similarly to the :class:`~nlp.weighting.tfidf.TFIDF` term-weighting scheme.
The IDF table does not have to use the event corpus.
Therefore this scorer can be used to promote candidate participants that appear frequently in the event corpus, but rarely outside of it.
"""

import math

from ..scorer import Scorer

class TFIDFScorer(Scorer):
    """
    The TF-IDF scorer assigns a score the candidate participants similarly to the :class:`~nlp.weighting.tfidf.TFIDF` term-weighting scheme.
    Therefore the scorer depends on an IDF table, given as a dictionary, and the number of documents in it.

    :ivar ~.idf: The IDF table used in conjunction with term weighting.
                 The keys are the terms, and the corresponding values are the number of documents in which they appear.
    :vartype ~.idf: dict
    :ivar ~.documents: The number of documents in the IDF table.
    :vartype ~.documents: int
    """

    def __init__(self, idf, documents, *args, **kwargs):
        """
        Create the term-weighting scheme with the IDF table and the number of documents in that scheme.

        :param idf: The IDF table used in conjunction with term weighting.
                    The keys are the terms, and the corresponding values are the number of documents in which they appear.
        :type idf: dict
        :param documents: The number of documents in the IDF table.
        :type documents: int

        :raises ValueError: When the document frequency of a term is higher than the number of the IDF documents.
        :raises ValueError: When the document frequency of a term is negative.
        :raises ValueError: When the number of documents is negative.
        """

        if max(idf.values()) > documents:
            raise ValueError(f"The number of documents ({documents}) must be greater or equal to the most common term ({max(idf.values())})")

        if min(idf.values()) < 0:
            raise ValueError("The IDF values must be non-negative")

        if documents < 0:
            raise ValueError("The number of documents in the IDF must be non-negative")

        super().__init__(*args, **kwargs)
        self.idf = idf
        self.documents = documents

    def score(self, candidates, *args, **kwargs):
        """
        Score the given candidates based on their relevance within the corpus.

        :param candidates: A list of candidate praticipants separated by document that were found in them earlier.
        :type candidates: list

        :return: A dictionary of participants and their associated scores.
        :rtype: dict
        """

        candidates = self._fold(candidates)

        """
        Go through each document, and then each of its candidates.
        For all of these candidates, increment their score by calculating the TF-IDF in that document.
        """
        scores = {}
        for candidate_set in candidates:
            for candidate in list(set(candidate_set)):
                scores[candidate] = scores.get(candidate, 0) + candidate_set.count(candidate) * math.log(self.documents / self.idf.get(candidate, 1), 10)

        return self._normalize(scores) if self.normalize_scores else scores


# -*- coding: utf-8 -*-
from __future__ import division, print_function, absolute_import

import os
import sys
import subprocess
from datetime import datetime
from pprint import pprint, pformat
import logging
from glob import glob
from collections import namedtuple

import numpy as np
import tensorflow as tf

_DEFAULT_SESSIONS_PATH = './_sessions/'
_PRINT_SUMMARY_FREQ = 50

logger = logging.getLogger(__name__)

###############################################################################
# Some helper functions
###############################################################################
def compute_accuracy(oneshot_labels, predictions, k):
    """Computes Top-k accuracy. Note that the behaviour of in_top_k differs from
    the top_k op in its handling of ties; if multiple classes have the same
    prediction value and straddle the top-k boundary, all of those classes are
    considered to be in the top k."""
    correct_mask = tf.nn.in_top_k(predictions, tf.argmax(oneshot_labels, 1),
                                  k, name="top_{}_correct_mask".format(k))
    return tf.reduce_mean(tf.cast(correct_mask, tf.float32)) * 100.00

def get_num_trainable_params():
    return sum(np.prod(p.get_shape().as_list())
               for p in tf.trainable_variables())

def get_timedelta(start_time):
    delta = datetime.now() - start_time

    # timedelta objects don't have hours and seconds!
    hours, remainder = divmod(delta.seconds, 3600)
    minutes, seconds = divmod(remainder, 60)

    return('[{:01d} day(s), {:02d} hr(s), {:02d} min(s)]'.
           format(delta.days, hours, minutes))

def time_per_step(start_time, num_steps):
    delta = datetime.now() - start_time

    return (delta / num_steps).total_seconds() * 1000

def get_resettable_mean_metric(values, scope):
    """Used for validation and test datasets where we're interested in computing
    accuracy over the entire dataset but due to their size still have to loop
    through them via batches. Since we do this multiple times during training
    we'd like the metric to be resettable."""

    with tf.variable_scope(scope) as s:
        mean_op, update_mean_op = tf.metrics.mean(values)

    # The .* regex makes filtering work in nested scopes
    variables = tf.get_collection(tf.GraphKeys.LOCAL_VARIABLES, '.*'+scope)

    if (len(variables) == 0):
        logger.error("Couldn't collect resettable mean \"{}\"".format(scope))
        sys.exit()

    reset_mean_op = tf.variables_initializer(variables)

    return {'value_op': mean_op,
            'update_op': update_mean_op,
            'reset_op': reset_mean_op}

def find_latest_chkpt(search_dir):
    try:

        sessions = glob(os.path.join(search_dir, '*/'))
        sessions.sort(key=os.path.getmtime, reverse=True)

        # We pick up index 2 from the sorted list instead of 0 or 1 because
        # we've already created the session directory for this run plus the
        # 'latest' symlink
        latest_session = sessions[2]

        latest_checkpoint = tf.train.latest_checkpoint(
                    os.path.join(latest_session, 'train_checkpoints'))

        logger.info('Latest session found: {}'.format(latest_session))
        logger.info('Resuming from checkpoint: {}'.format(latest_checkpoint))

        return latest_checkpoint
    except IndexError:
        logger.error("Couldn't find the checkpoint.")
        sys.exit()

def make_symbolic_link(sessions_dir, session_name):
    latest_symlink = os.path.join(sessions_dir, 'latest')

    try:
        os.symlink(session_name, latest_symlink)
    except FileExistsError:
        logger.debug("Replaced old symbolic link.")
        os.unlink(latest_symlink)
        os.symlink(session_name, latest_symlink)

def save_frozen_model(sess, output_node_names, output_path,
                      placeholder_values=None):
    """Args:
        placeholder_values: dictionary for injecting values into placeholders
    """
    vars_removed_graph_def = tf.graph_util.convert_variables_to_constants(
        sess, tf.get_default_graph().as_graph_def(), output_node_names)

    # We'd like to convert unrelated placeholders to consts at this stage.
    # Examples of such placeholders are "keep_prob" for Dropout layers or
    # "is_training" for BatchNorm layers. Unfortunately there is not an easy way
    # to do this when freezing the model. The only official API I'm aware of is
    # the "map_dict" argument in "tf.import_graph_def" method which means
    # placeholders values can be provided when loading the frozen models. That's
    # why we're doing a dummy load here to use that API and will store the
    # result. The downside is that calling import_graph_def() adds an extra
    # prefix which cannot be removed.

    with tf.Graph().as_default() as output_graph:
        tf.import_graph_def(
            vars_removed_graph_def,
            input_map=placeholder_values,
            name="frozen")

    tf.train.write_graph(
        output_graph,
        output_path,
        'frozen_model.pb',
        as_text=False)

def load_frozen_graph(frozen_graph):

    with open(frozen_graph, "rb") as f:
        restored_graph_def = tf.GraphDef()
        restored_graph_def.ParseFromString(f.read())

    # temporarily override the current default graph
    with tf.Graph().as_default() as graph:
        tf.import_graph_def(restored_graph_def, name="")

    return graph

def configure_logger(log_file):

    # Make sure we're not adding duplicate handlers if train() is called
    # multiple times.
    if not logger.handlers:

        logger.setLevel(logging.DEBUG)

        file_log_format = logging.Formatter(
                        fmt='%(asctime)s [%(levelname)s] %(message)s',
                        datefmt="%Y-%m-%d %H:%M:%S")

        console_log_format = file_log_format

        console_log_handler = logging.StreamHandler()
        console_log_handler.setFormatter(console_log_format)
        console_log_handler.setLevel(logging.INFO)

        logger.addHandler(console_log_handler)

        # Also store logs to a file
        file_log_handler = logging.FileHandler(log_file, 'w')
        file_log_handler.setFormatter(file_log_format)
        file_log_handler.setLevel(logging.DEBUG)
        logger.addHandler(file_log_handler)

def train(num_epochs, batch_size, dataset, model_fn, optimiser_fn,
          resume_from_latest_checkpoint=False, tag=None, freeze_model=False):

    # Hopefully the caller has already set the the graph-level random seed for
    # reproducibility.

    # Generate a unique name for this run. Used to name directories for
    # TensorBoard and stored checkpoints.
    this_session_name = datetime.now().strftime("%a-%d-%b-%I%M%p")
    if tag is not None:
        this_session_name = tag

    this_session_path = os.path.join(_DEFAULT_SESSIONS_PATH, this_session_name)
    os.makedirs(this_session_path)

    # Create a 'latest' symlink when necessary
    if len(os.listdir(_DEFAULT_SESSIONS_PATH)) > 1:
        make_symbolic_link(_DEFAULT_SESSIONS_PATH, this_session_name)

    SUMMARIES_PATH = os.path.join(this_session_path, 'summaries')
    TRAIN_CHECKPOINTS_PATH = os.path.join(
                this_session_path, 'train_checkpoints/train_checkpoint')
    BEST_VAL_CHECKPOINT_PATH = os.path.join(
                this_session_path, 'val_checkpoints/best_val_checkpoint')

    configure_logger(os.path.join(this_session_path, 'log.txt'))

    ###########################################################################
    # Placeholders
    ###########################################################################
    batch_images = tf.placeholder(
            tf.float32,
            [None, dataset.image_size, dataset.image_size, dataset.channels],
            'model_input')
    batch_labels = tf.placeholder(tf.float32, [None, dataset.num_classes])

    tf.summary.image('images', batch_images, max_outputs=6)

    is_training = tf.placeholder(tf.bool, name='is_training')
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')

    ###########################################################################
    # The Model
    ###########################################################################
    model = model_fn(batch_images, dataset.num_classes, is_training, keep_prob)

    ###########################################################################
    # Accuracy
    ###########################################################################
    batch_top1_accuracy_op = compute_accuracy(batch_labels, model.output, 1)
    batch_top5_accuracy_op = compute_accuracy(batch_labels, model.output, 5)

    top1_mean_acc_ops = get_resettable_mean_metric(batch_top1_accuracy_op,
                                                   'val_top1_mean')
    top5_mean_acc_ops = get_resettable_mean_metric(batch_top5_accuracy_op,
                                                   'val_top5_mean')

    tf.summary.scalar('Top-1 Training Accuracy', batch_top1_accuracy_op)
    tf.summary.scalar('Top-5 Training Accuracy', batch_top5_accuracy_op)

    # Validation-related summaries are added to a separate collection so that
    # they can be evaluated at separate time from training summaries.
    tf.summary.scalar('Validation Top-1 Accuracy',
                      top1_mean_acc_ops['value_op'],
                      collections=['VALIDATION_SUMMARIES'])

    ###########################################################################
    # Optimiser
    ###########################################################################
    global_step_op = tf.train.create_global_step()
    steps_per_epoch = dataset.num_train_samples // batch_size

    train_op, total_loss_op = optimiser_fn(batch_labels, model.output)

    ###########################################################################
    # TensorBoard Summaries/Checkpoints
    ###########################################################################
    train_summary_op = tf.summary.merge_all()
    val_summary_op = tf.summary.merge_all('VALIDATION_SUMMARIES')

    train_chkpt_op = tf.train.Saver(max_to_keep=5, keep_checkpoint_every_n_hours=2)
    best_val_chkpt_op = tf.train.Saver(max_to_keep=1)

    ###########################################################################
    # Session
    ###########################################################################

    def evaluate(dataset_init_fn, dataset_select_fn):
        """A helper function used to compute accuracy on validation and
        training dataset. Ideally we'd like to do this in one go but often the
        entire validation set is too big to fit in memory and therefore we
        still need to use batches for validation as well.

        Args:

        Returns:
            Top 1% and Top 5% accuracies
        """
        dataset_init_fn(sess)
        sess.run([top1_mean_acc_ops['reset_op'],
                  top5_mean_acc_ops['reset_op']])

        while True:
            try:
                _, images, labels = sess.run(dataset.next_element,
                                             feed_dict=dataset_select_fn())

                sess.run([top1_mean_acc_ops['update_op'],
                          top5_mean_acc_ops['update_op']],
                         feed_dict={batch_images: images,
                                    batch_labels: labels,
                                    is_training: False,
                                    keep_prob: 1.0})

            except tf.errors.OutOfRangeError:
                top1, top5 = sess.run([top1_mean_acc_ops['value_op'],
                                       top5_mean_acc_ops['value_op']])
                break

        return top1, top5

    def main_training_loop(sess, starting_epoch, num_epochs):

        #################################
        #    The Actual Training Loop
        #################################
        summary_writer = tf.summary.FileWriter(SUMMARIES_PATH, sess.graph)

        dataset.evaluate_handles(sess)

        train_start_time = summary_start_time = datetime.now()
        logger.info('Training start time: {}'.format(train_start_time))

        current_step = starting_epoch * steps_per_epoch
        best_epoch = 0
        best_validation_acc = 0.0
        testing_acc = 0.0

        # TODO: Put these in the right place
        # --------8<----------
        epoch_loss = tf.Variable(0, trainable=False, dtype=tf.float32)
        update_epoch_loss = tf.assign_add(epoch_loss, total_loss_op)
        reset_epoch_loss = tf.variables_initializer([epoch_loss])
        tf.summary.scalar('Epoch Training Loss', epoch_loss, collections=['EPOCH_SUMMARIES'])
        epoch_summary_op = tf.summary.merge_all('EPOCH_SUMMARIES')
        # --------8<----------

        for epoch_num in range(starting_epoch, num_epochs):

            sess.run(reset_epoch_loss)

            for batch_num in range(steps_per_epoch):

                _, images, labels = sess.run(
                                dataset.next_element,
                                feed_dict=dataset.from_training_set())

                sess.run([train_op, update_epoch_loss], feed_dict={batch_images: images,
                                              batch_labels: labels,
                                              is_training: True,
                                              keep_prob: 0.5})

                if batch_num % _PRINT_SUMMARY_FREQ == 0:

                    top1, top5, batch_summary = sess.run(
                            [batch_top1_accuracy_op, batch_top5_accuracy_op,
                             train_summary_op],
                            feed_dict={batch_images: images,
                                       batch_labels: labels,
                                       is_training: False,
                                       keep_prob: 1.0})

                    logger.debug('time/step: {:.2f} ms'.
                                 format(time_per_step(summary_start_time,
                                                      _PRINT_SUMMARY_FREQ)))

                    logger.info(
                        '{} Epoch {:>3} - Batch {:>4} - '
                        'Batch accuracy: top-1 {:5.2f}% - top-5: {:5.2f}%'
                        .format(get_timedelta(train_start_time), epoch_num,
                                batch_num, top1, top5))

                    summary_writer.add_summary(batch_summary, current_step)
                    summary_start_time = datetime.now()

                current_step += 1

            ########################
            #     End of Epoch
            ########################
            train_chkpt_op.save(sess, TRAIN_CHECKPOINTS_PATH, global_step_op)

            # Evaluate accuracy on the validation dataset (and testing dataset
            # if observed validation is the best seen)
            val_acc, _ = evaluate(dataset.initialize_validation,
                                  dataset.from_validation_set)

            summary_writer.add_summary(sess.run(val_summary_op), current_step)
            summary_writer.add_summary(sess.run(epoch_summary_op), current_step)

            logger.info('Epoch training loss {} - Validation accuracy: top-1 {:5.2f}%'.format(
                    epoch_loss.eval(), val_acc))

            if val_acc > best_validation_acc:
                logger.info('New Best Validation!')

                best_validation_acc = val_acc
                best_epoch = epoch_num

                testing_acc, _ = evaluate(dataset.initialize_testing,
                                          dataset.from_testing_set)

                best_val_chkpt_op.save(sess, BEST_VAL_CHECKPOINT_PATH, global_step_op)

            logger.info(
                'Testing accuracy to report: {:5.2f}% (error: {:5.2f}%) - '
                'Seen in epoch {}'
                .format(testing_acc, 100.0 - testing_acc, best_epoch))

        ########################
        #   End of training!
        ########################
        total_train_time = datetime.now() - train_start_time

        logger.info('End of training! Overall training time: {}'
                    .format(total_train_time))

        logger.info('Best observed validation accuracy: {:5.2f}%'
                    .format(best_validation_acc))
        logger.info('Testing accuracy to report: {:5.2f}% (error: {:5.2f}%) - '
                    'Seen in epoch {}'
                    .format(testing_acc, 100-testing_acc, best_epoch))

        summary_writer.close()

        return testing_acc, best_epoch

    def _print_env_details():
        logger.info("=====================================")
        """ A helper function to print env details. """
        logger.info("Timestamp: {}".format(datetime.now()))
        logger.info("TensorFlow Version: {}".format(tf.VERSION))
        logger.info('Session Name: "{}"'.format(this_session_name))
        logger.info("Total number of trainable parameters: {:,}"
                    .format(get_num_trainable_params()))
        logger.info("{} Epochs - Batch Size {}".format(num_epochs, batch_size))
        logger.debug(pformat(globals()))
        logger.debug(pformat(locals()))
        logger.debug("All Trainable Parameters:")
        for var in tf.trainable_variables():
            logger.debug('{} {}'.format(var.name, var.shape))
        logger.info("=====================================")

    _print_env_details()

    with tf.Session() as sess:

        sess.run(tf.global_variables_initializer())

        if resume_from_latest_checkpoint:
            train_chkpt_op.restore(sess, find_latest_chkpt(_DEFAULT_SESSIONS_PATH))
            starting_epoch = global_step_op.eval() // steps_per_epoch
            # TODO: Restore best validation details
        else:
            starting_epoch = 0

        #######################################################################
        # Let's train!
        #######################################################################
        acc, best_epoch = main_training_loop(sess, starting_epoch, num_epochs)

        if freeze_model:
            logger.info("Feezing the model ...")
            save_frozen_model(sess, ['model_output'], this_session_path,
                              {'is_training': False})
            logger.info("Frozen model saved.")

        sess.close()

    TestResults = namedtuple('TestResults', ['session_name', 'accuracy',
                                             'best_epoch', 'trained_model'])

    return TestResults(this_session_name, acc, best_epoch, model)


ten = []
i = 0
while i <= 10:
    a = int(input("Please input your '10' numbers: "))
    ten.append(a)
    i =  i+1
    print(ten)
ten = ten % 42
print(ten)
input("Press ENTER to Exit!")

'''
n_maksa_50_biar_50_supaya_bisa_diterima = int(input())
print(n_maksa_50_biar_50_supaya_bisa_diterima)
'''
'''
i = input()
i_akhir = i[-1]
i_akhir2 = i[0]
hasil = int(i_akhir) + int(i_akhir2)
print(hasil)
'''
'''
i = input()
i2 = input()
if i > i2:
    print(">")
if i < i2:
    print("<")
if i == i2:
    print("=")

'''


import math
import textwrap

from My_Own.quiz_api import get_quiz, quiz_categories
import pygame
from pygame import mixer

from My_Own.constants import BLACK, WHITE

# https://stackoverflow.com/questions/13034496/using-global-variables-between-files
import common

QUIZ_TRANSP_GREEN_LIGHT = (14, 213, 41, 210)
QUIZ_TRANSP_GREEN_HIGHL = (14, 213, 41, 150)
QUIZ_TRANSP_GREEN = (5, 85, 15, 150)
QUIZ_TRANSP_RED = (215, 2, 30, 210)
QUIZ_DARKGREEN = (10, 150, 25)

FONT_ROBOTO = "fonts/RobotoSlab-Medium.ttf"
screen_size = (800, 600)

return_screen = None
poketer = None

def rel_to_pix(rel_pos):
    x = rel_pos[0] * screen_size[0]
    y = rel_pos[1] * screen_size[1]
    pix_pos = (x, y)
    return pix_pos

def pix_to_rel(pix_pos):
    rel_x = pix_pos[0] / screen_size[0]
    rel_y = pix_pos[1] / screen_size[1]
    rel_pos = (rel_x, rel_y)
    return rel_pos

def music(filename):
    pygame.mixer.init()
    pygame.mixer.music.load(filename)
    pygame.mixer.music.play(-1)
    pygame.mixer.music.set_volume(0.1)

def sound(filename):
    sound = mixer.Sound(filename)
    sound.play()
    sound.set_volume(0.2)

class TextBox:
    def __init__(self, rel_pos, font_name, font_size, font_bold, color, text, line_width=100):
        self.position = (screen_size[0] * rel_pos[0], screen_size[1] * rel_pos[1])
        self.font_size = font_size
        self.font = pygame.font.Font(font_name, font_size)
        self.font.set_bold(font_bold)
        self.color = color
        self.text_lines = []
        self.text_lines_shadow = []
        self.line_width = line_width
        self.set_text(text)

    def set_text(self, text):
        lines_specified_width = textwrap.fill(text, self.line_width)
        chopped_lines = lines_specified_width.split('\n')
        self.text_lines = []
        self.text_lines_shadow = []
        for line in chopped_lines:
            line_surface = self.font.render(line, True, self.color)
            self.text_lines.append(line_surface)
            line_surface_shadow = self.font.render(line, True, BLACK)
            self.text_lines_shadow.append(line_surface_shadow)

    def render(self, screen):
        # time = pygame.time.get_ticks()
        # x_off = 2 * math.cos(time*3.14/1000)
        # y_off = 2 * math.sin(time*3.14/1000)

        # shadow
        for idx, text_surface_shadow in enumerate(self.text_lines_shadow):
            text_rect_shadow = text_surface_shadow.get_rect()
            text_rect_shadow.center = self.position[0] + 1, self.position[1] + 2 + idx * (self.font_size + 15)
            screen.blit(text_surface_shadow, text_rect_shadow)

        for idx, text_surface in enumerate(self.text_lines):
            text_rect = text_surface.get_rect()
            text_rect.center = self.position[0], self.position[1] + idx * (self.font_size + 15)
            screen.blit(text_surface, text_rect)

class Button:
    def __init__(self, rel_pos, rel_size, color, highlight, font_size, font_color, text):
        self.position = (screen_size[0] * rel_pos[0], screen_size[1] * rel_pos[1])
        self.size = (screen_size[0] * rel_size[0], screen_size[1] * rel_size[1])
        self.color = color
        self.highlight = highlight
        self.text = TextBox(rel_pos=rel_pos, font_name=FONT_ROBOTO,
                            font_size=font_size, font_bold=False, color=font_color, text=text, line_width=28)
        self.button_rect = pygame.Rect(self.position[0], self.position[1], self.size[0] - 3, self.size[1] - 3)
        self.button_rect.center = self.position[0], self.position[1]
        self.button_frame_rect = pygame.Rect(0, 0, self.size[0], self.size[1])  # x, y, width, height
        self.button_frame_rect.center = self.position[0], self.position[1]
        self.enabled = True

    def handle_keydown(self, key):
        pass

    def handle_mouse_button(self, mouse_button):
        mouse_pos = pygame.mouse.get_pos()
        if self.button_rect.collidepoint(mouse_pos) and mouse_button == 1 and self.enabled:
            return True
        else:
            return False

    def render(self, screen):
        pygame.draw.rect(screen, QUIZ_DARKGREEN, self.button_frame_rect, 4)  # button frame

        mouse_pos = pygame.mouse.get_pos()
        if self.button_rect.collidepoint(mouse_pos) and self.enabled:  # If mouse on button - highlight button
            if len(self.highlight) == 4:
                s = pygame.Surface((self.button_rect.width, self.button_rect.height),
                                   pygame.SRCALPHA)  # per-pixel alpha
                s.fill(self.highlight)  # notice the alpha value in the color
                screen.blit(s, self.button_rect)
            else:
                pygame.draw.rect(screen, self.highlight, self.button_rect)
        else:
            if len(self.color) == 4:
                s = pygame.Surface((self.button_rect.width, self.button_rect.height),
                                   pygame.SRCALPHA)  # per-pixel alpha
                s.fill(self.color)  # notice the alpha value in the color
                screen.blit(s, self.button_rect)
            else:
                pygame.draw.rect(screen, self.color, self.button_rect)

        self.text.render(screen)

class QuizStartScreen:
    def __init__(self, number_of_quiz_questions, quiz_categories, return_screen_, poketer_):
        global poketer
        #self.music = music_battle() #cl
        poketer = poketer_

        global return_screen
        return_screen = return_screen_
        music("quizz_music.mp3")
        background_image_raw = pygame.image.load("Background_forest.jpg").convert()
        self.background_image = pygame.transform.scale(background_image_raw, screen_size)
        self.title = TextBox(rel_pos=(0.5, 0.1), font_name=FONT_ROBOTO,
                             font_size=30, font_bold=False, color=WHITE, text="It's quiz time!")

        quiz_start_text = f"""You will now get to try your luck with {number_of_quiz_questions} tricky questions. If you get at least
{number_of_quiz_questions - 1} correct answers you win a health bonus. Which category do you choose?"""

        self.info_text = TextBox(rel_pos=(0.5, 0.25), font_name=FONT_ROBOTO,
                                 font_size=25, font_bold=False, color=WHITE, text=quiz_start_text, line_width=55)
        self.category_buttons = []
        self.button_positions = [(0.3, 0.6),
                                 (0.7, 0.6),
                                 (0.3, 0.8),
                                 (0.7, 0.8)]

        self.categories = list(quiz_categories.keys())
        for idx, category in enumerate(self.categories):
            quiz_button = Button(rel_pos=self.button_positions[idx], rel_size=(0.4, 0.2),
                                 color=QUIZ_TRANSP_GREEN, highlight=QUIZ_TRANSP_GREEN_HIGHL,
                                 font_size=22, font_color=WHITE, text=category)
            self.category_buttons.append(quiz_button)

    def handle_keydown(self, key):
        if key == pygame.K_SPACE:
            return QuizScreen()
        return self

    def handle_mouse_button(self, mouse_button):
        clicked_button_idx = None

        for category_button in self.category_buttons:
            if category_button.handle_mouse_button(mouse_button):
                clicked_button_idx = self.category_buttons.index(category_button)
                print(clicked_button_idx, "the_clicked_button")
                sound("music/cartoon_cymbal_hit.mp3")
                break

        if clicked_button_idx is not None:
            for category_button in self.category_buttons:
                category_button.enabled = False
            common.next_screen = QuizScreen(self.categories[clicked_button_idx])

    def render(self, screen):
        screen.fill(BLACK)
        screen.blit(self.background_image, (0, 0))
        self.title.render(screen)
        self.info_text.render(screen)

        for category_button in self.category_buttons:
            category_button.render(screen)

class QuizScreen:

    def __init__(self, quiz_category):
        background_image_raw = pygame.image.load("Background_forest.jpg").convert()
        self.background_image = pygame.transform.scale(background_image_raw, screen_size)
        self.title = None
        self.question_text = None
        self.quiz_answer_buttons = []
        self.current_question = 0

        self.number_of_quiz_questions = 5

        category, questions, correct_answers, answer_options = get_quiz(self.number_of_quiz_questions, quiz_category)
        self.category = category
        self.questions = questions
        self.correct_answers = correct_answers
        self.answer_options = answer_options
        self.correct_answer_idx = None
        self.num_of_correct_ans = 0
        self.button_positions = [(0.3, 0.6),
                                 (0.7, 0.6),
                                 (0.3, 0.8),
                                 (0.7, 0.8)]
        self.set_question()
        self.next_question_timeout = 0

    def set_question(self):

        self.next_question_timeout = 0
        self.current_question += 1

        if self.current_question == self.number_of_quiz_questions + 1:
            common.next_screen = QuizFinishedScreen(self.num_of_correct_ans, self.number_of_quiz_questions)
            return

        self.correct_answer_idx = self.answer_options[self.current_question - 1].index(
            self.correct_answers[self.current_question - 1])

        self.title = TextBox(rel_pos=(0.5, 0.1), font_name=FONT_ROBOTO,
                             font_size=25, font_bold=False, color=WHITE,
                             text=f"{self.category} - Question {self.current_question}")

        self.question_text = TextBox(rel_pos=(0.5, 0.25), font_name=FONT_ROBOTO,
                                     font_size=25, font_bold=False, color=WHITE,
                                     text=self.questions[self.current_question - 1], line_width=55)
        self.quiz_answer_buttons = []
        for idx, answer_option in enumerate(self.answer_options[self.current_question - 1]):
            quiz_button = Button(rel_pos=self.button_positions[idx], rel_size=(0.4, 0.2),
                                 color=QUIZ_TRANSP_GREEN, highlight=QUIZ_TRANSP_GREEN_HIGHL,
                                 font_size=22, font_color=WHITE, text=answer_option)
            self.quiz_answer_buttons.append(quiz_button)

    def handle_keydown(self, key):
        if key == pygame.K_SPACE:
            pass
            #self.set_question()
        return self

    def handle_mouse_button(self, mouse_button):
        clicked_button_idx = None
        quiz_button = None
        for quiz_button in self.quiz_answer_buttons:
            if quiz_button.handle_mouse_button(mouse_button):
                clicked_button_idx = self.quiz_answer_buttons.index(quiz_button)
                print(clicked_button_idx, "the_clicked_button")
                break

        if clicked_button_idx is not None:

            self.next_question_timeout = pygame.time.get_ticks()

            print("correct_answer_idx", self.correct_answer_idx)
            if clicked_button_idx == self.correct_answer_idx:
                print("Rätt svar!")
                quiz_button.color = QUIZ_TRANSP_GREEN_LIGHT
                self.num_of_correct_ans += 1
                sound("music/kids_cheering.mp3")
            else:
                quiz_button.color = QUIZ_TRANSP_RED
                self.quiz_answer_buttons[self.correct_answer_idx].color = QUIZ_TRANSP_GREEN_LIGHT
                print("Det var fel, rätt svar var knapp", self.correct_answer_idx)
                sound("music/dinosaur_growl.mp3")

            for quiz_button in self.quiz_answer_buttons:
                quiz_button.enabled = False

    def render(self, screen):
        time_now = pygame.time.get_ticks()
        if time_now - self.next_question_timeout > 2000 and self.next_question_timeout != 0:
            self.set_question()

        screen.fill(BLACK)
        screen.blit(self.background_image, (0, 0))

        self.title.render(screen)

        self.question_text.render(screen)

        for quiz_answer_button in self.quiz_answer_buttons:
            quiz_answer_button.render(screen)

class QuizFinishedScreen:
    def __init__(self, num_of_correct_ans, number_of_quiz_questions):

        pygame.mixer.music.stop()
        if num_of_correct_ans >= number_of_quiz_questions - 1:
            info_text = "WOW you're awesome! You get 10 health points as an award! "
            sound("music/kids_cheering.mp3")
            poketer.add_health(10)
        else:
            info_text = f"You need at least {number_of_quiz_questions - 1} correct answers to get a bonus. " \
                        f"Better luck next time!"
            sound("music/booing_crowd.mp3")

        background_image_raw = pygame.image.load("Background_forest.jpg").convert()
        self.background_image = pygame.transform.scale(background_image_raw, screen_size)

        self.title = TextBox(rel_pos=(0.5, 0.1), font_name=FONT_ROBOTO,
                             font_size=30, font_bold=False, color=WHITE,
                             text=f"You answered {num_of_correct_ans} out of {number_of_quiz_questions} questions correctly.")

        self.info_text = TextBox(rel_pos=(0.5, 0.25), font_name=FONT_ROBOTO,
                                     font_size=25, font_bold=False, color=WHITE, text=info_text, line_width=55)

        self.poketer_image = pygame.image.load("Green_monster_resized.png").convert_alpha()
        self.poketer_image = pygame.transform.smoothscale(self.poketer_image, (207, 207))

        self.quiz_finished_button = Button(rel_pos=(0.5, 0.85), rel_size=(0.3, 0.15),
                                           color=QUIZ_TRANSP_GREEN, highlight=QUIZ_TRANSP_GREEN_HIGHL,
                                           font_size=22, font_color=WHITE, text="CONTINUE")

    def handle_keydown(self, key):
        if key == pygame.K_ESCAPE:
            return QuizScreen()
        return self

    def handle_mouse_button(self, mouse_button):
        if self.quiz_finished_button.handle_mouse_button(mouse_button):
            #common.next_screen = QuizStartScreen(5, quiz_categories)
            common.next_screen = return_screen
            music("music/battle_time_1.mp3")

    def render(self, screen):
        screen.fill(BLACK)
        screen.blit(self.background_image, (0, 0))
        self.title.render(screen)
        self.info_text.render(screen)

        time = pygame.time.get_ticks()
        y_off = 5 * math.sin(time*3.14/1000)

        pixel_pos = rel_to_pix((0.5, 0.55))
        poketer_image_rect = self.poketer_image.get_rect()
        poketer_image_rect.center = pixel_pos[0], pixel_pos[1] + y_off
        screen.blit(self.poketer_image, poketer_image_rect)

        self.quiz_finished_button.render(screen)

def mainloop(screen, font):
    # Initial state
    current_screen = QuizStartScreen(5, quiz_categories, None, None)

    clock = pygame.time.Clock()
    while True:

        # Event handling
        ev = pygame.event.poll()

        if ev.type == pygame.KEYDOWN:
            current_screen = current_screen.handle_keydown(ev.key)

        elif ev.type == pygame.MOUSEBUTTONDOWN:
            current_screen.handle_mouse_button(ev.button)

        elif ev.type == pygame.QUIT:
            break

        if common.next_screen is not None:
            print("changing frames to", type(common.next_screen))
            current_screen = common.next_screen
            common.next_screen = None

        # Render
        current_screen.render(screen)

        pygame.display.update()
        clock.tick(30)

if __name__ == '__main__':
    common.common_init()

    pygame.init()
    screen = pygame.display.set_mode(screen_size)
    pygame.display.set_caption("PokeMood")
    font = FONT_ROBOTO
    mainloop(screen, font)
    pygame.quit()


def merge(left: list, right: list):
    sorted_array = []
    left_index = 0
    right_index = 0

    while left_index < len(left) and right_index < len(right):
        if left[left_index] < right[right_index]:
            sorted_array.append(left[left_index])
            left_index += 1
        else:
            sorted_array.append(right[right_index])
            right_index += 1

    while left_index < len(left):
        sorted_array.append(left[left_index])
        left_index += 1

    while right_index < len(right):
        sorted_array.append(right[right_index])
        right_index += 1

    return sorted_array

def merge_sort(array: list):
    if len(array) == 1:
        return array

    else:
        mid_array = len(array) // 2
        left_array = array[:mid_array]
        right_array = array[mid_array:]
        sorted_left_array = merge_sort(left_array)
        sorted_right_array = merge_sort(right_array)

        return merge(sorted_left_array, sorted_right_array)

print(merge_sort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]))


import doctest
import sys
import unittest

def load_test_cases_from_module_name(suite, module_name):
    __import__(module_name)
    module = sys.modules[module_name]
    module_suite = unittest.defaultTestLoader.loadTestsFromModule(module)
    suite.addTest(module_suite)

def load_doc_tests_from_module_name(suite, module_name):
    __import__(module_name)
    module = sys.modules[module_name]
    try:
        module_suite = doctest.DocTestSuite(module)
    except ValueError:
        # No tests found
        pass
    else:
        suite.addTest(module_suite)

if __name__ == "__main__":
    suite = unittest.TestSuite()
    load_test_cases_from_module_name(suite, "test_wx")
    load_doc_tests_from_module_name(suite, "test_doc")
    print(unittest.TextTestRunner().run(suite))


import os
from flask import Flask, render_template, request, jsonify, make_response
from flask_mail import Mail, Message
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from sanitizer import sanitize_dict

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ['SECRET_KEY']
app.config['MAIL_SERVER'] = os.environ['MAIL_SERVER']
app.config['MAIL_PORT'] = os.environ['MAIL_PORT']
app.config['MAIL_USE_TLS'] = os.environ['MAIL_USE_TLS']
app.config['MAIL_USERNAME'] = os.environ['MAIL_USERNAME']
app.config['MAIL_DEFAULT_SENDER'] = os.environ['MAIL_DEFAULT_SENDER']
app.config['MAIL_PASSWORD'] = os.environ['MAIL_PASSWORD']

limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)

mail = Mail(app)

@app.route('/')
def index():
    return render_template("index.html")

@app.route('/contact', methods=["POST"])
@limiter.limit("10 per minute")
def contact():
    req = request.get_json()
    try:
        if sanitize_dict(req):
            msg = Message("Subject", sender=os.environ['MAIL_USERNAME'], recipients=[req['email']])
            msg.body = req['message']
            msg.subject = req['subject']
            mail.send(msg)
            res = jsonify({"result": "success"})
            return make_response(res, 200)
        res = jsonify({"result": "error"})
        return make_response(res, 400)
    except Exception:
        res = jsonify({"result": "error"})
        return make_response(res, 400)

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


"""
让按钮永远在窗口右下角

基本原理：
一分为二界面
上面任意布局
按钮放在水平布局里面
"""

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class RightBottomButton(QWidget):
    def __init__(self):
        super(RightBottomButton, self).__init__()
        self.setWindowTitle('让按钮永远在右下角')
        self.resize(400,300)

        # 添加两个按钮
        okButton = QPushButton("确定")
        cancelButton = QPushButton("取消")

        # 设置水平盒布局
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)

        # 设置垂直盒布局
        vbox = QVBoxLayout()
        btn1 = QPushButton('按钮1')
        btn2 = QPushButton('按钮2')
        btn3 = QPushButton('按钮3')
        btn4 =  QPushButton('按钮4')
        btn5 = QPushButton('按钮5')

        vbox.addStrut(0)
        vbox.addWidget(btn1)
        vbox.addWidget(btn2)
        vbox.addWidget(btn3)
        vbox.addWidget(btn4)
        vbox.addWidget(btn5)

        # 把水平盒布局添加到垂直盒布局里
        vbox.addStrut(2)
        vbox.addLayout(hbox)

        # 应用于垂直盒布局
        self.setLayout(vbox)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = RightBottomButton()
    demo.show()
    sys.exit(app.exec_())


#!/usr/bin/env python

# This script depends on the 'rnsd_b' script to be loaded.

# This script aligns a moving structure to a fixed one.
# The distances between the atom pairs are stored in the b-value fields of the moved structure.
# The b-values are then used to automatically colorize the structure using a spectrum.

from pymol import cmd

def align_and_color(moving, fixed, maximum=None, native_color="blue"):
    if maximum == "0":
        maximum = None
    alignment_name = "alignment_" + moving
    cmd.align(moving, fixed, object=alignment_name, cycles=0)
    cmd.disable(alignment_name)
    rmsd_b(moving + " & " + alignment_name, fixed + " & " + alignment_name)
    cmd.color(native_color, fixed)
    cmd.spectrum("b", "green_red", moving, 0, maximum)

cmd.extend("align_and_color", align_and_color)


print("\nМОДУЛЬ 3")

def input_list():
    inp=" "
    sep=''
    lst=[]
    len_lst=1
    len_inp=0

    while (len_lst>len_inp):
        inp=input("Ведите цифры с одним из разделителей ',' '/' ';': ")
        inp = inp.strip(' ')
        lst = inp;
        count1=bool(lst.count(','))
        count2=bool(lst.count('/'))
        count3=bool(lst.count(';'))
        if((count1^count2^count3)&(not(count1&count2&count3))):
            if(count1):
                sep=','
            if(count2):
                sep='/'
            if(count3):
                sep=';'
            lst = []
            try:
                for var in inp.split(sep):
                    lst.append(int(var))
                    len_lst=len(lst)
                    len_inp=int(len(inp)/2+1)
            except:
                print("В данных есть не только цифры")
                len_lst=1
                len_inp=0
        else:
            print("Разделители дожны быть одного типа")
    print(lst)
    return lst
print("Первый список")
lst1 = list(input_list())
print("Второй список")
lst2 = list(input_list())
lst3 = lst1
for val in lst2:
    try:
        lst3.remove(val)
    except:
        a=0
print("Результирующий список\n",lst3)


from typing import List, Union
from numbers import Number, Integral
import random
from math import ceil, log2
import datetime

from msdsl.generator.generator import CodeGenerator
from msdsl.expr.expr import ModelExpr, wrap_constant, ModelOperator, Constant, \
    ArithmeticOperator, ComparisonOperator, BitwiseOperator, Concatenate, Array, \
    TypeConversion, SIntToReal, UIntToSInt, BitwiseInv, ArithmeticShift, \
    BitwiseAccess, RealToSInt, SIntToUInt, BitwiseAnd, BitwiseOr, BitwiseXor, \
    ArithmeticRightShift, ArithmeticLeftShift, LessThan, LessThanOrEquals, \
    GreaterThan, GreaterThanOrEquals, EqualTo, NotEqualTo, Sum, Product, Min, \
    Max, CompressUInt, RandomInteger, MT19937, LCG
from msdsl.expr.table import Table, RealTable, UIntTable, SIntTable
from msdsl.expr.format import UIntFormat, SIntFormat, RealFormat, IntFormat
from msdsl.expr.signals import Signal, AnalogSignal, DigitalSignal, AnalogInput, AnalogOutput, DigitalOutput, \
    DigitalInput, DigitalParameter, RealParameter
from msdsl.generator.tree_op import tree_op
from msdsl.generator.svreal import compile_range_expr, compile_width_expr, compile_exponent_expr
from msdsl.expr.analyze import signal_names, signal_name
from msdsl.generator.case_statement import case_statment

BITWISE_OP = {
    BitwiseAnd: '&',
    BitwiseOr: '|',
    BitwiseXor: '^'
}

SHIFT_OP = {
    ArithmeticLeftShift: '<<<',
    ArithmeticRightShift: '>>>'
}

INT_COMP_OP = {
    LessThan: '<',
    LessThanOrEquals: '<=',
    GreaterThan: '>',
    GreaterThanOrEquals: '>=',
    EqualTo: '==',
    NotEqualTo: '!='
}

REAL_COMP_OP = {
    LessThan: 'LT_REAL',
    LessThanOrEquals: 'LE_REAL',
    GreaterThan: 'GT_REAL',
    GreaterThanOrEquals: 'GE_REAL',
    EqualTo: 'EQ_REAL',
    NotEqualTo: 'NE_REAL'
}

REAL_ARITH_OP = {
    Sum: 'ADD_REAL',
    Product: 'MUL_REAL',
    Min: 'MIN_REAL',
    Max: 'MAX_REAL'
}

INT_ARITH_OP = {
    Sum:     lambda a, b: f'({a}+{b})',
    Product: lambda a, b: f'({a}*{b})',
    Min:     lambda a, b: f'(({a} < {b}) ? {a} : {b})',
    Max:     lambda a, b: f'(({a} > {b}) ? {a} : {b})'
}

class VerilogGenerator(CodeGenerator):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.init_file()

    def make_section(self, label):
        self.comment(label)

    def expr_to_signal(self, expr: ModelExpr):
        # before starting, make sure that the expression is wrapped in case it is a number
        expr = wrap_constant(expr)

        if isinstance(expr, Signal):
            return expr
        elif isinstance(expr, Constant):
            return self.make_constant(expr)
        elif isinstance(expr, ArithmeticOperator):
            return self.make_arithmetic_operator(expr)
        elif isinstance(expr, CompressUInt):
            return self.make_compress_uint(expr)
        elif isinstance(expr, RandomInteger):
            return self.make_random_integer(expr)
        elif isinstance(expr, BitwiseInv):
            return self.make_bitwise_inv(expr)
        elif isinstance(expr, BitwiseOperator):
            return self.make_bitwise_operator(expr)
        elif isinstance(expr, ComparisonOperator):
            return self.make_comparison_operator(expr)
        elif isinstance(expr, Concatenate):
            return self.make_concatenation(expr)
        elif isinstance(expr, Array):
            return self.make_array(expr)
        elif isinstance(expr, ArithmeticShift):
            return self.make_arithmetic_shift(expr)
        elif isinstance(expr, BitwiseAccess):
            return self.make_bitwise_access(expr)
        elif isinstance(expr, TypeConversion):
            return self.make_type_conversion(expr)
        else:
            raise Exception(f'Unknown expression type: {expr.__class__.__name__}')

    def make_signal(self, signal: Signal):
        if isinstance(signal.format_, RealFormat):
            # compile the range, width, and exponent expressions
            range = compile_range_expr(signal.format_.range_)
            width = compile_width_expr(signal.format_.width)
            exponent = compile_exponent_expr(signal.format_.exponent)

            # call the appropriate macro
            if width is None:
                self.macro_call('MAKE_REAL', signal.name, range)
            elif exponent is None:
                self.macro_call('MAKE_GENERIC_REAL', signal.name, range, width)
            else:
                self.macro_call('MAKE_FORMAT_REAL', signal.name, range, width, exponent)
        elif isinstance(signal.format_, IntFormat):
            self.writeln(f'{self.int_type_str(signal.format_)} {signal.name};')
        else:
            raise Exception('Invalid signal type.')

    def make_probe(self, s: Signal):
        if isinstance(s, Signal) and isinstance(s.format_, RealFormat):
            self.macro_call('PROBE_ANALOG', s.name)
        elif isinstance(s, Signal) and isinstance(s.format_, IntFormat):
            self.macro_call('PROBE_DIGITAL', s.name, str(s.format_.width))
        else:
            raise Exception('Invalid signal type.')

    def make_assign(self, input_: Signal, output: Signal, check_format=True):
        if isinstance(input_.format_, RealFormat) and isinstance(output.format_, RealFormat):
            self.macro_call('ASSIGN_REAL', input_.name, output.name)
        elif ((not check_format) or
              ((isinstance(input_.format_, SIntFormat) and isinstance(output.format_, SIntFormat)) or
               (isinstance(input_.format_, UIntFormat) and isinstance(output.format_, UIntFormat)))):
            self.digital_assignment(signal=output, value=input_.name)
        else:
            raise Exception(f'Input and output formats do not match: {input_.name} with {input_.format_} vs. {output.name} with {output.format_}')

    def make_mem(self, next_: Signal, curr: Signal, init: Union[Number, DigitalParameter, RealParameter]=0,
                 clk: Signal=None, rst: Signal=None, ce: Signal = None, check_format=True):
        # set defaults
        clk_name = clk.name if clk is not None else '`CLK_MSDSL'

        # determine name of reset signal
        if rst is None:
            rst_name = '`RST_MSDSL'
        elif isinstance(rst, str):
            rst_name = rst
        else:
            rst_name = rst.name

        ce_name = ce.name if ce is not None else "1'b1"

        # create memory for real number
        if isinstance(next_.format_, RealFormat) and isinstance(curr.format_, RealFormat):
            # determine string expression for the initial value
            if isinstance(init, Number):
                init_str = str(init)
            elif isinstance(init, RealParameter):
                init_str = init.param_name
            elif isinstance(init, str):
                init_str = init
            else:
                raise Exception(f'Could not determine string representation for initial value {init}')

            # call the macro to create the memory
            self.macro_call('DFF_INTO_REAL', next_.name, curr.name, rst_name, clk_name, ce_name, init_str)
        # create memory for integer
        elif ((not check_format) or
              ((isinstance(next_.format_, SIntFormat) and isinstance(curr.format_, SIntFormat)) or
              (isinstance(next_.format_, UIntFormat) and isinstance(curr.format_, UIntFormat)))):
            # check that initial value is valid, if it's number. range checking for DigitalParameters is not
            # yet implemented
            if check_format:
                if isinstance(init, Number):
                    assert (curr.format_.min_val <= init <= curr.format_.max_val), \
                        (f'Initial value {init} does not fit in the range [{curr.format_.min_val}, '
                         f'{curr.format_.max_val}] of signal {curr.name}.')
                else:
                    print(f'Warning: could not validate range of init value {init}')

            # check that the widths of next_ and curr match
            if check_format:
                assert next_.format_.width == curr.format_.width, \
                    (f'The widths of {next_.name} ({next_.format_.width}) does not match '
                     f'the width of {curr.name} ({curr.format_.width}).')

            # determine string expression for the initial value
            if isinstance(init, Number):
                init_str = str(init)
            elif isinstance(init, DigitalParameter):
                init_str = init.name
            elif isinstance(init, str):
                init_str = init
            else:
                raise Exception(f'Could not determine string representation for initial value {init}')

            # call the macro to create the memory
            self.macro_call('MEM_INTO_DIGITAL', next_.name, curr.name, ce_name, clk_name,
                            rst_name, init_str, str(next_.format_.width))
        else:
            raise Exception(
                f'Next and current formats do not match: {next_.name} '
                f'with {next_.format_} vs. {curr.name} with {curr.format_}'
            )

    def make_sync_rom(self, signal: Signal, table: Table, addr: Signal,
                      clk: Signal=None, ce: Signal=None):
        # set defaults
        clk_name = clk.name if clk is not None else "`CLK_MSDSL"
        ce_name = ce.name if ce is not None else "1'b1"

        if isinstance(table, RealTable):
            self.macro_call('SYNC_ROM_INTO_REAL', addr.name, signal.name, clk_name,
                            ce_name, table.addr_bits, table.width, f'"{table.path.as_posix()}"',
                            table.exp)
        elif isinstance(table, SIntTable):
            self.macro_call('SYNC_ROM_INTO_SINT', addr.name, signal.name, clk_name,
                            ce_name, table.addr_bits, table.width, f'"{table.path.as_posix()}"')
        elif isinstance(table, UIntTable):
            self.macro_call('SYNC_ROM_INTO_UINT', addr.name, signal.name, clk_name,
                            ce_name, table.addr_bits, table.width, f'"{table.path.as_posix()}"')
        else:
            raise Exception(f'Unknown table type: {type(table)}')

    def make_sync_ram(self, signal: AnalogSignal, format_: RealFormat, addr: DigitalSignal,
                      clk: DigitalSignal=None, ce: DigitalSignal=None, we: DigitalSignal=None,
                      din: DigitalSignal=None):
        # set defaults
        din_name = din.name if din is not None else "'0"
        clk_name = clk.name if clk is not None else "`CLK_MSDSL"
        ce_name = ce.name if ce is not None else "1'b1"
        we_name = we.name if we is not None else "1'b0"

        # call the SVREAL macro
        self.macro_call('SYNC_RAM_INTO_REAL', addr.name, din_name, signal.name,
                        clk_name, ce_name, we_name, addr.format_.width, format_.width,
                        format_.exponent)

    def start_module(self, name: str, ios: List[Signal], real_params: List, digital_params: List=None):
        # set defaults
        if digital_params is None:
            digital_params = []

        # clear default nettype to make debugging easier
        self.default_nettype('none')
        self.writeln()

        # module name
        self.write(f'module {name}')

        # parameters
        parameters = []
        parameters += [f'parameter real {real_param.param_name}={real_param.default}' for real_param in real_params]
        for dig_param in digital_params:
            dig_param_str = 'parameter '
            if dig_param.signed:
                dig_param_str += 'signed '
            if dig_param.width > 1:
                dig_param_str += f'[{dig_param.width-1}:0] '
            dig_param_str += f'{dig_param.name}={dig_param.default}'
            parameters += [dig_param_str]
        parameters += [self.real_param_str(io) for io in ios if isinstance(io.format_, RealFormat)]
        if len(parameters) > 0:
            self.write(' #')
            self.comma_separated_lines(parameters)

        # ports
        ports = [self.port_str(io) for io in ios]
        if len(ports) > 0:
            self.write(' ')
            self.comma_separated_lines(ports)

        # end module definition and indent
        self.write(';' + self.line_ending)
        self.indent()

        # assign parameters to constants
        if len(real_params) > 0:
            self.comment('Assign real parameters to constant wires')
        for real_param in real_params:
            self.macro_call('MAKE_CONST_REAL', real_param.param_name, real_param.signal_name)

    def end_module(self):
        self.dedent()
        self.writeln('endmodule')
        self.writeln()
        self.default_nettype('wire')

    def make_constant(self, expr: Constant):
        output = Signal(name=next(self.namer), format_=expr.format_)

        if isinstance(expr.format_, RealFormat):
            # compile the range, width, and exponent expressions.
            if isinstance(expr.value, Integral):
                # avoid a synthesis corner-case:
                # https://forums.xilinx.com/t5/Synthesis/Possible-synthesis-bug-casting-integer-to-real-in-a-function/td-p/1140910
                const = str(float(expr.value))
            else:
                const = str(expr.value)
            range = compile_range_expr(expr.format_.range_)
            width = compile_width_expr(expr.format_.width)
            exponent = compile_exponent_expr(expr.format_.exponent)

            # call the appropriate macro
            if width is None:
                self.macro_call('MAKE_CONST_REAL', const, output.name)
            elif exponent is None:
                self.macro_call('MAKE_GENERIC_CONST_REAL', const, output.name, width)
            else:
                self.macro_call('MAKE_FORMAT_REAL', output.name, range, width, exponent)
                self.macro_call('ASSIGN_CONST_REAL', const, output.name)
        elif isinstance(expr.format_, IntFormat):
            self.make_signal(output)
            self.digital_assignment(output, expr.value)
        else:
            raise ValueError(f'Unknown expression format type: ' + expr.format_.__class__.__name__)

        return output

    def make_arithmetic_operator(self, expr: ArithmeticOperator):
        # first check for some special cases involving multiplication.  this is an attempt to get most multiplications
        # to consume only one DSP
        if isinstance(expr, Product) and (len(expr.operands) == 2) and isinstance(expr.format_, RealFormat):
            if isinstance(expr.operands[0], Constant) or isinstance(expr.operands[1], Constant):
                return self.make_constant_mul_signal(expr=expr)
            elif (isinstance(expr.operands[0], Array) and expr.operands[0].all_constants) or \
                 (isinstance(expr.operands[1], Array) and expr.operands[1].all_constants):
                return self.make_constant_array_mul_signal(expr=expr)

        # compile the inputs to signals
        inputs_ = [self.expr_to_signal(operand) for operand in expr.operands]

        # define the operator used to build up the expression.  it takes two signals as arguments and returns
        # a signal bound to the result
        def operator(a, b):
            # determine the parameters of the output signal
            name = next(self.namer)
            format_ = expr.function(a.format_, b.format_)

            # create the output signal
            c = Signal(name=name, format_=format_)

            # assign the result
            if isinstance(expr.format_, RealFormat):
                self.macro_call(REAL_ARITH_OP[type(expr)], a.name, b.name, c.name)
            elif isinstance(expr.format_, IntFormat):
                self.make_signal(c)
                value = INT_ARITH_OP[type(expr)](a.name, b.name)
                self.digital_assignment(signal=c, value=value)
            else:
                raise Exception(f'Unknown expression format type: {expr.format_.__class__.__name__}')

            # return the output signal
            return c

        # apply the operator in a tree-wise fashion
        output = tree_op(operands=inputs_, operator=operator)

        # return the resulting signal
        return output

    def make_constant_mul_signal(self, expr: Product):
        # figure out which operand is the constant and which is the signal (note: if both are constants, that is
        # not handled in a special fashion.  although that shouldn't usually occur due to the way that expressions
        # are built up.)
        if isinstance(expr.operands[0], Constant):
            constant = expr.operands[0]
            signal = self.expr_to_signal(expr.operands[1])
        elif isinstance(expr.operands[1], Constant):
            constant = expr.operands[1]
            signal = self.expr_to_signal(expr.operands[0])
        else:
            raise Exception(f'This expression does not represent a constant times a signal: {expr}.')

        # create the output signal
        output = Signal(name=next(self.namer), format_=expr.format_)

        # if multiplying by -1, use a special macro to reduce utilization
        if constant.value == -1:
            self.macro_call('NEGATE_REAL', signal.name, output.name)
        elif isinstance(constant.value, Integral):
            # avoid a synthesis corner-case:
            # https://forums.xilinx.com/t5/Synthesis/Possible-synthesis-bug-casting-integer-to-real-in-a-function/td-p/1140910
            self.macro_call('MUL_CONST_REAL', str(float(constant.value)), signal.name, output.name)
        else:
            self.macro_call('MUL_CONST_REAL', str(constant.value), signal.name, output.name)

        # return the output signal
        return output

    def make_constant_array_mul_signal(self, expr: Product):
        # figure out which operand is the constant array and which is the signal (note: if both are constant arrays,
        # that is not handled in a special fashion.  although that shouldn't usually occur due to the way that
        # expressions are built up.)
        if isinstance(expr.operands[0], Array) and expr.operands[0].all_constants:
            constant_array = expr.operands[0]
            signal = self.expr_to_signal(expr.operands[1])
        elif isinstance(expr.operands[1], Array) and expr.operands[1].all_constants:
            constant_array = expr.operands[1]
            signal = self.expr_to_signal(expr.operands[0])
        else:
            raise Exception(f'This expression does not represent a constant array times a signal: {expr}.')

        # create the output signal
        output = Signal(name=next(self.namer), format_=expr.format_)

        # create a short real variable to be assigned the selected value from the array
        array_name = next(self.namer)
        self.macro_call('MAKE_SHORT_REAL', array_name, compile_range_expr(constant_array.format_.range_))

        # perform the multiplication
        self.macro_call('MUL_REAL', array_name, signal.name, output.name)

        # compile the array address to a signal
        address = self.expr_to_signal(constant_array.address)

        # compute the valuess to go in the array
        values = [f'`FROM_REAL({element.value}, {array_name})' for element in constant_array.elements]

        # create the array itself
        case_statment(gen=self, sel=address.name, var=array_name, values=values, default=0)

        # return the output signal
        return output

    def make_compress_uint(self, expr: CompressUInt):
        # compile the input to a signal
        input_ = self.expr_to_signal(expr.operand)

        # determine the parameters of the output signal
        name = next(self.namer)
        format_ = expr.format_
        output = Signal(name=name, format_=format_)

        # assign the result
        self.macro_call('COMPRESS_UINT', input_.name, str(input_.format_.width), output.name)

        # return the resulting signal
        return output

    def make_random_integer(self, expr: RandomInteger):
        # validate input
        assert expr.format_.width == 32, 'Only width 32 is supported at this time.'

        # set defaults

        if expr.clk is None:
            clk = '`CLK_MSDSL'
        elif isinstance(expr.clk, str):
            clk = expr.clk
        else:
            clk = expr.clk.name

        if expr.rst is None:
            rst = '`RST_MSDSL'
        elif isinstance(expr.rst, str):
            rst = expr.rst
        else:
            rst = expr.rst.name

        if expr.cke is None:
            cke = "1'b1"
        elif isinstance(expr.cke, str):
            cke = expr.cke
        else:
            cke = expr.cke.name

        if expr.seed is None:
            seed = random.randint(0, (1<<expr.format_.width)-1)
            seed = self.hex_format(seed, expr.format_.width)
        elif isinstance(expr.seed, Integral):
            assert 0 <= expr.seed <= ((1<<expr.format_.width)-1), \
                'Seed is out of range.'
            seed = self.hex_format(expr.seed, expr.format_.width)
        elif isinstance(expr.seed, str):
            seed = expr.seed
        else:
            seed = expr.seed.name

        # determine the parameters of the output signal
        name = next(self.namer)
        output = Signal(name=name, format_=expr.format_)

        # assign the result
        if isinstance(expr, MT19937):
            self.macro_call('MT19937', clk, rst, cke, seed, output.name)
        elif isinstance(expr, LCG):
            self.macro_call('LCG_MSDSL', clk, rst, cke, seed, output.name)
        else:
            raise Exception(f'Unsupported expression: {expr}')

        # return the resulting signal
        return output

    def make_array(self, expr: Array):
        # make the output signal that will hold the results
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        # compile the array elements and address to signals
        elements = [self.expr_to_signal(element) for element in expr.elements]
        address  = self.expr_to_signal(expr.address)

        # extra step for analog signals -- they must be aligned to the output format
        if isinstance(expr.format_, RealFormat):
            # rename the elements list to indicate these values are not aligned to the output format
            non_aligned_elements = elements

            # created an "aligned" version of each signal
            elements = [Signal(name=next(self.namer), format_=expr.format_) for _ in range(len(expr))]
            for element, non_aligned_element in zip(elements, non_aligned_elements):
                self.make_signal(element)
                self.make_assign(input_=non_aligned_element, output=element)

        # now create the array
        case_statment(gen=self, sel=address.name, var=output.name, values=signal_names(elements), default=0)

        # and last return the output signal
        return output

    def make_bitwise_inv(self, expr: BitwiseInv):
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        input_ = self.expr_to_signal(expr.operand)
        value = f'~{input_.name}'
        self.digital_assignment(signal=output, value=value)

        return output

    def make_bitwise_operator(self, expr: BitwiseOperator):
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        inputs = [self.expr_to_signal(operand) for operand in expr.operands]
        value = BITWISE_OP[type(expr)].join(signal_names(inputs))
        self.digital_assignment(signal=output, value=value)

        return output

    def make_comparison_operator(self, expr: ComparisonOperator):
        output = Signal(name=next(self.namer), format_=expr.format_)

        lhs = self.expr_to_signal(expr.lhs)
        rhs = self.expr_to_signal(expr.rhs)

        if isinstance(lhs.format_, RealFormat) and isinstance(rhs.format_, RealFormat):
            self.macro_call(REAL_COMP_OP[type(expr)], lhs.name, rhs.name, output.name)
        elif isinstance(lhs.format_, IntFormat) and isinstance(rhs.format_, IntFormat):
            # make the output signal
            self.make_signal(output)

            # assign the output signal
            value = f"({lhs} {INT_COMP_OP[type(expr)]} {rhs}) ? 1'b1 : 1'b0"
            self.digital_assignment(signal=output, value=value)
        else:
            raise ValueError(f'Unknown format type combination for LHS and RHS: {lhs.format_.__class__.__name__} and {rhs.format_.__class__.__name__}.')

        return output

    def make_concatenation(self, expr: Concatenate):
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        inputs_ = [self.expr_to_signal(operand) for operand in expr.operands]
        value = '{' + ', '.join(signal_names(inputs_)) + '}'
        self.digital_assignment(signal=output, value=value)

        return output

    def make_arithmetic_shift(self, expr: ArithmeticShift):
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        input_ = self.expr_to_signal(expr.operand)
        value = f'{input_.name} {SHIFT_OP[type(expr)]} {expr.shift}'
        self.digital_assignment(signal=output, value=value)

        return output

    def make_bitwise_access(self, expr: BitwiseAccess):
        output = Signal(name=next(self.namer), format_=expr.format_)
        self.make_signal(output)

        input_ = self.expr_to_signal(expr.operand)
        value = f'{input_.name}[{expr.msb}:{expr.lsb}]'
        self.digital_assignment(signal=output, value=value)

        return output

    def make_type_conversion(self, expr: TypeConversion):
        # make the output signal
        output = Signal(name=next(self.namer), format_=expr.format_)

        # compile the input expression to a signal
        input_ = self.expr_to_signal(expr.operand)

        # handle the various cases
        if isinstance(expr, SIntToReal):
            self.macro_call('INT_TO_REAL', input_.name, str(input_.format_.width), output.name)
        elif isinstance(expr, RealToSInt):
            self.macro_call('REAL_TO_INT', input_.name, str(output.format_.width), output.name)
        elif isinstance(expr, UIntToSInt):
            # sanity check
            assert output.format_.width >= input_.format_.width+1, \
                f'Output SInt width ({output.format_.width}) is not at least one greater than the input UInt width ({input_.format_.width}).'

            # make the output signal
            self.make_signal(output)

            # construct string representation of new SInt
            num_zeros = output.format_.width - input_.format_.width
            value = f'{{{self.zero_const(num_zeros)}, {input_.name}}}'

            # make the assignment
            self.digital_assignment(signal=output, value=value, comment='UInt -> SInt')
        elif isinstance(expr, SIntToUInt):
            # sanity check
            assert output.format_.width >= input_.format_.width-1, \
                f'Output UInt width ({output.format_.width}) is not at least one less than the input SInt width ({input_.format_.width}).'

            # make the output signal
            self.make_signal(output)

            # then trim off the sign bit
            value = f'{input_.name}[{input_.format_.width-2}:0]'

            # pad with zeros if necessary
            num_zeros = output.format_.width - (input_.format_.width - 1)
            if num_zeros > 0:
                value = f'{{{self.zero_const(num_zeros)}, {value}}}'

            # make the assignment
            self.digital_assignment(signal=output, value=value, comment='SInt -> UInt')
        else:
            raise ValueError(f'Unknown type conversion: {expr.__class__.__name__}')

        return output

    def init_file(self):
        # print header
        self.comment(f'Model generated on {datetime.datetime.now()}')
        self.writeln()

        # set timescale
        self.writeln(f'`timescale 1ns/1ps')
        self.writeln()

        # include required libraries
        self.include('svreal.sv')
        self.include('msdsl.sv')
        self.writeln()

    def include(self, file):
        self.writeln(f'`include "{file}"')

    def default_nettype(self, type):
        self.writeln(f'`default_nettype {type}')

    def macro_call(self, macro_name, *args, comment=None):
        # format the basic macro call
        line = f"`{macro_name}({', '.join(str(arg) for arg in args)});"

        # add a comment if desired
        if comment is not None:
            line += f' // {comment}'

        # write the full line
        self.writeln(line)

    def digital_assignment(self, signal, value, comment=None):
        # format the basic assignment
        line = f'assign {signal.name} = {value};'

        # add a comment if desired
        if comment is not None:
            line += f' // {comment}'

        # write the full line
        self.writeln(line)

    def comment(self, content=''):
        self.writeln(f'// {content}')

    def comma_separated_lines(self, lines):
        self.write('(' + self.line_ending)
        self.write((',' + self.line_ending).join([self.tab_string + line for line in lines]))
        self.write(self.line_ending)
        self.write(')')

    @staticmethod
    def real_param_str(io):
        return f'`DECL_REAL({io.name})'

    @classmethod
    def port_str(cls, io):
        if isinstance(io, AnalogInput):
            return f'`INPUT_REAL({io.name})'
        elif isinstance(io, AnalogOutput):
            return f'`OUTPUT_REAL({io.name})'
        elif isinstance(io, DigitalInput):
            return f'input wire {cls.int_type_str(io.format_)} {io.name}'
        elif isinstance(io, DigitalOutput):
            return f'output wire {cls.int_type_str(io.format_)} {io.name}'
        else:
            raise Exception('Invalid type.')

    @classmethod
    def zero_const(cls, num_zeros):
        return str(num_zeros) + "'b" + '0'*num_zeros

    @classmethod
    def int_type_str(cls, format_: Union[SIntFormat, UIntFormat]):
        retval = 'logic'

        if isinstance(format_, UIntFormat):
            pass
        elif isinstance(format_, SIntFormat):
            retval += ' signed'
        else:
            raise Exception('Cannot determine if format is signed or unsigned.')

        if format_.width > 1:
            retval += f' [{format_.width-1}:0]'

        return retval

    @classmethod
    def hex_format(cls, val, width):
        str_width = ceil(width/4)
        return f"{width}'h{val:0{str_width}x}"


lines = [line.rstrip() for line in open('input.txt').readlines()]

g = {}
posts = set()
steps = set()
prereqs = {}

for line in lines:
    pre = line[5]
    post = line[36]
    g.setdefault(pre, set())
    g[pre].add(post)
    prereqs.setdefault(post, set())
    prereqs[post].add(pre)
    steps |= {pre, post}
    posts.add(post)

noDeps = steps - posts
print(noDeps)

from heapq import heappush, heappop
heap = []

for step in noDeps:
    heappush(heap, step)

order = []
visited = set()
while len(heap) > 0:
    step = heappop(heap)
    order.append(step)
    if step in g:
        for post in g[step]:
            prereqs[post].remove(step)
            if post not in visited and len(prereqs[post]) == 0:
                heappush(heap, post)
                visited.add(post)

print("".join(order))