import math
import random
from datetime import datetime

import firebase_admin
import geopy.distance
import pandas as pd
from faker import Faker
from firebase_admin import firestore
from geopy import distance

from api.models.hobby_enum import Hobby
from api.models.photo_model import PhotoModel

def deg2rad(degrees):
    return degrees * math.pi / 180

def getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2):
    R = 6371
    dLat = deg2rad(lat2 - lat1)
    dLon = deg2rad(lon2 - lon1)
    a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(deg2rad(lat1)) \
        * math.cos(deg2rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    d = R * c
    return d

def generateAddress():
    # Read the Excel file
    df = pd.read_excel('mienbac.xlsx')
    # select a random row
    row = df.sample()
    #  return { address = city+ admin_name, lat , lng} using python
    address = row['city'].values[0] + ", " + row['admin_name'].values[0]
    lat = row['lat'].values[0]
    lng = row['lng'].values[0]
    return lat, lng, address

def genLocationFromSheet():
    lat, lng, address = generateAddress()
    return {
        'latitude': float(lat),
        'longitude': float(lng),
        'address': address,
        'create_at': datetime.now().isoformat(),
        'update_at': datetime.now().isoformat()
    }

def generateLocation(latitude, longitude, max_distance, min_distance=0):
    if min_distance > max_distance:
        raise ValueError(f"min_distance({min_distance}) cannot be greater than max_distance({max_distance})")

    # earth radius in km
    EARTH_RADIUS = 6371

    # 1° latitude in meters
    DEGREE = EARTH_RADIUS * 2 * math.pi / 360 * 1000

    # random distance within [min_distance-max_distance] in km in a non-uniform way
    max_km = max_distance * 1000
    min_km = min_distance * 1000
    r = ((max_km - min_km + 1) * random.random() ** 0.5) + min_km

    # random angle
    theta = random.random() * 2 * math.pi

    dy = r * math.sin(theta)
    dx = r * math.cos(theta)

    new_latitude = latitude + dy / DEGREE
    new_longitude = longitude + dx / (DEGREE * math.cos(deg2rad(latitude)))

    distance = round(getDistanceFromLatLonInKm(latitude, longitude, new_latitude, new_longitude))
    # address = getAddressFromLocation(latitude=new_latitude, longitude=new_longitude)
    # address = generateAddress()
    address = "Hà Nội"
    return {
        "newLatitude": new_latitude,
        "newLongitude": new_longitude,
        "distance": distance,
        "address": address
    }

def delete_docs_without_name_field(collection_name):
    # Initialize Firestore client
    firebase_admin.initialize_app()
    db = firestore.client()

    # Define a reference to the collection
    collection_ref = db.collection(collection_name)

    # Query for documents without a "name" field
    query = collection_ref.where("name", "==", None)

    # Delete each document in the query results
    for doc in query.stream():
        doc.reference.delete()

# print all docs in collection
def print_all_docs_in_collection(collection):
    docs = collection.stream()

    for doc in docs:
        print(f'{doc.id} => {doc.to_dict()}')

def nextIntOfDigits(digitCount):
    assert 1 <= digitCount <= 9
    min_num = 0 if digitCount == 1 else 10 ** (digitCount - 1)
    max_num = 10 ** digitCount
    return random.randint(min_num, max_num - 1)

# fake user
def fake_user():
    # fake data
    fake = Faker(locale="vi_VN")
    # create fake data
    id = fake.user_name()
    name = fake.name()
    email = fake.email()
    phone_number = '+84' + str(nextIntOfDigits(9))
    username = fake.user_name()
    gender = fake.random_int(min=0, max=1)
    birthday = fake.date_of_birth(minimum_age=18, maximum_age=30).strftime("%Y-%m-%d")
    avatar_url = fake.image_url()
    job = fake.job()
    # fake PhotoModel and add to list
    photo_list = [PhotoModel(id=0, url=fake.image_url(),
                             create_at=fake.date_time_between(start_date='-1y', end_date='now').isoformat()) for _ in
                  range(3)]
    description = fake.text(max_nb_chars=200)

    hobbies = [fake.random_element(elements=Hobby) for _ in range(nextIntOfDigits(1))]
    # convert hobbies to json
    hobbies2 = [hobby.toJSON() for hobby in hobbies]
    hobbies = [fake.random_element(elements=Hobby) for _ in range(10)]
    premium_expire_at = fake.future_date(end_date='+30d').strftime("%Y-%m-%d")
    local_gen = genLocationFromSheet()
    # hobby = Hobby.PHOTOGRAPHY
    # # get hobby index
    # hobby_index = Hobby.PHOTOGRAPHY.value
    # # get hobby name
    # print(Hobby.aslist())
    # print(Hobby.fromint(0))
    # print(hobby.name)
    # print(hobby.getId())

    # Create the user object
    user = {
        'id': id,
        'name': name,
        'email': email,
        'phone_number': phone_number,
        'username': username,
        'gender': gender,
        'birthday': birthday,
        'avatar_url': avatar_url,
        'job': job,
        'photo_list': photo_list,
        'description': description,
        'hobbies': hobbies,
        'premium_expire_at': premium_expire_at,
        'location': local_gen,
        'feed_filter': {
            'distance': fake.random_int(min=1, max=100),
            'interested_in_gender': fake.random_int(min=0, max=1),
            'age_range': {
                'start': fake.random_int(min=18, max=18),
                'end': fake.random_int(min=100, max=100)
            }
        },
        'online_flag': False,
        'is_fake_data': True,
    }
    return user

# input a_b
# output b_a
def get_reverse_id(id: str):
    return id.split('_')[1] + '_' + id.split('_')[0]

def print_user_info_from_user_ids(users_data, recommend_df, k=10):
    # Merge the dataframes
    merged_data = pd.merge(users_data, recommend_df[['id', 'hybrid_score']], on='id', how='left')

    # Fill NaN values with 0
    merged_data['hybrid_score'] = merged_data['hybrid_score'].fillna(0)
    # Sort the dataframe by hybrid_score
    merged_data.sort_values(by='hybrid_score', ascending=False, inplace=True)
    # Print the top k users
    # merged_data = merged_data[]
    return merged_data.head(k)

def distanceInKm(lat1, lon1, lat2, lon2):
    # approximate radius of earth in km
    coords_1 = (lat1, lon1)
    coords_2 = (lat2, lon2)
    return distance.great_circle(coords_1, coords_2).km

def getAddressFromLocation(latitude, longitude):
    return geopy.geocoders.Nominatim(
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36").reverse(
        (latitude, longitude)).address

def date_time_parser(value):
    if type(value) is str:
        return datetime.fromisoformat(value)
    return pd.to_datetime(value, unit='s')

import uuid
import time

def generate_transaction_id():
    #Alphanumeric[1,100]
    return str(uuid.uuid4())


from config import *
from PIL import Image
from os import listdir
from os.path import join
from matplotlib import pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import datasets, transforms
from torchvision.transforms import (
    Compose, Resize,
    ToTensor, Normalize,
    CenterCrop, RandomRotation,
    RandomHorizontalFlip, RandomApply
)

class CustomDataset(Dataset):

    def __init__(self, img_dir, transform1=None, transform2=None):
        '''Custom Dataset
        Params:
            img_dir     -> Image Directory
            transform1  -> Transform 1
            transform2  -> Transform 2
        '''
        self.img_dir = img_dir
        self.img_names = listdir(img_dir)
        self.transform1 = transform1
        self.transform2 = transform2
        self.imgs = []
        for img_name in self.img_names:
            img = Image.open(join(img_dir, img_name))
            if self.transform1 is not None:
                img = self.transform1(img)
            self.imgs.append(img)

    def __getitem__(self, index):
        img = self.imgs[index]
        if self.transform2 is not None:
            img = self.transform2(img)
        return img

    def __len__(self):
        return len(self.imgs)

def get_transforms():
    '''Get Transforms'''
    transform1 = Compose([
        Resize(IMAGE_SIZE),
        CenterCrop(IMAGE_SIZE)
    ])
    random_transforms = [RandomRotation(degrees = 5)]
    transform2 = Compose([
        RandomHorizontalFlip(p = 0.5),
        RandomApply(random_transforms, p = 0.3),
        ToTensor(),
        Normalize(
            (0.5, 0.5, 0.5),
            (0.5, 0.5, 0.5)
        )
    ])
    return transform1, transform2

def get_data_loader():
    '''Get DataLoader'''
    transform1, transform2 = get_transforms()
    train_dataset = CustomDataset(
        img_dir = IMAGE_DIRECTORY,
        transform1 = transform1,
        transform2 = transform2
    )
    train_loader = DataLoader(
        dataset = train_dataset,
        batch_size = BATCH_SIZE,
        shuffle = True,
        num_workers = 4
    )
    return train_loader

def visualize(data_loader):
    '''Visualize Dataset'''
    imgs = next(iter(data_loader))
    imgs = imgs.numpy().transpose(0, 2, 3, 1)
    fig = plt.figure(figsize = (25, 16))
    for i, img in enumerate(imgs):
        ax = fig.add_subplot(4, 8, i + 1, xticks = [], yticks = [])
        plt.imshow((img + 1) / 2)


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import unittest

class NewVisitorTest(unittest.TestCase):

    def setUp(self):
        self.browser = webdriver.Firefox()

    def tearDown(self):
        self.browser.quit()

    def check_for_row_in_list_table(self, row_text):
        table = self.browser.find_element_by_id('id_list_table')
        rows = table.find_elements_by_tag_name('tr')
        self.assertIn(row_text, [row.text for row in rows])

    def test_can_start_a_list_and_retrieve_it_later(self):

        # Edith has heard about a new online to-do app.
        # She goes check out the homepage

        self.browser.get('http://localhost:8000')

        # She notices the page title and header mentions to-do lists
        self.assertIn('To-Do', self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn('To-Do', header_text)

        # She is invited to enter a to-do item straight away
        input_box = self.browser.find_element_by_id('id_new_item')
        self.assertEqual(
            input_box.get_attribute('placeholder'),
            'Enter a to-do item'
        )

        # She types "Buy peacock feathers" into a text box
        # (Edith's hobby is tying fly-fishing lures)
        input_box.send_keys('Buy peacock feathers')
        input_box.send_keys(Keys.ENTER)
        time.sleep(1)
        # When she hits enter, the page updates, and now the page lists
        # "1: Buy peacock feathers" as an item
        self.check_for_row_in_list_table('1: Buy peacock feathers')

        # There is still a text box inviting her to add another item. She
        # enters "Use peacock feathers to make a fly" (Edith is very
        # methodical)
        input_box = self.browser.find_element_by_id('id_new_item')
        input_box.send_keys('Use peacock feathers to make a fly')
        input_box.send_keys(Keys.ENTER)
        time.sleep(1)
        # There is still a text box inviting her to add another item.
        # She ads "use peacock feathers to make a fly"

        # The page updates and shows both items on her list

        self.check_for_row_in_list_table('1: Buy peacock feathers')
        self.check_for_row_in_list_table('2: Use peacock feathers to make a fly')

        # Edith wonders whether the site will remember her list.
        # She sees that the site has generate a unique URL for her
        self.fail('Finish the test!')
        # She visists that URL - her to-do list is still there!

        # She goes happily back to sleep

if __name__ == '__main__':
    unittest.main()


import json
from datetime import date
from urllib.parse import unquote

import functools
from flask_migrate import MigrateCommand
from flask_script import Manager

from cenotes_lib.crypto import get_supported_algorithm_options
from cenotes import create_app
from cenotes.api import craft_response, CENParams
from cenotes.models import Note

manager = Manager(create_app)
manager.add_option("-c", "--config", dest="app_settings", required=False)
manager.add_command('db', MigrateCommand)

def show_json_request_format(indent=False):
    with create_app().app_context():
        func = functools.partial(json.dumps, indent=4) if indent else json.dumps
        return func(CENParams(plaintext="", key="",
                              expiration_date=date.today().isoformat(),
                              visits_count=0, max_visits=0).__dict__)

def show_json_response_format(indent=False):
    func = functools.partial(json.dumps, indent=4) if indent else json.dumps
    return func(craft_response(
        error="", success=True, plaintext="", key="", dkey="",
        payload="ciphertext",
        enote=Note(payload="ciphertext", expiration_date=date.today())))

def list_url_endpoints():
    output = []
    for rule in manager.app.url_map.iter_rules():
        if rule.endpoint == "static":
            continue
        options = {}
        for arg in rule.arguments:
            options[arg] = "[{0}]".format(arg)

        methods = ','.join(rule.methods)
        line = unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
        output.append(line)
    return output

@manager.option('--response', dest="response", action="store_true", default=False)
@manager.option('--request', dest="request", action="store_true", default=False)
@manager.option('--both', dest="both", action="store_true", default=False)
def api(response, request, both):
    def response_format():
        print("Response format is always like this:\n"
              "(Some fields may be left empty depending on endpoint call)")
        print(show_json_response_format(indent=True))
        print("")

    def request_format():
        print("Request format is always like this:\n"
              "(Some fields may be left empty depending on endpoint call)")
        print(show_json_request_format(indent=True))
        print("")

    if both:
        response = request = True

    if response:
        response_format()
    if request:
        request_format()

@manager.command
def routes():
    for line in sorted(list_url_endpoints()):
        print(line)

@manager.option("--keygen", dest="enc", action="store_true", default=False)
def settings(enc):
    def craft_algo_params_format():
        return {algo: {"hardness": hardness}
                for algo, hardness in tuple(get_supported_algorithm_options())}
    if enc:
        print("Valid algorithm/hardness settings for your device are:\n"
              "{params}".format(params=craft_algo_params_format()))

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


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('profs', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='module',
            name='content',
            field=models.TextField(verbose_name=b'contenu', blank=True),
        ),
    ]


# experiments using "real" data

import numpy as np
import pandas as pd
import time
from sklearn.model_selection import train_test_split
from sklearn.model_selection import ShuffleSplit
import matplotlib.pyplot as plt

# methods
from SSP import SSP
from linreg import linreg, ridgereg
from adassp import adaSSP, constSSP, constSSPfull, adaSSP_1_3, adaSSP_2_3, adaSSP_1_100, adaSSP_1_6, adaSSP_5_6

from test_recovery import test_recovery, test_prediction_error

import scipy.io

# set delta globally, to be used - I may also use a particular function, as needed
delta = 10 ** (-6)

def delta_func(n):
    #return 10 ** (-6) # I could hardcode it
    return n ** (-1.1)

def plots_by_gamma():
    epslist = [0.001, 0.01, 0.1,1]

    # data_name_list = ["airfoil", "autompg", "bike", "wine", "yacht"] # and "autos"? and "3droad"?
    # the ones that work are ["airfoil", "autompg", "bike", "wine", "yacht"]
    # but I only have so much space, so use these:
    data_name_list = ["bike", "wine", "yacht"]

    cross_val_splits = 32

    #gammas = [0.05 * i for i in range(1, 10)] + [0.01, 0.02, 0.03, 0.04] + [0.66, 0.95] + [0.1 ** i for i in range(3,6)] # vary by 0.05? Maybe, sure, why not. I may make this more finegrained later
    #gammas  = [0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8]
    #gammas = [0.01 + 0.02 * i for i in range(50)]
    gammas = [0.05 + 0.05 * i for i in range(19)] + [0.01, 0.02, 0.03, 0.04]
    gammas.sort()
    print(f"using cross_val_splits of {cross_val_splits}, gammas are {gammas}")

    def create_budget_func(gamma):
        def temp_func(X,y,epsilon, delta):
            return adaSSP(X=X,y=y,epsilon=epsilon,delta=delta, gamma=gamma)
        return temp_func

    methodslist = [create_budget_func(gamma) for gamma in gammas]
    methodsNamelist = [f"adaSSPbudget {gamma:.4f}" for gamma in gammas]

    constSSPfull_func = lambda X,y,epsilon,delta: constSSPfull(X=X,y=y,epsilon=epsilon,delta=delta, gamma=0.3)#

    num_data = len(data_name_list)
    num_eps = len(epslist)
    num_method = len(methodslist)

    sigma = 1

    # do the SSP algorithm on its own
    #non_private_results = np.zeros((num_eps, num_data))
    SSP_results = np.zeros((num_eps, num_data))
    SSP_std = np.zeros((num_eps, num_data))

    results_err = np.zeros((num_method,num_eps,num_data))
    results_std = np.zeros((num_method,num_eps,num_data))

    # for the const values (the constSSP)
    #const_results_err = np.zeros((num_method,num_eps,num_data))
    #const_results_std = np.zeros((num_method,num_eps,num_data))

    const_full_results_err = np.zeros((num_eps,num_data))
    const_full_results_std = np.zeros((num_eps,num_data))

    zero_error_counts = np.zeros((num_method,num_eps,num_data))

    d_map = {}
    n_map = {}

    for i in range(num_data):
        # extract and parse data
        data_name = data_name_list[i]
        print("data is " + data_name)
        all_data = scipy.io.loadmat('data/data_uci/' + data_name + '/' + data_name + '.mat')['data']

        n = all_data.shape[0]
        d = all_data.shape[1] - 1 # minus 1, because of the y part

        d_map[i] = d
        n_map[i] = n

        X = all_data[:,:d]
        y = all_data[:,-1]

        X = X - X.mean()
        y = y - y.mean()
        y = y / y.std()

        X_sqrt_sum = np.sqrt(np.sum(np.square(X), axis=1))
        X = X / X_sqrt_sum[:,None]

        all_indices = np.arange(n)
        cvo = [splits for splits in ShuffleSplit(n_splits=cross_val_splits, test_size=0.1).split(all_indices)]

        for j in range(num_eps):
        #% set parameters of the algorithm
            eps = epslist[j]
            print(f"eps is {eps:.4f}")

            # may as well also track SSP
            t = time.time()
            errs, cvErr,cvStd, errorDict = test_prediction_error(X, y, cvo, SSP, eps, delta, d)
            assert(not np.isnan(cvErr))
            t_run = time.time() - t
            print(f"method = SSP, Time run was {t_run:.4f}s")
            SSP_results[j, i] = cvErr
            SSP_std[j, i] = cvStd

            # constSSPfull
            errs, cvErr,cvStd, errorDict = test_prediction_error(X, y, cvo, constSSPfull_func, eps, delta, d)
            assert(not np.isnan(cvErr).any())
            const_full_results_err[j,i] = cvErr
            const_full_results_std[j,i] = cvStd

            # then for the rest of them
            for k in range(num_method):
                fun = methodslist[k]
                t = time.time()
                errs, cvErr,cvStd, errorDict = test_prediction_error(X, y, cvo, fun, eps, delta, d)
                assert(not np.isnan(cvErr).any())
                t_run = time.time() - t
                print(f"method = {methodsNamelist[k]}, Time run was {t_run:.4f}s")
                results_err[k,j,i] = cvErr
                results_std[k,j,i] = cvStd
                # the "lambda zero proportion" from the thesis
                zero_error_counts[k,j,i] = errorDict["zero_counter"]

    # plotting prediction error
    fig, axs = plt.subplots(2, 2, figsize=(16,14), sharex=True, sharey=True)
    fig.suptitle('Prediction Error (MSE), UCI Data', fontsize=20)
    axs_raveled = list(np.ravel(axs))
    for j in range(num_eps):
        eps = epslist[j]
        ax = axs_raveled[j]

        # instead of a different curve for each method, do a different curve for each n
        for i in range(num_data):
            # plot gammas on the x-axis
            adaSSPbudget_yerr = np.concatenate(    (np.zeros((num_method, 1)), results_std[:,j,i].reshape((num_method,1))),    axis=1).transpose()
            ax.errorbar(x=gammas, y=results_err[:,j,i], yerr=adaSSPbudget_yerr, label=f"adaSSPbudget, data={data_name_list[i]}, n={n_map[i]}, d={d_map[i]}")

            #constant set to 3 because of SSP, adaSSPbudget, constSSPfull
            temp_color = ax.get_lines()[3*i].get_color()

            constSSPfull_vals = [const_full_results_err[j,i]] * len(gammas)
            constSSPfull_stds = np.array([const_full_results_std[j,i]] * len(gammas))
            constSSPfull_yerr = np.concatenate(    (np.zeros((num_method, 1)), constSSPfull_stds.reshape((num_method,1))),    axis=1).transpose()
            ax.errorbar(x=gammas, y=constSSPfull_vals, yerr=constSSPfull_yerr, label=f"constSSPfull, data={data_name_list[i]}, n={n_map[i]}, d={d_map[i]}", color=temp_color, linestyle="dotted")

            ssp_vals = [SSP_results[j,i]] * len(gammas)
            ssp_stds = np.array([SSP_std[j,i]] * len(gammas))
            ax.errorbar(x=gammas, y=ssp_vals, yerr=np.concatenate(    (np.zeros((num_method, 1)), ssp_stds.reshape((num_method,1))),    axis=1).transpose(), label=f"SSP, data = {data_name_list[i]}", color=temp_color, linestyle="dashed")

        ax.plot([1.0/3.0, 1.0/3.0], [0, 10** 5], label="adaSSP gamma value")
        ax.set_xlabel("Gamma")
        ax.set_ylabel('Prediction Error (MSE)')
        ax.set_title(f"epsilon = {eps:.3f}")
        ax.set_yscale('log')

    handles, labels = ax.get_legend_handles_labels()
    fig.legend(handles, labels, loc='center')
    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    plt.savefig(f"plots/pred_err_by_gamma_all_eps_data.png")
    plt.close()

    # for plotting errors
    for j in range(num_eps):
        fig, ax = plt.subplots(1, figsize=(9,6)) # just one, for now
        eps = epslist[j]

        # instead of a different curve for each method, do a different curve for each n
        for i in range(num_data):
            # plot gammas on the x-axis
            error_props = [val / cross_val_splits for val in list(zero_error_counts[:,j,i])]
            ax.plot(gammas,error_props, label=f"data={data_name_list[i]}, n={n_map[i]}, d={d_map[i]}", alpha=0.7)

        ax.set_xlabel("Gamma")
        ax.set_ylabel('Lambda Zero Proportion (for adaSSPbudget)')
        ax.set_title(f"Lambda Zero Proportion For epsilon = {eps:.3f}, UCI Data")
        ax.legend()
        plt.savefig(f"plots/zero_count_by_gamma_eps_{eps:.4f}_data.png")

"""
# this checks non private ridge regression
def non_private_checks():

    cross_val_splits = 6 # maybe crank up for real results...

    data_name_list = ["airfoil", "autompg", "bike", "wine", "yacht"]

    lambs = [10 ** i for i in range(-5,5)]
    lambs.sort()

    #vanilla_index = methodsNamelist.index('Non-Private')
    #if vanilla_index < 0:
        #print("You need the nonprivate version to compute relative efficiency!")
        #assert(False)

    def create_ridge_func(lamb):
        def temp_func(X,y,epsilon, delta):
            return ridgereg(X=X,y=y,epsilon=epsilon,delta=delta, lamb=lamb)
        return temp_func

    methodslist = [create_ridge_func(lamb) for lamb in lambs]
    methodsNamelist = [f"Ridge Regression {lamb:.4f}" for lamb in lambs]

    num_data = len(data_name_list)
    num_method = len(methodslist)

    sigma = 1

    linreg_results = np.zeros((num_data))
    linreg_std = np.zeros((num_data))

    ridge_results = np.zeros((num_method, num_data))
    ridge_std = np.zeros((num_method, num_data))

    zero_error_counts = np.zeros((num_method, num_data))

    d_map = {}
    n_map = {}

    for i in range(num_data):
        data_name = data_name_list[i]
        print("data is " + data_name)
        all_data = scipy.io.loadmat('data/data_uci/' + data_name + '/' + data_name + '.mat')['data']

        n = all_data.shape[0]
        d = all_data.shape[1] - 1 # minus 1, because of the y part

        d_map[i] = d
        n_map[i] = n

        X = all_data[:,:d]
        y = all_data[:,-1]

        X = X - X.mean() # do I get mean for free?
        y = y - y.mean()
        y = y / y.std()

        X_sqrt_sum = np.sqrt(np.sum(np.square(X), axis=1))
        X = X / X_sqrt_sum[:,None]

        #cvo = cvpartition(length(y),'KFold',10);
        all_indices = np.arange(n)
        cvo = [splits for splits in ShuffleSplit(n_splits=cross_val_splits, test_size=0.1).split(all_indices)] #, random_state=0) # I could put random state here, if I wanted

        #delta = 1 / (n ** (1.1)) # not so sure what this is about
        delta = delta_func(n)
        eps = 1.0

        # have to do the linreg version
        t = time.time()
        errs, cvErr,cvStd, errorDict = test_prediction_error(X, y, cvo, linreg, eps, delta, d)
        assert(not np.isnan(cvErr))
        t_run = time.time() - t
        print(f"method = linreg, Time run was {t_run:.4f}s")
        linreg_results[i] = cvErr
        linreg_std[i] = cvStd

        # then for the rest of them
        for k in range(num_method):
            fun = methodslist[k]
            t = time.time()
            errs, cvErr,cvStd, errorDict = test_prediction_error(X, y, cvo, fun, eps, delta, d)
            assert(not np.isnan(cvErr))
            #t_run=toc; # this is for timing, which I am not keeping track of
            t_run = time.time() - t
            print(f"method = {methodsNamelist[k]}, Time run was {t_run:.4f}s")
            #fprintf('%s at eps = %f: Test err = %.2f, std = %.2f, runtime = %.2f s.\n', methodsNamelist{k}, opts.eps, cvErr,cvStd,t_run)
            ridge_results[k,i] = cvErr
            ridge_std[k,i] = cvStd

    fig, ax = plt.subplots(1, figsize=(9,6)) # just one, for now

    # instead of a different curve for each method, do a different curve for each n
    #for k in range(num_method):
    for i in range(num_data):

        # plot gammas on the x-axis
        ax.errorbar(x=lambs, y=ridge_results[:,i], yerr=np.concatenate(    (np.zeros((num_method, 1)), ridge_std[:,i].reshape((num_method,1))),    axis=1).transpose(), label=f"data = {data_name_list[i]}, n={n_map[i]}, d={d_map[i]}")

        temp_color = ax.get_lines()[2*i].get_color()#ax.get_color()

        #ssp_vals = [SSP_rel_eff[j,i]] * len(gammas)
        #ssp_stds = np.array([SSP_rel_eff_std[j,i]] * len(gammas))
        linreg_vals_display = [linreg_results[i]] * len(lambs)
        linreg_stds_display = np.array([linreg_std[i]] * len(lambs))
        #ax.plot([0,1], [SSP_rel_eff[j,i], SSP_rel_eff[j,i]], label=f"SSP, n = {nlist[i]}", color=temp_color, linestyle="dashed")

        ax.errorbar(x=lambs, y=linreg_vals_display, yerr=np.concatenate(    (np.zeros((num_method, 1)), linreg_stds_display.reshape((num_method,1))),    axis=1).transpose(), label=f"linreg, data = {data_name_list[i]}, n={n_map[i]}, d={d_map[i]}", color=temp_color, linestyle="dashed")

    #ax.set_xlabel("n values (size of data set)")
    ax.set_xlabel("Ridge Regression Lambda Parameter")
    ax.set_ylabel('Prediction Error (MSE)')
    ax.set_title(f"Prediction Error, UCI Data, Nonprivate Methods (Ridge and Linear Regression)")
    ax.set_yscale('log')
    ax.set_xscale('log')
    ax.legend()
    plt.savefig(f"plots/pred_err_nonprivate_data.png")
"""

if __name__ == "__main__":
    plots_by_gamma()
    #non_private_checks()


import torch
import torchvision.transforms.functional as F

NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}

