import requests

# Define API key and base URL for OpenWeatherMap API
api_key = 'your-api-key'
base_url = 'http://api.openweathermap.org/data/2.5/weather?'

# Define function to get weather information for a given city
def get_weather(city):
    # Construct API URL for given city and API key
    complete_url = base_url + 'q=' + city + '&appid=' + api_key

    # Send API request and get response
    response = requests.get(complete_url)

    # If API request is successful, parse JSON response and return weather information
    if response.status_code == 200:
        data = response.json()
        weather = {
            'city': data['name'],
            'country': data['sys']['country'],
            'temperature': round(data['main']['temp'] - 273.15, 1), # convert from Kelvin to Celsius
            'description': data['weather'][0]['description']
        }
        return weather
    # If API request fails, return None
    else:
        return None

# Example usage: get weather information for London and print it
london_weather = get_weather('London')
if london_weather:
    print('Weather in', london_weather['city'] + ',', london_weather['country'])
    print('Temperature:', london_weather['temperature'], '°C')
    print('Description:', london_weather['description'])
else:
    print('Failed to get weather information')


import tkinter as tk
from tkinter import *
from tkinter import messagebox
main=tk.Tk()
import ml
y=0
def cal():
    y=ml.pr(preg.get(),glu.get(),blood.get(),skin.get(),ins.get(),bmi.get(),pdf.get(),age.get())
    if y==1:
        messagebox.showinfo("Prediction","Diabetes test is Positive.\n(It means that you have diabetes)")
    else:
        messagebox.showinfo("Prediction","Diabetes test is Negative.\n(It means that you don't have diabetes)")
    #print(ml.pr(preg.get(),glu.get(),blood.get(),skin.get(),ins.get(),bmi.get(),pdf.get(),age.get()))

preg=tk.IntVar()
glu=tk.IntVar()
blood=tk.IntVar()
skin=tk.IntVar()
bmi=tk.IntVar()
age=tk.IntVar()
ins=tk.IntVar()
pdf=tk.IntVar()

def diebetes():
    main.geometry("400x400")
    tk.Label(main,text="Pregnencies").pack()
    tk.Entry(main,textvariable=preg).pack()

    tk.Label(main,text="Glucose").pack()
    tk.Entry(main,textvariable=glu).pack()

    tk.Label(main,text="Blood Pressure").pack()
    tk.Entry(main,textvariable=blood).pack()

    tk.Label(main,text="Skin Thickness").pack()
    tk.Entry(main,textvariable=skin).pack()

    tk.Label(main,text="insulin").pack()
    tk.Entry(main,textvariable=ins).pack()

    tk.Label(main,text="BMI").pack()
    tk.Entry(main,textvariable=bmi).pack()

    tk.Label(main,text="Pedgree function").pack()
    tk.Entry(main,textvariable=pdf).pack()

    tk.Label(main,text="Age").pack()
    tk.Entry(main,textvariable=age).pack()

    tk.Button(main,text="Check",command=cal).pack()

diebetes()
main.mainloop()


from odoo import _, api, fields, models
from odoo.exceptions import ValidationError

class AccountPaymentMode(models.Model):
    """This corresponds to the object payment.mode of v8 with some
    important changes. It also replaces the object payment.method
    of the module sale_payment_method of OCA/e-commerce"""

    _name = "account.payment.mode"
    _description = "Payment Modes"
    _order = "name"
    _check_company_auto = True

    name = fields.Char(required=True, translate=True)
    company_id = fields.Many2one(
        "res.company",
        string="Company",
        required=True,
        ondelete="restrict",
        default=lambda self: self.env.company,
    )
    bank_account_link = fields.Selection(
        [("fixed", "Fixed"), ("variable", "Variable")],
        string="Link to Bank Account",
        required=True,
        help="For payment modes that are always attached to the same bank "
        "account of your company (such as wire transfer from customers or "
        "SEPA direct debit from suppliers), select "
        "'Fixed'. For payment modes that are not always attached to the same "
        "bank account (such as SEPA Direct debit for customers, wire transfer "
        "to suppliers), you should select 'Variable', which means that you "
        "will select the bank account on the payment order. If your company "
        "only has one bank account, you should always select 'Fixed'.",
    )
    fixed_journal_id = fields.Many2one(
        "account.journal",
        string="Fixed Bank Journal",
        domain="[('company_id', '=', company_id), ('type', 'in', ('bank', 'cash'))]",
        ondelete="restrict",
        check_company=True,
    )
    # I need to explicitly define the table name
    # because I have 2 M2M fields pointing to account.journal
    variable_journal_ids = fields.Many2many(
        comodel_name="account.journal",
        relation="account_payment_mode_variable_journal_rel",
        column1="payment_mode_id",
        column2="journal_id",
        string="Allowed Bank Journals",
        domain="[('company_id', '=', company_id), ('type', 'in', ('bank', 'cash'))]",
    )
    payment_method_id = fields.Many2one(
        "account.payment.method",
        string="Payment Method",
        required=True,
        ondelete="restrict",
    )
    payment_type = fields.Selection(
        related="payment_method_id.payment_type", readonly=True, store=True
    )
    payment_method_code = fields.Char(
        related="payment_method_id.code", readonly=True, store=True
    )
    active = fields.Boolean(default=True)
    note = fields.Text(translate=True)

    @api.onchange("company_id")
    def _onchange_company_id(self):
        self.variable_journal_ids = False
        self.fixed_journal_id = False

    @api.constrains("bank_account_link", "fixed_journal_id", "payment_method_id")
    def bank_account_link_constrains(self):
        for mode in self.filtered(lambda x: x.bank_account_link == "fixed"):
            if not mode.fixed_journal_id:
                raise ValidationError(
                    _(
                        "On the payment mode '%s', the bank account link is "
                        "'Fixed' but the fixed bank journal is not set"
                    )
                    % mode.name
                )
            else:
                if mode.payment_method_id.payment_type == "outbound":
                    if (
                        mode.payment_method_id.id
                        not in mode.fixed_journal_id.outbound_payment_method_ids.ids
                    ):
                        raise ValidationError(
                            _(
                                "On the payment mode '%s', the payment method "
                                "is '%s', but this payment method is not part "
                                "of the payment methods of the fixed bank "
                                "journal '%s'"
                            )
                            % (
                                mode.name,
                                mode.payment_method_id.name,
                                mode.fixed_journal_id.name,
                            )
                        )
                else:
                    if (
                        mode.payment_method_id.id
                        not in mode.fixed_journal_id.inbound_payment_method_ids.ids
                    ):
                        raise ValidationError(
                            _(
                                "On the payment mode '%s', the payment method "
                                "is '%s' (it is in fact a debit method), "
                                "but this debit method is not part "
                                "of the debit methods of the fixed bank "
                                "journal '%s'"
                            )
                            % (
                                mode.name,
                                mode.payment_method_id.name,
                                mode.fixed_journal_id.name,
                            )
                        )

    @api.constrains("company_id", "variable_journal_ids")
    def company_id_variable_journal_ids_constrains(self):
        for mode in self:
            if any(mode.company_id != j.company_id for j in mode.variable_journal_ids):
                raise ValidationError(
                    _(
                        "The company of the payment mode '%s', does not match "
                        "with one of the Allowed Bank Journals."
                    )
                    % mode.name
                )


import numpy as np
import matplotlib.pyplot as plt

font = {'size': 11.5}
plt.rc('font', **font)

fig, ax = plt.subplots(figsize=(7, 3), subplot_kw=dict(aspect="equal"))

# bigram
real = 84+140
gen = 138+113
cd = 54+23

# hybrid
# real = 144+126
# gen = 99+100
# cd = 33+50

total = real+gen+cd

realp = str(round(real/total*100,1))
genp = str(round(gen/total*100,1))
cdp = str(round(cd/total*100,1))

recipe = ["Real: "+realp+"%", "Generated: "+genp+"%", "Cannot Determine: "+cdp+"%"]

data = [real, gen, cd]

wedges, texts = ax.pie(data, colors=["white", "white", "white"], wedgeprops={"width":0.5, "edgecolor": "black"}, startangle=-40)

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),
          bbox=bbox_props, zorder=0, va="center")

patterns = ["-" , "+" , "o"]

for i, p in enumerate(wedges):
    p.set_hatch(patterns[(i)%len(patterns)])
    ang = (p.theta2 - p.theta1)/2. + p.theta1
    y = np.sin(np.deg2rad(ang))
    x = np.cos(np.deg2rad(ang))
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = "angle,angleA=0,angleB={}".format(ang)
    kw["arrowprops"].update({"connectionstyle": connectionstyle})
    ax.annotate(recipe[i], xy=(x, y), xytext=(1.35*np.sign(x), 1.4*y),
                horizontalalignment=horizontalalignment, **kw)

plt.savefig('1.png')


"""Contains PyTorch Lightning LightningModule class for contrastive learning (SimCLR model)."""

import torch, torch.nn as nn
from torch import Tensor

from simclr.modules import NT_Xent, LARS
from pytorch_lightning import LightningModule

class ContrastiveLearning(LightningModule):
    def __init__(self, args, encoder: nn.Module):
        super().__init__()
        self.save_hyperparameters(args)

        # backbone encoder:
        self.encoder = encoder
        # dimensionality of representation:
        self.n_features = self.encoder.output_size
        # projection head:
        self.projector = nn.Sequential(
            nn.Linear(self.n_features, self.n_features, bias=False),
            nn.ReLU(),
            nn.Linear(self.n_features, self.hparams.projection_dim, bias=False),
        )
        self.model = nn.Sequential(self.encoder, self.projector)

        # criterion function:
        self.criterion = self.configure_criterion()

    def forward(self, x_i: Tensor, x_j: Tensor) -> Tensor:
        z_i = self.model(x_i)
        z_j = self.model(x_j)
        return self.criterion(z_i, z_j)

    def training_step(self, batch, _) -> Tensor:
        x, _ = batch
        loss = self.forward(x[:, 0, :], x[:, 1, :])
        self.log("Train/loss", loss)
        return loss

    def validation_step(self, batch, _) -> Tensor:
        x, _ = batch
        loss = self.forward(x[:, 0, :], x[:, 1, :])
        self.log("Valid/loss", loss)
        return loss

    def configure_criterion(self) -> nn.Module:
        # PL aggregates differently in DP mode
        if self.hparams.accelerator == "dp" and self.hparams.gpus:
            batch_size = int(self.hparams.batch_size / self.hparams.gpus)
        else:
            batch_size = self.hparams.batch_size

        return NT_Xent(batch_size, self.hparams.temperature, world_size=1)

    def configure_optimizers(self) -> dict:
        scheduler = None
        if self.hparams.optimizer == "Adam":
            optimizer = torch.optim.AdamW(self.model.parameters(), lr=3e-4)
        elif self.hparams.optimizer == "LARS":
            # optimized using LARS with linear learning rate scaling
            # (i.e. LearningRate = 0.3 × BatchSize/256) and weight decay of 10−6.
            learning_rate = 0.3 * self.hparams.batch_size / 256
            optimizer = LARS(
                self.model.parameters(),
                lr=learning_rate,
                weight_decay=self.hparams.weight_decay,
                exclude_from_weight_decay=["batch_normalization", "bias"],
            )
            # "decay the learning rate with the cosine decay schedule without restarts"
            scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
                optimizer, self.hparams.max_epochs, eta_min=0, last_epoch=-1
            )
        else:
            raise NotImplementedError

        if scheduler:
            return {"optimizer": optimizer, "lr_scheduler": scheduler}
        else:
            return {"optimizer": optimizer}


