import os
import re
import pytest
import pandas as pd
from os.path import join
from battetl.extract import Extractor
from battetl import Constants

BASE_DATA_PATH = os.path.join(os.path.dirname(__file__), 'data')
MACCOR_PATH = os.path.join(BASE_DATA_PATH, 'maccor_cycler_data')
MACCOR_SIMPLE_PATH = os.path.join(MACCOR_PATH, 'simple_data')
MACCOR_FRA_PATH = os.path.join(MACCOR_PATH, 'fra_data')
MACCOR_FASTWAVE_PATH = os.path.join(MACCOR_PATH, 'fastwave_data')
MACCOR_TYPE2_PATH = os.path.join(MACCOR_PATH, 'type2_data')
ARBIN_PATH = os.path.join(BASE_DATA_PATH, 'arbin_cycler_data')
ARBIN_SINGLE_PATH = os.path.join(ARBIN_PATH, 'single_data_file')
ARBIN_MULTIPLE_PATH = os.path.join(ARBIN_PATH, 'multiple_data_files')
ARBIN_CAN_PATH = os.path.join(ARBIN_PATH, 'can_data_files')
ARBIN_SIMULATION_PATH = os.path.join(ARBIN_PATH, 'simulation_data_files')

@pytest.mark.extract
def test_bad_path():
    path = join(
        BASE_DATA_PATH,
        'fake/data/path - 079.txt',
    )

    extractor = Extractor()

    with pytest.raises(TypeError):
        df_extracted = extractor.data_from_files(path)

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_test_data():
    path = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_Testdata - 079.txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(
        path,
        sep='\t',
        header=2,
        skipinitialspace=True,
        index_col=False
    )

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_test_data_type2():
    path = join(MACCOR_TYPE2_PATH, 'BG_Maccor_Type2 - 075.txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(
        path,
        sep='\t',
        header=3,
        skipinitialspace=True,
        index_col=False
    )

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_stats_data():
    path = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_TestData - 079 [STATS].txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_cycle_stats

    df_loaded = pd.read_csv(
        path, sep='\t',
        skiprows=8,
        skipinitialspace=True,
        index_col=False)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_stats_data_pickle():
    path_pkl = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_TestData - 079.pkl')
    path_txt = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_Testdata - 079.txt')

    extractor = Extractor()
    df_extracted = extractor.from_pickle(path_pkl)

    df_loaded = pd.read_csv(
        path_txt,
        sep='\t',
        header=2,
        skipinitialspace=True,
        index_col=False)

    assert (df_extracted.equals(df_loaded))

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_single_data_file():
    path = join(ARBIN_SINGLE_PATH,
                'BG_Arbin_TestData_Single_File_Channel_26_Wb_1.CSV')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(path, index_col=False)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'arbin')

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_multiple_data_files():
    paths = [
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_1.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_2.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_3.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_4.CSV')
    ]

    extractor = Extractor()
    extractor.data_from_files(paths)
    df_extracted = extractor.raw_test_data

    df_1 = pd.read_csv(paths[0], index_col=False)
    df_2 = pd.read_csv(paths[1], index_col=False)
    df_3 = pd.read_csv(paths[2], index_col=False)
    df_4 = pd.read_csv(paths[3], index_col=False)
    df_loaded = pd.concat([df_1, df_2, df_3, df_4], ignore_index=True)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'arbin')

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_globalinfo():
    path = join(ARBIN_SINGLE_PATH,
                'BG_Arbin_TestData_Single_File_Channel_26_GlobalInfo.CSV')

    extractor = Extractor()
    extractor.data_from_files([path])

    assert (
        extractor.raw_test_data_meta_data[0] == {
            'Test Name': 'BG_Characterization_25R_Cell_2',
            'Export Time': '06/01/2022 14:47:10',
            'Serial Number': '213079',
            'Channel': '26',
            'Start DateTime': '05/22/2022 12:42:59',
            'Schedule File Name': 'BG\\BG_25R_Characterization+BG_25R.sdx',
            'Creator': 'admin',
            'Comments': '',
            'Software Version': 'Mits8 PV Build: 202110',
            'Schedule Version': 'Schedule Version 8.00.11',
            'MASS(g)': '0',
            'Specific Capacity(Ah/g)': '0',
            'Capacity(Ah)': '2.5',
            'BarCode': '',
            'Has Aux': '512',
            'Has Specail': '0',
            'Log Aux Data Flag': 'True',
            'Log Special Flag': 'False'
        }
    )

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_simple_procedure():
    procedure_file_name = 'BG_Maccor_Schedule.000'
    path = join(MACCOR_SIMPLE_PATH, procedure_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([path])
    assert (extractor.schedule['file_name'] == path)
    procedure_extracted = extractor.schedule['schedule']

    assert (extractor.cycler_make == Constants.MAKE_MACCOR)

    schedule_check_dict = {
        'step_types': ['Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'End'],
        'chg_steps': [2, 7, 12, 17, 22, 27, 32, 37],
        'dsg_steps': [5, 10, 15, 20, 25, 30, 35],
        "rest_steps": [1, 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 33, 36, 38]
    }

    # Check that all step types are correctly defined
    for i, step_type in enumerate(schedule_check_dict['step_types']):
        assert (procedure_extracted['MaccorProcedure']['ProcSteps']
                ['TestStep'][i]['StepType'] == step_type)

    assert (extractor.schedule['steps']['chg']
            == schedule_check_dict['chg_steps'])
    assert (extractor.schedule['steps']['dsg']
            == schedule_check_dict['dsg_steps'])
    assert (extractor.schedule['steps']['rst']
            == schedule_check_dict['rest_steps'])

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_fra_files():
    procedure_file_name = 'BG_EIS.000'
    fra_file_1 = 'BG_EIS_5mV_BaselineCycle.FRA'
    fra_file_2 = 'BG_EIS_10mV_Pot_DQ1.FRA'
    procedure_path = join(MACCOR_FRA_PATH, procedure_file_name)
    fra_path_1 = join(MACCOR_FRA_PATH, fra_file_1)
    fra_path_2 = join(MACCOR_FRA_PATH, fra_file_2)

    extractor = Extractor()
    extractor.schedule_from_files([procedure_path, fra_path_1, fra_path_2])
    assert (extractor.schedule['file_name'] == procedure_path)
    schedule_extracted = extractor.schedule['schedule']

    fra_dict_1 = schedule_extracted['fra_files'][0][fra_file_1]
    fra_dict_2 = schedule_extracted['fra_files'][1][fra_file_2]

    # Check a sample of values.
    assert (fra_dict_1['General']['fratype'] == '3')
    assert (fra_dict_1['Setup']['range'] == '200 mA')
    assert (fra_dict_1['Sweep']['endfreq'] == '.001')

    assert (fra_dict_2['General']['fratype'] == '3')
    assert (fra_dict_2['Setup']['range'] == '200 mA')
    assert (fra_dict_2['Sweep']['endfreq'] == '1')

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_fastwave_files():
    procedure_file_name = 'BG_ProfileCycling_MP_CVP_MBC2.000'
    fastwave_file_1 = 'MP_CVP_MBC2.MWF'
    fastwave_file_2 = 'other.MWF'
    procedure_path = join(MACCOR_FASTWAVE_PATH, procedure_file_name)
    fastwave_path_1 = join(MACCOR_FASTWAVE_PATH, fastwave_file_1)
    fastwave_path_2 = join(MACCOR_FASTWAVE_PATH, fastwave_file_2)

    extractor = Extractor()
    extractor.schedule_from_files(
        [procedure_path, fastwave_path_1, fastwave_path_2])
    assert (extractor.schedule['file_name'] == procedure_path)
    schedule_extracted = extractor.schedule['schedule']

    fastwave_string_1 = schedule_extracted['fastwave_files'][0][fastwave_file_1]
    fastwave_string_2 = schedule_extracted['fastwave_files'][1][fastwave_file_2]

    # Check the first and last lines
    assert (re.split('\n', fastwave_string_1)[
            0] == 'C\tI\t6.749\tV\t4.2\t1\tV\t>=\t4.2\tT\t1\tA')
    assert (re.split('\n', fastwave_string_1)
            [-1] == 'C\tI\t1.858\tV\t4.2\t3600\tI\t<=\t0.15\tT\t1\tA')

    assert (re.split('\n', fastwave_string_2)[
            0] == 'C\tI\t6.555\tV\t4.2\t1\tV\t>=\t4.2\tT\t1\tA')
    assert (re.split('\n', fastwave_string_2)
            [-1] == 'C\tI\t1.858\tV\t4.2\t3600\tI\t<=\t0.16\tT\t1\tA')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_simple_schedule():
    schedule_file_name = 'BG_25R_Characterization+BG_25R.sdx'
    path = join(ARBIN_SINGLE_PATH, schedule_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([path])
    assert (extractor.schedule['file_name'] == path)
    schedule_extracted = extractor.schedule['schedule']

    schedule_check_dict = {
        'step_types': ['Rest', 'Internal Resistance', 'Current(A)', 'Rest'
                       'Set Variable(s)', 'Internal Resistance', 'Current(A)', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Current(A)', 'Rest'],
        "chg_steps": [7, 13, 19, 25, 31, 37, 43, 48],
        "dsg_steps": [3, 9, 15, 21, 27, 33, 39, 45],
        "rest_steps": [1, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 49]
    }

    # Check that all step types were correctly loaded.
    steps = {key: val for key, val in schedule_extracted['ArbinSchedule']['Schedule'].items()
             if key.startswith('step')}
    for i, step in enumerate(steps):
        assert (steps[step]['m_szStepCtrlType'] ==
                schedule_check_dict['step_types'][i])

    assert (extractor.schedule['steps']['chg']
            == schedule_check_dict['chg_steps'])
    assert (extractor.schedule['steps']['dsg']
            == schedule_check_dict['dsg_steps'])
    assert (extractor.schedule['steps']['rst']
            == schedule_check_dict['rest_steps'])

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_object_file():
    schedule_file_name = 'BG_25R_Characterization+BG_25R.sdx'
    object_file_name = 'BG_25R.to'
    schedule_path = join(ARBIN_SINGLE_PATH, schedule_file_name)
    object_path = join(ARBIN_SINGLE_PATH, object_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, object_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    object_dict = schedule_extracted['object_file'][object_file_name]['Content']

    assert (object_dict['m_bautocalcncapacity'] == '0')
    assert (object_dict['m_fmass'] == '0')
    assert (object_dict['m_fmaxcurrentcharge'] == '10')
    assert (object_dict['m_fmaxvoltagecharge'] == '4.2')
    assert (object_dict['m_fminvoltagecharge'] == '2.5')
    assert (object_dict['m_fnorminalcapacitor'] == '0')
    assert (object_dict['m_fnorminalcapacity'] == '2.5')
    assert (object_dict['m_fnorminalir'] == '0')
    assert (object_dict['m_fnorminalvoltage'] == '0')
    assert (object_dict['m_fspecificcapacity'] == '0')
    assert (object_dict['ser'] == '508182206')
    assert (object_dict['ver'] == '27265537')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_can_bms_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    can_file_name = 'model_control_channel_29.can'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    can_path = join(ARBIN_CAN_PATH, can_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, can_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    can_dict = schedule_extracted['can_bms_file'][can_file_name]['CANConfig']

    # Just spot check a few because the file is big
    assert (can_dict['Creator'] == 'admin')
    assert (can_dict['CANBaudRate'] == '2')
    assert (can_dict['DataEntryItemList']['DataEntryItem']
            [0]['VariableName'] == 'CAN_MV_RX1')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_can_formula_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    can_fm_file_name = 'model_control_channel_29.fm'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    formula_path = join(ARBIN_CAN_PATH, can_fm_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, formula_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    can_fm_dict = schedule_extracted['can_formula_file'][can_fm_file_name]

    # Just spot check a few because the file is big
    assert (can_fm_dict['CAN_AuxDataMaxRow']['datamaxrow'] == '0')
    assert (can_fm_dict['BaudRate']['baudrate'] == '2')
    assert (can_fm_dict['CAN_Formalu1']['lableformalu'] == 'F_A')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_mapping_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    batch_file_name = 'ArbinSys.bth'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    batch_path = join(ARBIN_CAN_PATH, batch_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, batch_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    batch_dict = schedule_extracted['mapping_file'][batch_file_name]

    # Just spot check a few because the file is big
    assert (batch_dict['Version Section']
            ['current_version'] == 'Map Version 8.00.02')
    assert (batch_dict['Batch_Test29']['m_uglobalcanbmschanidx'] == '-1')
    assert (batch_dict['Batch']['m_szcreator'] == 'admin')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_simulation_files():
    schedule_file_name = 'BG_MBC_eta0p025_25R+BG_25R.sdx'
    sim_file_1 = 'MWT_MBC_eta0p025.txt'
    sim_file_2 = 'sim_file_2.txt'
    schedule_path = join(ARBIN_SIMULATION_PATH, schedule_file_name)
    sim_path_1 = join(ARBIN_SIMULATION_PATH, sim_file_1)
    sim_path_2 = join(ARBIN_SIMULATION_PATH, sim_file_2)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, sim_path_1, sim_path_2])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    sim_string_1 = schedule_extracted['simulation_files'][0][sim_file_1]
    sim_string_2 = schedule_extracted['simulation_files'][1][sim_file_2]

    # Check the first and last lines in the simulation files
    assert (re.split('\n', sim_string_1)[0] == '1\t7.5')
    assert (re.split('\n', sim_string_1)[-1] == '2059\t0.1')

    assert (re.split('\n', sim_string_2)[0] == '1\t8.5')
    assert (re.split('\n', sim_string_2)[-1] == '2059\t0.2')


theInt = 3
theStr = "hi"
if True:
    union = 3
else:
    union = "hi"

def if_else_base1(a):
    b = "hi"
    if type(a) is int:
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"
    r5 = a / 3
    r6 = b / 3

def if_else_base2(a):
    b = "hi"
    if type(a) is int:
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"
    r5 = a / 3
    r6 = b / 3

def if_else_base3(a):
    b = "hi"
    if type(a) is int:
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"
    r5 = a / 3
    r6 = b / 3

def if_else_base4(a):
    b = "hi"
    if type(a) is int:
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"
    r5 = a / 3
    r6 = b / 3

bigUnion = int() if True else str() if False else False

if_else_base1(theInt)
if_else_base2(theStr)
if_else_base3(union)
if_else_base4(bigUnion)

def simple_if_else_idiom_variant(a):
    b = "hi"
    if type(a) is type(3):
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"

    r5 = a / 3
    r6 = b / 3

simple_if_else_idiom_variant(union)

def simple_if_else_not_idiom(a):
    b = "hi"
    if type(a) is 3:
        r = a / 3
        r2 = a[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"

    r5 = a / 3
    r6 = b / 3

simple_if_else_not_idiom(union)

class Foo:
    def __init__(self):
        self.attr = 4
        self.strattr = "bar"

def simple_if_else_idiom_attr(a):
    b = "hi"
    if type(a.attr) is int:
        r = a.attr / 3
        r2 = a.attr[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"

    r5 = a.attr / 3
    r6 = b / 3

def simple_if_else_idiom_attr_b(a):
    b = "hi"
    if type(a.strattr) is int:
        r = a.attr / 3
        r2 = a.strattr[0]
        b = 3
    else:
        r3 = a[0]
        r4 = a / 3
        b = "bye"

    r3 = a.strattr / 3
    r4 = b / 3

simple_if_else_idiom_attr(Foo())
simple_if_else_idiom_attr_b(Foo())


# coding: utf-8

# ## Encryption Machine
# ### Created by: Jamila Smith-Dell
# #### April 11, 2021
# ![Windows](encryption_image.png)

# ## Import the relevant libraries

# In[1]:

import math
import random
import string

# ## Function that checks if numbers are prime or not
# This function will be used to check if the user inputted values for p and q are actually prime. If not, it will notify the user that the number is not prime so they can choose again.

# In[2]:

def prime_check(number):

    """
    This function checks if a number is prime or not,
    if the number is greater than 1, and if q is greater than p.

    Arguments:
    - Any number

    Outputs:
    - Error message if the number is not prime or not greater than 1
    - Error message if q is less than p
    - Success message if the number is prime
    - The boolean of the 'check' variable if the number is prime or not

    """

    if number >= 13:
        for i in range(2, number):
            if number % i == 0:
                print(f'{number} is not a prime number.')
                check = False
                break
            else:
                print(f'{number} is a prime number, perfect!')
                check = True
                break
    else:
        print(f'{number} is not greater than 13.')
        check = False

    return check

# ## Ask the user for prime numbers: p & q
# This while loop will run the prime_check function above to check the user input and prompt for them to input another number if needed.

# In[3]:

p = 1

while p != "q":
    p = input('Please type "q" to quit. Please select a prime number (p) that is greater than or equal to 13: ')
    if p =='q':
        break
    else:
        p = int(p)
        check = prime_check(p)
        if check == False:
            p = int(input('Please select a prime number (p) greater than or equal to 13: '))
        else:
            check = True
            while check:
                q = int(input('\nPlease select a prime number (q), greater than p (i.e. 17): '))
                if q > p:
                    check = prime_check(q)
                    if check == False:
                        q = int(input('\nPlease select a (q) that is greater than p and is prime (i.e. 17): '))
                    else:
                        break
            print(f'\nGreat job! p = {p} and q = {q}\n')
            break

# ## Ask the user for a value for e
# I will then use a series of if statements to make sure phi_n is not divisible by e and e is greater than 1 and less than phi_n.

# In[4]:

if p and q:
    n = p * q
    phi_n = int((p - 1) * (q - 1))
else:
    default_p = 13
    default_q = 17
    n = default_p * default_q
    phi_n = int((default_p - 1) * (default_q - 1))

e = input(f'Please type "q" to quit. Please choose a number greater than 1 and less than {phi_n} (i.e. 5): ')

check_e = True

while check_e:
    if e == "q":
        break
    else:
        e = int(e)
        if e > 1 and e < 10:
            if e < phi_n:
                if math.gcd(phi_n, e):
                    print(f'Awesome! There is no greatest common divisor between {phi_n} and {e}.\n')
                    break
                else:
                    print('')
                    e = int(input(f'Something is wrong. Please choose a different value for e (i.e. 5). '))
            else:
                e = int(input(f'Something is wrong. Please choose a different value for e (i.e. 5). '))
        else:
            e = int(input(f'Please choose a value for e that is less than 10 (i.e. 5). '))

# ## Function to calculate the private key (d)
# Calculate the private key and check to make sure all other importnant encryption variables are integers.

# In[5]:

def private_key():
    """
    This function creates the private key (d) for the encryption machine
    and calculates the n and phi_n values as well.

    Arguments:
    - None. It uses the values of p, q, and e from the user input above

    Outputs:
    - Prime numbers: p and q
    - Private key: d
    - Other encryption variables: e, n, phi_n, and i
    """
    i = random.randint(1,100)

    d = int((i * phi_n + 1) / e)

    return p, q, n, phi_n, e, d, i

# In[6]:

private_key()

# ## Create the Public Key
# 'Letters' is a dictionary with string keys mapped to integer values. The c_list is the list of cipher values that are calculated using the integer values from the dictionary. We will use the c_list as the public key from here on out.

# In[7]:

letters = {}
value = 0

for letter in string.ascii_lowercase:
    value += 1
    letters[letter] = value

#add common punctuation
punctuation = [' ','.',"’","'","!","?","/",",",'"',":"]

for punct in punctuation:
    value += 1
    letters[punct] = value

c_list = [] #cipher list

for letter in letters:
    c = (letters[letter] ** e) % n
    c_list.append(c)

# ## Encryption
# Here the user will input the message that they want encrypted. The result will then be printed as a list that should be copied over to the decryption machine for decryption.

# In[8]:

def return_encryption():
    """
    This function creates the encryption list from the message the user
    provides using the cipher list and letters dictionary.

    Arguments:
    - User input for the message to encrypt

    Outputs:
    - A message telling the use that they encryption was successful
    - List of calculated encryption values

    """

    encryption = input('What message do you want to encrypt? ').lower()

    encrypt_list = []

    for value in encryption:
        c = (letters[value] ** e) % n
        encrypt_list.append(c)

    encrypt_list_str = []

    for value in encrypt_list:
        encrypt_list_str.append(str(value))

    encryption_result = ' '.join(encrypt_list_str)
    print(f'\nYour encryption was successful! Here is the result: {encrypt_list} \n\n\n')

    return encrypt_list

# In[9]:

return_encryption()

# In[10]:

print('Please copy this encryption list, run the decryption.py file, and paste the encryption list when prompted.')
print(f'\n\n\n')


import argparse, os, sys, glob
import torch
import numpy as np
from omegaconf import OmegaConf
from PIL import Image
from tqdm import tqdm, trange
from einops import rearrange
from torchvision.utils import make_grid

from ldm.util import instantiate_from_config
from ldm.models.diffusion.ddim import DDIMSampler
from ldm.models.diffusion.plms import PLMSSampler

def setup_parser():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--prompt",
        type=str,
        nargs="?",
        default="a photo of *",
        help="the prompt to render"
    )

    parser.add_argument(
        "--outdir",
        type=str,
        nargs="?",
        help="dir to write results to",
        default="outputs/txt2img-samples"
    )
    parser.add_argument(
        "--ddim_steps",
        type=int,
        default=50,
        help="number of ddim sampling steps",
    )

    parser.add_argument(
        "--plms",
        action='store_true',
        help="use plms sampling",
    )

    parser.add_argument(
        "--ddim_eta",
        type=float,
        default=0.0,
        help="ddim eta (eta=0.0 corresponds to deterministic sampling",
    )
    parser.add_argument(
        "--n_iter",
        type=int,
        default=1,
        help="sample this often",
    )

    parser.add_argument(
        "--H",
        type=int,
        default=32,
        help="image height, in pixel space",
    )

    parser.add_argument(
        "--W",
        type=int,
        default=32,
        help="image width, in pixel space",
    )

    parser.add_argument(
        "--n_samples",
        type=int,
        default=4,
        help="how many samples to produce for the given prompt",
    )

    parser.add_argument(
        "--scale",
        type=float,
        default=10.0,
        help="unconditional guidance scale: eps = eps(x, empty) + scale * (eps(x, cond) - eps(x, empty))",
    )

    parser.add_argument(
        "--ckpt_path",
        type=str,
        default="/local/scratch/chowdhury.150/ldm/text2img-large/model.ckpt",
        help="Path to pretrained ldm text2img model")

    parser.add_argument(
        "--embedding_path",
        type=str,
        help="Path to a pre-trained embedding manager checkpoint")

    parser.add_argument(
        "--embedding_ckpt",
        type=str,
        default="./utils/cifar_trained_embeddings.pth",
        help="Path to a pre-trained all embedding model pth ")

    parser.add_argument(
        "--step",
        type=int,
        default=0,
        choices=[499, 999, 1499],
        help="global step for embeddings")

    parser.add_argument(
        "--class_name",
        type=str,
        default= "" ,
        help="class_name to consider for generation from model")

    parser.add_argument(
        "--cluster",
        type=int,
        default=-1,
        choices=[0, 1, 2] ,
        help="global step for embeddings")

    return parser

def load_model_from_config(config, ckpt, verbose=False):
    print(f"Loading model from {ckpt}")
    pl_sd = torch.load(ckpt, map_location="cpu")
    sd = pl_sd["state_dict"]
    model = instantiate_from_config(config.model)
    m, u = model.load_state_dict(sd, strict=False)
    if len(m) > 0 and verbose:
        print("missing keys:")
        print(m)
    if len(u) > 0 and verbose:
        print("unexpected keys:")
        print(u)

    model.cuda()
    model.eval()
    return model

def generate_images_and_returnNumpyArray(prompt,
    ddim_steps, model, all_embeddings_ckpt, class_name, step,cluster,n_samples,n_iter,
    scale=10.0,ddim_eta=0.0,H=32,W=32):

    sampler = DDIMSampler(model)
    with torch.no_grad():
        with model.ema_scope():
            uc = None
            if opt.scale != 1.0:
                uc = model.get_learned_conditioning(n_samples * [""])
            for n in trange(n_iter, desc="Sampling"):
                c = model.get_learned_conditioning(n_samples * [prompt])
                shape = [4, H//8, W//8]
                shape = [4, H, W]
                samples_ddim, _ = sampler.sample(S=ddim_steps,
                                                 conditioning=c,
                                                 batch_size=n_samples,
                                                 shape=shape,
                                                 verbose=False,
                                                 unconditional_guidance_scale=scale,
                                                 unconditional_conditioning=uc,
                                                 eta=ddim_eta)

                x_samples_ddim = model.decode_first_stage(samples_ddim)
                x_samples_ddim = torch.clamp((x_samples_ddim+1.0)/2.0, min=0.0, max=1.0)

                for i in range(len(x_samples_ddim)):
                    x_samples_ddim[i]= 255. * rearrange(x_samples_ddim[i].cpu().numpy(), 'c h w -> h w c')

def load_embeddings_diffusion_model(embedding_ckpt_path,device, config_path):
    config = OmegaConf.load(config_path)
    model = load_model_from_config(config, embedding_ckpt_path)
    all_embeddings_ckpt= torch.load(embedding_ckpt_path,map_location = device )

    return model, all_embeddings_ckpt

def generate_images_save(model, opt):

    if opt.plms:
        sampler = PLMSSampler(model)
    else:
        sampler = DDIMSampler(model)

    os.makedirs(opt.outdir, exist_ok=True)
    outpath = opt.outdir

    prompt = opt.prompt

    sample_path = os.path.join(outpath, "samples")
    os.makedirs(sample_path, exist_ok=True)
    base_count = len(os.listdir(sample_path))

    all_samples=list()
    with torch.no_grad():
        with model.ema_scope():
            uc = None
            if opt.scale != 1.0:
                uc = model.get_learned_conditioning(opt.n_samples * [""])
            for n in trange(opt.n_iter, desc="Sampling"):
                c = model.get_learned_conditioning(opt.n_samples * [prompt])
                shape = [4, opt.H, opt.W]
                samples_ddim, _ = sampler.sample(S=opt.ddim_steps,
                                                 conditioning=c,
                                                 batch_size=opt.n_samples,
                                                 shape=shape,
                                                 verbose=False,
                                                 unconditional_guidance_scale=opt.scale,
                                                 unconditional_conditioning=uc,
                                                 eta=opt.ddim_eta)

                x_samples_ddim = model.decode_first_stage(samples_ddim)
                x_samples_ddim = torch.clamp((x_samples_ddim+1.0)/2.0, min=0.0, max=1.0)

                for x_sample in x_samples_ddim:
                    x_sample = 255. * rearrange(x_sample.cpu().numpy(), 'c h w -> h w c')
                    Image.fromarray(x_sample.astype(np.uint8)).save(os.path.join(sample_path, f"{base_count:04}.jpg"))
                    base_count += 1
                all_samples.append(x_samples_ddim)

    # additionally, save as grid
    grid = torch.stack(all_samples, 0)
    grid = rearrange(grid, 'n b c h w -> (n b) c h w')
    grid = make_grid(grid, nrow=opt.n_samples)

    # to image
    grid = 255. * rearrange(grid, 'c h w -> h w c').cpu().numpy()
    Image.fromarray(grid.astype(np.uint8)).save(os.path.join(outpath, f'{prompt.replace(" ", "-")}.jpg'))

if __name__ == "__main__":

    parser = setup_parser()
    opt = parser.parse_args()

    device = 'cuda:0' if torch.cuda.is_available() else 'cpu'
    if device=='cpu':
        print("Need a gpu to run, cuda not available!")
        exit()

    config = OmegaConf.load("configs/latent-diffusion/txt2img-1p4B-eval_with_tokens.yaml")
    model = load_model_from_config(config, opt.ckpt_path)

    if '*' not in opt.prompt:
        print("There is no * in prompt. Direct diffusion Image generation")
        opt.outdir="outputs/"+opt.prompt+"_ddim"+str(opt.ddim_steps)
    elif opt.embedding_path:
        model.embedding_manager.load(opt.embedding_path)
    elif opt.embedding_ckpt:
        all_embeddings_ckpt= torch.load(opt.embedding_ckpt,map_location = device )
        if opt.class_name=="":
            print("Please provide class name to choose the embedding from the pretrained embeddings")
            exit()

        if opt.step=="":
            print("Please provide which step to choose the embedding from the pretrained embeddings choices[499,999,1499]")
            exit()

        if opt.cluster=="":
            print("Please provide which cluster to choose the embedding from the pretrained embeddings choices[0,1,2]")
            exit()

        selected_embedding=all_embeddings_ckpt[opt.class_name][opt.step][opt.cluster]
        #print(selected_embedding)
        model.embedding_manager.load_from_script(selected_embedding)
        opt.outdir="outputs/"+opt.class_name+"_"+str(opt.step)+"_"+str(opt.cluster)+"_"+"ddim"+str(opt.ddim_steps)

    model = model.to(device)
    generate_images_save(model, opt)


def fib(value):
    a,b= 0,1
    while value!=0:
        a,b = b,a+b
        value-=1
    return a

arr = []
i= 0
while i != '':
    i = input()
    if i =='':
        break
    else:
        i =int(i)
        arr.append(i)

for i in arr:
    print(fib(i))

"""
def fib(value):
    a,b= 0,1
    while value!=0:
        a,b = b,a+b
        value-=1
    return a
i= 0
arr = []
while i != '':
    try:
        i = input()
        i =int(i)
        arr.append(i)
    except (EOFError):
        break

for i in arr:
    print(fib(i))

"""


def printBoard(board):
    print('\n')
    print(board['tl']+' | '+board['tm']+' | '+board['tr'])
    print('---------')
    print(board['ml']+' | '+board['mm']+' | '+board['mr'])
    print('---------')
    print(board['ll']+' | '+board['lm']+' | '+board['lr'])
    print('\n')

def Winner(board):
    if board['tl']==board['tm']==board['tr']:
        if board['tl']=='X':
            return 1
        elif board['tl']=='O':
            return 2
        else:
            return 0
    elif board['ml']==board['mm']==board['mr']:
        if board['ml']=='X':
            return 1
        elif board['ml']=='O':
            return 2
        else:
            return 0
    elif board['ll']==board['lm']==board['lr']:
        if board['ll']=='X':
            return 1
        elif board['ll']=='O':
            return 2
        else:
            return 0
    elif board['tl']==board['ml']==board['ll']:
        if board['tl']=='X':
            return 1
        elif  board['tl']=='O':
            return 2
        else:
            return 0
    elif board['tm']==board['mm']==board['lm']:
        if board['tm']=='X':
            return 1
        elif board['tm']=='O':
            return 2
        else:
            return 0
    elif board['tr']==board['mr']==board['lr']:
        if board['tr']=='X':
            return 1
        elif board['tr']=='O':
            return 2
        else:
            return 0
    elif board['tl']==board['mm']==board['lr']:
        if board['tl']=='X':
            return 1
        elif board['tl']=='O':
            return 2
        else:
            return 0
    elif board['tr']==board['mm']==board['ll']:
        if board['tr']=='X':
            return 1
        elif board['tr']=='O':
            return 2
        else:
            return 0
    else:
        return 0

theBoard={'tl':' ', 'tm':' ','tr':' ',
          'ml':' ','mm':' ','mr':' ',
          'll':' ','lm':' ','lr':' '}
printBoard(theBoard)

currMove='X'

for i in range(9):
    print("Turn "+str(i+1)+". The current move is "+currMove+". What position?: ")
    pos=input()
    while(theBoard[pos]!=' '):
        print("wrong move... try again!")
        pos=input("What position?")
    theBoard[pos]=currMove
    if currMove=='X':
        currMove='O'
    else:
        currMove='X'
    if Winner(theBoard)>0:
        if Winner(theBoard)==1:
            print('X has won')
        else:
            print('O has won')
        break
    printBoard(theBoard)

print("Final Board: \n")
printBoard(theBoard)

input()


# -*- coding: utf-8 -*-

# import libraries
import re
import utils
from monster import Monster
from spellprofile import SpellProfile
from spelllikeprofile import SpellLikeProfile
from specialrule import SpecialRule
from collections import OrderedDict

def get_string(str, buffer):
    regex = re.compile(str)
    match = regex.search(buffer)
    if match:
        result = match.group()
        return result
    else:
        return ''

def get_signed_integer(str, buffer):
    regex = re.compile(str)
    match = regex.search(buffer)
    if match:
        result = match.group()
        if result[0] == '+':
            return int(result[1:])
        else:
            return (int(result[1:]) * -1)
    else:
        return 0

def get_integer(str, buffer):
    regex = re.compile(str)
    match = regex.search(buffer)
    if match:
        result = match.group()
        return int(result)
    else:
        return 0

def split_csv(str):
    return re.split(', (?![^(]*\))', str)

def get_csv(str, buffer):
    regex = re.compile(str)
    match = regex.search(buffer)
    if match:
        result = split_csv(match.group())
        return result
    else:
        return []

def get_language_special_rules(buffer):
    regex = re.compile('(?<=Languages ).+')
    match = regex.search(buffer)
    if match:
        val = match.group().split("; ")
        if len(val) > 1:
            result = split_csv(val[1])
            return result
        else:
            return []
    else:
        return []

def get_class_line(buffer):
    regex = re.compile('(?<=\n)[A-Z][a-z\-]+(?:[a-z/\(\)\d\- ]+) *\d{1,2}(?=\n)')
    matches = regex.findall(buffer)
    if len(matches) is 1:
        result = matches[0]
        if 'Speed' not in result and 'Resist' not in result and 'speed' not in result and 'resist' not in result:
            return result
        else:
            return ''
    elif len(matches) > 1:
        result = matches[0]
        for s in range(1, len(matches)):
            if 'Speed' not in matches[s] and 'Resist' not in matches[s] and 'speed' not in matches[s] and 'resist' not in matches[s]:
                result += '/' + matches[s].lower()

        if 'Speed' not in result and 'Resist' not in result and 'speed' not in result and 'resist' not in result:
            return result
        else:
            return ''
    else:
        return ''

def get_psychic_pool_and_abilities(buffer):
    regex = re.compile('(?:\d+ PE—)[\d\w ;,\(\)%\.\'\/]+')
    match = regex.search(buffer)

    if match:
        result = match.group()
        return result.split(' PE—')
    else:
        regex = re.compile('(?:\d+ PE —)[\d\w ;,\(\)%\.\'\/]+')
        match = regex.search(buffer)

        if match:
            result = match.group()
            return result.split(' PE —')
        else:
            regex = re.compile('(?:\d+ PE \(see whelp magic\)—)[\d\w ;,\(\)%\.\'\/]+')
            match = regex.search(buffer)

            if match:
                result = match.group()
                return result.split(' PE (see whelp magic)—')

def get_spells(str, buffer):
    regex = re.compile(str)
    match = regex.search(buffer)
    spells = OrderedDict()
    if match:
        lines = match.group().split('\n')
        for line in lines:
            if line != '':
                val = line.split('—')
                spells[val[0]] = split_csv(val[1])

    return spells

def get_spell_casting_profiles(buffer, name, source):
    regex = re.compile('.+\n(?:(?:\d[strdthn]{2} \(\d{1,2}\/day\)|0 \(at will\)|\d[strdthn]{2}|0|\d[strdthn]{2} \(\d+\))(?:—[\d\w -+;,\(\)%\.\'\/]+\n))+(?:(?:D |Bloodline [a-z]|Opposition Schools [a-z]|Patron [a-z]|Mystery [a-z]| Domain [a-z]| Domains [a-z])[\*\d\w\(\) ;,]+\n){0,1}')
    matches = regex.findall(buffer)
    results = []
    if len(matches) > 0:
        results.append(True)
        for s in matches:
            spell_profile = SpellProfile(name)
            # Caster Level & Concentration & Type
            spell_profile.caster_level = get_integer('((?<=Spells Known \(CL )|(?<=Spells Prepared \(CL )|(?<=Extracts Prepared \(CL ))\d+', s)
            spell_profile.concentration = get_integer('((?<=Prepared \(CL \d\w\w; concentration \+)|(?<=Prepared \(CL \d\d\w\w; concentration \+)|(?<=Known \(CL \d\w\w; concentration \+)|(?<=Known \(CL \d\d\w\w; concentration \+))\d+', s)
            spell_profile.type = get_string('[A-Z][a-z]+(?= Spells Known| Spells Prepared| Extracts Prepared)', s)

            #Spells
            spell_profile.spells = get_spells('((?:\d[strdthn]{2} \(\d{1,2}\/day\)|0 \(at will\)|\d[strdthn]{2}|0|\d[strdthn]{2} \(\d+\))(?:—[\d\w -+;,\(\)%\.\'\/-]+\n))+', s)

            # Domains, Bloodline, Opposition Schools, Mystery
            spell_profile.opposition_schools = get_csv('(?<=Opposition Schools )[A-Za-z, ]+', s)
            spell_profile.domains = get_csv('((?<=Domains )|(?<=Domain ))[A-Z][A-Za-z, ]+(?=\n)', s)
            spell_profile.bloodline = get_string('(?<=Bloodline )[a-z\(\) ]+', s)
            spell_profile.mystery = get_string('(?<=Mystery )[a-z\(\) ]', s)
            spell_profile.patron = get_string('(?<=Patron )[a-z\(\) ]+', s)

            # Source
            spell_profile.source = source

            results.append(spell_profile)
    else:
        results.append(False)

    return results

def get_spell_like_ability_profiles(buffer, name, source):
    regex = re.compile('.+\n(?:(?:(?:Constant|\d+\/day|At will|\d+\/week|\d+\/year)—[\d\w \/;,\(\)%\.\'-\+]+\n))+')
    matches = regex.findall(buffer)
    results = []
    if len(matches) > 0:
        results.append(True)
        for s in matches:
            spell_like_profile = SpellLikeProfile(name)

            # Caster Level & Concentration & Type
            spell_like_profile.caster_level = get_integer('(?<=Spell-Like Abilities \(CL )\d+', s)
            spell_like_profile.type = get_string('[A-Z][a-z]+(?= Spell-Like Abilities)', s)
            spell_like_profile.concentration = get_integer('((?<=Spell-Like Abilities \(CL \d\w\w; concentration \+)|(?<=Spell-Like Abilities \(CL \d\d\w\w; concentration \+))\d+', s)

            # Spell-Like Abiltiies
            spell_like_profile.abilities = get_spells('((?:(?:Constant|\d+\/day|At will|\d+\/week|\d+\/year)—[\d\w \/;,\(\)%\.\'-\+]+\n))+', s)

            # Source
            spell_like_profile.source = source

            results.append(spell_like_profile)
    else:
        results.append(False)
    return results

def scrape_monster(buffer, name, cr, monsters, spell_profiles, spell_like_profiles, page, source, flavor_text, description):
    monster = Monster(name, cr)

    ##Flavor Text and Description
    monster.flavor_text = flavor_text
    monster.description = description

    ## General
    #Typeline
    monster.type = get_string('[LEGCN]{1,2} (Fine|Diminutive|Tiny|Small|Medium|Large|Huge|Gargantuan|Colossal).+', buffer)
    #Classline
    monster.classline = get_class_line(buffer)
    # Initiative Bonus
    monster.init = get_signed_integer('(?<=Init ).\d+', buffer)
    # Senses
    monster.senses = get_csv('(?<=Senses ).+(?=;)', buffer)
    # Perception Bonus
    monster.perception = get_signed_integer('(?<=Perception ).\d+', buffer)
    # Auras
    monster.aura = get_csv('(?<=Aura ).+', buffer)

    ## Defense
    # AC and Bonuses
    monster.ac = get_integer('(?<=AC )\d+', buffer)
    monster.ac_touch = get_integer('(?<=touch )\d+', buffer)
    monster.ac_flat_footed = get_integer('(?<=flat-footed )\d+', buffer)
    monster.ac_bonuses = get_csv('((?<=flat-footed \d\d \()|(?<=flat-footed \d \()).+(?=\))', buffer)
    # HP & Special Rules
    monster.hp = get_string('(?<=hp )[0-9\(\)d\+– ]+(?=[;\n])', buffer)
    monster.health_rules = get_string('(?<=\d\); ).+(?=\nFort)', buffer)
    # Saves
    monster.save_fortitude = get_signed_integer('(?<=Fort ).\d+', buffer)
    monster.save_reflex = get_signed_integer('(?<=Ref ).\d+', buffer)
    monster.save_will = get_signed_integer('(?<=Will ).\d+', buffer)
    monster.saving_throw_modifiers = get_csv('((?<=Will \+\d; )|(?<=Will \+\d\d; )).+', buffer)
    # Resistences, Immunities and Weaknesses
    monster.spell_resist = get_integer('(?<=SR )\d+', buffer)
    monster.damage_reductions = get_csv('(?<=DR )[\d\/, \w]+', buffer)
    monster.immunities = get_csv('(?<=Immune )[\d \w\+\(\)–,]+', buffer)
    monster.weaknesses = get_csv('(?<=Weaknesses )[\d \w\+\(\)–,]+', buffer)
    monster.resistences = get_csv('(?<=Resist )[\d \w\+\(\)–,]+', buffer)
    # Defenseive Abilities
    monster.defensive_abilities = get_csv('(?<=Defensive Abilities )[\d \w\+\(\)–,]+', buffer)

    ## Offense
    # Speed Profile
    monster.speed_profile = get_string('(?<=Speed ).+', buffer)
    # Attacks
    monster.melee_profile = get_string('(?<=Melee ).+', buffer)
    monster.ranged_profile = get_string('(?<=Ranged ).+', buffer)
    monster.special_attacks = get_string('(?<=Special Attacks ).+', buffer)
    # Space & Reach
    monster.space = get_integer('(?<=Space )\d+', buffer)
    monster.reach = get_integer('(?<=Reach )\d+', buffer)
    # Offensive Abilities
    monster.offensive_abilities = get_csv('(?<=Offensive Abilities )[\d \w\+\(\)–,]+', buffer)

    ##Statistics
    # Ability Scores
    monster.strength = get_integer('(?<=\nStr )\d+', buffer)
    monster.dexterity = get_integer('(?<=, Dex )\d+', buffer)
    monster.constitution = get_integer('(?<=, Con )\d+', buffer)
    monster.intelligence = get_integer('(?<=, Int )\d+', buffer)
    monster.wisdom = get_integer('(?<=, Wis )\d+', buffer)
    monster.charisma = get_integer('(?<=, Cha )\d+', buffer)
    # Base Attack Bonus
    monster.base_attack_bonus = get_integer('(?<=Base Atk \+)\d+', buffer)
    # Combat Maneuver Bonus & Defense
    monster.combat_maneuver_bonus = get_signed_integer('(?<=CMB ).\d+', buffer)
    monster.combat_maneuver_defense = get_integer('(?<=CMD )\d+', buffer)
    # Feats, Skills and Languages
    monster.feats = get_csv('(?<=Feats ).+', buffer)
    monster.skills = get_csv('(?<=Skills )[A-Za-z \(\)\+–—,\d]+', buffer)
    monster.racial_skill_modifiers = get_csv('(?<=Racial Modifiers )[A-Za-z \(\)\+–,\d]+', buffer)
    monster.languages = get_csv('(?<=Languages )[A-Za-z\d,\.\' ]+', buffer)
    monster.language_special_rules = get_language_special_rules(buffer)
    # Special Qualities
    monster.special_qualities = get_string('(?<=SQ ).+', buffer)

    ##Ecology
    # Enviroment, Organization, Treasure
    monster.environment = get_string('(?<=Environment ).+', buffer)
    monster.organization = get_string('(?<=Organization ).+', buffer)
    monster.treasure = get_string('(?<=Treasure ).+', buffer)

    # Encode the buffer for spellcasting checks
    buffer = buffer

    ## Spellcasting, Spell-Like Abilities and Psychic Magic
    # Psychic Magic
    monster.psychic_magic_caster_level = get_integer('(?<=Psychic Magic \(CL )\d+', buffer)

    if monster.psychic_magic_caster_level != 0:
        # Concentration
        monster.psychic_magic_concentration = get_integer('((?<=Psychic Magic \(CL \d\w\w; concentration \+)|(?<=Psychic Magic \(CL \d\d\w\w; concentration \+))\d+', buffer)
        # Energy Pool and Abilities
        result = get_psychic_pool_and_abilities(buffer)
        monster.psychic_energy_pool = int(result[0])
        monster.psychic_magic_abilities = split_csv(result[1])

    # Spellcasting
    result = get_spell_casting_profiles(buffer, monster.name, source)
    monster.spellcaster = result[0]
    if monster.spellcaster is True:
        for s in range(1, len(result)):
            spell_profiles.append(result[s])

    # Spell-Like Abilities
    result = get_spell_like_ability_profiles(buffer, monster.name, source)
    monster.spell_like_abilities = result[0]
    if monster.spell_like_abilities is True:
        for s in range(1, len(result)):
            spell_like_profiles.append(result[s])

    ## Tactics
    monster.tactics_before_combat = get_string('(?<=Before Combat ).+', buffer)
    monster.tactics_during_combat = get_string('(?<=During Combat ).+', buffer)
    monster.tactics_base_statistics = get_string('(?<=Base Statistics ).+', buffer)
    monster.combat_gear = get_csv('(?<=Combat Gear ).+', buffer)

    monster.boon = get_string('(?<=Boon ).+', buffer)

    # Add Source
    monster.page = page
    monster.source = source
    monsters.append(monster)

def scrape_special_rules(special_rules, buffer, universal, page, source):
    regex = re.compile('(?:[\w.()-]+ )+\((?:Su|Ex|Sp)\):* .+')
    matches = regex.findall(buffer)

    for s in matches:
        special_rule = SpecialRule(page)
        special_rule.name = get_string('.+(?= \((?:Su|Ex|Sp)\))', s)
        special_rule.type = get_string('(?:Su|Ex|Sp)', s)
        special_rule.text = get_string('((?<=\((?:Su|Ex|Sp)\) )|(?<=\((?:Su|Ex|Sp)\): )).+', s)
        special_rule.source = source
        special_rule.universal = universal

        special_rules.append(special_rule)


#!/usr/bin/env python
import os
import numpy
import psutil
import pcraster
import pcraster.framework

# User writes 10 scalar values for 10 variables for 10000 timesteps
# for 500 samples: 500.000.000 values.
# During post-processing, reading these values back in takes ages.

first_time_step = 1
last_time_step = 5000 # 10000
nr_samples = 250 # 500
nr_state_variables = 10
nr_locations_to_write = 10

class Model(
    pcraster.framework.DynamicModel,
    pcraster.framework.MonteCarloModel):

    @staticmethod
    def generate_name(
            variable_id,
            sample_nr,
            timestep):
        return "{}/state{}_{}".format(sample_nr, variable_id, timestep)

    def __init__(self,
            clone_map,
            nr_state_variables,
            nr_locations_to_write):
        pcraster.framework.DynamicModel.__init__(self)
        pcraster.framework.MonteCarloModel.__init__(self)
        pcraster.setclone(clone_map)
        self.nr_state_variables = nr_state_variables
        self.nr_locations_to_write = nr_locations_to_write
        self.process = psutil.Process(os.getpid())
        self.memory_log_file = file("memory.col", "w")
        self.runtime_log_file = file("runtime.col", "w")

    def log_memory_used(self):
        nr_mbytes = self.process.get_memory_info().rss / 1048576.0
        self.memory_log_file.write("{}\n".format(nr_mbytes))

    def log_time_spent(self):
        # System + user.
        cpu_time = sum(self.process.get_cpu_times())
        self.runtime_log_file.write("{}\n".format(cpu_time))

    def log_process_statistics(self):
        self.log_memory_used()
        self.log_time_spent()

    def premcloop(self):
        pass

    def initial(self):
        pass

    def dynamic(self):
        # Per state variable a file with nr_locations_to_write values.
        for i in xrange(1, self.nr_state_variables + 1):
            filename = Model.generate_name(i, self.currentSampleNumber(),
                self.currentTimeStep())
            file(filename, "w").write("\t".join([str(i) for i in xrange(
                self.nr_locations_to_write)]))
            self.log_process_statistics()

    def postmcloop(self):
        for i in xrange(1, self.nr_state_variables + 1):
            output = []
            for timestep in xrange(1, self.nrTimeSteps() + 1):
                all_samples = []
                for sample_nr in xrange(1, self.nrSamples() + 1):
                    filename = Model.generate_name(i, sample_nr, timestep)
                    array = numpy.loadtxt(filename)
                    all_samples.append(array)
                    self.log_process_statistics()
                output.append(all_samples)
            output_as_array = numpy.array(output)

model = Model("clone.map", nr_state_variables, nr_locations_to_write)
dynamic_model = pcraster.framework.DynamicFramework(model,
    firstTimestep=first_time_step, lastTimeStep=last_time_step)
dynamic_model.setQuiet(True)
monte_carlo_model = pcraster.framework.MonteCarloFramework(dynamic_model,
    nrSamples=nr_samples)
monte_carlo_model.run()


import nltk
# import re, pprint, os, sys
from nltk import word_tokenize
from nltk.corpus import stopwords
import random
import array
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

import numpy as np
#from query_integral_image import query_integral_image

def query_integral_image(integral_image, size_x, size_y):
    x = integral_image.shape[0]
    y = integral_image.shape[1]
    hits = 0

    # count how many possible locations
    for i in range(x - size_x):
        for j in range(y - size_y):
            area = integral_image[i, j] + integral_image[i + size_x, j + size_y]
            area -= integral_image[i + size_x, j] + integral_image[i, j + size_y]
            if not area:
                hits += 1
    if not hits:
        # no room left
        return None
    # pick a location at random
    goal = np.random.randint(hits)
    hits = 0
    for i in range(x - size_x):
        for j in range(y - size_y):
            area = integral_image[i, j] + integral_image[i + size_x, j + size_y]
            area -= integral_image[i + size_x, j] + integral_image[i, j + size_y]
            if not area:
                hits += 1
                if hits == goal:
                    return i, j

FONT_PATH = "C:\Windows\Fonts\BASKVILL.TTF"

tokens = word_tokenize(open("reddit2.txt").read())
#outfile = open("freqdist.txt", mode='w')
#orig_stdout = sys.stdout
#sys.stdout = outfile
tokenlist = []

redditstopwords = ['permalinkembed', 'save', 'gold', 'reply', 'parent', 'days', 'hours', 'permalink', 'embed', 'parent', 'give', 'report', 'reddit', 'points', 'ago']

for word in tokens:
    word = word.lower()
    if word.isalpha():
        tokenlist.append(word)

filtered_tokens = [word for word in tokenlist if word not in stopwords.words('english') and word not in redditstopwords]

wor = []
counts = []

fdist1 = nltk.FreqDist(filtered_tokens)

#fdist1.sort(reverse=True)
for (token, freq) in fdist1.most_common(100):
    if freq<100 and freq>5:
        wor.append(token)
        ct = float(freq)/100
        counts.append(ct)
       # print (token, ':', fdist1[token])

fname = 'cloud.png'

width = 400
height = 200
font_path=FONT_PATH
margin=5
ranks_only=False
prefer_horiz=0.9

# create image
img_grey = Image.new("L", (width, height))
draw = ImageDraw.Draw(img_grey)
integral = np.zeros((height, width), dtype=np.uint32)
img_array = np.asarray(img_grey)
font_sizes, positions, orientations = [], [], []
# intitiallize font size "large enough"
font_size = 1000
# start drawing grey image
for word, count in zip(wor, counts):
    # alternative way to set the font size
    if not ranks_only:
        font_size = min(font_size, int(100 * np.log(count + 100)))
    while True:
        try:
            # try to find a position
            font = ImageFont.truetype(font_path, font_size)
        except IOError:
            fontfile = FONT_PATH.rsplit('/', 1)[-1]
            raise IOError("Font '%s' not found. Please change 'FONT_PATH' "
                          "to a valid font file path." % fontfile)
        # transpose font optionally
        if random.random() < prefer_horiz:
            orientation = None
        else:
            orientation = Image.ROTATE_90
        transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
        draw.setfont(transposed_font)
        # get size of resulting text
        box_size = draw.textsize(word)
        # find possible places using integral image:
        result = query_integral_image(integral, box_size[1] + margin,
                                      box_size[0] + margin)
        if result is not None or font_size == 0:
            break
        # if we didn't find a place, make font smaller
        font_size -= 1

    if font_size == 0:
        # we were unable to draw any more
        break

    x, y = np.array(result) + margin // 2
    # actually draw the text
    draw.text((y, x), word, fill="white")
    positions.append((x, y))
    orientations.append(orientation)
    font_sizes.append(font_size)
    # recompute integral image
    img_array = np.asarray(img_grey)
    # recompute bottom right
    # the order of the cumsum's is important for speed ?!
    partial_integral = np.cumsum(np.cumsum(img_array[x:, y:], axis=1),
                                 axis=0)
    # paste recomputed part into old image
    # if x or y is zero it is a bit annoying
    if x > 0:
        if y > 0:
            partial_integral += (integral[x - 1, y:]
                                 - integral[x - 1, y - 1])
        else:
            partial_integral += integral[x - 1, y:]
    if y > 0:
        partial_integral += integral[x:, y - 1][:, np.newaxis]

    integral[x:, y:] = partial_integral

img_grey.show()
img_grey.save(fname)

#sys.stdout = orig_stdout
#outfile.close()


import os

class CodeWriter(object):

    def __init__(self, input_file):
        self.VM = ""
        self.a = open(input_file, 'w')
        self.label = 0
        self.uniquelabel = []
        self.currentFunction = ""

    def setFileName(self, fileName):
        self.VM, ext = os.path.splitext(fileName)

    def close(self):
        self.a.close()

    def writeInit(self):
        self.a.write("// Bootstrap\n")
        self.a_command("256")
        self.c_command("D", "A", None)
        self.a_command("SP")
        self.c_command("M", "D", None)
        self.writeCall("Sys.init", 0)

    def writeLabel(self, label):
        if label not in self.uniquelabel:
            newLabel = self.currentFunction + "$" + label
            self.addUniqueLabel(newLabel)
            self.a.write("\n // " + label + "\n")
            self.loop(newLabel)
        else:
            self.loop(label)

    def writeGoto(self, label):
        self.a.write("\n // " + "goto " + label + "\n")
        if label in self.uniquelabel:
            self.a_command(label)
            self.c_command(None, "0", "JMP")
        else:
            newLabel = self.currentFunction + "$" + label
            self.addUniqueLabel(newLabel)
            self.a_command(newLabel)
            self.c_command(None, "0", "JMP")

    def writeIf(self, label):
        self.a.write("\n // " + "if-goto " + label + "\n")
        if label in self.uniquelabel:
            self.a_command("SP")
            self.c_command("AM", "M-1")
            self.c_command("D", "M")
            self.a_command(label)
            self.c_command(None, "D", "JNE")
        else:
            newLabel = self.addUniqueLabel(self.currentFunction + "$" + label)
            self.a_command("SP")
            self.c_command("AM", "M-1")
            self.c_command("D", "M")
            self.a_command(newLabel)
            self.c_command(None, "D", "JNE")

    def writeCall(self, functionName, numArgs):
        self.currentFunction = functionName
        RETURN_ADDRESS = self.getUniqueLabel(self.currentFunction + "$" + "RETURN")
        self.a.write("\n// " + functionName  + " " + str(numArgs) + "\n")
        self.a_command(RETURN_ADDRESS)
        self.equals("D", "A")
        self.a_command("SP")
        self.equals("A", "M")
        self.equals("M", "D")
        self.a_command("SP")
        self.equals("M", "M+1")

        self.pushTemp_yesP("LCL", 0);
        self.pushTemp_yesP("ARG", 0);
        self.pushTemp_yesP("THIS", 0);
        self.pushTemp_yesP("THAT", 0);

        self.equals("D", "M")
        self.a_command("5")
        self.equals("D", "D-A")
        self.a_command(numArgs)
        self.equals("D", "D-A")
        self.a_command("ARG")
        self.equals("M", "D")
        self.a_command("SP")
        self.equals("D", "M")
        self.a_command("LCL")
        self.equals("M", "D")
        self.a_command(functionName)
        self.c_command(None, "0", "JMP")
        self.loop(RETURN_ADDRESS)

    def writeReturn(self):
        self.a.write("\n // " + "return\n")
        self.a_command("LCL")
        self.equals("D", "M")
        self.a_command("R15")
        self.equals("M", "D")

        self.a_command("5")
        self.equals("A", "D-A")
        self.equals("D", "M")
        self.a_command("R14")
        self.equals("M", "D")

        self.a_command("SP")
        self.equals("AM", "M-1")
        self.equals("D", "M")
        self.a_command("ARG")
        self.c_command("A", "M")
        self.equals("M", "D")

        self.a_command("ARG")
        self.equals("M", "M+1")
        self.equals("D", "M")
        self.a_command("SP")
        self.equals("M", "D")

        self.preTemplate("THAT")
        self.preTemplate("THIS")
        self.preTemplate("ARG")
        self.preTemplate("LCL")

        self.a_command("R14")
        self.equals("A", "M")
        self.c_command(None, "0", "JMP")

    def writeFunction(self, functionName, numLocals):
        self.currentFunction = functionName
        self.addUniqueLabel(functionName)
        self.a.write("\n// " + functionName + " " + str(numLocals) + "\n")
        self.loop(self.currentFunction)
        for i in range(0, int(numLocals)):
            self.writePushPop(1, "constant", 0)

    def preTemplate(self, pos):
        self.a_command("R15")
        self.equals("D", "M-1")
        self.equals("AM", "D")
        self.equals("D", "M")
        self.a_command(pos)
        self.equals("M", "D")

    def writeArithmetic(self, command):
        self.a.write("\n // " + command + "\n")
        if command == "sub":
            self.arithmeticTemp()
            self.equals("M", "M-D")
        elif command == "add":
            self.arithmeticTemp()
            self.equals("M", "M+D")
        elif command == "or":
            self.arithmeticTemp()
            self.equals("M", "D|M")
        elif command == "and":
            self.arithmeticTemp()
            self.equals("M", "D&M")
        elif command == "not":
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "!M")
        elif command == "neg":
            self.equals("D", "0")
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "D-M")
        elif command == "gt":
            self.arithmeticTemp()
            self.equals("D", "M-D")
            FALSE_gt = self.getUniqueLabel("FALSE_gt")
            self.a_command(FALSE_gt)
            self.c_command(None, "D", "JLE")
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "-1")
            CONTINUE_gt = self.getUniqueLabel("CONTINUE_gt")
            self.a_command(CONTINUE_gt)
            self.c_command(None, "0", "JMP")
            self.loop(FALSE_gt)
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "0")
            self.loop(CONTINUE_gt)
        elif command == "eq":
            self.arithmeticTemp()
            self.equals("D", "M-D")
            FALSE_eq = self.getUniqueLabel("FALSE_eq")
            self.a_command(FALSE_eq)
            self.c_command(None, "D", "JNE")
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "-1")
            CONTINUE_eq = self.getUniqueLabel("CONTINUE_eq")
            self.a_command(CONTINUE_eq)
            self.c_command(None, "0", "JMP")
            self.loop(FALSE_eq)
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "0")
            self.loop(CONTINUE_eq)
        elif command == "lt":
            self.arithmeticTemp()
            self.equals("D", "M-D")
            FALSE_lt = self.getUniqueLabel("FALSE_lt")
            self.a_command(FALSE_lt)
            self.c_command(None, "D", "JGE")
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "-1")
            CONTINUE_lt = self.getUniqueLabel("CONTINUE_lt")
            self.a_command(CONTINUE_lt)
            self.c_command(None, "0", "JMP")
            self.loop(FALSE_lt)
            self.a_command("SP")
            self.equals("A", "M-1")
            self.equals("M", "0")
            self.loop(CONTINUE_lt)

    def writePushPop(self, command, segment, index):
        if command == 1:
            self.a.write("\n// " + "push " + segment + " " + str(index) + "\n")
            if segment == "constant":
                self.a_command(index)
                self.equals("D", "A")
                self.a_command("SP")
                self.equals("A", "M")
                self.equals("M", "D")
                self.a_command("SP")
                self.equals("M", "M+1")
            elif segment == "local":
                self.pushTemp_noP("LCL", index)
            elif segment == "argument":
                self.pushTemp_noP("ARG", index)
            elif segment == "this":
                self.pushTemp_noP("THIS", index)
            elif segment == "that":
                self.pushTemp_noP("THAT", index)
            elif segment == "pointer":
                if index == "0":
                    self.pushTemp_yesP("THIS", index)
                elif index == "1":
                    self.pushTemp_yesP("THAT", index)
            elif segment == "temp":
                self.a_command(index)
                self.equals("D", "A")
                self.a_command("5")
                self.equals("A", "A+D")
                self.equals("D", "M")
                self.a_command("SP")
                self.equals("A", "M")
                self.equals("M", "D")
                self.a_command("SP")
                self.equals("M", "M+1")
            elif segment == "static":
                self.a_command(self.VM + str(index))
                self.equals("D", "M")
                self.pushD_toSP()

        elif command == 2:
            self.a.write("\n// " + "pop " + segment + " " + str(index) +"\n")
            if segment == "local":
                self.popTemp_noP("LCL", index)
            elif segment == "argument":
                self.popTemp_noP("ARG", index)
            elif segment == "this":
                self.popTemp_noP("THIS", index)
            elif segment == "that":
                self.popTemp_noP("THAT", index)
            elif segment == "pointer":
                if index == "0":
                    self.popTemp_yesP("THIS", index)
                elif index == "1":
                    self.popTemp_yesP("THAT", index)
            elif segment == "temp":
                self.a_command(index)
                self.equals("D", "A")
                self.a_command("5")
                self.equals("D", "D+A")
                self.a_command("R13")
                self.equals("M", "D")
                self.a_command("SP")
                self.equals("AM", "M-1")
                self.equals("D", "M")
                self.a_command("R13")
                self.equals("A", "M")
                self.equals("M", "D")
            elif segment == "static":
                self.a_command(self.VM + str(index))
                self.equals("D", "A")
                self.a_command("R13")
                self.equals("M", "D")
                self.a_command("SP")
                self.equals("AM", "M-1")
                self.equals("D", "M")
                self.a_command("R13")
                self.equals("A", "M")
                self.equals("M", "D")
            else:
                print("Something is wrong")

    def arithmeticTemp(self):
        self.a_command("SP")
        self.equals("AM", "M-1")
        self.equals("D", "M")
        self.equals("A", "A-1")

    def pushTemp_yesP(self, segment, index):
        self.a_command(segment)
        self.equals("D", "M")
        self.pushD_toSP()

    def pushTemp_noP(self, segment, index):
        self.a_command(index)
        self.equals("D", "A")
        self.a_command(segment)
        self.equals("A", "M")
        self.equals("D", "D+A")
        self.equals("A", "D")
        self.equals("D", "M")
        self.pushD_toSP()

    def popTemp_yesP(self, segment, index):
        self.a_command("SP")
        self.equals("M", "M-1")
        self.equals("A", "M")
        self.equals("D", "M")
        self.a_command(segment)
        self.equals("M", "D")

    def popTemp_noP(self, segment, index):
        self.a_command(index)
        self.equals("D", "A")
        self.a_command(segment)
        self.equals("A", "M")
        self.equals("D", "D+A")
        self.a_command(segment)
        self.equals("M", "D")
        self.a_command("SP")
        self.equals("AM", "M-1")
        self.equals("D", "M")
        self.a_command(segment)
        self.equals("A", "M")
        self.equals("M", "D")
        self.a_command(index)
        self.equals("D", "A")
        self.a_command(segment)
        self.equals("A", "M")
        self.equals("D", "A-D")
        self.a_command(segment)
        self.equals("M", "D")

    def pushD_toSP(self):
        self.a_command("SP")
        self.equals("A", "M")
        self.equals("M", "D")
        self.a_command("SP")
        self.equals("M", "M+1")

    def equals(self, left, right):
        self.a.write(left + "=" + right + "\n")

    def loop(self, item):
        self.a.write("(" + item + ")" + "\n")

    def a_command(self, address):
        address = str(address)
        self.a.write("@" + address + "\n")

    def c_command(self, dest, comp, jump = None):
        if dest != None and jump == None:
            self.a.write(dest + "=" + comp)
        elif dest == None and jump != None:
            self.a.write(comp + ";" + jump)
        elif dest != None and jump != None:
            self.a.write(dest + "=" + comp + ";" + jump)
        elif dest == None and jump == None:
            self.a.write(comp)
        self.a.write("\n")

    def getUniqueLabel(self, oldLabel):
        self.label += 1
        unique = oldLabel + str(self.label)
        self.uniquelabel.append(unique)
        return unique

    def addUniqueLabel(self, label):
        self.uniquelabel.append(label)
        return label


# Write a function that takes an array of numbers (integers for the tests) and a target number. It should find two different items in the array that, when added together, give the target value. The indices of these items should then be returned in a tuple / list (depending on your language) like so: (index1, index2).

# The input will always be valid (numbers will be an array of length 2 or greater, and all of the items will be numbers; target will always be the sum of two different items from that array).

# two_sum([1, 2, 3], 4) # returns [0, 2] or [2, 0]

# original attempt
# def two_sum(numbers, target):
#     arr = {}
#     for i, num in enumerate(numbers):
#         print(i, num)
#         if target - num in arr:
#             print("in")
#             print(f'in again: {target-num, i}')
#             return [arr[target-num], i]
#         arr[num] = i

# refractored
def two_sum(numbers, target):
    for i, x in enumerate(numbers):
        for j, y in enumerate(numbers):
            if i != j and x + y == target:
                return [i, j]

# idx = two_sum([1,2,3], 4) #[0,2]
# idx = two_sum([1234,5678,9012], 14690) #[1,2]
idx = two_sum([2,2,3], 4) #[0,1]
print(idx)


import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(224)

maxY=100
ax1.set_xlim([0,20])
ax1.set_ylim([0,maxY])

x2=range(0,10)
y2=[i/2 for i in x2]

x3=range(0,4)
y3=[i/2 for i in x3]

ax2.plot(x2,y2)
ax3.plot(x3,y3)

yPos = 90
ax1.set_aspect('equal')

yPos =[]
curY=maxY;
while (curY >= 0):
    curY=curY-10
    yPos.append(curY)

for j in yPos:
    circle=plt.Circle((10,j), 1)
    ax1.add_patch(circle)

plt.show()

chap_역학/역학_자유낙하프로그래밍실습4.py

역학_자유낙하프로그래밍실습4.py


from pyspark import SparkConf, SparkContext

if __name__ == '__main__':
    conf = SparkConf().setAppName("test").setMaster("local[*]")
    sc = SparkContext(conf=conf)

    rdd = sc.parallelize([('a', 1), ('b', 2), ('a', 4)])
    ##reduceByKey中的函数体接受两个参数，返回一个同类型的参数
    rdd1 = rdd.reduceByKey(lambda a, b: a + b)
    print(rdd1.collect())


# The implementation is derivated work of (https://github.com/jiecaoyu/pytorch_imagenet)
# There is no implementation of LRN (local response normalization) in pytorch
import torch
import os
import torch.nn as nn
import torch.utils.model_zoo as model_zoo

__all__ = ['AlexNet', 'alexnet']

class LRN(nn.Module):
    def __init__(self, local_size=1, alpha=1.0, beta=0.75, ACROSS_CHANNELS=True):
        super(LRN, self).__init__()
        self.ACROSS_CHANNELS = ACROSS_CHANNELS
        if ACROSS_CHANNELS:
            self.average=nn.AvgPool3d(kernel_size=(local_size, 1, 1),
                    stride=1,
                    padding=(int((local_size-1.0)/2), 0, 0))
        else:
            self.average=nn.AvgPool2d(kernel_size=local_size,
                    stride=1,
                    padding=int((local_size-1.0)/2))
        self.alpha = alpha
        self.beta = beta

    def forward(self, x):
        if self.ACROSS_CHANNELS:
            div = x.pow(2).unsqueeze(1)
            div = self.average(div).squeeze(1)
            div = div.mul(self.alpha).add(1.0).pow(self.beta)
        else:
            div = x.pow(2)
            div = self.average(div)
            div = div.mul(self.alpha).add(1.0).pow(self.beta)
        x = x.div(div)
        return x

class AlexNet(nn.Module):

    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=0),
            nn.ReLU(inplace=True),
            LRN(local_size=5, alpha=0.0001, beta=0.75),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(96, 256, kernel_size=5, padding=2, groups=2),
            nn.ReLU(inplace=True),
            LRN(local_size=5, alpha=0.0001, beta=0.75),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(256, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 384, kernel_size=3, padding=1, groups=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1, groups=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        return x


from pyspark.sql import SparkSession
from pyspark.sql.functions import expr, col, max

if __name__ == '__main__':
    spark = SparkSession.builder.appName("learning").master("local").getOrCreate()
    #Only 1 stage
    df = spark.range(0, 100000)
    df = df.filter(col("id") > 1)
    df = df.filter(col("id") < 1000)
    df = df.select(max("id"))
    df.explain()
    df.show()
    print(1)

    #2 stage
    df = spark.range(0, 100000).sort(col("id").desc())
    df = df.filter(col("id") > 1)
    df = df.filter(col("id") < 1000)
    df = df.select(max("id"))
    df.explain()
    df.show()
    print(1)


# -*- coding: UTF-8 -*-
"""
title: 相同的树
Given the roots of two binary trees p and q, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.

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

Example 2:
Input: p = [1,2], q = [1,null,2]
Output: false

Example 3:
Input: p = [1,2,1], q = [1,1,2]
Output: false

Constraints:
The number of nodes in both trees is in the range [0, 100].
-10^4 <= Node.val <= 10^4
"""
from typing import Optional

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

class Solution:
    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        """同时对两棵树进行层次遍历，比较值是否相等"""
        queue_1, queue_2 = [p], [q]
        while queue_1:
            cur_1, cur_2 = queue_1.pop(0), queue_2.pop(0)
            if cur_1 and cur_2 and cur_1.val == cur_2.val:
                queue_1.extend([cur_1.left, cur_1.right])
                queue_2.extend([cur_2.left, cur_2.right])
            elif not cur_1 and not cur_2:
                continue
            else:
                return False
        # 退出上述while循环时，queue_1和queue_2一定都为空，因为它们是同步增删元素
        return True

    def isSameTree_2(self, p: TreeNode, q: TreeNode) -> bool:
        """也可通过深度优先遍历来比较"""
        if not p and not q:
            return True
        elif not p or not q:
            return False
        elif p.val != q.val:
            return False
        else:
            return self.isSameTree_2(p.left, q.left) and self.isSameTree_2(p.right, q.right)

def bfs_build_tree(bfs_li: list) -> Optional[TreeNode]:
    """使用层次序列构建二叉树。所输入的层次序列任意，可以有None，可以重复"""
    if not bfs_li or bfs_li[0] is None:
        return
    root = TreeNode(bfs_li.pop(0))
    nodes = [root]
    while bfs_li:
        cur_node = nodes.pop(0)
        val = bfs_li.pop(0)
        if val is not None:
            node = TreeNode(val)
            cur_node.left = node
            nodes.append(node)
        if bfs_li:
            val = bfs_li.pop(0)
            if val is not None:
                node = TreeNode(val)
                cur_node.right = node
                nodes.append(node)
    return root

if __name__ == '__main__':
    p = [1, 2, 1]
    q = [1, 1, 2]
    print(Solution().isSameTree(bfs_build_tree(p), bfs_build_tree(q)))


from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import pytest

from baseclass.base import BaseClass
from pageobjects.checkout import CheckOut
from pageobjects.homepage import HomePage

@pytest.mark.usefixtures("test_set")
class FamEz(BaseClass):

    def test_p(self, test_set):
        homepage = HomePage(self.dt)
        homepage.shoitem().click
        self.dt.find_element_by_css_selector("a[class*='btn-primary']").click()
        self.dt.find_element_by_css_selector("button[class*='btn-success']").click()
        self.dt.find_element_by_xpath("//input[@id='country']").send_keys("ind")
        wait = WebDriverWait(self.dt, 6)

        check = CheckOut(self.dt)
        check.checkit().click
        self.dt.find_element_by_css_selector("input[class*='btn-success']").click()
        suc = self.dt.find_element_by_css_selector(".alert-success").text
        assert "Success! Thank you!" in suc


# coding=utf-8
import requests
import json
import random
import sys
from html.parser import HTMLParser
import re
from clark_demo.mail_send import send_usermail

class MyHTMLParser(HTMLParser):
    def error(self, message):
        pass

    def __init__(self, ):
        self.d = []
        super().__init__()

    def handle_data(self, data):
        data = data.strip()  # 去空格
        if len(data) == 0:
            pass
        else:
            self.d.append(data)
            # print(data)

    def return_data(self):
        return self.d

class Caiyun_tranlate(object):
    # 类的初始化
    def __init__(self, language, source):
        # 彩云小译API tokens，每个每月100字符，超过就无法使用
        self.tokens = [
            "nayce5w4niupbzt7suwv", "oqbk1rmv5klxnunzll9h", "r9f3au6ewp3n21bq2ow9",
            "jqwp6km1cmuh0mc499je", "heh7enay4t0l68w8siyl", "zj0sqg5tpirb873voao2",
            "a8qjh8gins07q72qz2ww", "kbymilu02yje537nxrls", "d3xnbflunxut3hl2i0jv",
            "6se8xvgeeeceyq5cf889", "oo0qkkory6t37b4n55bd", "9sk3sdtwz9afpmkuxe1g",
            "p2j92sxjsrwetvveblwu", "8j4802tg30z6xlxks3du", "f0fd7fm8e3b823nd4v57",
            "pgbsrsurz2zx36y7xg45", "r3f6b9h1j8mej5jeolev"
        ]

        self.language = language
        self.source = source

    def caiyun_base(self):
        url = "http://api.interpreter.caiyunai.com/v1/translator"
        # WARNING, this token is a test token for new developers, and it should be replaced by your token
        payload = {
            "source": self.source,
            # 中to英 zh2en     中to日 zh2ja   auto自动识别源语言
            "trans_type": "auto2{}".format(self.language),
            "request_id": "demo",
            "detect": True,
        }
        headers = {
            'content-type': "application/json",
            'x-authorization': "token " + random.choice(self.tokens),
        }

        response = requests.request("POST", url, data=json.dumps(payload), headers=headers, timeout=30)
        return json.loads(response.text)['target']

    def caiyun_list(self):
        try:
            i = 1
            while i < 20:
                try:
                    tranlate = Caiyun_tranlate(self.language, self.source)
                    target = tranlate.caiyun_base()
                    return target
                    break

                except (KeyError, TypeError) as e:
                    print(e, "删除无效toke：", token)
                    self.tokens.remove(token)
                    # print(tokens,"  错误代码：",e)
                    continue

        except IndexError:
            print("所有的彩云小译api都已用完，程序结束")
            send_usermail(title="所有的彩云小译api都已用完，程序结束", mail_content="所有的彩云小译api都已用完，程序结束",
                          send_mail="1094470534@qq.com")
            sys.exit()

    def tj_tokes(self):
        try:
            i = 1
            while i < 20:
                i = i + 1
                token = random.choice(self.tokens)
                try:
                    tranlate = Caiyun_tranlate(self.language, self.source)
                    target = tranlate.caiyun_list()
                    print("有效toke：", token, target)
                    pass

                except (KeyError, TypeError) as e:
                    self.tokens.remove(token)
                    # print(tokens,"  错误代码：",e)
                    continue

        except IndexError as e:
            print("所有的彩云小译api都已用完，程序结束")
            send_usermail(title="所有的彩云小译api都已用完，程序结束", mail_content="所有的彩云小译api都已用完，程序结束")
            sys.exit()

# 通过标签替换来翻译HTML
def caiyun_translate(language, source):
    html = source
    new_html = html

    # 不翻译标签中的内容
    a_list = re.findall(r'<a[\s\S]*?', html)
    for i, o in zip(a_list, range(0, len(a_list))):
        o = "".format(o)
        html = new_html
        new_html = html.replace(i, o, 1)

    # 不翻译标签中的内容
    code_list = re.findall(r'<code[\s\S]*?', html)
    for i, o in zip(code_list, range(0, len(code_list))):
        o = "".format(o)
        html = new_html
        new_html = html.replace(i, o, 1)

    # 调用彩云小译代码Api翻译HTML
    parser = MyHTMLParser()
    parser.feed(new_html)
    html_list = parser.return_data()
    tranlate = Caiyun_tranlate(language=language, source=html_list)
    en_html_list = tranlate.caiyun_list()
    for cn, en in zip(html_list, en_html_list):
        html = new_html
        new_html = html.replace(cn, en, 1)
        # print(cn,"翻译内容：",en)

    # 把占位符替换回去
    for i, o in zip(a_list, range(0, len(a_list))):
        o = "".format(o)
        html = new_html
        new_html = html.replace(o, i, 1)

    for i, o in zip(code_list, range(0, len(code_list))):
        o = "".format(o)
        html = new_html
        new_html = html.replace(o, i, 1)

    return new_html

if __name__ == '__main__':
    # data_str = ['1','有直达公交(不堵车，有空位)或直达地铁','单程 1 小时-1.5 小时。可以在座位上看书或看视频，不算浪费时间。只要不至于早上太早起床就行。']
    # # data_str = '有直达公交(不堵车，有空位)或直达地铁'
    # print(len(data_str))
    #
    # # 文本或列表翻译
    # tranlate = Caiyun_tranlate(language="en",source=data_str)
    # print(tranlate.caiyun_list())

    #
    # html 翻译
    html = '''
    1，有直达公交(不堵车，有空位)或直达地铁，单程 1 小时-1.5 小时。可以在座位上看书或看视频，不算浪费时间。只要不至于早上太早起床就行。

    2，骑自行车，10km，单程 40 分钟。太远就太累了。

    3，开车，单程 20 分钟。我宁愿坐 1 小时地铁也不开车——开车太浪费时间，啥也干不了。

    4，公交太堵或者没空位，单程最多半小时。再长换交通工具。

        '''
    new_html = sub_biaoqian_en2zh(language="en", source=html)
    print(new_html)

    tranlate = Caiyun_tranlate(language="en", source=["测试"])

    # tranlate.tj_tokes()


from ViralKnots_utils import *

if __name__=='__main__':

    parser=argparse.ArgumentParser()

    parser.add_argument('--seqs', nargs='+', required=True)
    parser.add_argument('--coords', nargs='+', required=True)
    parser.add_argument('--shape_windows', nargs='+', required=True)
    parser.add_argument('--window', '-w', type=int, required=True)
    parser.add_argument('--shape_name', type=str, required=True)
    parser.add_argument('--temp_folder', default=None, type=str)

    args=parser.parse_args()

    shape_windows_str = args.shape_windows
    shape_windows = []
    for shape_window_str in shape_windows_str:
        shape_windows.append(list(map(float, shape_window_str.split(','))))

    struct_list = []
    for seq,coord,shape in zip(args.seqs,args.coords,shape_windows):
        struct_list.extend(shapeknots_predict(seq, shape, args.shape_name, coord, args.window))

    df = pd.DataFrame(struct_list,columns=["predictor","start","end","sequence", "struct", "pseudoknot"])

    csv_name = ''
    for i in range(len(args.coords)):
        # RCK added so does not overwrite pk_predict outputs
        csv_name += args.coords[i] + '_'

    df.to_csv(f"{args.temp_folder}/{csv_name}_{args.shape_name}_shapeknots.csv", index=False)


class Board(object):
    def __init__(self):
        self.empty = '.'
        self._board = [[self.empty for _ in range(8)] for _ in range(8)]
        self._board[3][4], self._board[4][3] = 'X', 'X'
        self._board[3][3], self._board[4][4] = 'O', 'O'

    def print_b(self):
        board = self._board
        print(' ', ' '.join(list('ABCDEFGH')))
        for i in range(8):
            print(str(i+1), ' '.join(board[i]))
        # print('\n')

    def __getitem__(self, index):
        return self._board[index]

    def teminate(self):
        list1 = list(self.get_legal_action('X'))
        list2 = list(self.get_legal_action('O'))
        return[False, True][len(list1) == 0 and len(list2) == 0]

    def get_winner(self):
        s1, s2 = 0, 0
        for i in range(8):
            for j in range(8):
                if self._board[i][j] == 'X':
                    s1 += 1
                if self._board[i][j] == 'O':
                    s2 += 1
        if s1 > s2:
            return 0
        if s1 < s2:
            return 1
        if s1 == s2:
            return 2

    def _move(self, action, color):
        x, y = action
        # print(action)
        self._board[x][y] = color
        return self._flip(action, color)

    def _flip(self, action, color):
        flipped_pos = []
        for line in self._get_lines(action):
            # print(line)
            for i, p in enumerate(line):
                if self._board[p[0]][p[1]] == self.empty:
                    break
                elif self._board[p[0]][p[1]] == color:
                    flipped_pos.extend(line[:i])
                    break
        # if
        # print(flipped_pos)
        assert len(flipped_pos) > 0
        for p in flipped_pos:
            self._board[p[0]][p[1]] = color
        # print(flipped_pos)
        return flipped_pos

    def _unmove(self, action, flipped_pos, color):
        self._board[action[0]][action[1]] = self.empty
        uncolor = ['X', 'O'][color == 'X']
        for p in flipped_pos:
            self._board[p[0]][p[1]] = uncolor

    def _get_lines(self, action):
        board_coord = [(i, j) for i in range(8) for j in range(8)]

        r, c = action
        ix = r*8+c
        r, c = ix//8, ix % 8

        left = board_coord[r*8:ix]
        right = board_coord[ix+1:(r+1)*8]
        top = board_coord[c:ix:8]
        bottom = board_coord[ix+8:8*8:8]

        if r <= c:
            lefttop = board_coord[c-r:ix:9]
            rightbottom = board_coord[ix+9:(7-(c-r))*8+7+1:9]
        else:
            lefttop = board_coord[(r-c)*8:ix:9]
            rightbottom = board_coord[ix+9:7*8+(7-(c-r))+1:9]
        if r+c <= 7:
            leftbottom = board_coord[ix+7:(r+c)*8+1:7]
            righttop = board_coord[r+c:ix:7]
        else:
            leftbottom = board_coord[ix+7:7*8+(r+c)-7+1:7]
            righttop = board_coord[((r+c)-7)*8+7:ix:7]

        left.reverse()
        top.reverse()
        lefttop.reverse()
        righttop.reverse()
        lines = [left, top, lefttop, righttop, right, bottom, leftbottom, rightbottom]
        # print(lines)
        return lines

    def _can_fliped(self, action, color):
        flipped_pos = []
        # print(action)
        # n = 0
        for line in self._get_lines(action):
            '''
            t = ['left', 'top', 'lefttop', 'righttop', 'right', 'bottom', 'leftbottom', 'rightbottom']
            print(t[n])
            n = n + 1
            print(line)
            '''
            for i, p in enumerate(line):
                if self._board[p[0]][p[1]] == self.empty:
                    # print(i, p)
                    break
                elif self._board[p[0]][p[1]] == color:
                    flipped_pos.extend(line[:i])
                    # print (flipped_pos)
                    break
            # print(flipped_pos)
        return [False, True][len(flipped_pos) > 0]

    def get_legal_action(self, color):
        uncolor = ['X', 'O'][color == 'X']
        uncolor_near_pos = []
        board = self._board
        for i in range(8):
            for j in range(8):
                if board[i][j] == uncolor:
                    for dx, dy in [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]:
                        x, y = i+dx, j+dy
                        if 0 <= x <= 7 and 0 <= y <= 7 and board[x][y] == self.empty and (x, y) not in uncolor_near_pos:
                            uncolor_near_pos.append((x, y))
        # print(uncolor_near_pos)
        for p in uncolor_near_pos:
            if self._can_fliped(p, color):
                yield p

if __name__ == '__main__':
    board = Board()
    board.print_b()
    print(list(board.get_legal_action('X')))


from src.utils.datetime_converter import convert_to_datetime
import pandas as pd
from src import data
from src.features.feature_base import FeatureBase
import sys
import os
sys.path.append(os.getcwd())

# OK
class AvgSpeedSensorHour(FeatureBase):
    """
    say for each street the avg speed
    | KEY | KM | DATETIME_UTC_SPEED_SENSOR_HOUR| avg_speed_sensor_hour | avg_speed_sd_sensor_hour | avg_speed_min_sensor_hour | avg_speed_max_sensor_hour | avg_n_vehicles_sensor_hour
    """

    def __init__(self, mode):
        name = 'avg_speed_sensor_hour'
        super(AvgSpeedSensorHour, self).__init__(
            mode=mode, name=name)

    def extract_feature(self):
        df = None

        if self.mode == 'local':
            tr = data.speeds_original('train')
            te = data.speed_test_masked()
            df = pd.concat([tr, te])
            del tr
            del te

        elif self.mode == 'full':
            tr = data.speeds(mode='full')
            te = data.speeds_original('test2')
            df = pd.concat([tr, te])
            del tr
            del te

        df.DATETIME_UTC = df.DATETIME_UTC.dt.strftime('%H:%M:%S')
        return df[['KEY', 'KM', 'DATETIME_UTC', 'SPEED_AVG', 'SPEED_SD', 'SPEED_MIN', 'SPEED_MAX', 'N_VEHICLES']].groupby(['KEY', 'KM', 'DATETIME_UTC']).mean().reset_index()\
            .rename(columns={'DATETIME_UTC': 'DATETIME_UTC_SPEED_SENSOR_HOUR',
                            'SPEED_AVG': 'avg_speed_sensor_hour',
                            'SPEED_SD': 'avg_speed_sd_sensor_hour',
                            'SPEED_MIN': 'avg_speed_min_sensor_hour',
                            'SPEED_MAX': 'avg_speed_max_sensor_hour',
                            'N_VEHICLES': 'avg_n_vehicles_sensor_hour'})

    def join_to(self, df, one_hot=False):
        feature_df = convert_to_datetime(self.read_feature(one_hot=one_hot))
        feature_df.DATETIME_UTC_SPEED_SENSOR_HOUR = feature_df.DATETIME_UTC_SPEED_SENSOR_HOUR.dt.strftime(
            '%H:%M:%S')

        feature_df_y_0 = feature_df.rename(columns={'avg_speed_sensor_hour': 'avg_speed_sensor_hour_y_0',
                                                    'avg_speed_sd_sensor_hour': 'avg_speed_sd_sensor_hour_y_0',
                                                    'avg_speed_min_sensor_hour': 'avg_speed_min_sensor_hour_y_0',
                                                    'avg_speed_max_sensor_hour': 'avg_speed_max_sensor_hour_y_0',
                                                    'avg_n_vehicles_sensor_hour': 'avg_n_vehicles_sensor_hour_y_0'})
        df['DATETIME_UTC_y_0_m'] = pd.to_datetime(df.DATETIME_UTC_y_0)
        df['DATETIME_UTC_y_0_m'] = df['DATETIME_UTC_y_0_m'].dt.strftime(
            '%H:%M:%S')
        df = df.merge(feature_df_y_0, left_on=['KEY', 'KM', 'DATETIME_UTC_y_0_m'], right_on=[
                      'KEY', 'KM', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], how='left')
        df = df.drop(
            ['DATETIME_UTC_y_0_m', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], axis=1)

        feature_df_y_1 = feature_df.rename(columns={'avg_speed_sensor_hour': 'avg_speed_sensor_hour_y_1',
                                                    'avg_speed_sd_sensor_hour': 'avg_speed_sd_sensor_hour_y_1',
                                                    'avg_speed_min_sensor_hour': 'avg_speed_min_sensor_hour_y_1',
                                                    'avg_speed_max_sensor_hour': 'avg_speed_max_sensor_hour_y_1',
                                                    'avg_n_vehicles_sensor_hour': 'avg_n_vehicles_sensor_hour_y_1'})
        df['DATETIME_UTC_y_1_m'] = pd.to_datetime(df.DATETIME_UTC_y_1)
        df['DATETIME_UTC_y_1_m'] = df['DATETIME_UTC_y_1_m'].dt.strftime(
            '%H:%M:%S')
        df = df.merge(feature_df_y_1, left_on=['KEY', 'KM', 'DATETIME_UTC_y_1_m'], right_on=[
                      'KEY', 'KM', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], how='left')
        df = df.drop(
            ['DATETIME_UTC_y_1_m', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], axis=1)

        feature_df_y_2 = feature_df.rename(columns={'avg_speed_sensor_hour': 'avg_speed_sensor_hour_y_2',
                                                    'avg_speed_sd_sensor_hour': 'avg_speed_sd_sensor_hour_y_2',
                                                    'avg_speed_min_sensor_hour': 'avg_speed_min_sensor_hour_y_2',
                                                    'avg_speed_max_sensor_hour': 'avg_speed_max_sensor_hour_y_2',
                                                    'avg_n_vehicles_sensor_hour': 'avg_n_vehicles_sensor_hour_y_2'})
        df['DATETIME_UTC_y_2_m'] = pd.to_datetime(df.DATETIME_UTC_y_2)
        df['DATETIME_UTC_y_2_m'] = df['DATETIME_UTC_y_2_m'].dt.strftime(
            '%H:%M:%S')
        df = df.merge(feature_df_y_2, left_on=['KEY', 'KM', 'DATETIME_UTC_y_2_m'], right_on=[
                      'KEY', 'KM', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], how='left')
        df = df.drop(
            ['DATETIME_UTC_y_2_m', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], axis=1)

        feature_df_y_3 = feature_df.rename(columns={'avg_speed_sensor_hour': 'avg_speed_sensor_hour_y_3',
                                                    'avg_speed_sd_sensor_hour': 'avg_speed_sd_sensor_hour_y_3',
                                                    'avg_speed_min_sensor_hour': 'avg_speed_min_sensor_hour_y_3',
                                                    'avg_speed_max_sensor_hour': 'avg_speed_max_sensor_hour_y_3',
                                                    'avg_n_vehicles_sensor_hour': 'avg_n_vehicles_sensor_hour_y_3'})
        df['DATETIME_UTC_y_3_m'] = pd.to_datetime(df.DATETIME_UTC_y_3)
        df['DATETIME_UTC_y_3_m'] = df['DATETIME_UTC_y_3_m'].dt.strftime(
            '%H:%M:%S')
        df = df.merge(feature_df_y_3, left_on=['KEY', 'KM', 'DATETIME_UTC_y_3_m'], right_on=[
                      'KEY', 'KM', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], how='left')
        df = df.drop(
            ['DATETIME_UTC_y_3_m', 'DATETIME_UTC_SPEED_SENSOR_HOUR'], axis=1)

        return df

if __name__ == '__main__':
    from src.utils.menu import mode_selection
    mode = mode_selection()
    c = AvgSpeedSensorHour(mode)

    print('Creating {}'.format(c.name))
    c.save_feature()

    print(c.read_feature(one_hot=True))


from django.conf import settings
from encrypted_credentials import django_credentials
from .backup_db import BackupDb
from .backup_local_files import BackupLocal
try:
    from .backup_s3 import BackupS3
except ImportError:
    # Allow for not using S3 and not installing boto3
    BackupS3 = None

class Backup:

    def __init__(self):
        pass

    @staticmethod
    def get_backup_db(schema=None):
        google_directory = settings.BACKUP_GDRIVE_DB
        if schema:
            google_directory += '/' + schema
        return BackupDb(django_credentials.get_credentials('drive'),
                        google_directory,
                        settings.DATABASES['default'],
                        settings.BACKUP_LOCAL_DB_DIR, schema=schema)

    def backup_db_and_folders(self):
        db = self.get_backup_db()
        db.backup_db_gdrive()

        db.prune_old_backups(settings.BACKUP_DB_RETENTION)

        if hasattr(settings, 'BACKUP_DIRS'):
            b = BackupLocal(django_credentials.get_credentials('drive'), settings.BACKUP_GDRIVE_DIR)
            for backup in settings.BACKUP_DIRS:
                b.backup_to_drive(*backup)

        if hasattr(settings, 'S3_BACKUP_DIRS'):
            s3_backup = BackupS3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY,
                                 django_credentials.get_credentials('drive'),
                                 settings.BACKUP_GDRIVE_DIR)
            for s3 in settings.S3_BACKUP_DIRS:
                s3_backup.backup(settings.AWS_PRIVATE_STORAGE_BUCKET_NAME, *s3)