def register_node(identifier: str, display_name: str):
    def decorator(cls):
        NODE_CLASS_MAPPINGS[identifier] = cls
        NODE_DISPLAY_NAME_MAPPINGS[identifier] = display_name

        return cls

    return decorator

@register_node("JWImageMix", "Image Mix")
class _:
    CATEGORY = "jamesWalker55"
    BLEND_TYPES = ("mix", "multiply")

    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "blend_type": (cls.BLEND_TYPES, {"default": "mix"}),
                "factor": ("FLOAT", {"min": 0, "max": 1, "step": 0.01, "default": 0.5}),
                "image_a": ("IMAGE",),
                "image_b": ("IMAGE",),
            }
        }

    RETURN_TYPES = ("IMAGE",)
    FUNCTION = "execute"

    def execute(
        self,
        blend_type: str,
        factor: float,
        image_a: torch.Tensor,
        image_b: torch.Tensor,
    ):
        assert blend_type in self.BLEND_TYPES
        assert isinstance(factor, float)
        assert isinstance(image_a, torch.Tensor)
        assert isinstance(image_b, torch.Tensor)

        assert image_a.shape == image_b.shape

        if blend_type == "mix":
            mixed = image_a * (1 - factor) + image_b * factor
        elif blend_type == "multiply":
            mixed = image_a * (1 - factor + image_b * factor)
        else:
            raise NotImplementedError(f"Blend type not yet implemented: {blend_type}")

        return (mixed,)