import numpy as np
import os
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

if __name__ == '__main__':
    # dirpath1 = './calculated_ci/93.73_adapter15resnet_56_cifar10'
    # dirpath1 = './calculated_ci/93.99_adapter_vgg_16_bn_cifar10'
    dirpath1 = 'calculated_ci/68.72_adapter19resnet_20_cifar100'
    # dirpath1 = 'calculated_ci/92.22_adapter15resnet_20_cifar10'
    # dirpath1 = './calculated_ci/93.91_adapter_vgg_16_bn_v4_cifar10'
    # dirpath2 = 'calculated_ci/92.21_resnet_20_cifar10'
    # dirpath2 = './calculated_ci/93.59_resnet_56_cifar10'
    # dirpath2 = './calculated_ci/93.96_vgg_16_bn_cifar10'
    dirpath2 = 'calculated_ci/68.70_resnet_20_cifar100'

    file = 'ci_conv10.npy'
    # file = 'ci_conv52.npy'
    filepath1 = os.path.join(dirpath1, file)
    filepath2 = os.path.join(dirpath2, file)

    data1 = np.load(filepath1); data2 = np.load(filepath2)
    data1.sort(); data2.sort()
    data1_sum = np.sum(data1); data2_sum = np.sum(data2)

    delta = 0.1; start = 0.1; end = 1.1
    y1, y2 = [], []
    x = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    while abs(start - end) >= 0.1:
        data1_ratio = np.sum([data1[i] for i in range(0, int(start * len(data1)))])
        data2_ratio = np.sum([data2[i] for i in range(0, int(start * len(data2)))])
        data1_ratio = round(data1_ratio / data1_sum, 2)
        data2_ratio = round(data2_ratio / data2_sum, 2)
        # print('start: ', round(start, 2), data1_ratio, data2_ratio)
        y1.append(data1_ratio); y2.append(data2_ratio)
        start += delta

    # y2[9] = 1.0; y2[8] = 0.85
    print(y1)
    print(y2)
    plt.rcParams['savefig.dpi'] = 600; plt.rcParams['figure.dpi'] = 600
    sns.set_theme(style='darkgrid')  # 图形主题
    df = pd.DataFrame()

    df['Filter pruning ratio'] = x; df['PI'] = y1
    # ax = sns.lineplot(data=df, x='Filter pruning ratio', y='PI', label='Adapter-ResNet-20-V1', marker='o')
    ax = sns.lineplot(data=df, x='Filter pruning ratio', y='PI', label='Adapter-ResNet-20-V2', marker='o')
    # ax = sns.lineplot(data=df, x='Filter pruning ratio', y='PI', label='Adapter-ResNet-56', marker='o')

    df['Filter pruning ratio'] = x; df['PI'] = y2
    ax = sns.lineplot(data=df, x='Filter pruning ratio', y='PI', label='ResNet-20', marker='o')
    # ax = sns.lineplot(data=df, x='Filter pruning ratio', y='PI', label='ResNet-56', marker='o')

    ax.set_title('Layer12')
    # ax.set_title('Layer18')
    # ax.set_title('Layer52')
    plt.legend(loc="best", fontsize=12)
    plt.savefig('calci_plot5.jpg')
    plt.show()


import os

import gc

import sys

import cv2

import glob

import time

import signal

import shutil

import numpy as np

import pandas as pd

from collections import OrderedDict, Counter

from PIL import Image

import skimage.io

import cv2

import matplotlib.pyplot as plt

from sklearn.metrics import cohen_kappa_score

from sklearn.model_selection import StratifiedKFold

from tqdm.notebook import tqdm
DATA = "/kaggle/input/prostate-cancer-grade-assessment"

gls2isu = {"0+0":0,'negative':0,'3+3':1,'3+4':2,'4+3':3,'4+4':4,'3+5':4,'5+3':4,'4+5':5,'5+4':5,'5+5':5}
df_train = pd.read_csv(os.path.join(DATA, "train.csv"))

df_train = df_train[df_train.data_provider == 'radboud']
def extract_features(mask):

    counts = []

    for i in range(1,6):

        counts.append(np.count_nonzero(mask == i))

    percents = np.array(counts).astype(np.float32)

    percents /= percents.sum()

    return counts, percents

def quadratic_weighted_kappa(y_hat, y):

    return cohen_kappa_score(y_hat, y, weights='quadratic')

for label in range(1,6):

    df_train[f'percent_{label}'] = None

    df_train[f'count_{label}'] = None

for i in tqdm(range(len(df_train))):

    idx = df_train.iloc[i, 0]

    isup = df_train.iloc[i, 2]

    gleason = df_train.iloc[i, 3]

    mask_file = os.path.join(DATA, 'train_label_masks', f'{idx}_mask.tiff')

    if os.path.exists(mask_file):

        mask = skimage.io.MultiImage(mask_file)

        mask = np.array(mask[2]) # smallest resolution

        cnt, feat = extract_features(mask)

        for label in range(1,6):

            df_train[f'count_{label}'].iloc[i] = cnt[label-1]

            df_train[f'percent_{label}'].iloc[i] = feat[label-1]

    else:

        continue
df_train = df_train.replace(to_replace='None', value=np.nan).dropna()

df_train.reset_index(drop=True)
skf = StratifiedKFold(5, shuffle=True, random_state=42)

splits = list(skf.split(df_train, df_train.isup_grade))

#features = [f"percent_{label}" for label in range(1, 6)]

features = [f"percent_{label}" for label in range(1, 6)] + [f"count_{label}" for label in range(1, 6)]

target = 'isup_grade'
# kNN

from sklearn.neighbors import KNeighborsClassifier

scores = []

for fold in range(5):

    train = df_train.iloc[splits[fold][0]]

    valid = df_train.iloc[splits[fold][1]]

    model = KNeighborsClassifier(n_neighbors=5)

    model.fit(train[features], train[target])

    preds = model.predict(valid[features])

    score = quadratic_weighted_kappa(preds, valid[target])

    scores.append(score)

    print(f"Fold = {fold}, QWK = {score:.4f}")

print(f"Mean = {np.mean(scores):.4f}")
# rfc

from sklearn.ensemble import RandomForestClassifier

scores = []

for fold in range(5):

    train = df_train.iloc[splits[fold][0]]

    valid = df_train.iloc[splits[fold][1]]

    model = RandomForestClassifier(random_state=42)

    model.fit(train[features], train[target])

    preds = model.predict(valid[features])

    score = quadratic_weighted_kappa(preds, valid[target])

    scores.append(score)

    print(f"Fold = {fold}, QWK = {score:.4f}")

print(f"Mean = {np.mean(scores):.4f}")
# lgb

import lightgbm as lgb

def QWK(preds, dtrain):

    labels = dtrain.get_label()

    preds = np.rint(preds)

    score = quadratic_weighted_kappa(preds, labels)

    return ("QWK", score, True)

scores = []

for fold in range(5):

    train = df_train.iloc[splits[fold][0]]

    valid = df_train.iloc[splits[fold][1]]

    train_dataset = lgb.Dataset(train[features], train[target])

    valid_dataset = lgb.Dataset(valid[features], valid[target])

    params = {

                "objective": 'regression',

                "metric": 'rmse',

                "seed": 42,

                "learning_rate": 0.01,

                "boosting": "gbdt",

            }

    model = lgb.train(

                params=params,

                num_boost_round=1000,

                early_stopping_rounds=200,

                train_set=train_dataset,

                valid_sets=[train_dataset, valid_dataset],

                verbose_eval=100,

                feval=QWK,

            )

    preds = model.predict(valid[features], num_iteration=model.best_iteration)

    preds = np.rint(preds)

    score = quadratic_weighted_kappa(preds, valid[target])

    scores.append(score)

    print(f"Fold = {fold}, QWK = {score:.4f}")

print(f"Mean = {np.mean(scores):.4f}")


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import math
import os
from datenbasis_funktionen import *

def autolabel(rects, ax):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = np.round(rect.get_height(), 2)
        if height > 0:
            ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, 3),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
    return ax

def plot_bars(df_auswertung, kategorie, streckentyp, sht):
    x = np.arange(len(df_auswertung.index))
    width = 0.18
    alpha = 1
    colors = ["#292929", "#4d4d4d", "#717171", "#959595", "#b9b9b9"]

    if streckentyp == "I":
        streckentyp = "Intercity"
    elif streckentyp == "L":
        streckentyp = "Langstrecke"
    elif streckentyp == "UL":
        streckentyp = "Urban-Langstrecke"
    elif streckentyp == "UK":
        streckentyp = "Urban-Kurzstrecke"

    # fig, ax = plt.subplots(figsize = [8, 4.8])
    fig = plt.figure(figsize=[9, 4.8])
    ax = plt.subplot(111)

    rects1 = ax.bar(
        x - 10*width/5,
        df_auswertung["Klassisch"],
        width=width,
        alpha=alpha,
        label="Klassisch",
        color=colors[0],
        linewidth=0
    )
    rects2 = ax.bar(
        x - 5*width/5,
        df_auswertung["Trendszenario"],
        width=width,
        alpha=alpha,
        label="Trendszenario",
        color=colors[1],
        linewidth=0
    )
    rects3 = ax.bar(
        x,
        df_auswertung["Autonom"],
        width=width,
        alpha=alpha,
        label="Autonom",
        color=colors[2],
        linewidth=0
    )
    rects4 = ax.bar(
        x + 5*width/5,
        df_auswertung["Optimiert"],
        width=width,
        alpha=alpha,
        label="Optimierte Multimodale Mobilität",
        color=colors[3],
        linewidth=0
    )
    rects5 = ax.bar(
        x + 10*width/5,
        df_auswertung["Pod"],
        width=width,
        alpha=alpha,
        label="Pod-Szenario",
        color=colors[4],
        linewidth=0
    )

    ax.set_xticks(x)
    if kategorie in ["THG", "PM", "NOx"]:
        ax.set_title(streckentyp + ": " + kategorie + "-Emissionen")
        ax.set_ylabel("g/Tkm")
    elif kategorie == "Energieverbrauch":
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("MJ/Tkm")
    elif kategorie in ["Fahrtzeit", "Transferzeit", "Wartezeit"]:
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("min")
    elif kategorie == "Unfallrisiko":
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("Unfallrisiko je 1 Mrd. Pkm")
    elif kategorie == "Length":
        ax.set_title(streckentyp + ": " + "Streckenlänge")
        ax.set_ylabel("Länge [m]")
    elif kategorie == "Kosten":
        ax.set_title(streckentyp + ": " + "Kosten pro Weg")
        ax.set_ylabel("Kosten [Euro]")
    else:
        ax.set_title(kategorie)
        ax.set_ylabel(kategorie)

    ax.set_xticklabels(df_auswertung.index)

    # Einfügen der Legende an der Seite
    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width, box.height])
    ax.legend(loc="center left", bbox_to_anchor=(1, 0.5))

    # Einfügen von vertikalen Grid Lines
    ax.set_axisbelow(True)
    ax.yaxis.grid(color="black", linestyle='-', linewidth=0.4)

    fig.tight_layout()
    plt.subplots_adjust(bottom=0.28)
    plt.setp(ax.get_xticklabels(), rotation=90)
    plt.savefig("./plots/" + streckentyp + kategorie)

    plot = sht.pictures.add(
        plt.gcf(), name=streckentyp + kategorie, update=True)