@register_node("JWImageContrast", "Image Contrast")
class _:
    CATEGORY = "jamesWalker55"
    INPUT_TYPES = lambda: {
        "required": {
            "image": ("IMAGE",),
            "factor": (
                "FLOAT",
                {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.01},
            ),
        }
    }
    RETURN_TYPES = ("IMAGE",)
    FUNCTION = "execute"

    def execute(
        self,
        image: torch.Tensor,
        factor: float,
    ):
        assert isinstance(image, torch.Tensor)
        assert isinstance(factor, float)

        image = image.permute(0, 3, 1, 2)
        image = F.adjust_contrast(image, factor)
        image = image.permute(0, 2, 3, 1)

        return (image,)

@register_node("JWImageSaturation", "Image Saturation")
class _:
    CATEGORY = "jamesWalker55"
    INPUT_TYPES = lambda: {
        "required": {
            "image": ("IMAGE",),
            "factor": (
                "FLOAT",
                {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.01},
            ),
        }
    }
    RETURN_TYPES = ("IMAGE",)
    FUNCTION = "execute"

    def execute(
        self,
        image: torch.Tensor,
        factor: float,
    ):
        assert isinstance(image, torch.Tensor)
        assert isinstance(factor, float)

        image = image.permute(0, 3, 1, 2)
        image = F.adjust_saturation(image, factor)
        image = image.permute(0, 2, 3, 1)

        return (image,)

@register_node("JWImageLevels", "Image Levels")
class _:
    CATEGORY = "jamesWalker55"
    INPUT_TYPES = lambda: {
        "required": {
            "image": ("IMAGE",),
            "min": (
                "FLOAT",
                {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01},
            ),
            "max": (
                "FLOAT",
                {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01},
            ),
        }
    }
    RETURN_TYPES = ("IMAGE",)
    FUNCTION = "execute"

    def execute(
        self,
        image: torch.Tensor,
        min: float,
        max: float,
    ):
        assert isinstance(image, torch.Tensor)
        assert isinstance(min, float)
        assert isinstance(max, float)

        image = (image - min) / (max - min)
        image = torch.clamp(image, 0.0, 1.0)

        return (image,)


caw = 0
nu = [0,0,0]
while True:
    cur = input()

    if cur == "caw caw":
        print(nu[caw])
        caw += 1
        if caw >= 3:break
        continue

    i = 3
    for s in cur:
        i -= 1
        if(s == "*"):
            nu[caw] = nu[caw] + 2 ** i


def zigzag(s, rows)->str:
	ans = ""
	a, b = (rows-2)*2, 2
	for i in range(rows):
		if i==0 or i==rows-1:
			for j in range(i, len(s), (rows-1)*2):
				ans += s[j]
			continue
		alter = False
		for j in range(i, len(s), b if alter else a):
			ans += s[j]
		a-=2
		b+=2
	return ans

print(zigzag("INSTAGRAMISAWESOME", 4))


import boto3
import datetime
import csv
import sys
import re

from datetime import datetime

def get_volumes(volume_type):
    region_client = boto3.client('ec2')
    regions = []
    try:
        regions = region_client.describe_regions()['Regions']
    except Exception as ex:
        print('Unable to fetch Regions:' + str(ex))

    Filters = [{'Name': 'status', 'Values': ['in-use']}]
    if volume_type != 'all':
        Filters.append({'Name': 'volume-type', 'Values': [volume_type]})

    rows = []
    for region in regions:
        ec2 = boto3.client('ec2', region_name=region['RegionName'])
        volumes = ec2.describe_volumes(Filters=Filters)['Volumes']

        for volume in volumes:
            try:
                row = {}
                row["AvailabilityZone"] = volume['AvailabilityZone']
                row["volumeId"] = volume['VolumeId']
                row["VolumeType"] = volume['VolumeType']
                row["State"] = volume['State']
                row["SnapshotId"] = volume['SnapshotId']
                row["Size"] = str(volume['Size'])
                row["Encrypted"] = 'True' if volume['Encrypted'] else 'False'
                row["CreateTime"] = volume['CreateTime'].strftime("%m/%d/%Y, %H:%M:%S")
                row["Device"] = row["InstanceId"] = row['DeleteOnTermination'] = row['AttachTime'] = ''
                row["InstanceState"] = row["InstanceType"] = row["StateChangeTime"] = ''

                if 'Attachments' in volume and len(volume['Attachments']) > 0:
                    row["Device"] = volume['Attachments'][0]['Device']
                    row["InstanceId"] = volume['Attachments'][0]['InstanceId']
                    row["DeleteOnTermination"] = 'True' if volume['Attachments'][0]['DeleteOnTermination'] else 'False'
                    row["AttachTime"] = volume['Attachments'][0]['AttachTime'].strftime("%m/%d/%Y, %H:%M:%S")
                    reservations = ec2.describe_instances(InstanceIds=[row["InstanceId"]])
                    if 'Reservations' in reservations and 'Instances' in reservations['Reservations'][0] and len(
                            reservations['Reservations'][0]['Instances']):
                        instance = reservations['Reservations'][0]['Instances'][0]
                        row["InstanceState"] = instance["State"]["Name"]
                        row["InstanceType"] = instance['InstanceType']
                        row["IsRootVolume"] = 'true' if row["Device"] == instance['RootDeviceName'] else 'false'
                        if row["InstanceState"] == 'running':
                            row["StateChangeTime"] = instance['LaunchTime'].strftime("%m/%d/%Y, %H:%M:%S")
                        elif row["InstanceState"] == 'stopped':
                            stop_time_str = re.search(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}',
                                                      instance['StateTransitionReason'])
                            stop_time = datetime.strptime(stop_time_str.group(), "%Y-%m-%d %H:%M:%S")
                            row["StateChangeTime"] = stop_time.strftime("%m/%d/%Y, %H:%M:%S")
                rows.append(row)
            except Exception as ex:
                print('Error Extracting Volume Meta Data: ' + str(ex))
    return rows

if __name__ == "__main__":
    try:
        volume_type = 'all'

        if len(sys.argv) == 2 and len(sys.argv[1]) > 0:
            volume_type = sys.argv[1]

        header = ["AvailabilityZone", "volumeId", "VolumeType", "State", "SnapshotId", "Size", "Encrypted",
                  "CreateTime", "Device", "InstanceId", "DeleteOnTermination", "AttachTime", "InstanceState",
                  "InstanceType", "IsRootVolume", "StateChangeTime"]

        try:
            metadata = get_volumes(volume_type)
            if metadata is not None and len(metadata) > 0:
                outfile = open("volume_metadata.csv", 'w', newline='\n')
                writer = csv.writer(outfile)
                writer.writerow(header)
                for data in metadata:
                    row = [data.get(key, "") for key in header]
                    writer.writerow(row)
                outfile.close()
        except Exception as ex:
            print('Exception while Getting Volumes: ' + str(ex))
    except Exception as ex:
        print('Exception in Main' + str(ex))


import discord
import random
import os
import time
from discord.ext import commands, tasks
from itertools import cycle

status = cycle(['Cyperbunk 2077', 'Rocket League', 'SpeedRunners', 'Grand Theft Auto V'])
class Commands(commands.Cog):

    def __init__(self, client):
        self.client=client

    #Events
    @commands.Cog.listener()
    async def on_ready(self):
        self.change_status.start()
        await self.client.change_presence(status=discord.Status.do_not_disturb)
        print("Bot is running")

    @commands.Cog.listener()
    async def on_command_error(self, ctx, error):
        if isinstance(error, commands.CommandNotFound):
            await ctx.send('Command does not exist.')
        elif isinstance(error, commands.MissingRequiredArgument):
            await ctx.send('Please input the required argument')

    #Tasks
    @tasks.loop(seconds=600)
    async def change_status(self):
        await self.client.change_presence(activity=discord.Game(next(status)))

    #Commands
    @commands.command()
    async def ping(self, ctx):
        await ctx.send(f'{round(self.client.latency * 1000)}ms')

    @commands.command()
    async def clear(self, ctx, amount, times):
        times = int(times)
        amount = int(amount)
        while times:
            await ctx.channel.purge(limit=amount)
            time.sleep(2)
            times-=1

    @commands.command(aliases=["8ball"])
    async def _8ball(self, ctx, *, question):
        responses = ["It is certain.",
                 "It is decidedly so.",
                "Without a doubt.",
                  "Yes - definitely.",
                     "You may rely on it.",
                      "As I see it, yes.",
                    "Most likely.",
                    "Outlook good.",
               "Signs point to yes.",
              "Reply hazy, try again.",
           "Ask again later.",
                "Better not tell you now.",
             "Cannot predict now.",
               "Concentrate and ask again.",
              "Don't count on it.",
                 "My reply is no.",
               "My sources say no.",
            "Outlook not so good.",
             "Very doubtful."]
        await ctx.send(f"Question: {question}\nAnswer: {random.choice(responses)}")

def setup(client):
    client.add_cog(Commands(client))


#LinearRegression
###############################algorith##########################
# y =  mx+b

# m (slope )
# b = y (intersept) or best fit

# m = [(mean(x) * mena(y)) - mean(x * y) ]/mean (x) power2 - mean (x power2)

# b = mean(y) - m * mean(x)

###################################Accruecy determinaintion #################
#THE way to determine the accurecy is R^2 or the coefficent or determiontaion
# it is calculated by squred error
# theroy the error is the distance from the point from the best fit line
#the reson why  we squre is the we might get negative value when are determining the points from the best fit line
# we only want to deal with positive values and we also want to avoid out lier

# r**2 = 1 - (SE * y^ )/SE * mean(y)

# SE = squred error
# y = normal y values
# y^ = y hatline or best fit line = b =mean(y) - m * mean(x)

from statistics import mean
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
import random