def create_plots(df, sht):
    for y in df.index.get_level_values(0).drop_duplicates():
        df_vorauswahl = df.xs(y, level="Streckentyp")
        for x in df.index.get_level_values(2).drop_duplicates():
            if not x == "Auslastung" and not x == "Unfallrisiko":
                try:
                    df_auswertung = df_vorauswahl.xs(x, level="Kategorien")
                    plot_bars(df_auswertung, x, y, sht)
                except:
                    pass

def plot_basics(df, fig, ax, streckentyp, kategorie):
    x = np.arange(len(df.index.get_level_values(1).values))
    width = 0.18
    alpha = 1
    colors = ["#292929", "#4d4d4d", "#717171", "#959595", "#b9b9b9"]

    lines = list()

    if streckentyp == "I":
        streckentyp = "Intercity"
    elif streckentyp == "L":
        streckentyp = "Langstrecke"
    elif streckentyp == "UL":
        streckentyp = "Urban-Langstrecke"
    elif streckentyp == "UK":
        streckentyp = "Urban-Kurzstrecke"

    l1 = ax.bar(
        x - 10*width/5,
        df["Klassisch"],
        width=width,
        alpha=alpha,
        label="Klassisch",
        color=colors[0],
        linewidth=0
    )
    lines.append(l1)
    l2 = ax.bar(
        x - 5*width/5,
        df["Trendszenario"],
        width=width,
        alpha=alpha,
        label="Trendszenario",
        color=colors[1],
        linewidth=0
    )
    lines.append(l2)
    l3 = ax.bar(
        x,
        df["Autonom"],
        width=width,
        alpha=alpha,
        label="Autonom",
        color=colors[2],
        linewidth=0
    )
    lines.append(l3)
    l4 = ax.bar(
        x + 5*width/5,
        df["Optimiert"],
        width=width,
        alpha=alpha,
        label="Optimierte Multimodale Mobilität",
        color=colors[3],
        linewidth=0
    )
    lines.append(l4)
    l5 = ax.bar(
        x + 10*width/5,
        df["Pod"],
        width=width,
        alpha=alpha,
        label="Pod-Szenario",
        color=colors[4],
        linewidth=0
    )
    lines.append(l5)
    labels = df.index.get_level_values(1).values.tolist()
    labels = [labels[0]] + labels
    ax.set_xticklabels(labels)

    if kategorie in ["THG", "PM", "NOx"]:
        ax.set_title(streckentyp + ": " + kategorie + "-Emissionen")
        ax.set_ylabel("g")
    elif kategorie == "Energieverbrauch":
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("MJ")
    elif kategorie in ["Fahrtzeit", "Transferzeit", "Wartezeit"]:
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("Zeit [min]")
    elif kategorie == "Unfallrisiko":
        ax.set_title(streckentyp + ": " + kategorie)
        ax.set_ylabel("Unfallrisiko je 1 Mrd. Pkm")
    elif kategorie == "Length":
        ax.set_title(streckentyp + ": " + "Streckenlänge")
        ax.set_ylabel("Länge [m]")
    elif kategorie == "Kosten":
        ax.set_title(streckentyp + ": " + "Kosten pro Weg")
        ax.set_ylabel("Kosten [Euro]")
    else:
        ax.set_title(kategorie)
        ax.set_ylabel(kategorie)

    # Einfügen von vertikalen Grid Lines
    ax.set_axisbelow(True)
    ax.yaxis.grid(color="black", linestyle='-', linewidth=0.4)

    # plt.setp(ax.get_xticklabels(), rotation=90)

    return fig, ax, lines

def times(df):
    grouped = df.groupby(["Kategorien", "Streckentyp"])
    # cat = ["Fahrtzeit", "Wartezeit", "Transferzeit"]
    # styp = ["UK", "UL", "I", "L"]
    cat = ["THG", "NOx", "PM", "Energieverbrauch"]
    styp = ["N", "F"]

    for streckentyp in styp:
        x = list()
        fig = plt.figure(figsize=[10, 12])
        fig.subplots_adjust(hspace=1, wspace=0.4)
        for i, name in enumerate(cat):
            i += 1
            df_tmp = grouped.get_group((name, streckentyp))
            ax = fig.add_subplot(4, 1, i)
            fig, ax, lines = plot_basics(df_tmp, fig, ax, streckentyp, name)
            i -= 1
        # Einfügen der Legende an der Seite
        handles, labels = ax.get_legend_handles_labels()
        fig.legend(handles, labels, bbox_to_anchor=(1, 0), loc="lower right",
                   bbox_transform=fig.transFigure, ncol=5)
        fig.tight_layout()
        plt.savefig("./plots/" + streckentyp + "_Emissionen")

def main():
    wb = xw.Book.caller()

    sht_daten = wb.sheets["rf_gv_erg"]
    df = sht_daten.range("A1").options(
        pd.DataFrame, expand="table", header=1, index=3).value
    sht = wb.sheets["Plots"]
    create_plots(df, sht)
    times(df)

if __name__ == "__main__":
    xw.Book("190910_Bewertungstool_v03.xlsm").set_mock_caller()

    main()


from code_challenges.graph.graph import Graph, Vertex
import pytest

def test_add_node():
    g = Graph()
    added_vertex = g.add_node("test")
    expected = "test"
    actual = added_vertex.value
    assert actual == expected

def test_size_empty():
    g = Graph()
    expected = 0
    actual = g.size()
    assert actual == expected

def test_get_nodes_empty():
    g = Graph()
    expected = []
    actual = g.get_node()
    assert actual == expected

def test_size():
    g = Graph()
    g.add_node("test")
    expected = 1
    actual = g.size()
    assert actual == expected

def test_get_nodes():
    g = Graph()
    apple = g.add_node("apple")
    banana = g.add_node("banana")
    mango = Vertex("mango")
    expected = 2
    actual = len(g.get_node())
    assert actual == expected

def test_add_edge_simple():
    g = Graph()
    apple = g.add_node("apple")
    banana = g.add_node("banana")
    g.add_edge(apple, banana, 5)
    assert True

def test_add_edge_with_neighbors():
    g = Graph()
    apple = g.add_node("apple")
    banana = g.add_node("banana")
    g.add_edge(apple, banana, 5)

    neighbors = g.get_neighbor(apple)
    assert len(neighbors) == 1
    edge = neighbors[0]
    assert edge.vertex == banana
    assert edge.weight == 5

def test_bouquet():
    g = Graph()
    apple = g.add_node("apple")
    g.add_edge(apple, apple, 10)
    neighbors = g.get_neighbor(apple)
    assert len(neighbors) == 1
    edge = neighbors[0]
    assert edge.vertex == apple
    assert edge.weight == 10

def test_add_edge_interloper_start():
    g = Graph()
    start = Vertex("start")
    end = g.add_node("end")
    with pytest.raises(KeyError):
        g.add_edge(start, end)

def test_add_edge_interloper_end():
    g = Graph()
    end = Vertex("end")
    start = g.add_node("start")
    with pytest.raises(KeyError):
        g.add_edge(start, end)

def test_get_neighbors_weight():
    g = Graph()
    banana = g.add_node("banana")
    apple = g.add_node("apple")
    g.add_edge(apple, banana, 44)
    neighbors = g.get_neighbor(apple)
    assert len(neighbors) == 1
    neighbor_edge = neighbors[0]
    assert neighbor_edge.vertex.value == "banana"
    assert neighbor_edge.weight == 44


from VesselValidator import VesselValidator
from TrackValidator import TrackValidator
from cust_logging import log_error, log_message, log_warning

# Topic class
# Resembles a topic from the protocol
# Has lane type, max group id of lane type and a list of components
class Topic:
    def __init__(self, lane_type, max_group_id, components):
        self.lane_type = lane_type
        self.max_group_id = max_group_id
        self.components = components

# Odd Rules class
# Resembles odd rules where (in all cases) a group has more than 2 sensors
# Has the parent group id and new amount of sensors (max component id)
class Odd_Rules:
    def __init__(self, group_id, max):
        self.group_id = group_id
        self.max = max

# Component class
# Resembles a component
# Has a component type, max component id, payload and possibule odd rules
class Component:
    def __init__(self, component_type, max_component_id, max_payload, odd_rules = None):
        self.component_type = component_type
        self.max_component_id = max_component_id
        self.max_payload = max_payload
        self.odd_rules = odd_rules