# xs = np.array([1,2,3,4,5,6],dtype = np.float64)
# ys = np.array([5,4,6,5,6,7],dtype = np.float64)

def create_dataset(howmany,variance,step=2 ,correlation =False):
	val =1
	ys= []
	for i in range(howmany):
		y = val + random.randrange(-variance,variance)
		ys.append(y)
		if correlation and correlation == 'pos':
			val +=step
		elif correlation and correlation == 'neg':
			val -=step
	xs = [i for i in range(len(ys))]

	return np.array(xs,dtype=np.float64),np.array(ys,dtype=np.float64)

def best_fit_slope_and_intercept(xs,ys):
	m = ( ((mean(xs)*mean(ys)) - mean(xs*ys))/
		((mean(xs)**2) - mean(xs**2)) )
	b= (mean(ys) - (m * mean(xs)))
	return m , b

def squred_error(ys_orig,ys_line):
	return sum((ys_line - ys_orig)**2)

def coeffienet_of_determination(ys_orig,ys_line):
	y_mean_line = [mean(ys_orig) for y in ys_orig]
	squred_error_reg = squred_error(ys_orig,ys_line)
	squred_error_y_mean = squred_error(ys_orig,y_mean_line)
	return 1 - (squred_error_reg/squred_error_y_mean)

xs,ys =create_dataset(40,40,2,correlation='neg')
m,b =best_fit_slope_and_intercept(xs,ys)

# regession_line = [(m*x)+b for x in xs]
regession_line = []
for x in xs:
    regession_line.append((m*x)+b)
predict_x = 15
predicrt_y = (m*predict_x)+b
# print (predicrt_y)

r_squred =coeffienet_of_determination(ys,regession_line)
print (r_squred)

plt.scatter(xs,ys)
plt.scatter(predict_x,predicrt_y,color='red')
plt.plot(regession_line)
plt.show()


#!/usr/bin/python
import os
import pickle

def disasm_init(filename):
	pkl_file_name=".{0}.pkl".format(os.path.basename(filename))

	inst=[]
	if os.path.isfile(pkl_file_name) is False:
		print ("[+] disasm_init(): disassembling {0}...".format(filename))
		dis_txt=".{0}.dis".format(os.path.basename(filename))
		cmd="objdump -D {0} > {1}".format(filename, dis_txt)
		os.system(cmd)

		prologue="Disassembly of section .text:"
		epilogue="Disassembly of section .fini:"
		with open(dis_txt, 'rb') as f:
			in_text=False
			for line in f:
				if prologue in line:
					in_text=True
				elif epilogue in line:
					break
				elif in_text is True:
					ll=map(lambda x:x.strip(),line.replace(':','').split('\t'))
					i={}
					try:
						i['addr']=int(ll[0],16)
						i['opcode']=ll[1]
						i_str=ll[2]
						i_str=i_str[0:i_str.find('<')].strip()
						i_str=i_str[0:i_str.find('#')].strip()
						i['str']=i_str
						inst.append(i)
					except ValueError:
						pass
					except IndexError:
						pass
		with open(pkl_file_name,'wb') as pkl_file:
			pickle.dump(inst, pkl_file)

	with open(pkl_file_name,'rb') as pkl_file:
		inst=pickle.load(pkl_file)

	return inst

if __name__ == '__main__':
	inst=disasm_init ("./libcrypto.so.1.0.0")
	for i in inst:
		if "call" in i['str']:
			try:
				op=i['str'].split()[1]
				int(op,16)
			except ValueError:
				if len(i['opcode'])==5:
					print ("{0:x} {1}\t{2}({3})".format(i['addr'],op, i['opcode'], len(i['opcode'])))


from widebrim.gamemodes.nazo_popup.mode.const import PATH_ANI_COUPLE
from widebrim.engine_ext.utils import getBottomScreenAnimFromPath
from pygame import Rect
from pygame.draw import rect
from widebrim.engine.const import RESOLUTION_NINTENDO_DS
from .base import BaseQuestionObject
from widebrim.madhatter.typewriter.strings_lt2 import OPCODES_LT2

class Jar():
    def __init__(self, surfaceOff, surfaceOn, jarType, x, y):
        pass

class HandlerCouple(BaseQuestionObject):
    def __init__(self, laytonState, screenController, callbackOnTerminate):
        super().__init__(laytonState, screenController, callbackOnTerminate)

        self._assets = getBottomScreenAnimFromPath(laytonState, PATH_ANI_COUPLE)

        self.jars = []
        self._collisionRects = []

        self._lengthColliders = 0
        self._lengthJars = 0
        self._offsetX = 0
        self._offsetY = 0x50 + RESOLUTION_NINTENDO_DS[1]

    def hasSubmitButton(self):
        return False

    def drawPuzzleElements(self, gameDisplay):
        for collider in self._collisionRects:
            rect(gameDisplay, (255,255,255), collider)
        return super().drawPuzzleElements(gameDisplay)

    def _doUnpackedCommand(self, opcode, operands):
        if opcode == OPCODES_LT2.Couple_SetInfo.value and len(operands) == 3:
            self._lengthColliders = operands[1].value
            self._lengthJars = operands[0].value
            self._offsetX = operands[2].value
        else:
            return super()._doUnpackedCommand(opcode, operands)
        return True

    def doOnComplete(self):
        for collider in range(min(16, self._lengthColliders)):
            self._collisionRects.append(Rect(self._offsetX, self._offsetY, 16, 32))
            self._offsetX += self._collisionRects[-1].width

        for indexJar in range(min(16, self._lengthJars, self._lengthColliders)):
            pass

        return super().doOnComplete()


from pyad import *
import csv

##########################################################################
# Création de plusieurs Ordinateurs via un fichier CSV
#########################################################################

def ajouter_ordinateurs():

        # Déclaration de l'OU dans laquelle on veut travailler
    pc_ou=pyad.adcontainer.ADContainer.from_dn("OU=Ordinateurs,OU=Logistique,OU=Employés,DC=akb,DC=lab")

        # Déclaration du fichier csv contenant la liste des PC
    with open("base_utilisateurs.csv") as fichier_utilisateurs:

        # Lecture du fichier csv: les données sont délimitées par ","
            liste_utilisateurs=csv.reader(fichier_utilisateurs,delimiter=",")

            print()
            print("Liste des PC ajoutés")
            print()
        # Utilisation d'une boucle pour traiter toutes les lignes du fichier
            i=0
            for utilistateur in liste_utilisateurs:

                if(i>0):

                    nom_pc=utilistateur[7]

                    print(nom_pc)

                    #ajouter_pc=pyad.aduser.ADUser.create(sAMAccountName, pc_ou, upn_suffix=None, enable=True, optional_attributes={"employeeID":employeeID, "givenName":givenName, "sn":sn, "mail":mail, "department":department})
                    ajouter_pc=pyad.adcomputer.ADComputer.create(nom_pc, pc_ou, enable=True, optional_attributes={"Description":"PC ajouté via script Python"})

                i=i+1


from enum import Enum
from operator import itemgetter

class MDP:

    init_value = 0

    def __init__(self, s, a, p, r, y):
        self.states = s
        self.get_actions = a
        self.reward = r
        self.transition_model = p
        self.discount = y
        self.get_successors = None
        self.is_terminal_state = None
        self.u = None
        self.u_prime = None
        self.pi = None
        self.optimal_policies = None
        self.delta = 0
        self.e = 0.01

    def __str__(self):
        return self.draw_grid()

    def value_iteration(self):
        self.u = dict()
        self.u_prime = dict()
        for state in self.states:
            self.u[state] = self.init_value
            self.u_prime[state] = self.init_value
        self.delta = 0

        while True:
            self.u = dict(self.u_prime)
            self.delta = 0
            #print(self.u)

            self.value_update()
            if self.discount == 0:
                d = 0
            else:
                d = self.e * (1 - self.discount) / self.discount
            if self.delta < max(d, 0.001):
                self.update_optimal_policies()
                return self.u

    def policy_iteration(self):
        self.u = dict()
        self.u_prime = dict()
        self.pi = dict()
        for state in self.states:
            some_action = self.get_actions(state)[0]
            self.u[state] = self.init_value
            self.pi[state] = some_action

        while True:
            self.policy_evaluation()
            unchanged = True
            for state in self.states:
                a = self.max_action_value(state, self.get_actions(state), self.get_successors(state))
                b = self.sum_successors(state, self.pi[state], self.get_successors(state))
                if a > b:
                    self.pi[state] = self.argmax(state, self.get_actions(state), self.get_successors(state))
                    unchanged = False

            if unchanged: break

        self.optimal_policies = dict(self.pi)

    def max_action_value(self, state, action_list, successor_list):
        t_list = list()
        for action in action_list:
            t_list.append(self.sum_successors(state, action, successor_list))

        return max(t_list)

    def sum_successors(self, state, action, successor_list):
        t = 0
        for s_prime in successor_list:
            t += self.transition_model(state, action, s_prime) * self.u[s_prime]

        return t

    def argmax(self, state, action_list, successor_list):
        action_value_pairs = list()
        for action in action_list:
            value = self.sum_successors(state, action, successor_list)
            action_value_pairs.append((value, action))

        return max(action_value_pairs, key=itemgetter(0))[1]

    def value_update(self):
        for state in self.states:
            if self.is_terminal_state(state):
                self.u_prime[state] = self.reward(state)
            else:
                #print(self.reward(state))
                actions = self.get_actions(state)
                successor_states = self.get_successors(state)
                max_value = self.max_action_value(state, actions, successor_states)
                self.u_prime[state] = self.reward(state) + (self.discount * max_value)

            b = abs(self.u[state] - self.u_prime[state])
            if b > self.delta:
                self.delta = b

    def policy_evaluation(self):
        for state in self.states:
            if self.is_terminal_state(state):
                self.u[state] = self.reward(state)
            else:
                sum = self.sum_successors(state, self.pi[state], self.get_successors(state))
                self.u[state] = self.reward(state) + self.discount * sum

    def update_optimal_policies(self):
        self.optimal_policies = dict()

        for state in self.states:
            self.optimal_policies[state] = self.argmax(state, self.get_actions(state), self.get_successors(state))

    def draw_grid(self):
        s = str()
        max_i = 0
        max_j = 0
        for state in self.states:
            i = state[0]
            j = state[1]
            if i > max_i:
                max_i = i
            if j > max_j:
                max_j = j

        for i in range(1, max_i + 1):
            for j in range(1, max_j + 1):
                if (i, j) in self.states:
                    if self.is_terminal_state((i, j)):
                        s += str(self.reward((i, j)))
                    else:
                        optimal_action = self.optimal_policies[(i, j)]
                        if optimal_action == Direction.NORTH:
                            s += "^"
                        if optimal_action == Direction.EAST:
                            s += ">"
                        if optimal_action == Direction.SOUTH:
                            s += "v"
                        if optimal_action == Direction.WEST:
                            s += "<"
                else:
                    s += "*"
                s += "\t"
            s += "\n"

        return s

class Direction(Enum):
    NORTH = 0
    EAST = 1
    SOUTH = 2
    WEST = 3


import os
import keras
import resnet
import pandas as pd
import tensorflow as tf
from keras.models import Model
from generator import Generator
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard
from keras.layers import Input, Flatten, Dense, Dropout
from optparse import OptionParser

os.environ['CUDA_VISIBLE_DEVICES'] = "0"
os.environ['TF_CPP_MIN_LOG_LEVEL'] = "2"

def get_session():
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    return tf.Session(config=config)

keras.backend.tensorflow_backend.set_session(get_session())

def set_model(network, num_classes, include_top=False, weights='imagenet', input_shape=(224, 224, 3)):
    """
    The function constructs the base model with

    """

    if network == 'resnet50':
        base_model = resnet.ResNet50(include_top=include_top, weights=weights, input_shape=input_shape)
    elif network == 'resnet101':
        base_model = resnet.ResNet50(include_top=include_top, weights=weights, input_shape=input_shape)
    else:
        raise ValueError("Oops, wrong network, {} doesn't exist".format(network))

    x = base_model.output
    x = Flatten()(x)
    x = Dense(1024, activation='relu', name='fc1')(x)
    x = Dropout(0.7, name='dropout1')(x)
    x = Dense(128, activation='relu', name='fc2')(x)
    x = Dropout(0.5, name='dropout2')(x)
    x = Dense(num_classes, activation='sigmoid')(x)

    model = Model(inputs=base_model.input, outputs=x)

    return model

def training(network, num_classes, epochs, batch_size, part):
    """Function that trains selected network"""

    train_data = pd.read_pickle('../data/dataframe/{}_train_df.pkl'.format(part))
    nb_epoch_steps = train_data.shape[0]//batch_size

    model = set_model(network, num_classes, include_top=False, weights='imagenet')

    # Freeze 15% of the early layers
    no_train = int(len(model.layers)*0.15)
    for layer in model.layers[:no_train]:
        layer.trainable=False
    for layer in model.layers[no_train:]:
        layer.trainable=True

    gen = Generator()
    train_gen = gen.generator('../data/dataframe/{}_train.csv'.format(part), num_classes=3, augmentation=True)
    val_gen = gen.generator('../data/dataframe/{}_val.csv'.format(part), num_classes=3, augmentation=False)

    opt = Adam(lr=0.0001, decay=1e-5)
    es = EarlyStopping(patience=5)
    chkpt = ModelCheckpoint(filepath='../data/snapshots/{}_{}_{{epoch:02d}}.h5'.format(model.name, part), save_best_only=True)
    model.compile(loss='binary_crossentropy', metrics=['accuracy'],optimizer=opt)

    # Fit model
    tensorboard = TensorBoard(log_dir='./logs/{}'.format(part), histogram_freq=0, write_graph=True, write_images=True)
    history = model.fit_generator(train_gen, epochs=epochs, steps_per_epoch=nb_epoch_steps,
                                validation_data=val_gen, validation_steps=8, callbacks=[es,chkpt, tensorboard])

def parse_command_line():
    version = "%prog 1.0"
    usage = "usage %prog [options]"
    parser = OptionParser(usage=usage, version=version)

    parser.add_option("-c", "--classes", dest="classes",
            help="Number of classes", type=int)
    parser.add_option("-e", "--epochs", dest="epochs",
            help="Number of epochs", type=int, default=10)
    parser.add_option("-b", "--batch_size", dest="batch_size",
            help="Batch size", type=int, default=96)
    parser.add_option("-p","--part", dest="part",
            help="Lung part to use ['lungs, cardio, nothing, pleural", type=str)
    parser.add_option("-n","--network", dest="network",
            help="Type of network to use", type=str)

    return parser.parse_args()

if __name__ == '__main__':

    (options, args) = parse_command_line()
    training(options.classes,
             options.epochs,
             options.batch_size,
             options.part,
             options.network)


from unittest import TestCase

from problems.dragonCurve.DragonCurve import rotate

class Test(TestCase):
    def test_rotate(self):
        self.assertEqual((-5, 4), rotate((4, 5)))
        with self.assertRaises(Exception):
            rotate('s')


''' You can find this exercise at the following website: https://www.practicepython.org/

1. Character Input

Create a program that asks the user to enter their name and their age. Print out a message addressed to them that tells them the year that they will turn 100 years old.

Extras:

Add on to the previous program by asking the user for another number and printing out that many copies of the previous message. (Hint: order of operations exists in Python)
Print out that many copies of the previous message on separate lines. (Hint: the string "\n is the same as pressing the ENTER button) '''

name = input("Enter your name: ")
age = int(input("Enter your age: "))
number = int(input("Enter a number between 1 and 10: "))
print()

from datetime import date
currentYear = date.today().year
answer = currentYear - age + 100
print(number * ("Hi, " + name + "! You will be 100 yrs old in " + str(answer) + "!\n"))


import matplotlib.pyplot as plt
import csv
import math

X = []
Y = []

with open('LiLog.csv', 'r') as datafile:
    plotting = csv.reader(datafile, delimiter=';')

    for ROWS in plotting:
        X.append(float(ROWS[3])*math.sin(float(ROWS[3])))
        # X.append('{} {}'.format(ROWS[3], ROWS[4]))
        Y.append(float(ROWS[1]))

print('X {} Nums'.format(len(X)))
print('Y {} Nums'.format(len(Y)))

threshold = 3.0
T = [threshold] * len(Y)

print('Type X {} '.format(type(X)))
print('Type Y {} '.format(type(Y)))
print('Type T {} '.format(type(T)))

plt.plot(X, Y)
plt.plot(X, T)
plt.title('Illumination change')
plt.xlabel('Time,[s]')
plt.ylabel('Light level, [Lx]')
plt.grid()
plt.xticks(rotation=-90)
plt.legend(['illumination', 'threshold {} Lx'.format(threshold)])
plt.show()

08 Практика программирования/Построение графиков/график_из_csv_2.py


N = int(input())
T = input()

pos = [0, 0]
direction = [(1, 0), (0, -1), (-1, 0), (0, 1)]
x = 0
for i in range(N):
    if T[i] == "S":
        pos[0] += direction[x][0]
        pos[1] += direction[x][1]
    else:
        x += 1
        x %= 4

print(*pos)