# Topic Validator class
# Resembles a topic validator
# Check if the current topic is valid and is permitted to be sent
class TopicValidator:
	sensor_max_payload = 1

	traffic_light_max_id = 0
	traffic_light_max_payload = 2

	warning_light_max_id = 0
	warning_light_max_payload = 1

	barrier_max_id = 0
	barrier_max_payload = 1

	deck_max_id = 0
	deck_max_payload = 1

	motorised_group_max_id = 8
	motorised_sensor_single_lane_max_id = 1
	motorised_sensor_dual_lane_max_id = 3

	cycle_group_max_id = 4
	cycle_sensor_one_way_max_id = 0
	cycle_sensor_two_way_max_id = 1

	foot_group_max_id = 6
	foot_sensor_max_id = 1

	track_group_max_id = 0
	track_sensor_max_id = 2
	track_light_max_id = 1
	track_light_max_payload = 1

	vessel_group_max_id = 0
	vessel_light_max_id = 1
	vessel_sensor_max_id = 3
	vessel_light_max_payload = 1

	odd_motorised_sensor = [Odd_Rules(1, motorised_sensor_dual_lane_max_id), Odd_Rules(5, motorised_sensor_dual_lane_max_id)]
	odd_cycle_sensor = [Odd_Rules(3, cycle_sensor_two_way_max_id), Odd_Rules(4, cycle_sensor_two_way_max_id)]

	track_sensor = Component("sensor", track_sensor_max_id, sensor_max_payload)
	vessel_sensor = Component("sensor", vessel_sensor_max_id, sensor_max_payload)
	foot_sensor = Component("sensor", foot_sensor_max_id, sensor_max_payload)
	cycle_sensor = Component("sensor", cycle_sensor_one_way_max_id, sensor_max_payload, odd_cycle_sensor)
	motorised_sensor = Component("sensor", motorised_sensor_single_lane_max_id, sensor_max_payload, odd_motorised_sensor)

	deck = Component("deck", deck_max_id, deck_max_payload)
	barrier = Component("barrier", barrier_max_id, barrier_max_payload)

	traffic_light = Component("traffic_light", traffic_light_max_id, traffic_light_max_payload)
	warning_light = Component("warning_light", warning_light_max_id, warning_light_max_payload)
	train_light = Component("train_light", track_light_max_id, track_light_max_payload)
	boat_light = Component("boat_light", vessel_light_max_id, vessel_light_max_payload)

	motorised = Topic("motorised", motorised_group_max_id, [traffic_light, motorised_sensor])
	foot = Topic("foot", foot_group_max_id, [traffic_light, foot_sensor])
	cycle = Topic("cycle", cycle_group_max_id, [traffic_light, cycle_sensor])
	vessel = Topic("vessel", vessel_group_max_id, [vessel_sensor, warning_light, barrier, boat_light, deck])
	track = Topic("track", track_group_max_id, [track_sensor, warning_light, barrier, train_light])

	valid_parts = [motorised, foot, cycle, vessel, track]

	vessel_validator = VesselValidator()
	track_validator = TrackValidator()

	# Validates topic
	def validate(self, topic, payload):
		split_topics = topic.split('/', -1)

		# Team id
		del split_topics[0]

		if len(split_topics) == 4:

			# Get the parts of the topic
			lane_type = split_topics[0]
			group_id = split_topics[1]
			component_type = split_topics[2]
			component_id = split_topics[3]

			# Check if all numbers are ints
			group_id, is_int = self.intTryParse(group_id)
			if not is_int:
				log_error(f'invalid int group_id {group_id}')
				return

			component_id, is_int = self.intTryParse(component_id)
			if not is_int:
				log_error(f'invalid int component_id {component_id}')
				return

			payload, is_int = self.intTryParse(payload)
			if not is_int:
				log_error(f'invalid int payload {payload}')
				return

			# Check if message is permitted (warning)
			self.track_validator.validate(topic, payload)
			self.vessel_validator.validate(topic, payload)

			found_lane_type = False
			found_component_type = False

			# Search for part base on lane_type
			for valid_part in self.valid_parts:
				# Check lane_type
				if valid_part.lane_type == lane_type:
					found_lane_type = True

					# Check group_id
					if int(group_id) <= valid_part.max_group_id:

						# Check component_type
						for component in valid_part.components:
							if component.component_type == component_type:
								found_component_type = True

								# Check for odd rules
								if component.odd_rules is not None:
									for odd_rule in component.odd_rules:
										if odd_rule.group_id == int(group_id):
											component.max_component_id = odd_rule.max

								# Check component_id
								if int(component_id) <= component.max_component_id:
									if int(payload) <= component.max_payload:
										log_message("valid topic")
									else:
										log_error(f'invalid payload {payload}\nMAX: {component.max_payload}')
								else:
									# Invalid component id
									log_error(f'invalid component_id {component_id}\nMAX: {component.max_component_id}')

						# Not found error
						if not found_component_type:
							valid_component_types = []
							for component in valid_part.components:
								valid_component_types.append(component.component_type)
							valid_components_string = ", ".join(valid_component_types)

							log_error(f'invalid component_type {component_type}\nALLOWED: {valid_components_string}')
					else:
						# Invalid group_id
						log_error(f'invalid group_id {group_id}\nMAX: {valid_part.max_group_id}')

			# Not found error
			if not found_lane_type:
				valid_lanes = []
				for valid_part in valid_parts:
					valid_lanes.append(valid_part.lane_type)
				valid_lanes_string = ", ".join(valid_lanes)

				log_error(f'invalid lane_type {lane_type}\nALLOWED: {valid_lanes_string}')

		else:
			log_error(f'invalid topic length {len(split_topics)}')

	# Try parse int, returns success
	def intTryParse(self, value):
		try:
			return int(value), True
		except ValueError:
			return value, False


import socket
import threading

name = input('Choose a Name: ')

client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect(('127.0.0.1', 5555))

def receive():
    while True:
        try:
            msg = client_sock.recv(1024).decode('ascii')
            if msg == 'NICK':
                client_sock.send(name.encode('ascii'))
            else:
                print(msg)
        except:
            print('An error occured!')
            client_sock.close()
            break

def write():
    while True:
        msg = f'{name}: {input("")}'
        client_sock.send(msg.encode('ascii'))

receive_thread = threading.Thread(target=receive)
receive_thread.start()

write_thread = threading.Thread(target=write)
write_thread.start()


#
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.nn.functional as F
from torch.utils.data import DataLoader, ConcatDataset
from torch.utils.tensorboard import SummaryWriter
from torch.optim.lr_scheduler import StepLR, CosineAnnealingLR, ExponentialLR

#
from torchvision import transforms

#
from torch_ema import ExponentialMovingAverage

#
import numpy as np

#
from sklearn.model_selection import train_test_split

#
from ptflops import get_model_complexity_info

#
from tqdm import tqdm

#
import argparse

#
import os
import shutil

#
import models
from data.dataset import OrchidDataSet
from config import DefualtConfig
from utils import get_confidence_score
from utils import mixup_data, mixup_criterion
from utils import rand_bbox
from utils.self_supervised import get_pseudo_labels
from optim.scheduler import GradualWarmupScheduler

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

config = DefualtConfig()
device = torch.device(f'cuda:{config.use_gpu_index}' if torch.cuda.is_available() else'cpu') if config.use_gpu_index != -1 else torch.device('cpu')

def main(logdir):

    # Step 1 : prepare logging writer
    writer = SummaryWriter(log_dir=logdir)

    # Step 2 :
    print(config.model_name)
    model = getattr(models, config.model_name)(config)
    if config.load_model:
        model.load_state_dict(torch.load(config.model_path))
    model.to(device)

    #
    # Metrics : FLOPs, Params
    # resize = (224, 224) if config.model_name != 'ConvNeXt' else (384, 384)
    resize = (config.resize, config.resize)
    macs, params = get_model_complexity_info(model, (3, resize[0], resize[1]), as_strings=True, print_per_layer_stat=False, verbose=False)
    print('pthflops : ')
    print('{:<30}  {:<8}'.format('Computational complexity: ', macs))
    print('{:<30}  {:<8}'.format('Number of parameters: ', params))

    # Step 3 : DataSets}
    # Data Augumentation
    transform_set = [
        transforms.RandomResizedCrop((resize[0])),
        # transforms.ColorJitter(brightness=0.5),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.RandomRotation(degrees=15),
        # transforms.RandAugment()
        # transforms.AutoAugment(transforms.AutoAugmentPolicy.IMAGENET)
    ]

    transform_set = transforms.Compose([

        # # Reorder transform randomly
        transforms.RandomOrder(transform_set),

        # Resize the image into a fixed shape
        transforms.Resize(resize),

        # ToTensor() should be the last one of the transforms.
        transforms.ToTensor(),
        # transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),

        #
        transforms.RandomErasing()
    ])
    ds = OrchidDataSet(config.trainset_path, transform_set=transform_set)
    ds_unlabeled = None
    if config.do_semi:
        ds_unlabeled = OrchidDataSet(config.unlabeledset_path, transform_set=transform_set)

    # Step 3
    # Deal with imbalance dataset
    #   For the classification task, we use cross-entropy as the measurement of performance.
    #   Since the wafer dataset is serverly imbalance, we add class weight to make it classifier better
    class_weights = [1 - (ds.targets.count(c))/len(ds) for c in range(config.num_classes)]
    class_weights = torch.FloatTensor(class_weights).to(device)
    criterion = nn.CrossEntropyLoss(weight=class_weights, label_smoothing=0.1)
    # criterion = LabelSmoothingCrossEntropy()

    optimizer = torch.optim.AdamW(model.parameters(), lr=config.lr, weight_decay=1e-8)
    # optimizer = torch.optim.Adam(model.parameters(), lr=config.lr)
    # optimizer = torch.optim.SGD(model.parameters(), lr=config.lr, momentum=0.9)

    ema = ExponentialMovingAverage(model.parameters(), decay=0.995)
    if config.load_model:
        ema = ema.load_state_dict(torch.load(config.ema_path))

    # scheduler_warmup is chained with schduler_steplr
    # scheduler_steplr = StepLR(optimizer, step_size=10, gamma=0.1)
    scheduler_steplr = CosineAnnealingLR(optimizer, T_max=config.cosine_tmax)
    # scheduler_steplr = CosineAnnealingLR(optimizer, T_max=config.num_epochs - config.lr_warmup_epoch + 1)
    # scheduler_steplr = ExponentialLR(optimizer, gamma=0.9)
    # if config.lr_warmup_epoch > 0:
    scheduler_warmup = GradualWarmupScheduler(optimizer, multiplier=1, total_epoch=config.lr_warmup_epoch, after_scheduler=scheduler_steplr)

    # Step 4
    # train_loader, valid_loader = get_loader(ds)
    ds_train, ds_valid = get_train_valid_ds(ds)

    # Step 5
    history = {'train_acc' : [], 'train_loss' : [], 'valid_acc' : [], 'valid_loss' : []}
    best_epoch, best_epoch_ema, best_loss, best_acc_ema, best_acc = 0, 0, 1e100, 0, 0
    nonImprove_epochs = 0

    # this zero gradient update is needed to avoid a warning message, issue #8.
    optimizer.zero_grad()
    optimizer.step()

    #
    # assert not(config.do_cutMix and config.do_MixUp), "Only support one of the mix-based augmentation"

    for epoch in range(config.start_epoch, config.start_epoch + config.num_epochs):

        print('=' * 150)

        #
        # if config.lr_warmup_epoch > 0:
        scheduler_warmup.step(epoch + 1)

        writer.add_scalar("lr", optimizer.param_groups[0]["lr"], epoch)
        print(f'Epoch {epoch}, LR = {optimizer.param_groups[0]["lr"]}')

        #
        collator = torch.utils.data.dataloader.default_collate
        # if config.do_cutMix:
        #     collator = CutMixCollator(config.cutMix_alpha)

        train_loader = DataLoader(ds_train, batch_size=config.batch_size, shuffle=True, collate_fn=collator, num_workers=config.num_workers, pin_memory=True)
        # if epoch == 35:
        #     torch.save(model.state_dict(), f'{config.model_path[:-4]}_normal.pth')
        #     torch.save(ema.state_dict(), f'{config.ema_path[:-4]}_normal.pth')

        if epoch >= config.semi_start_epoch and config.do_semi:
            # Obtain pseudo-labels for unlabeled data using trained model.
            print(f"[ Train | Start pseudo labeling]")
            pseudo_set = get_pseudo_labels(model, ds_unlabeled)

            if pseudo_set != None:
                # Construct a new dataset and a data loader for training.
                # This is used in semi-supervised learning only.
                concat_dataset = ConcatDataset([ds_train, pseudo_set])
                train_loader = DataLoader(concat_dataset, batch_size=config.batch_size, shuffle=True, collate_fn=collator, num_workers=config.num_workers, pin_memory=True)

        valid_loader = DataLoader(ds_valid, batch_size=config.batch_size, shuffle=False, num_workers=config.num_workers, pin_memory=True)

        #
        train_criterion = criterion
        # if config.do_cutMix:
        #     train_criterion = CutMixCriterion(reduction='mean', label_smoothing=0.1)

        train_acc, train_loss = train(model, train_loader, train_criterion, optimizer, ema)
        print(f"[ Train | {epoch + 1:03d}/{config.num_epochs:03d} ] loss = {train_loss:.5f}, acc = {train_acc:.5f}")

        #
        valid_acc, valid_loss = valid(model, valid_loader, criterion, None)
        print(f"[ Valid | {epoch + 1:03d}/{config.num_epochs:03d} ] loss = {valid_loss:.5f}, acc = {valid_acc:.5f}")

        #
        valid_acc_ema, valid_loss_ema = valid(model, valid_loader, criterion, ema)
        print(f"[ Valid | {epoch + 1:03d}/{config.num_epochs:03d} ] loss = {valid_loss_ema:.5f}, acc = {valid_acc_ema:.5f} (EMA)")

        # Append the training statstics into history
        history['train_acc'].append(train_acc)
        history['valid_acc'].append(valid_acc)
        history['train_loss'].append(train_loss)
        history['valid_loss'].append(valid_loss)

        # Tensorboard Visualization
        writer.add_scalar("Train/train_acc", train_acc, epoch)
        writer.add_scalar("Valid/valid_acc", valid_acc, epoch)
        writer.add_scalar("Valid/valid_acc_ema", valid_acc_ema, epoch)
        writer.add_scalar("Train/train_loss", train_loss, epoch)
        writer.add_scalar("Valid/valid_loss", valid_loss, epoch)
        writer.add_scalar("Valid/valid_loss_ema", valid_loss_ema, epoch)

        #
        if valid_acc > best_acc:
            best_acc = valid_acc
            torch.save(model.state_dict(), f'{logdir}/{config.model_path}')
            torch.save(ema.state_dict(), f'{logdir}/{config.ema_path}')
            get_confidence_score(model, loader=valid_loader, use_gpu_index=config.use_gpu_index, batch_size=config.batch_size, outpu_file_path=f'{logdir}/prediction-Confidence-best.csv')
            print(f'Saving model with acc {valid_acc:.4f} and loss {valid_loss:.4f}')

        # EarlyStop
        # if the model improves, save a checkpoint at this epoch
        if valid_acc_ema > best_acc_ema:
            best_loss = valid_loss_ema
            best_acc_ema = valid_acc_ema
            best_epoch = epoch
            torch.save(model.state_dict(), f'{logdir}/ema_{config.model_path}')
            torch.save(ema.state_dict(), f'{logdir}/ema_{config.ema_path}')
            get_confidence_score(model, loader=valid_loader, use_gpu_index=config.use_gpu_index, batch_size=config.batch_size, outpu_file_path=f'{logdir}/prediction-Confidence-best-ema.csv')
            print(f'Saving model with acc {valid_acc_ema:.4f} and loss {valid_loss_ema:.4f} (EMA)')
            nonImprove_epochs = 0
        else:
            nonImprove_epochs += 1

        # Stop training if your model stops improving for "config['early_stop']" epochs.
        if nonImprove_epochs >= config.earlyStop_interval:
            break

    torch.save(model.state_dict(), f'{logdir}/last_{config.model_path}')
    torch.save(ema.state_dict(), f'{logdir}/last_{config.ema_path}')
    print(f'Best epoch: {best_epoch} with acc {best_acc:.4f}')
    print(f'Best epoch: {best_epoch_ema} with acc {best_acc_ema:.4f} (EMA)')

    writer.flush()
    writer.close()

    # Step 6 : Explanation & Visualization
    get_confidence_score(model, loader=valid_loader, use_gpu_index=config.use_gpu_index, batch_size=config.batch_size, outpu_file_path=f'{logdir}/last-prediction-Confidence.csv')

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

def get_train_valid_ds(ds):

    # Split the train/test with each class should appear on both train/test dataset
    valid_split = config.train_valid_split

    indices = list(range(len(ds)))  # indices of the dataset
    train_indices, valid_indices = train_test_split(indices, test_size=valid_split, stratify=ds.targets, random_state=42)

    # Creating sub dataset from valid indices
    # Do not shuffle valid dataset, let the image in order
    valid_indices.sort()
    ds_valid = torch.utils.data.Subset(ds, valid_indices)

    ds_train = torch.utils.data.Subset(ds, train_indices)

    return ds_train, ds_valid

def get_loader(ds):

    # Split the train/test with each class should appear on both train/test dataset
    valid_split = config.train_valid_split

    indices = list(range(len(ds)))  # indices of the dataset
    train_indices, valid_indices = train_test_split(
        indices, test_size=valid_split, stratify=ds.targets)

    # Creating sub dataset from valid indices
    # Do not shuffle valid dataset, let the image in order
    valid_indices.sort()
    ds_valid = torch.utils.data.Subset(ds, valid_indices)

    # Creating PT data samplers and loaders:
    train_sampler = torch.utils.data.SubsetRandomSampler(train_indices)

    # Construct data loaders.
    train_loader = DataLoader(
        ds, batch_size=config.batch_size, sampler=train_sampler, num_workers=config.num_workers, pin_memory=True)
    valid_loader = DataLoader(
        ds_valid, batch_size=config.batch_size, shuffle=False, num_workers=config.num_workers, pin_memory=True)

    return train_loader, valid_loader

def train(model, train_loader, criterion, optimizer, ema):

    # ---------- Training ----------
    # Make sure the model is in train mode before training.
    model.train()

    losses, accs = [], []

    # Iterate the training set by batches.
    for batch in tqdm(train_loader):

        # A batch consists of image data and corresponding labels.
        # imgs = (batch_size, 3, 224, 224)
        # labels = (batch_size)
        imgs, labels = batch
        imgs = imgs.to(device)

        target_a, target_b, lam = None, None, None
        # do_mix = False

        r = np.random.rand(1)
        do_mix = True if r < config.mix_prob else False

        r_mix_method = np.random.rand(1)
        mix_method = 'cutmix'
        if config.do_cutMix and config.do_MixUp:
            mix_method = 'cutmix' if r_mix_method < 0.5 else 'mixup'
        elif config.do_cutMix:
            mix_method = 'cutmix'
        elif config.do_MixUp:
            mix_method = 'mixup'

        if config.do_cutMix and mix_method == 'cutmix':
            if config.beta > 0 and do_mix:
                # generate mixed sample
                do_mix = True
                lam = np.random.beta(config.beta, config.beta)
                rand_index = torch.randperm(imgs.size()[0]).cuda()
                target_a = labels
                target_b = labels[rand_index]
                bbx1, bby1, bbx2, bby2 = rand_bbox(imgs.size(), lam)
                imgs[:, :, bbx1:bbx2, bby1:bby2] = imgs[rand_index, :, bbx1:bbx2, bby1:bby2]
                # adjust lambda to exactly match pixel ratio
                lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (imgs.size()[-1] * imgs.size()[-2]))
        else:
            labels = labels.to(device)

        if config.do_MixUp and do_mix and mix_method == 'mixup':
            labels = labels.to(device)
            imgs, targets_a, targets_b, lam = mixup_data(imgs, labels, alpha=0.2, use_cuda=torch.cuda.is_available())
            imgs, targets_a, targets_b = map(Variable, (imgs, targets_a, targets_b))

        # Forward the data. (Make sure data and model are on the same device.)
        logits = model(imgs.to(device))

        # Calculate the cross-entropy loss.
        # We don't need to apply softmax before computing cross-entropy as it is done automatically.
        # loss = criterion(logits, labels.to(device))

        loss = None
        if (config.do_cutMix or config.do_MixUp) and do_mix:
            if config.do_MixUp and mix_method == 'mixup':
                loss = mixup_criterion(criterion, logits, targets_a, targets_b, lam)
            elif config.do_cutMix and mix_method == 'cutmix':
                # loss = criterion(logits, labels)
                target_a = target_a.to(device)
                target_b = target_b.to(device)
                # lam = lam.to(device)
                loss = criterion(logits, target_a) * lam + criterion(logits, target_b) * (1. - lam)
        else:
            loss = criterion(logits, labels.to(device))

        # Gradients stored in the parameters in the previous step should be cleared out first.
        optimizer.zero_grad()

        # Compute the gradients for parameters.
        loss.backward()

        # # STN : Allow transformes to do like translation, cropping, isotropic scaling but rotation
        # #           , with a intention to let STN learns where to focus on instead of how to transform the image.
        # # Below is what matrix should look like :
        # #    [ x_ratio, 0 ] [offset_X]
        # #    [ 0, y_ratio ] [offset_y]
        # if config.model_name == "STN_ViT":
        #     model.fc_loc[-1].weight.grad[1].zero_()
        #     model.fc_loc[-1].weight.grad[3].zero_()

        # Update the parameters with computed gradients.
        optimizer.step()
        ema.update()

        # # Clip the gradient norms for stable training.
        # grad_norm = nn.utils.clip_grad_norm_(model.parameters(), max_norm=10)

        # Compute the accuracy for current batch.
        # acc = torch.tensor([0])
        # if not config.do_cutMix:
        acc = (logits.argmax(dim=-1) == labels.to(device)).float().mean()
        accs.append(acc.item())
        losses.append(loss.item())

    return np.mean(accs), np.mean(losses)