import hashlib
import os
import binascii
import rsa
import OpenSSL.crypto
import base64
from OpenSSL.crypto import PKey
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM, TYPE_DSA, FILETYPE_ASN1
from OpenSSL.crypto import dump_privatekey, dump_publickey,load_publickey, load_privatekey
from OpenSSL.crypto import sign, verify
from OpenSSL.crypto import X509
from OpenSSL.crypto import load_certificate, dump_certificate
class function:
    #MD5加密返回MD5的十六进制
    def md5(self,clearText, algorithms = "md5"):
        h = hashlib.new(algorithms)
        h.update(bytes(clearText, 'utf8'))
        print(h.hexdigest())

    # sha1哈希，返回sha1的十六进制
    def sha1(self, clearText, algorithms = "sha1"):
        h = hashlib.new(algorithms)
        h.update(bytes(clearText, 'utf8'))
        print(h.hexdigest())

    # sha224哈希，返回sha224的十六进制
    def sha224(self, clearText, algorithms= "sha224"):
        h = hashlib.new(algorithms)
        h.update(bytes(clearText, 'utf8'))
        print(h.hexdigest())

    # sha256哈希，返回sha256的十六进制
    def sha256(self, clearText, algorithms = "sha256"):
        h = hashlib.new(algorithms)
        h.update(bytes(clearText, 'utf8'))
        print(h.hexdigest())

    # sha512哈希，返回sha512的十六进制
    def sha512(self, clearText, algorithms = "sha512" ):
        h = hashlib.new(algorithms)
        h.update(bytes(clearText,'utf8'))
        print(h.hexdigest())

    # pbkdf2_hmac哈希，返回十六进制
    def pbkdf2_hmac(self, clearText, salt, times,  algorithms="sha256"):
        print(binascii.hexlify(hashlib.pbkdf2_hmac(algorithms,bytes(clearText, 'utf8'), bytes(salt, 'utf8'),times)))
    # 生成RSA的公钥和私钥
    # 采用的是OpenSSL提供的API
    def generateKey(self,directory = "D:\\test",bits=1024):
        pk = PKey()
        pk.generate_key(TYPE_RSA, bits)
        with open (directory+'\pubkey.pem', mode='wb') as f:
            f.write(dump_publickey(FILETYPE_PEM, pk))
            f.close()
        with open (directory+'\prikey.pem', mode='wb') as f:
            f.write(dump_privatekey(FILETYPE_PEM, pk))
            f.close()

    #从PEM文件加载公钥
    def loadPublicKey(self,absolutePath):
        pk = PKey()
        pk  = load_publickey(FILETYPE_PEM, open(absolutePath).read())
        return  pk

    # 从PEM文件加载私钥
    def loadPrivateKey(self,absolutePath):
        pk = PKey()
        key  = load_privatekey(FILETYPE_PEM, open(absolutePath).read())
        return key

    # RSA加密采用的是RSA库
    def rsaEncrypt(self, absolutePathWithClearText, absolutePathWithPEM, absolutePathEncryptText):
        publicKey = rsa.PublicKey.load_pkcs1_openssl_pem(open(absolutePathWithPEM, 'rb').read())
        crypto = rsa.encrypt(open(absolutePathWithClearText, 'rb').read(), publicKey)
        with open(absolutePathEncryptText, 'wb') as enFp:
            enFp.write(crypto)

    # RSA解密采用的是RSA库
    def rsaDecrypt(self, absolutePathWithClearText, absolutePathWithPEM, absolutePathEncryptText):
        with open(absolutePathWithPEM, 'rb') as fp:
            priKey = rsa.PrivateKey.load_pkcs1(fp.read())
        cleartText = rsa.decrypt(open(absolutePathEncryptText, 'rb').read(), priKey)
        with open (absolutePathWithClearText, 'wb') as clearFp:
            clearFp.write(cleartText)

    # RSA签名采用的是OpenSSL提供的API
    def signature(self, absolutePathWithText, absolutePathWithPriKey,absolutePathWithSig):
        pk = self.loadPrivateKey(absolutePathWithPriKey)
        signature = sign(pk, open(absolutePathWithText).read(), 'sha256')
        print("签名成功：\n")
        print(base64.b64encode(signature),"\n")
        with open(absolutePathWithSig, 'wb') as SigFp:
            SigFp.write(signature)
            SigFp.close()
        return signature
    # RSA验证采用的是OpenSSL提供的API
    def verifyFunction(self,absolutePathWithText, absolutePathWithPubKey, absolutePathWithSig):
        pk = self.loadPublicKey(absolutePathWithPubKey)
        x509 = X509()
        x509.set_pubkey(pk)
        signature = open(absolutePathWithSig, 'rb').read()
        try:
            if (verify(x509, signature, open(absolutePathWithText).read(), 'sha256') == None):
                print("验证成功")
        except:
            print("验证失败！")
if __name__ == "__main__":
    f = function()
    while True:
        try:
            select = int(input('''请输入选择：
                        \n1：md5 \t 2：sha1 \t 3：sha224
                        \n4：sha256\t5：sha512\t6：pbkdf2_hmac
                        \n7：生成rsa密钥\t8:rsa加密\t9：rsa解密
                        \n10：rsa签名\t11：rsa验证\t12：退出\n
                        '''))
            if select == 1:
                f.md5(input("请输入待hash文本:\n"))
            elif select == 2:
                f.sha1(input("请输入待hash文本:\n"))
            elif select ==3:
                f.sha224(input("请输入待hash文本:\n"))
            elif select == 4:
                f.sha256(input("请输入待hash文本:\n"))
            elif select == 5:
                f.sha512(input("请输入待hash文本:\n"))
            elif select == 6:
                f.pbkdf2_hmac(input("请输入待hash文本:\n"),input("请输入Salt:\n"),int(input("请输入待Times:\n")),input("请输入算法：如：sha256:\n"))
            elif select == 7:
                f.generateKey(input("输入保存目录"),int(input("请输入位数：")))
            elif select == 8:
                f.rsaEncrypt(input("absolutePathWithClearText\n"), input("absolutePathWithPEM\n"), input("absolutePathEncryptText\n"))
            elif select == 9:
                f.rsaDecrypt(input("absolutePathWithClearText\n"), input("absolutePathWithPEM\n"), input("absolutePathEncryptText\n"))
            elif select == 10:
                f.signature(input("absolutePathWithText\n"), input("absolutePathWithPriKey\n"),input("absolutePathWithSig\n"))
            elif select == 11:
                f.verifyFunction(input("absolutePathWithText\n"), input("absolutePathWithPubKey\n"), input("absolutePathWithSig\n"))
            elif select == 12:
                break
        except Exception as e:
            print(e)


import ast
from typing import Union
import textwrap

from py2many.analysis import get_id
from py2many.ast_helpers import create_ast_block, create_ast_node
from py2many.astx import ASTxFunctionDef
from py2many.clike import CLikeTranspiler
from py2many.inference import get_inferred_type
from py2many.scope import ScopeList

from typing import Any, cast, Optional

from py2many.tracer import find_node_by_type

class InferredAnnAssignRewriter(ast.NodeTransformer):
    def visit_Assign(self, node):
        target = node.targets[0]  # Assumes all targets have same annotation
        if isinstance(target, ast.Subscript):
            return node
        annotation = getattr(target, "annotation", False)
        if not annotation:
            return node

        if isinstance(annotation, ast.ClassDef):
            annotation = ast.Name(id=get_id(annotation))

        col_offset = getattr(node, "col_offset", None)

        assigns = []
        for assign_target in node.targets:
            definition = node.scopes.parent_scopes.find(get_id(assign_target))
            if definition is None:
                definition = node.scopes.find(get_id(assign_target))
            if definition is not assign_target:
                previous_type = get_inferred_type(definition)
                if get_id(previous_type) == get_id(annotation):
                    if len(node.targets) == 1:
                        return node
                    else:
                        new_node = ast.Assign(
                            targets=[assign_target],
                            value=node.value,
                            lineno=node.lineno,
                            col_offset=col_offset,
                        )
                        assigns.append(new_node)
                        continue
            new_node = ast.AnnAssign(
                target=assign_target,
                value=node.value,
                lineno=node.lineno,
                col_offset=col_offset,
                simple=True,
                annotation=annotation,
            )
            assigns.append(new_node)

        if len(assigns) == 1:
            return assigns[0]

        return create_ast_block(body=assigns, at_node=node)

class ComplexDestructuringRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._disable = False
        if language in {"cpp", "julia", "dart", "v"}:
            self._disable = True
        self._no_underscore = False
        if language in {"nim"}:
            self._no_underscore = True
        self._temp = 0

    def _get_temp(self):
        self._temp += 1
        if self._no_underscore:
            return f"tmp{self._temp}"
        return f"__tmp{self._temp}"

    def visit_Assign(self, node):
        if self._disable:
            return node
        target = node.targets[0]
        if isinstance(target, ast.Tuple) and not (isinstance(target.elts[0], ast.Name)):
            temps = []
            orig = [None] * len(target.elts)
            body = [node]
            for i in range(len(target.elts)):
                temps.append(ast.Name(id=self._get_temp(), lineno=node.lineno))
                # The irony!
                target.elts[i], orig[i] = temps[i], target.elts[i]
                body.append(
                    ast.Assign(targets=[orig[i]], value=temps[i], lineno=node.lineno)
                )
            return create_ast_block(body=body, at_node=node)
        return node

class RenameTransformer(ast.NodeTransformer):
    def __init__(self, old_name, new_name):
        super().__init__()
        self._old_name = old_name
        self._new_name = new_name

    def visit_Name(self, node):
        if node.id == self._old_name:
            node.id = self._new_name
        return node

    def visit_FunctionDef(self, node):
        if node.name == self._old_name:
            node.name = self._new_name
        self.generic_visit(node)
        return node

    def visit_Call(self, node):
        if isinstance(node.func, ast.Name) and node.func.id == self._old_name:
            node.func.id = self._new_name
        self.generic_visit(node)
        return node