def valid(model, valid_loader, criterion, ema=None):
    # ---------- Validation ----------
    # Make sure the model is in eval mode so that some modules like dropout are disabled and work normally.
    model.eval()

    accs, losses = [], []

    if ema is not None:

        with ema.average_parameters():

            # Iterate the validation set by batches.
            for batch in tqdm(valid_loader):

                # A batch consists of image data and corresponding labels.
                imgs, labels = batch

                # We don't need gradient in validation.
                # Using torch.no_grad() accelerates the forward process.
                with torch.no_grad():
                    logits = model(imgs.to(device))

                # We can still compute the loss (but not the gradient).
                losses.append(criterion(logits, labels.to(device)).item())

                # Compute the accuracy for current batch.
                accs.append((logits.argmax(dim=-1) == labels.to(device)).float().mean().item())

    else:

        # Iterate the validation set by batches.
        for batch in tqdm(valid_loader):

            # A batch consists of image data and corresponding labels.
            imgs, labels = batch

            # We don't need gradient in validation.
            # Using torch.no_grad() accelerates the forward process.
            with torch.no_grad():
                logits = model(imgs.to(device))

            # We can still compute the loss (but not the gradient).
            losses.append(criterion(logits, labels.to(device)).item())

            # Compute the accuracy for current batch.
            accs.append((logits.argmax(dim=-1) == labels.to(device)).float().mean().item())

    return np.mean(accs), np.mean(losses)

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

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='AICUP - Orchid Classifier')

    # parser.add_argument('--lr', default=2e-5, type=float,
    #                     help='Base learning rate')
    # parser.add_argument('--bs', default=32, type=int, help='Batch size')
    # parser.add_argument('--e', default=50, type=int, help='Numbers of epoch')
    # parser.add_argument('--v', default=50, type=int, help='Experiment version')
    # parser.add_argument('--device', default=-1, type=int,
    #                     help='GPU index, -1 for cpu')
    parser.add_argument('--logdir', default='model', type=str, required=True,
                                help='The folder to store the training stats of current model')

    args = parser.parse_args()

    #
    assert not os.path.isdir(os.path.join(os.getcwd(), args.logdir)), "Already has a folder with the same name"
    os.mkdir(args.logdir)

    shutil.copy('./config.py', f'{args.logdir}/config.py')

    main(args.logdir)

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


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="whoishiring",
    version="0.0.1",
    author="Ahmad Bilal Khalid",
    author_email="ahmedbilal96@gmail.com",
    description="A simple command-line program to filter hackernews whoishiring post's comments.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/ahmedbilal/whoishiring",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    entry_points = {
        'console_scripts': ['whoishiring=whoishiring.whoishiring:main'],
    },
    install_requires=["beautifulsoup4", "requests"]
)


def is_odd_even(arr):
    if not arr:
        return False
    odd_sum = sum([n%2==1 for n in arr])
    even_sum = sum([n%2==0 for n in arr])
    return odd_sum == even_sum

if __name__ == "__main__":
    n_length = int(input())
    arr = list(map(int, input().split()))
    n_subs = 0

    for i in range(n_length):
        for j in range(n_length):
            if is_odd_even(arr[i:j+1]):
                # print(arr[i:j+1])
                n_subs += 1

    print(n_subs)

Competive Programming/Airtel Crack The Code/odd-even.py


"""
Support for the CO2signal platform.
For more details about this platform, please refer to the documentation
"""
import logging
import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
    ATTR_ATTRIBUTION, ATTR_TIME, ATTR_TEMPERATURE, CONF_TOKEN, CONF_LATITUDE, CONF_LONGITUDE)
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA
from homeassistant.helpers.entity import Entity

CONF_REFRESH = "refresh_rate"
CONF_COUNTRY_CODE = "country_code"

REQUIREMENTS = ['co2signal==0.2']

_LOGGER = logging.getLogger(__name__)

ATTRIBUTION = 'Data provided by CO2signal'

# Sensor types are defined like: Name, units
SENSOR_TYPES = {
    'co2_intensity': ['Carbon Dioxide Intensity', 'CO2eq/kWh'],
}

# Sensor types are defined like: Name, Name_API
SENSOR_TYPES_NAMES = {
    'co2': 'Carbon Dioxide',
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Optional(CONF_TOKEN, default = None): cv.string,
    vol.Optional(CONF_COUNTRY_CODE, default = None): cv.string,
    vol.Optional(CONF_LATITUDE, default = 50): cv.latitude,
    vol.Optional(CONF_LONGITUDE, default = 5): cv.longitude,
    vol.Optional(CONF_REFRESH, default = 60): cv.positive_int,
})

def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the CO2signal sensor."""
    import CO2Signal

    _LOGGER.debug("Setting up the CO2signal platform")

    token = config.get(CONF_TOKEN)
    country_code = config.get(CONF_COUNTRY_CODE)
    refresh_rate = config.get(CONF_REFRESH)
    lat = None
    lon = None
    location_type = None

    # find station ID
    if country_code is not None:
        location_type = 'country_code'
    else:
        lat = config.get(CONF_LATITUDE)
        lon = config.get(CONF_LONGITUDE)
        location_type = 'coordinates'

    _LOGGER.debug("Setting up the sensor using the %s", location_type)

    devs = []

    devs.append(CO2Sensor(token, country_code, lat, lon, location_type, refresh_rate))

    add_devices(devs)

class CO2Sensor(Entity):
    """Implementation of the CO2Signal sensor."""

    _friendly_name: str

    def __init__(self, token, country_code, lat, lon, location_type, refresh_rate = 15):
        """Initialize the sensor."""
        import CO2Signal

        self._token = token
        self._country_code = country_code
        self._latitude = lat
        self._longitude = lon
        self._location_type = location_type
        self._unit = 'CO2eq/kWh'
        self._device_name = "LatLon"
        if country_code is not None:
            self._device_name = country_code
        self._friendly_name = 'CO2 intensity - {}'.format(self._device_name)
        self._refresh_rate = refresh_rate

        _LOGGER.debug("Initialise %s", self._friendly_name)

        self.update()

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._friendly_name

    @property
    def icon(self):
        """Icon to use in the frontend, if any."""
        return 'mdi:periodic-table-co2'

    @property
    def device_class(self):
        """Return the device class."""
        """Icon to use in the frontend, if any."""
        return 'carbon_dioxide_intensity'

    @property
    def state(self):
        import datetime
        """Return the state of the device."""
        _LOGGER.debug("Get state for %s", self._friendly_name)
        return self._data

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this entity, if any."""
        return self._unit

    def update(self):
        """Get the latest data and updates the states."""
        import CO2Signal

        _LOGGER.debug("Update data for %s", self._friendly_name)

        if self._location_type == 'country_code':
            self._data = CO2Signal.get_latest_carbon_intensity(self._token, country_code = self._country_code)
        elif self._location_type == 'coordinates':
            self._data = CO2Signal.get_latest_carbon_intensity(self._token, latitude = self._latitude, longitude = self._longitude)
        else:
            raise ValueError("Unknown location type: {location_type}".format(location_type = self._location_type))


# https://github.com/rakeshvar/kmedoids/blob/master/kmedoids.py

import numpy as np

import fastdtw
from sklearn.cluster import KMeans
from scipy.spatial.distance import euclidean

######################### K-Medoids
'''
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
Find the intersection of two arrays.
>>> np.argmin(a)
0
>>> np.argmin(a, axis=0)
array([0, 0, 0])
>>> np.argmin(a, axis=1)
array([0, 0])
'''
class KMedoids:
    def __init__(self, n_clusters= 2, batch_size= 300, max_iter= 100,
                tol = 0.01, metric="dtw"):
        self.metric = metric
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.batch_size = batch_size
        self.tol = tol

    def _dist(self, xa, xb):
        if self.metric== 'euclidean':
            return np.sqrt(np.sum(np.square(xa-xb)), axis = -1)
        elif self.metric == 'dtw':
            value, _  = fastdtw.fastdtw(xa, xb, radius=5, dist=(lambda a,b: np.linalg.norm(a-b)))
            return value
        else:
            return np.sum(np.abs(xa - xb))

    def _assign_nearest(self, ids_of_mediods):
        dists = np.empty((0,self.n_clusters), float)
        for xa in self.X :
            temp = np.array([])
            for j in ids_of_mediods:
                temp = np.append(temp, self._dist(xa,self.X[j]))
            dists = np.vstack((dists, temp))
            print(dists.shape)
        # dists = self._dist(self.X[:,None,:], self.X[None,ids_of_mediods,:])

        z = np.argmin(dists, axis=1)
        print(z)
        return z

    def _find_medoids(self, whole_num, assignments):
        # k 개의 클러스터 만큼의 medoid 를 -1로 설정한다.
        medoid_ids = np.full(self.n_clusters, -1, dtype=int)
        # batch size 만큼 whole_num 에서 고른다.
        # 적절한 subset을 찾을때까지 계속해서 고른다(후보군을 잘 골라야함).
        select_subset = True
        while select_subset:
            select_subset = False
            subset = np.random.choice(whole_num, self.batch_size, replace=False)
            indices = []
            for i in range(self.n_clusters):
                temp = np.intersect1d(np.where(assignments==i)[0], subset)
                if temp.size == 0:
                    select_subset = True
                    break
                indices.append(temp)

        for i, indice in enumerate(indices):
            # id 가 i 인 cluster에 할당된 data가 있는지 확인한다. (* 없을 수도 있음 !)
   #         indicew = np.intersect1d(np.where(assignments==i)[0], subset)

            # cluster i 안에 있는 data들 끼리의 모든 길이(distance)를 다 재본다.
            dist = np.empty((0,len(indice)),float)
            for w in indice :
                temp = np.array([])
                for j in indice:
                    # 이 부분이 많이 늦다.
                    temp = np.append(temp, self._dist(self.X[w] , self.X[j]))
                dist = np.vstack((dist, temp))
                print(dist.shape)
            # 각 data 들이 가지는 다른 data와의 거리를 모두 합한다.
            # 즉, cluster i에 n 개의 data들이 있다면 n 개의 거리 값이 나온다.
            distances = dist.sum(axis=0)
            # distances = self._dist(self.X[indices, None, :], self.X[None, indices, :]).sum(axis=0)

            # 이 거리 중에서 최소를 가지는 index를 찾아내어 그 data를 medoid_id로 정한다.
            medoid_ids[i] = indice[np.argmin(distances)]

        return medoid_ids

    def fit(self, X):
        whole_num = X.shape[0]
        if self.batch_size == 'all':
            self.batch_size = whole_num
        self.X = X

        print("Initializing to random medoids.")
        ids_of_medoids = np.random.choice(whole_num, self.n_clusters, replace=False)
        # 랜덤하게 고른 medoid 들
        print(ids_of_medoids)
        # 이 기준점을 이용해서 근처에 있는 data를 assign 하는 작업을 한다.
        class_assignments = self._assign_nearest(ids_of_medoids)

        # 각각의 data들은 이제 특정 medoid에 assign 되있는 상태 (index 로 표현됨.)
        for i in range(self.max_iter):
            print("\tFinding new medoids.")
            # 새로운 medoid를 찾아본다.
            ids_of_medoids = self._find_medoids(whole_num, class_assignments)
            # 새로찾은 medoid 에게 기존의 assign된 data들을 다시 배분해본다.
            print("\tReassigning points.")
            new_class_assignments = self._assign_nearest(ids_of_medoids)

            # 다름의 정도를 다시 재 측정한다.
            diffs = np.mean(new_class_assignments != class_assignments)
            # 이전 assign 된 내용은 삭제되고 새롭게 assign된 내용이 main이 된다.
            class_assignments = new_class_assignments

            # 만약 이전과 assign 된 내용이 별로 차이가 없다면 clustering 종료.
            print("iteration {:2d}: {:.2%} of points got reassigned."
                  "".format(i, diffs))
            if diffs <= self.tol:
                break

        return class_assignments, ids_of_medoids