class WithToBlockTransformer(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._no_underscore = False
        if language in {"nim"}:
            self._no_underscore = True
        self._temp = 0

    def _get_temp(self):
        self._temp += 1
        if self._no_underscore:
            return f"tmp{self._temp}"
        return f"__tmp{self._temp}"

    def visit_With(self, node):
        self.generic_visit(node)
        stmts = []
        for i in node.items:
            if i.optional_vars:
                target = i.optional_vars
            else:
                target = ast.Name(id=self._get_temp(), lineno=node.lineno)
            stmt = ast.Assign(
                targets=[target], value=i.context_expr, lineno=node.lineno
            )
            stmts.append(stmt)
        node.body = stmts + node.body
        ret = create_ast_block(body=node.body, at_node=node)
        # Hint to UnpackScopeRewriter below to leave the new scope alone
        ret.unpack = False
        return ret

def capitalize_first(name):
    first = name[0].upper()
    remainder = list(name)
    remainder.remove(name[0])
    remainder = "".join(remainder)
    return first + remainder

def camel_case(name):
    if "_" not in name:
        return name
    # Dont rewrite dunders
    if name.startswith("__") and name.endswith("__"):
        return name
    return "".join(capitalize_first(part) if part else "" for part in name.split("_"))

def rename(scope, old_name, new_name):
    tx = RenameTransformer(old_name, new_name)
    tx.visit(scope)

class PythonMainRewriter(ast.NodeTransformer):
    def __init__(self, main_signature_arg_names):
        self.main_signature_arg_names = set(main_signature_arg_names)
        super().__init__()

    def visit_If(self, node):
        is_main = (
            isinstance(node.test, ast.Compare)
            and isinstance(node.test.left, ast.Name)
            and node.test.left.id == "__name__"
            and isinstance(node.test.ops[0], ast.Eq)
            and isinstance(node.test.comparators[0], ast.Constant)
            and node.test.comparators[0].value == "__main__"
        )
        if is_main:
            if hasattr(node, "scopes") and len(node.scopes) > 1:
                rename(node.scopes[-2], "main", "main_func")
            # ast.parse produces a Module object that needs to be destructured
            if self.main_signature_arg_names == {"argc", "argv"}:
                ret = cast(
                    ast.FunctionDef,
                    create_ast_node(
                        "def main(argc: int, argv: List[str]) -> int: True", node
                    ),
                )
            elif self.main_signature_arg_names == {"argv"}:
                ret = create_ast_node("def main(argv: List[str]): True", node)
            else:
                ret = create_ast_node("def main(): True")
            ret = cast(ASTxFunctionDef, ret)
            ret.lineno = node.lineno
            ret.body = node.body
            # So backends know to handle argc, argv etc
            ret.python_main = True
            return ret
        return node

class FStringJoinRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()

    def visit_JoinedStr(self, node):
        new_node = cast(ast.Expr, create_ast_node('"".join([])', node)).value
        new_node = cast(ast.Call, new_node)
        args = new_node.args
        arg0 = cast(ast.List, args[0])
        for v in node.values:
            if isinstance(v, ast.Constant):
                arg0.elts.append(v)
            elif isinstance(v, ast.FormattedValue):
                arg0.elts.append(
                    ast.Call(
                        func=ast.Name(id="str", ctx="Load"), args=[v.value], keywords=[]
                    )
                )
        new_node.lineno = node.lineno
        new_node.col_offset = node.col_offset
        ast.fix_missing_locations(new_node)
        return new_node

class DocStringToCommentRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._docstrings = set()
        self._docstring_parent = {}

    def _get_doc_node(self, node) -> Optional[ast.AST]:
        if not (node.body and isinstance(node.body[0], ast.Expr)):
            return None
        node = node.body[0].value
        if isinstance(node, ast.Str):
            return node
        elif isinstance(node, ast.Constant) and isinstance(node.value, str):
            return node
        return None

    def _visit_documentable(self, node):
        doc_node = self._get_doc_node(node)
        self._docstrings.add(doc_node)
        self._docstring_parent[doc_node] = node
        self.generic_visit(node)
        return node

    def visit_FunctionDef(self, node):
        return self._visit_documentable(node)

    def visit_ClassDef(self, node):
        return self._visit_documentable(node)

    def visit_Module(self, node):
        return self._visit_documentable(node)

    def visit_Constant(self, node):
        if node in self._docstrings:
            parent = self._docstring_parent[node]
            parent.docstring_comment = ast.Constant(value=node.value)
            return None
        return node

    def visit_Expr(self, node):
        self.generic_visit(node)
        if not hasattr(node, "value"):
            return None
        return node

class PrintBoolRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._language = language

    def _do_other_rewrite(self, node) -> ast.AST:
        ifexpr = cast(
            ast.Expr, create_ast_node("'True' if true else 'False'", node)
        ).value
        ifexpr = cast(ast.IfExp, ifexpr)
        ifexpr.test = node.args[0]
        ifexpr.lineno = node.lineno
        ifexpr.col_offset = node.col_offset
        ast.fix_missing_locations(ifexpr)
        node.args[0] = ifexpr
        return node

    # Go can't handle IfExpr in print. Handle it differently here
    def _do_go_rewrite(self, node) -> ast.AST:
        if_stmt = create_ast_node(
            textwrap.dedent(
                """\
            if True:
                print('True')
            else:
                print('False')
        """
            ),
            node,
        )
        if_stmt = cast(ast.If, if_stmt)
        if_stmt.test = node.args[0]
        if_stmt.lineno = node.lineno
        if_stmt.col_offset = node.col_offset
        ast.fix_missing_locations(if_stmt)
        return if_stmt

    def visit_Call(self, node):
        if get_id(node.func) == "print":
            if len(node.args) == 1:
                anno = getattr(node.args[0], "annotation", None)
                if get_id(anno) == "bool":
                    if self._language == "go":
                        return self._do_go_rewrite(node)
                    else:
                        return self._do_other_rewrite(node)
        return node

class StrStrRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._language = language

    def visit_Compare(self, node):
        if self._language in {"dart", "kotlin", "nim", "python"}:
            return node

        if isinstance(node.ops[0], ast.In):
            left = node.left
            right = node.comparators[0]
            left_type = get_id(get_inferred_type(left))
            right_type = get_id(get_inferred_type(right))
            if left_type == "str" and right_type == "str":
                if self._language == "julia":
                    ret = ast.parse("findfirst(a, b) != Nothing").body[0].value
                    ret.left.args[0] = left
                    ret.left.args[1] = right
                elif self._language == "go":
                    # To be rewritten to strings.Contains via plugins
                    ret = ast.parse("StringsContains(a, b)").body[0].value
                    ret.args[0] = right
                    ret.args[1] = left
                elif self._language == "cpp":
                    ret = ast.parse("a.find(b) != string.npos").body[0].value
                    ret.left.func.value = right
                    ret.left.args[0] = left
                else:
                    # rust and c++23
                    ret = ast.parse("a.contains(b)").body[0].value
                    ret.func.value = right
                    ret.args[0] = left
                ret.lineno = node.lineno
                ast.fix_missing_locations(ret)
                return ret

        return node

class IgnoredAssignRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._language = language
        self._disable = language in {"nim", "v"}
        self._unpack = language in {"cpp", "dart", "go", "rust"}

    def _visit_assign_unpack_all(self, node):
        keep_ignored = self._language == "go"
        body = []
        target = node.targets[0]
        for i in range(len(target.elts)):
            elt = target.elts[i]
            if isinstance(elt, ast.Name):
                name = get_id(elt)
                if name == "_" and not keep_ignored:
                    body.append(ast.Expr(value=node.value.elts[i]))
                    body[-1].unused = True
                    continue
            body.append(ast.Assign(targets=[target.elts[i]], value=node.value.elts[i]))
        return create_ast_block(body=body, at_node=node)

    def visit_Assign(self, node):
        if self._disable:
            return node

        target = node.targets[0]
        if isinstance(target, ast.Tuple) and isinstance(node.value, ast.Tuple):
            names = [get_id(elt) for elt in target.elts if isinstance(elt, ast.Name)]
            has_ignored = "_" in names
            if self._unpack and has_ignored:
                return self._visit_assign_unpack_all(node)
            if not has_ignored:
                return node

            body = [node]
            to_eval = []
            for i in range(len(target.elts)):
                if names[i] == "_":
                    del target.elts[i]
                    to_eval.append(node.value.elts[i])
                    del node.value.elts[i]
            # TODO: Evaluation order - we may have to split the tuple assignment to get
            # it right. For now, keep it simple
            body = [ast.Expr(value=e) for e in to_eval] + body
            return create_ast_block(body=body, at_node=node)
        return node

class UnpackScopeRewriter(ast.NodeTransformer):
    def __init__(self, language):
        super().__init__()
        self._language = language

    def _visit_body(self, body):
        unpacked = []
        for s in body:
            do_unpack = getattr(s, "unpack", True)
            if isinstance(s, ast.If) and CLikeTranspiler.is_block(s) and do_unpack:
                unpacked.extend(self._visit_body(s.body))
            else:
                unpacked.append(s)
        return unpacked

    def _visit_assign_node_body(self, node):
        node.body = self._visit_body(node.body)
        return node

    def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
        return self._visit_assign_node_body(node)

    def visit_For(self, node: ast.For) -> ast.For:
        return self._visit_assign_node_body(node)

    def visit_If(self, node: ast.If) -> ast.If:
        return self._visit_assign_node_body(node)

    def visit_With(self, node: ast.With) -> ast.With:
        return self._visit_assign_node_body(node)

    def visit_While(self, node: ast.With) -> ast.With:
        return self._visit_assign_node_body(node)

class LoopElseRewriter(ast.NodeTransformer):
    def __init__(self, language) -> None:
        super().__init__()
        self._language = language
        self._has_break_var_name = "has_break"

    def visit_Module(self, node: ast.Module) -> Any:
        self._visit_Scope(node)
        return node

    def visit_FunctionDef(self, node: ast.FunctionDef) -> Any:
        self._visit_Scope(node)
        return node

    def visit_If(self, node: ast.If) -> Any:
        self._visit_Scope(node)
        return node

    def visit_With(self, node: ast.With) -> Any:
        self._visit_Scope(node)
        return node

    def visit_For(self, node: ast.For) -> Any:
        self._generic_loop_visit(node)
        self._visit_Scope(node)
        return node

    def visit_While(self, node: ast.While) -> Any:
        self._generic_loop_visit(node)
        self._visit_Scope(node)
        return node

    def _generic_loop_visit(self, node: Union[ast.For, ast.While]):
        scopes = getattr(node, "scopes", ScopeList())
        if len(node.orelse) > 0:
            lineno = node.orelse[0].lineno
            if_expr = ast.If(
                test=ast.Compare(
                    left=ast.Name(id=self._has_break_var_name),
                    ops=[ast.NotEq()],
                    comparators=[ast.Constant(value=True, scopes=scopes)],
                    scopes=scopes,
                ),
                body=[oe for oe in node.orelse],
                orelse=[],
                lineno=lineno,
                scopes=scopes,
            )
            node.if_expr = if_expr

    def _visit_Scope(self, node) -> Any:
        self.generic_visit(node)
        scopes = getattr(node, "scopes", ScopeList())
        assign = ast.Assign(
            targets=[ast.Name(id=self._has_break_var_name)], value=None, scopes=scopes
        )
        ast.fix_missing_locations(assign)
        body = []
        for n in node.body:
            if hasattr(n, "if_expr"):
                assign.value = ast.Constant(value=False, scopes=scopes)
                body.append(assign)
                body.append(n)
                body.append(n.if_expr)
            elif isinstance(n, ast.Break):
                for_node = find_node_by_type((ast.For, ast.While), scopes)
                if hasattr(for_node, "if_expr"):
                    assign.value = ast.Constant(value=True, scopes=scopes)
                    body.append(assign)
                body.append(n)
            else:
                body.append(n)

        node.body = body