if __name__ == '__main__':

    x = np.array([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]])
    print(x)
    y = np.array([[2, 2], [3, 3], [4, 4]])
    distance, path = fastdtw.fastdtw(x, y, dist=euclidean)
    print(distance)

    ######################### Generate Fake Data
    print("Initializing Data.")
    # dimension
    d = 16
    k = 6
    n = k * 1000
    batch_sz = 1000
    x = np.random.normal(size=(n, d))
    EUCLIDEAN = False

    print("n={}\td={}\tk={}\tbatch_size={} ".format(n, d, k, batch_sz))
    print("Distance metric: ", "Eucledian" if EUCLIDEAN else "Manhattan")

    print("\nMaking k-groups as:")
    for kk in range(k):
        dd = (kk-1)%d
        print("    x[{}:{}, {}] += {}".format(kk*n//k, (kk+1)*n//k, dd , 3*d*kk))
        x[kk*n//k:(kk+1)*n//k,dd] += 3*d*kk

    KMedoids_model = KMedoids(n_clusters=k, metric='dtw', batch_size= batch_sz)
    ######################### Fitting
    print("\nFitting Kmedoids.")
    final_assignments, final_medoid_ids = KMedoids_model.fit(x)

    print("\nFitting Kmeans from Scikit-Learn")
    fit = KMeans(n_clusters=k).fit(x)
    kmeans_assignments = fit.labels_
    kmeans = fit.cluster_centers_

    mismatch = np.zeros((k, k))
    for i, m in (zip(final_assignments, kmeans_assignments)):
        mismatch[i, m] += 1

    np.set_printoptions(suppress=True)
    print("\nKMedoids:")
    print(x[final_medoid_ids, ])
    print("K-Medoids class sizes:")
    print(mismatch.sum(axis=-1))
    print("\nKMeans:")
    print(kmeans)
    print("K-Means class sizes:")
    print(mismatch.sum(axis=0))
    print("\nMismatch between assignment to Kmeans and Kmedoids:")
    print(mismatch)
    print("Should ideally be {} * a permutation matrix.".format(n//k))


from enum import unique
from django.db import models
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _

from GraphQL.models import BaseModelNative

# Create your models here.

class Language(BaseModelNative):
    iso_639_1 = models.CharField(
        max_length=5,
        unique=True,
        verbose_name = _("ISO_639_1"),
    )
    rtl = models.BooleanField(
        default=False,
        verbose_name=_("RightToLeft"),
    )
    # is_active = models.BooleanField(
    #     default=True,
    #     verbose_name=_("is_Active"),
    # )

    class Meta:
        verbose_name = _("Language")
        verbose_name_plural = _("Languages")


import pandas as pd
import numpy as np
import math
import json

# list of relevant aa indeces as per the paper
aaindex_list = [pd.read_excel("AZAE970101.xlsx", index_col="Unnamed: 0"), pd.read_excel("BENS940104.xlsx", index_col="Unnamed: 0"), pd.read_excel("BETM990101.xlsx", index_col="Unnamed: 0"), pd.read_excel("BONM030103.xlsx", index_col="Unnamed: 0"), pd.read_excel("BONM030104.xlsx", index_col="Unnamed: 0"),
                pd.read_excel("KOLA920101.xlsx", index_col="Unnamed: 0"), pd.read_excel("LUTR910108.xlsx", index_col="Unnamed: 0"), pd.read_excel("MUET010101.xlsx", index_col="Unnamed: 0"), pd.read_excel("TANS760101.xlsx", index_col="Unnamed: 0"), pd.read_excel("ZHAC000106.xlsx", index_col="Unnamed: 0")]

# load positions that have been pre-determined using the logistic regression
pos = []
with open("positions.json", "r") as file:
    pos = json.load(file)

intervals = []
for position in pos:
    if len(intervals) == 0:
        intervals.append([position, 1])
    else:
        if intervals[-1:][0][0] == (position - 1):
            intervals[-1:][0][1] += 1
        else:
            intervals.append([position, 1])

# intervals in format
# (start_pos, length)

def encode(shape, serum_seq, antigen_seq):
    global aaindex_list
    # shape in
    # (number of amino acids, number of aaindex)

    global pos
    answer = np.zeros((len(pos), 10))

    i = 0
    for position in pos:
        if serum_seq[position] != antigen_seq[position]:
            try:
                for j in range(len(aaindex_list)):
                    df = aaindex_list[j]
                    letter_val = df.loc[serum_seq[position], antigen_seq[position]]
                    if math.isnan(letter_val):
                        letter_val = -(df.loc[antigen_seq[position], serum_seq[position]])
                    #print(answer.shape, i, j)
                    answer[i][j] = letter_val
            except:
                pass
        i = i + 1

    return answer

sequence_dict = {}
def construct_x(serum, sequences, distances, len_sequence):
    # takes in the serum name and all antigen sequences
    # also: the csv containing all antigenic distances,
    # start position, length of sequence,
    # important aaindex for use by aaindex_encode,
    # and the list of all important positions
    global aaindex_list
    global pos
    global sequence_dict
    num_pos = len(pos)

    df = pd.read_csv(distances, index_col = 0)
    x = np.zeros((df.shape[0], num_pos, len(aaindex_list)))
    # SHAPE: (num_antigens, 566, 10)
    # where 566 is the standardized length of all the aligned sequences
    # and 10 is the # of aaindeces being examined

    sep = "/"
    with open(sequences, "r") as seq_file:

        content = seq_file.read().split(">")
        serum_sequence = ""

        if len(sequence_dict.keys())==0:
            for line in content:
                entries = line.split("\n")
                try:
                    name = entries[0].split("/")[0]
                    sequence = "".join(entries[1:])
                    if name not in sequence_dict.keys():
                        sequence_dict[name] = sequence
                except Exception as e:
                    print(e)

        serum_sequence = sequence_dict[serum]

        i = 0
        keys_list = list(sequence_dict.keys())
        keys_list.sort()
        for key in keys_list:
            if key in df.index.values:
                try:
                    substring = np.zeros((len_sequence, 10))
                    substring = np.array(encode(substring.shape, serum_sequence, sequence_dict[key]))
                    x[i] = substring
                    i += 1

                except ValueError as e:
                    print(e)

    return x

def scale(vector):
    min = vector[0]
    max = vector[0]
    for val in vector:
        if val < min:
            min = val
        if val > max:
            max = val

    for i in range(len(vector)):
        vector[i] = (vector[i] - min) / (max - min)
    return vector

def construct_y(serum, distances):
    # y values are the distances between each antigen-serum pair

    df = pd.read_csv(distances)
    y = np.zeros(df.shape[0], )
    for antigen_index in range(y.shape[0]):
        #y_val = df.iloc[antigen_index].loc[serum]
        # if y_val > 4:
        #     y[antigen_index] = 1
        # else:
        #     y[antigen_index] = 0
        y[antigen_index] = df.iloc[antigen_index].loc[serum]
    return y


a, b = input(), input()

len_r, len_c = len(a), len(b)
dp = [[0]*(len_c+1) for _ in range(len_r+1)]

for cr in range(1, len_r+1):
    for cc in range(1, len_c+1):
        if a[cr-1] == b[cc-1]:
            dp[cr][cc] = dp[cr-1][cc-1] + 1
        else:
            dp[cr][cc] = max(dp[cr][cc-1], dp[cr-1][cc])
print(dp[-1][-1])


import time
import logging
import math
import board
import busio
import adafruit_si5351

# Default I2C address for device.
MCP9808_I2CADDR_DEFAULT        = 0x3c

# Register addresses.
MCP9808_REG_CONFIG             = 0x01
MCP9808_REG_UPPER_TEMP         = 0x02
MCP9808_REG_LOWER_TEMP         = 0x03
MCP9808_REG_CRIT_TEMP          = 0x04
MCP9808_REG_AMBIENT_TEMP       = 0x05
MCP9808_REG_MANUF_ID           = 0x06
MCP9808_REG_DEVICE_ID          = 0x07

class MCP9808(object):
	"""Class to represent an Adafruit MCP9808 precision temperature measurement
	board.
	"""

	def __init__(self, address=MCP9808_I2CADDR_DEFAULT, i2c=None, **kwargs):
		"""Initialize MCP9808 device on the specified I2C address and bus number.
		Address defaults to 0x18 and bus number defaults to the appropriate bus
		for the hardware.
		"""
		self._logger = logging.getLogger('Adafruit_MCP9808.MCP9808')
		if i2c is None:
			import Adafruit_GPIO.I2C as I2C
			i2c = I2C
		self._device = i2c.get_i2c_device(address, **kwargs)

	def begin(self):
		"""Start taking temperature measurements. Returns True if the device is
		intialized, False otherwise.
		"""
		# Check manufacturer and device ID match expected values.
		mid = self._device.readU16BE(MCP9808_REG_MANUF_ID)
		did = self._device.readU16BE(MCP9808_REG_DEVICE_ID)
		self._logger.debug('Read manufacturer ID: {0:04X}'.format(mid))
		self._logger.debug('Read device ID: {0:04X}'.format(did))
		return mid == 0x0054 and did == 0x0400

	def readTempC(self):
		"""Read sensor and return its value in degrees celsius."""
		# Read temperature register value.
		t = self._device.readU16BE(MCP9808_REG_AMBIENT_TEMP)
		self._logger.debug('Raw ambient temp register value: 0x{0:04X}'.format(t & 0xFFFF))
		# Scale and convert to signed value.
		temp = (t & 0x0FFF) / 16.0
		if t & 0x1000:
			temp -= 256.0
		return temp

def getTemperature():
	sensor = MCP9808()
	sensor.begin()
	return sensor.readTempC()

def writeClock(freq_mult, divisor):
	i2c = busio.I2C(board.SCL, board.SDA)

	# Initialize SI5351.
	si5351 = adafruit_si5351.SI5351(i2c)

	si5351.pll_a.configure_integer(freq_mult)
	print('PLL A frequency: {0}mhz'.format(si5351.pll_a.frequency/1000000))

	# si5351.pll_b.configure_fractional(24, 2, 3)  # Multiply 25mhz by 24.667 (24 2/3)
	# print('PLL B frequency: {0}mhz'.format(si5351.pll_b.frequency/1000000))

	si5351.clock_0.configure_integer(si5351.pll_a, divisor)
	print('Clock 0: {0}mhz'.format(si5351.clock_0.frequency/1000000))

	# si5351.clock_1.configure_fractional(si5351.pll_b, 45, 1, 2) # Divide by 45.5 (45 1/2)
	# print('Clock 1: {0}mhz'.format(si5351.clock_1.frequency/1000000))

	# si5351.clock_2.configure_integer(si5351.pll_b, 900)

	# si5351.clock_2.r_divider = adafruit_si5351.R_DIV_64
	# print('Clock 2: {0}khz'.format(si5351.clock_2.frequency/1000))

	# After configuring PLLs and clocks, enable the outputs.
	si5351.outputs_enabled = True
	# You can disable them by setting false.


#! usr/bin/env python3

import unittest
import decode
import shutil
import os
from subprocess import call

class testSequences(unittest.TestCase):

    def setUp(self):
        pass

    def test1(self):
        ''' from Task description, 2 ways of decoding 12

        asserts that there are 2 ways of decoding 12'''

        tinput = 12
        expOutput = 2
        self.assertEqual(decode.main(tinput), expOutput)

    def test2(self):
        '''from task description, 3 ways of decoding 123

        asserts that there are three ways of decoding 123'''

        tinput = 123
        expOutput = 3
        self.assertEqual(decode.main(tinput), expOutput)

    def test3(self):
        '''edge case - 1111 should have 5 ways of solving

        asserts that there are 5 ways of decoding 1111
        1) aaaa
        2) kk
        3) kaa
        4) aka
        5) aak
        '''

        tinput = 1111
        expOutput = 5
        self.assertEqual(decode.main(tinput), expOutput)

if __name__ == "__main__":

    direct = os.getcwd()
    print(direct)
    src = os.path.join(direct, 'decode.py')
    dst = os.path.join(direct, 'decode.py3')
    shutil.copyfile(src, dst)
    style = call(['pep8', 'decode.py'])
    unittest.main(verbosity=3)


# Refer to RFC3565
# coding: utf-8

from __future__ import unicode_literals

from base64 import b64encode
from email import message_from_string
from email.mime.text import MIMEText

from .cert import certs_from_pem
from .block import get_cipher
from .print_util import wrap_lines

from asn1crypto import cms

def __iterate_recipient_infos(certs, session_key):
    if isinstance(certs, (tuple, list)):
        for cert_file in certs:
            for cert in certs_from_pem(cert_file):
                recipient_info = cert.recipient_info(session_key)
                yield recipient_info
    else:
        for cert in certs_from_pem(certs):
            recipient_info = cert.recipient_info(session_key)
            yield recipient_info

def encrypt(message, certs, algorithm='aes256'):
    """
    Takes the contents of the message parameter, formatted as in RFC 2822, and encrypts them,
    so that they can only be read by the intended recipient specified by pubkey.
    :return: string containing the new encrypted message.
    """
    # Get the chosen block cipher
    block_cipher = get_cipher(algorithm)
    if block_cipher == None:
        raise ValueError('Unknown block algorithm')

    # Get the message content
    msg = message_from_string(message)
    to_encode = MIMEText(msg.get_payload())
    content = to_encode.as_string()

    # Generate the recipient infos
    recipient_infos = []
    for recipient_info in __iterate_recipient_infos(certs, block_cipher.session_key):
        if recipient_info == None:
            raise ValueError('Unknown public-key algorithm')
        recipient_infos.append(recipient_info)

    # Encode the content
    encrypted_content_info = block_cipher.encrypt(content)

    # Build the enveloped data and encode in base64
    enveloped_data = cms.ContentInfo({
        'content_type': 'enveloped_data',
        'content': {
            'version': 'v0',
            'recipient_infos': recipient_infos,
            'encrypted_content_info': encrypted_content_info
        }
    })
    encoded_content = '\n'.join(wrap_lines(b64encode(enveloped_data.dump()), 64))

    # Create the resulting message
    result_msg = MIMEText(encoded_content)
    overrides = (
        ('MIME-Version', '1.0'),
        ('Content-Type', 'application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m'),
        ('Content-Transfer-Encoding', 'base64'),
        ('Content-Disposition', 'attachment; filename=smime.p7m')
    )

    for name, value in list(msg.items()):
        if name in [x for x, _ in  overrides]:
            continue
        result_msg.add_header(name, value)

    for name, value in overrides:
        if name in result_msg:
            del result_msg[name]
        result_msg[name] = value

    return result_msg.as_string()


"""
7. Two Sum

Write a function that, when passed a list and a target sum, returns, efficiently with respect to
time used, two distinct zero-based indices of any two of the numbers, whose sum is equal to
the target sum. If there are no two numbers, the function should return None.

For example, find_two_sum([3, 1, 5, 7, 5, 9], 10) should return a single tuple containing any of the
following pairs of indices:

0 and 3 (or 3 and 0) as 3 + 7 = 10
1 and 5 (or 5 and 1) as 1 + 9 = 10
2 and 4 (or 4 and 2) as 5 + 5 = 10

* Subject - Eradicate duplicate elements

* Learning
    1. When put list's index, element into dictionary,
       Key : element , Value : [index]
       (Because if put element into Value, No way to find the value.
        So, put element into Value, but input indexes as a list for duplicate issue.)

    2. Do not use "list.index(x)", "x in [list]" etc on a problem with time efficiency issue

    3. 'key in dict' is as fast as 'dict.get(key)', I guess
"""

class TwoSum:

    @staticmethod
    def find_two_sum(numbers, target_sum):
        """
        Time : (more than) 40 min
        Tests: 3 pass / 1 fail
          Example case: Correct answer
          Distinct numbers with and without solutions: Correct answer
          Duplicate numbers with and without solutions: Correct answer
          Performance test with a large list of numbers: Time limit exceeded
        """
        """
        # 1) 1 for loop + 'in' + 'index' - O(n³)
        """
        # for i_num, i in enumerate(numbers):
        #     j = target_sum - i
        #     temp_list = numbers.copy()
        #     temp_list.pop(i_num)
        #     print(temp_list)
        #     if j in temp_list:
        #         j_num = numbers.index(j)
        #         if j_num != i_num:
        #             return i_num, j_num
        #         else:
        #             # 1) for loop
        #             # for k_num, k in enumerate(numbers):
        #             #     if k == j and i_num != k_num:
        #             #         return i_num, k_num
        #             # 2) change the first same element
        #             numbers[j_num] = -1
        #             return i_num, numbers.index(j)
        # return None
        """
        2) two for loop - O(n²)
        """
        # for i in range(len(numbers)):
        #
        #     for j in range(len(numbers)):
        #         if j == i:
        #             continue
        #         if numbers[i] + numbers[j] == target_sum:
        #             return i, j
        """
        3) dict + "num in dict1"

        Time : 52 min
        Tests: 4 pass / 0 fail
          Example case: Correct answer
          Distinct numbers with and without solutions: Correct answer
          Duplicate numbers with and without solutions: Correct answer
          Performance test with a large list of numbers: Correct answer
        """
        dict1 = {}
        for i_num, i in enumerate(numbers):

            # To cope with 'numbers' having duplicate numbers
            if dict1.get(i):
                dict1[i] += [i_num]
            else:
                dict1[i] = [i_num]

        for key, value in dict1.items():
            target_num = target_sum - key
            if target_num in dict1:

                if key != target_num:
                    return dict1[key][0], dict1[target_num][0]

                elif key == target_num and len(dict1[key]) > 1:
                    return dict1[key][0], dict1[key][1]

print(TwoSum.find_two_sum([3, 3, 5, 7, 5, 9], 10))

"""
181111 Review

Time : 17 (min)
Tests: 4 pass / 0 fail
  Example case: Correct answer
  Distinct numbers with and without solutions: Correct answer
  Duplicate numbers with and without solutions: Correct answer
  Performance test with a large list of numbers: Correct answer
"""

class TwoSum:

    @staticmethod
    def find_two_sum(numbers, target_sum):
        """
        :param numbers: (list of ints) The list of numbers.
        :param target_sum: (int) The required target sum.
        :returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
        """

        number_dict = {}
        for idx, i in enumerate(numbers):
            if number_dict.get(i):
                number_dict[i] += [idx]
            else:
                number_dict[i] = [idx]

        for key in number_dict.keys():
            num = target_sum - key
            # if num in number_dict:
            if number_dict.get(num):

                # 1) fail - because the exception case go to else: directly
                # if num == key and len(number_dict[num]) > 1:
                #     print(number_dict[key][0], number_dict[num][1])
                #     return number_dict[key][0], number_dict[num][1]
                # else:
                #     print(number_dict[key][0], number_dict[num][0])
                #     return number_dict[key][0], number_dict[num][0]

                # 2) pass
                # if num == key:
                #     if len(number_dict[num]) > 1:
                #         print(number_dict[key][0], number_dict[num][1])
                #         return number_dict[key][0], number_dict[num][1]
                # else:
                #     print(number_dict[key][0], number_dict[num][0])
                #     return number_dict[key][0], number_dict[num][0]

                # 3) pass (But I didn't know there could be a flaw)
                if num != key:
                    print(number_dict[key][0], number_dict[num][0])
                    return number_dict[key][0], number_dict[num][0]
                elif num == key and len(number_dict[num]) > 1:
                    print(number_dict[key][0], number_dict[num][1])
                    return number_dict[key][0], number_dict[num][1]
        return None

print(TwoSum.find_two_sum([5, 1, 2, 7, 3, 9], 10))

"""
181129 Review 2

Time : 14 (min)
Tests: 3 pass / 1 fail
  Example case: Correct answer
  Distinct numbers with and without solutions: Correct answer
  Duplicate numbers with and without solutions: Correct answer
  * Performance test with a large list of numbers: Time limit exceeded
"""

# class TwoSum:
#
#     @staticmethod
#     def find_two_sum(numbers, target_sum):
#         """
#         :param numbers: (list of ints) The list of numbers.
#         :param target_sum: (int) The required target sum.
#         :returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
#         """
#
#         for i in range(len(numbers)):
#             numbers2 = numbers.copy()
#             num = target_sum - numbers[i]
#             if num in numbers:
#                 if num != numbers[i]:
#                     return i, numbers.index(num)
#                 else:
#                     del numbers2[i]
#                     if num in numbers2:
#                         return i, numbers2.index(num)+1
#         return None

"""
181129 Review 2

Time : 10 (min)
Tests: 4 pass / 0 fail
  Example case: Correct answer
  Distinct numbers with and without solutions: Correct answer
  Duplicate numbers with and without solutions: Correct answer
  Performance test with a large list of numbers: Correct answer
"""

class TwoSum:

    @staticmethod
    def find_two_sum(numbers, target_sum):
        """
        :param numbers: (list of ints) The list of numbers.
        :param target_sum: (int) The required target sum.
        :returns: (a tuple of 2 ints) The indices of the two elements whose sum is equal to target_sum
        """

        dict1 = {}
        for idx, i in enumerate(numbers):
            if dict1.get(i):
                dict1[i].append(idx)
            else:
                dict1[i] = [idx]

        for i in numbers:
            num = target_sum - i

            # (x) 'in' made a loop
            # if num in numbers:

            # 181129
            # 1) This also works !
            if num in dict1:

            # 2)
            # if dict1.get(num):

                if i != num:
                    return dict1[i][0], dict1[num][0]
                if len(dict1[i]) > 1:
                    return dict1[i][0], dict1[i][1]
        return None

print(TwoSum.find_two_sum([1, 1, 5, 7, 5, 8], 10))