import augmentation as aug
import numpy as np
from tqdm import tqdm
import threading

class MatrixParameterDistribution(aug.DualMatrixDistributionInterface):
    def __init__(self, matrix_parameters, fixed_hyper_parameters):
        self.matrix_parameters = matrix_parameters
        self.fixed_hyper_parameters = fixed_hyper_parameters

    def draw_parameters(self):
        raise Exception('draw not implemented!')

    # Sample only the A matrix for Ax = b
    def draw_sample(self) -> aug.MatrixSampleInterface:
        return self.convert(self.draw_parameters())

    # Sample both the A and M matrices in Ax = Mb
    def draw_dual_sample(self) -> (aug.MatrixSampleInterface, aug.MatrixSampleInterface):
        params = self.draw_parameters()
        return self.convert(params), self.convert_auxiliary(params)

    # Convert matrix parameters into an actual matrix
    def convert(self, matrix_parameters) -> aug.MatrixSampleInterface:
        raise Exception('convert not implemented!')

    # Convert matrix parameters into auxilliary matrix M
    def convert_auxiliary(self, matrix_parameters) -> aug.MatrixSampleInterface:
        return aug.IdentityMatrixSample()

    def get_dimension(self) -> int:
        raise Exception('get_dimension not implemented!')

    def is_dual_distribution(self) -> bool:
        return False

class ProblemDefinition:
    def __init__(self, tru_distribution: MatrixParameterDistribution):
        self.tru_distribution = tru_distribution
        self.b_distribution = aug.VectorDistributionFromLambda(
            lambda: np.random.randn(self.tru_distribution.get_dimension()))

        self.tru_mat = self.tru_distribution.convert(self.tru_distribution.matrix_parameters)
        self.tru_aux = self.tru_distribution.convert_auxiliary(self.tru_distribution.matrix_parameters)
        self.energy_norm_squared = lambda x: np.sqrt(np.dot(x, self.tru_mat.apply(x)))
        self.l2_norm_squared = lambda x: np.sqrt(np.dot(x, x))

class ProblemRun:
    def __init__(self, parent: ProblemDefinition, name):
        self.parent = parent
        self.q_distribution = self.parent.b_distribution
        self.q_u_distribution = aug.IdenticalVectorPairDistributionFromLambda(self.q_distribution.draw_sample)
        self.num_sub_runs = 10
        self.samples_per_sub_run = 10
        self.samples_per_system = 1
        self.name = name
        self.err_arrays = []
        self.norms = []
        self.norm_names = []
        self.norms.append(parent.l2_norm_squared)
        self.norms.append(parent.energy_norm_squared)
        self.norm_names.append('L2 norm')
        self.norm_names.append('Energy norm')

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray) -> np.ndarray:
        raise Exception('sub_run not implemented!')

# Do nothing besides solve the noisy system
class NaiveProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition):
        name = 'Naive'
        ProblemRun.__init__(self, parent, name)

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        aux_mat = bootstrap_distribution.convert_auxiliary(bootstrap_distribution.matrix_parameters)
        aux_mat.preprocess()
        return sampled_mat.solve(aux_mat.apply(b))

class AugProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition, op_R = lambda x: x, op_B = lambda x: x):
        name = 'Augmentation'
        ProblemRun.__init__(self, parent, name)
        self.op_B = op_B
        self.op_R = op_R

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        op_Ahat_inv = lambda x: sampled_mat.solve(x)
        return aug.aug(self.samples_per_sub_run, self.samples_per_system, b,
                       op_Ahat_inv, bootstrap_distribution, self.q_u_distribution, self.op_R, self.op_B)

class EnAugProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition, op_C = lambda x: x):
        name = 'Energy-Norm Augmentation'
        ProblemRun.__init__(self, parent, name)
        self.op_C = op_C

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        op_Ahat_inv = lambda x: sampled_mat.solve(x)
        op_Ahat = lambda x: sampled_mat.apply(x)
        return aug.en_aug(self.samples_per_sub_run, self.samples_per_system, b,
                          op_Ahat_inv, op_Ahat, bootstrap_distribution, self.q_distribution, self.op_C)

class TruncEnAugProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition, order, window_funcs='default', op_C = lambda x: x):
        if window_funcs == 'default':
            name = f'Trunc. En-Norm Augmentation (Order {order})'
        else:
            name = f'Trunc. En-Norm Augmentation (Order {order}, {window_funcs.capitalize()} Window)'
        self.order = order
        self.op_C = op_C
        self.window_funcs = window_funcs
        ProblemRun.__init__(self, parent, name)

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        op_Ahat_inv = lambda x: sampled_mat.solve(x)
        op_Ahat = lambda x: sampled_mat.apply(x)
        if self.window_funcs == 'hard':
            return aug.en_aug_trunc(self.samples_per_sub_run, self.samples_per_system, b, self.order,
                                    op_Ahat_inv, op_Ahat, bootstrap_distribution, self.q_distribution, self.op_C,
                                    aug.hard_window_func_numerator,
                                    aug.hard_window_func_denominator)
        else:
            return aug.en_aug_trunc(self.samples_per_sub_run, self.samples_per_system, b, self.order,
                                    op_Ahat_inv, op_Ahat, bootstrap_distribution, self.q_distribution, self.op_C)

class TruncEnAugShiftedProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition, order, alpha, window_funcs='default', op_C=lambda x: x):
        if window_funcs == 'default':
            name = f'Shifted Trunc. En-Norm Augmentation (Order {order})'
        else:
            name = f'Shifted Trunc. En-Norm Augmentation (Order {order}, {window_funcs.capitalize()} Window)'
        self.order = order
        self.op_C = op_C
        self.alpha = alpha
        self.window_funcs = window_funcs
        ProblemRun.__init__(self, parent, name)

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        op_Ahat_inv = lambda x: sampled_mat.solve(x)
        op_Ahat = lambda x: sampled_mat.apply(x)
        if self.window_funcs == 'hard':
            return aug.en_aug_shift_trunc(self.samples_per_sub_run, self.samples_per_system,
                                          b, self.order, self.alpha, op_Ahat_inv, op_Ahat,
                                          bootstrap_distribution,
                                          self.q_distribution, self.op_C,
                                          aug.hard_shifted_window_func_numerator,
                                          aug.hard_shifted_window_func_denominator)

        else:
            return aug.en_aug_shift_trunc(self.samples_per_sub_run, self.samples_per_system,
                                          b, self.order, self.alpha, op_Ahat_inv, op_Ahat,
                                          bootstrap_distribution,
                                          self.q_distribution, self.op_C)

class TruncEnAugAccelProblemRun(ProblemRun):
    def __init__(self, parent: ProblemDefinition, order, window_funcs='default', op_C = lambda x: x):
        if window_funcs == 'default':
            name = f'Accel. Shifted Trunc. En-Norm Augmentation (Order {order})'
        else:
            name = f'Accel. Shifted Trunc. En-Norm Augmentation (Order {order}, {window_funcs.capitalize()} Window)'
        self.order = order
        self.op_C = op_C
        self.eps = 0.01
        self.window_funcs = window_funcs
        ProblemRun.__init__(self, parent, name)

    def sub_run(self, bootstrap_distribution: MatrixParameterDistribution,
                b: np.ndarray):
        sampled_mat = bootstrap_distribution.convert(bootstrap_distribution.matrix_parameters)
        sampled_mat.preprocess()
        op_Ahat_inv = lambda x: sampled_mat.solve(x)
        op_Ahat = lambda x: sampled_mat.apply(x)
        if self.window_funcs == 'hard':
            return aug.en_aug_accel_shift_trunc(self.samples_per_sub_run, self.samples_per_system,
                                                b, self.order, op_Ahat_inv, op_Ahat,
                                                bootstrap_distribution, self.eps,
                                                self.q_distribution, self.op_C,
                                                aug.hard_shifted_window_func_numerator,
                                                aug.hard_shifted_window_func_denominator)
        else:
            return aug.en_aug_accel_shift_trunc(self.samples_per_sub_run, self.samples_per_system,
                                                b, self.order, op_Ahat_inv, op_Ahat,
                                                bootstrap_distribution, self.eps,
                                                self.q_distribution, self.op_C)

class ProblemRunResults:
    def __init__(self, run: ProblemRun, raw_err_data: np.ndarray, solution_norms: np.ndarray):
        self.name = run.name
        self.norm_names = run.norm_names
        self.raw_err_data = raw_err_data
        self.mean_errs = np.mean(raw_err_data, axis=1)
        self.std_errs = np.std(raw_err_data, axis=1) / np.sqrt(run.num_sub_runs)
        self.mean_sol_norms = np.mean(solution_norms, axis=1)
        self.relative_errs = self.mean_errs / self.mean_sol_norms
        self.relative_std_errs = self.std_errs / self.mean_sol_norms

    def print(self):
        for i in range(0, len(self.norm_names)):
            print(f'{self.name}: {self.norm_names[i]}: {self.mean_errs[i]:#.4g} +- {2 * self.std_errs[i]:#.4g}')
            print(f'{self.name}: {self.norm_names[i]} (Relative): {self.relative_errs[i]:#.4g} +-'
                  f' {2 * self.relative_std_errs[i]:#.4g}')

class DiagnosticThreadWorker:
    def __init__(self, tru_distribution: MatrixParameterDistribution,
                 parent_run: ProblemRun, problem: ProblemDefinition, num_sub_runs: int,
                 thread_id: int):
        self.tru_distribution = tru_distribution
        self.num_sub_runs = num_sub_runs
        self.parent_run = parent_run
        self.problem = problem
        self.thread_id = thread_id
        self.errs = np.zeros((len(self.parent_run.norms), num_sub_runs))
        self.sol_norms = np.zeros((len(self.parent_run.norms), num_sub_runs))

    def run(self):
        tru_mat = self.problem.tru_mat
        tru_distribution = self.problem.tru_distribution
        tru_aux = self.problem.tru_aux

        if self.thread_id == 0:
            iter = tqdm(range(0, self.num_sub_runs), desc=self.parent_run.name)
        else:
            iter = range(0, self.num_sub_runs)

        for i in iter:
            # Draw rhs from Bayes prior distribution
            b = self.problem.b_distribution.draw_sample()

            # Solve the true linear system b
            tru_solution = tru_mat.solve(tru_aux.apply(b))

            # Perform bootstrap operator augmentation
            noisy_parameters = self.problem.tru_distribution.draw_parameters()
            dist_type = self.problem.tru_distribution.__class__
            bootstrap_distribution = dist_type(noisy_parameters, tru_distribution.fixed_hyper_parameters)
            result = self.parent_run.sub_run(bootstrap_distribution, b)

            # Get error from dis
            for i_norm in range(0, len(self.parent_run.norms)):
                self.errs[i_norm, i] = self.parent_run.norms[i_norm](result - tru_solution)
                self.sol_norms[i_norm, i] = self.parent_run.norms[i_norm](tru_solution)

class DiagnosticRun:
    def __init__(self, problem: ProblemDefinition):
        self.runs = []
        self.results = []
        self.problem = problem

    def add_run(self, run):
        self.runs.append(run)

    def run(self, num_threads=1):
        # Preprocess true solution if necessary
        tru_mat = self.problem.tru_mat
        tru_distribution = self.problem.tru_distribution
        tru_aux = self.problem.tru_aux
        tru_mat.preprocess()

        for run in self.runs:
            sub_runs_per_thread = int(run.num_sub_runs / num_threads)
            total_sub_runs = sub_runs_per_thread * num_threads
            workers = [DiagnosticThreadWorker(tru_distribution, run, self.problem, sub_runs_per_thread, i)
                       for i in range(0, num_threads)]

            # Break up work among the threads
            if num_threads == 1:
                workers[0].run()
            else:
                # Launch threads
                worker_threads = [threading.Thread(target=DiagnosticThreadWorker.run, args=(w,), daemon=True)
                                  for w in workers]
                for t in worker_threads:
                    t.start()

                # Wait to finish
                for t in worker_threads:
                    t.join()

            # Concatenate results
            errs = np.hstack([w.errs for w in workers])
            sol_norms = np.hstack([w.sol_norms for w in workers])

            self.results.append(ProblemRunResults(run, errs, sol_norms))

    def print_results(self):
        for result in self.results:
            result.print()
            print('')


# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import itertools
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

d = collections.deque()
def LI(): return list(map(int, sys.stdin.readline().split()))
N, M, Q = LI()

abcd = []

all = 0
for i in range(Q):
    a, b, c, d = LI()
    a -= 1
    b -= 1
    abcd.append([a, b, c, d])
    all += d

abcd = sorted(abcd, key= lambda x:x[3], reverse= True)
ans = 0
if Q <= 2:
    for q in range(Q):
        ans += abcd[q][-1]
    print(ans)
    sys.exit()

def cal_ans(A):
    ans = 0
    for i in range(Q):
        a, b, c, d = abcd[i]
        if A[b] - A[a] == c:
            ans += d
    return ans

def n2kdigit(n, k):
    bi=''
    before = 1
    while n!=0:
        if before <= (n % k):
            # print(n)
            bi+=str(n%abs(k))
            before = n % k
            if k<0:n=-(-n//k)
            else:n=n//k
        else:
            return None
    if len(bi) < N:
        return None
    return bi
ans = 0

for i in itertools.combinations_with_replacement(range(1, M+1), N):
    # print(i)
    ans = max(ans, cal_ans(i))
print(ans)


from customtkinter import *
from tkinter import *
from tkinter import ttk
import pandas as pd
import datetime
'''
Branded Colours
background: bedrock dark gray "#2E2E2E"
hover: bedrock green "#72c05b"
foreground/accent: bedrock orange "#f37367"
'''
#define branded colours for repeated use in formatting of elements
bedrock_green= "#72c05b"
bedrock_orange= "#f37367"
bedrock_gray="#2E2E2E"

# Custom module imports to provide functionality to each secondary window

import adjust
from add_product import add_product
from BCUTILS import backup
import BCUTILS
import frontend_components
import order_manager
import stock_viewer
import table_edit

def main():
    r'''
    Function containing main window Tkinter GUI: includes 8 buttons linking to each main function
    of software
    '''
    win = CTk()
    win.geometry("1280x720")
    win.configure(fg_color="#2E2E2E")
    win.title("Bedrock Inventory System 1.1")
    titleframe = CTkFrame(win)
    titleframe.configure(fg_color="#2E2E2E")
    titleframe.grid(row=0, column=0)
    win.iconbitmap('datafiles/icon.ico')
    backup.create_backup()
    titleimg = PhotoImage(file="datafiles/bedrock.png")
    logotitle = Label(titleframe, image = titleimg,bg = "#2E2E2E")
    logotitle.grid(row=0, column= 0)
    titletext = Label(titleframe, text= "Bedrock Computers Inventory Management", font="Berlin, 20", bg="#2E2E2E", fg="#de6210")
    titletext.grid(row=0, column= 1, columnspan= 1,padx=20, pady=20)
    buttonframe= CTkFrame(win)
    buttonframe.configure(fg_color="#2E2E2E")
    buttonframe.grid(row=1, column=0, pady=50)
    hvcol="#72c05b"
    button_fg = "#de6210"

    #create button objects and provide necessary formatting and commands

    button1 = CTkButton(buttonframe, text="Add New Components", command=frontend_components.main,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200,corner_radius= 50)

    button2 = CTkButton(buttonframe, text="Configure Shop Product", command=add_product.product_window,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200, corner_radius= 50)

    button3 = CTkButton(buttonframe, text="Order Manager", command=order_manager.main,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200, corner_radius= 50)

    button4 = CTkButton(buttonframe, text="View Current Stock", command=stock_viewer.main_stock,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200,corner_radius= 50)

    button5 = CTkButton(buttonframe, text="Stock Dashboard", command=stock_viewer.main_backup,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200, corner_radius= 50)

    button6 = CTkButton(buttonframe, text="Manage Database",command=table_edit.launch_stock_database_app,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200, corner_radius= 50)

    button7 = CTkButton(buttonframe, text="Edit Stock |ADMIN|", command=adjust.runwin,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b",height=100, width=200, corner_radius= 50)

    button8 = CTkButton(buttonframe, text="Backup Database", command=BCUTILS.backup.create_backup,
    fg_color=button_fg,border_color="#72c05b",hover_color="#72c05b", height=100, width=200, corner_radius= 50)

    #manually arange button placement on home screen for accessible visual interface.

    button1.grid(row=4, column= 0,padx=15, pady=15)
    button2.grid(row=4, column=1,padx=15, pady=15)
    button3.grid(row=4, column=2,padx=15, pady=15)
    button4.grid(row=4, column=3,padx=15, pady=15)
    button5.grid(row=5, column=0,padx=15, pady=15)
    button6.grid(row=5, column=1,padx=15, pady=15)
    button7.grid(row=5, column=2,padx=15, pady=15)
    button8.grid(row=5, column=3,padx=15, pady=15)

    win.mainloop()

main()


#MCLINE_FUNCTIONS.py
#Keegan Marr
#Last Modified: June 24, 2020

import warnings
warnings.filterwarnings('ignore')
import os
import sys
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.gridspec as gridspec
matplotlib.rcParams['font.family'] = "sans-serif"
font_color = "black"
tick_color = "black"
import scipy.stats as sp
import scipy.constants as const
import scipy.interpolate as interp
import scipy.integrate as integrate
import pyhdust.spectools as spc
import glob
import math
import emcee
import time
import datetime
import operator
from corner import corner
from astropy.io import fits
from astropy.convolution import Gaussian1DKernel, convolve, Box1DKernel
from scipy.interpolate import griddata, interp2d
from random import randint
from gaussfold import gaussfold as gf
from multiprocessing import Pool

#Reads in the reddened fullsed file from HDUST simulation
def readInReddeningFile(filename, luminosity, distance):
    file=open(filename, "r")

    #List stores: MU, LAMBDA, FLUX
    redParam=[[],[],[]]

    #Reads in each line of redParam from the file and appends each point to the
    #proper row in the table
    i=-1
    prevMu=-20000
    for line in file:
        line=line.split()
        if (float(line[0].strip())==prevMu):
            redParam[0][i].append(float(line[0].strip()))
            redParam[1][i].append(float(line[1].strip()))
            redParam[2][i].append(float(line[2].strip())*float(line[1].strip())*\
                10**23/10**4/2.99792458/10**10*2.99792458*10**8/\
                (float(line[1].strip()))*10**6/(3.9*10**33*luminosity)*\
                (4*np.pi*(distance*3.08568*10**18)**2)*float(line[1].strip()))

        else:
            i+=1
            for k in range(3):
                redParam[k].append([])
            redParam[0][i].append(float(line[0].strip()))
            redParam[1][i].append(float(line[1].strip()))
            redParam[2][i].append(float(line[2].strip())*float(line[1].strip())*\
                (float(line[1].strip()))*10**6/(3.9*10**33*luminosity)*\
                (4*np.pi*distance)*float(line[1].strip()))

            prevMu=redParam[0][i][0]

    file.close()

    return redParam

#Reads in observed Halpha profile obtained from Chris Tycner
def readInHalphaFile(fileName):
    file=open(fileName, "r")

    observ=[[],[]]

    for line in file:
        line=line.rsplit(" ", 1)
        observ[0].append(float(line[0].strip()))
        observ[1].append(float(line[1].strip()))

    file.close()

    return observ

#Reads in and plots the observed Halpha profile obtained from Rivinius
def plotRiviData():
    #REDACTED
    return wav[0], flx[0]

#Performs calculations needed to plot the H_alpha line
def findHAlphaLine(wavelength, flux, plotWave, normFlux, subtractCont):
    #Put arrays in order from least to greatest (if they are in inverse order)
    n=len(wavelength)
    if (wavelength[0]>wavelength[-1]):
        temp_wave=wavelength[:]
        temp_flux=flux[:]
        for i in range(n):
            wavelength[n-1-i]=temp_wave[i]
            flux[n-1-i]=temp_flux[i]

    speedOfLight=299792 #speed of light in km/s
    h_alpha_wavelength=6564.61 #wavelength of H_alpha emission line (angstroms)

    #Convert from wavelength to equivalent velocity
    velocity=list(map(lambda obs:(obs-h_alpha_wavelength)*speedOfLight/\
        h_alpha_wavelength, wavelength))

    #Find the velocities within a reasonable range of the H_alpha line
    leftmost=findExtremeVelocity(velocity, -2500)
    rightmost=findExtremeVelocity(velocity, 2500)

    #Adjust the index value of the rightmost velocity (it is not included in the
    #[x:x] operation
    if (rightmost<n):
        rightmost+=1

    #Take only the velocities within the desired range
    velocity=velocity[leftmost:rightmost+1]
    flux=flux[leftmost:rightmost+1]
    wavelength=wavelength[leftmost:rightmost+1]

    n=len(velocity)

    #For low resolution observ around the H_alpha line, make the velocity plot
    #flat (all 1's)
    if(n<3):
        if plotWave:
            return [wavelength, [1]*n]
        else:
            return [velocity, [1]*n]
    else:
        if normFlux:
            #number of points of the continuum that will be used in the fitting
            ncont=6

            #Takes the six left/rightmost points to use as the continuum
            wave_fit=wavelength[:ncont-1]+wavelength[len(wavelength)-1-ncont:]
            flux_fit=flux[:ncont-1]+flux[len(flux)-1-ncont:rightmost-1]

            #Converts from a list to a numpy array
            wave_fit=np.array(wave_fit)
            flux_fit=np.array(flux_fit)

            #Calculates the normalized linear equation from the continuum points
            normal_eqn=np.polyfit(wave_fit, flux_fit, 1)

            #New set of normalized points
            normalized_continuum=list(map(lambda x: normal_eqn[0]*\
                x+normal_eqn[1], wavelength))

            #Normalizes the flux
            flux=list(map(lambda x,y: x/y, flux, normalized_continuum))

        if subtractCont:
            #This line is for comparing the fluxes of halpha lines with different
            #continuum emissions
            flux = np.array(flux) - np.array(flux[leftmost])

        if plotWave:
            return [wavelength, flux]
        else:
            return [velocity, flux]

#Used to find the left/rightmost velocity in a given range
def findExtremeVelocity(velocity, extremeValue):
    n=len(velocity)

    #current upper and lower bounds of the range
    lower=-1
    upper=n

    #Loop continues until the range consists of only one value
    while (upper-lower>1):
        #Finds the middle value in the range
        middle=(upper+lower//2)
        #If the endpoint of the range is greater than the middle value, make the
        #middle value the lower bound of the new range
        if (extremeValue>velocity[middle]):
            lower=middle
        #Otherwise make the middle value the upper bound of the new range
        else:
            upper=middle

    #Note that lower contains the INDEX value of the observ point that fits the
    #above description
    #Adjust the value of lower accordingly in these special cases so that it is
    #a valid index value
    if (lower==-1):
        lower=0
    elif (lower==n):
        lower=n-1

    #Returns the index value of the observ point
    return lower

#Organizes simulation observ acquisition, interpolation and convolution
def getSim(filename, inclAngle, ranges, luminosity, distance, fac_e, v_h,
            v_e, inclFlag, plotWave, normFlux, subtractCont, *inclSpacing):
    values=[]
    flux=[]
    flow=[]
    fhigh=[]
    flux=[]

    #returns list of mu, lambda, flux in the same units as reddened fullsed
    observ=readInReddeningFile(filename, luminosity, distance)

    inclIndex=0

    if inclFlag: #If there are a range of inclinations
        inclSpacing = inclSpacing[0][0][0] #remove from tuple
        lowiinrange = ranges[0][0]
        #determine what inclinations were simulated around the incoming i
        ilow = lowiinrange + math.floor((inclAngle-lowiinrange)/\
            inclSpacing)*inclSpacing
        #ilow = math.floor(inclAngle*(1./inclSpacing))/(1./inclSpacing)
        ihigh = ilow+inclSpacing
        #get the idx of the mu/incl in the fullsed
        idxlow = getMuIdx(observ[0], ilow)
        idxhigh = getMuIdx(observ[0], ihigh)
        #get the flux at these inclinations
        flow.append([observ[1][idxlow], observ[2][idxlow]])
        fhigh.append([observ[1][idxhigh], observ[2][idxhigh]])
        #interpolate the Halpha line at the desired inclination
        flux.append([observ[1][idxlow], np.ndarray.tolist(inclInterp(inclAngle,\
            [ilow,ihigh], flow, fhigh))])
        #convolve the flux of the inclination interpolated line
        for values in flux:
            (flux_conv, origData) = gaussconv(values, fac_e, v_h, v_e, plotWave,\
             normFlux, subtractCont)

    else: #If just one inclination is given
        inclIndex = getMuIdx(observ[0], inclAngle)
        flux.append([observ[1][inclIndex],observ[2][inclIndex]])
        #convolve the Halpha line
        for values in flux:
            (flux_conv, origData) = gaussconv(values, fac_e, v_h, v_e, plotWave,\
             normFlux, subtractCont)

    return values[0], flux_conv, origData

#Convolving the halpha line with two Gaussians
def gaussconv(values, fac_e, v_h, v_e, plotWave, normFlux, subtractCont):

    xyParams=findHAlphaLine(list(map(lambda x: x*10**4, values[0])), values[1],
                                            plotWave, normFlux, subtractCont)
    values[0]=xyParams[0] #velocity
    values[1]=xyParams[1] #flux before convolution

    #Adding junk ones to either side of the halpha continuum
    #other gaussfold complains about x and y not being the same
    #length, as lammin and lammax
    #Start by finding the second largest and smallest velocity to extend from
    velo2ndlarg = max(n for n in values[0] if n!=max(values[0]))
    velo2ndsmal = min(n for n in values[0] if n!=min(values[0]))
    #velocity
    values[0].extend(np.linspace(velo2ndlarg+1,24000,10000))
    values[0].extend(np.linspace(-24000, velo2ndsmal-1, 10000))
    #flux
    values[1].extend(np.ones(10000))
    values[1].extend(np.ones(10000))
    #Sort the junk values so that x is in numerically increasing order
    L = sorted(zip(values[0],values[1]), key=operator.itemgetter(0))
    values[0], values[1] = zip(*L)

    notscat_flux = [i*(1-fac_e) for i in values[1]]
    scat_flux = [i*fac_e for i in values[1]]
    notscat_conv = gf(values[0], notscat_flux, v_h)
    scat_conv = gf(values[0], scat_flux, v_e)
    flux_conv = scat_conv + notscat_conv #flux after convolution

    return flux_conv, xyParams

#Checks if the calculated mu angle is within the accepted variance
#and returns the index of that mu as it is in the observers list
def getMuIdx(muAngles, inclAngle):
    for muAng in muAngles:
        if (inclAngle==muAng[0]):
            inclIndex=muAngles.index(muAng)
            break
        elif (muAng==muAngles[-1]):
            print("Observer angle", inclAngle, "does not exist.")
            exit()
    return inclIndex

#Interpolates the flux over at a desired inclination
def inclInterp(inclAngle, inclRange, flow, fhigh):
    flux = interp2d(np.arange(1., len(flow[0][1])+1), inclRange,
                    np.stack((flow[0][1], fhigh[0][1])), kind='linear')

    return flux(np.arange(1., len(flow[0][1])+1), inclAngle)

#Cuts the velocity range to only be within a desired window
def veloWindow(velo, flux, interpFlux, veloUBound, veloLBound):
    idxs = []
    idxs.extend(np.argwhere(velo > veloUBound))
    idxs.extend(np.argwhere(velo < veloLBound))

    velo = np.delete(velo, idxs)
    flux = np.delete(flux, idxs)
    interpFlux = np.delete(interpFlux, idxs)

    return velo, flux, interpFlux

#Cuts the spectrum to within a range of -1500 to +1500 km/s
def trimSpectrum(wavelength, flux):
    minWave=-1500/299792*6564.61+6564.61
    maxWave=1500/299792*6564.61+6564.61

    newWave=[]
    newFlux=[]

    for i in range(len(wavelength)):
        if minWave<=wavelength[i]<=maxWave:
            newWave.append(wavelength[i])
            newFlux.append(flux[i])

    return (newWave, newFlux)

#Computes the equivalent width of a spectral line
def ewcalc(velocity,flux,plotWave,normFlux,subtractCont):
    #Convert from velocity [km/s] to wavelength [angstroms]
    speedOfLight=299792#speed of light in km/s
    h_alpha_wavelength=6564.61#wavelength of H_alpha emission line (angstroms)
    wavelength=list(map(lambda obs: (obs/speedOfLight)*h_alpha_wavelength+\
        h_alpha_wavelength, velocity))

    #define list names
    lambdatable = []
    Hfluxtable = []
    polylambda = []
    polyflux = []

    #manipulates observ to find h-alpha line
    normFlux=False
    plotWave=True
    (wavelength, flux)=trimSpectrum(wavelength, flux)
    xyParams=findHAlphaLine(wavelength, flux, plotWave, normFlux, subtractCont)
    Hfluxtable=xyParams[1]
    lambdatable=xyParams[0]

    for idx, num in enumerate(lambdatable):
        if num<6555 or num>6575:
            polylambda.append(num)
            polyflux.append(Hfluxtable[idx])

    #fit linear polynomial to 'poly' lists
    a = np.polyfit(polylambda, polyflux, 1)
    #normalize every flux value to polynomial 'a'
    normfluxtable = []
    for i in range(0,len(Hfluxtable)):
        normfluxtable.append(Hfluxtable[i]/(a[1]+a[0]*lambdatable[i]))
    #uses eqn(9.59) from carroll and ostille for EW calc (F_c = 1 here)
    ewfluxtable = []
    for i in range(len(normfluxtable)):
        ewfluxtable.append(1-normfluxtable[i])
    #interpolates function of 1-flux over all lambdas
    f = interp.interp1d(lambdatable,ewfluxtable,axis=0,fill_value='extrapolate')
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        #integrates f*dlambda with lambda in chris's fixed integration limits
        #(i.e integral((1-flux)dlambda), lambda = 0.653997 to 0. 658586)
        ew = integrate.quad(f,6539.77,6585.86)
    ew = ew[0]*0.1 #convert ew from angstroms to nanometers
    return ew

#Writes the flux, velocity, and other parameters to a text file for use elsewhere
def writeBestFit(filename, bestIncl, fac_e, v_h, v_e, interpFlux, obsValX,
                ew_fit, bestChi2, bestRedChi2):
    #Make the out folder
    dir0 = os.getcwd()
    savepath = dir0+'/out/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    filename = savepath+filename.split("/")[-1]+".txt"

    #Write to the file
    with open(filename, 'w') as file:
        file.write('%'+filename+'\n')
        file.write('%Date Created:'+datetime.datetime.today()\
            .strftime('%y-%m-%d %H:%M:%S')+'\n')
        file.write('{0:20}{1:20}{2:20}{3:20}{4:20}{5:20}{6:20} \n'\
            .format('Incl [deg]', 'f_e', 'v_h [km/s]', 'v_e [km/s]', 'EW [nm]',\
            'chi2', 'redChi2'))
        file.write('{0:20}{1:20}{2:20}{3:20}{4:20}{5:20}{6:20} \n'.format(\
            str('{0:.5f}'.format(bestIncl)),str('{0:.5f}'.format(fac_e)),\
            str('{0:.5f}'.format(v_h)),str('{0:.5f}'.format(v_e)),\
            str('{0:.5f}'.format(ew_fit)),str('{0:.5f}'.format(bestChi2)),\
            str('{0:.5f}'.format(bestRedChi2))))
        file.write('\n {0:30}{1} \n'\
            .format('%Flux [Normalized]', 'Velocity [km/s]'))
        for idx, val in enumerate(interpFlux):
            towrite='{0:30}{1}'.format(str(interpFlux[idx]), str(obsValX[idx]))
            file.write('%s \n' % towrite)

#Plots the best fitting observ set simulation observ
def pltBestFit(params, inclAngles, ranges, obsValX, obsValY, inclFlag,
                reddeningFiles, luminosity, distance, plotWave, normFlux,
                subtractCont, filename, veloUBound, veloLBound, bestChi2,
                plotOrigLine, replotting, *inclSpacing):
    if inclFlag:
        bestIncl, fac_e, v_h, v_e = params
        simX, simY, origData = getSim(reddeningFiles[0], bestIncl, ranges,
                        luminosity[0], distance, fac_e, v_h, v_e, inclFlag,
                        plotWave, normFlux, subtractCont, inclSpacing)
    else:
        fac_e, v_h, v_e = params
        bestIncl = inclAngles
        simX, simY, origData = getSim(reddeningFiles[0], bestIncl, ranges,
                        luminosity[0], distance, fac_e, v_h, v_e, inclFlag,
                        plotWave, normFlux, subtractCont)

    #Interpolate the flux to match x array of sim to obs
    interpFlux = griddata(np.array(simX),simY,np.array(obsValX),method='linear',
        fill_value=1)

    #Compute the equivalent widths of the observed and simulated lines
    ew_ori=ewcalc(origData[0],origData[1],plotWave,normFlux,subtractCont)
    ew_fit=ewcalc(obsValX,interpFlux,plotWave,normFlux,subtractCont)
    ew_obs=ewcalc(obsValX,obsValY,plotWave,normFlux,subtractCont)
    print('EW Simulation Original:', str('{0:.2f}'.format(ew_ori)))
    print('EW Simulation Fitted:', str('{0:.2f}'.format(ew_fit)))
    print('EW Observed:', str('{0:.2f}'.format(ew_obs)))
    print('Best Fitting Model - Chi-squared:', str('{0:.2f}'\
        .format(bestChi2 * -1)))

    #Getting the reduced chi-squared
    #Interpolate the flux to match x array of sim to obs
    interpFlux = griddata(np.array(simX),simY,np.array(obsValX),
        method='linear',fill_value=1)
    #All chi2 are divided equally by this value
    st_dev = 1
    #Cut the velocity range over which the chi-squared is being computed
    obsValXCut, obsValYCut, interpFluxCut = veloWindow(obsValX,obsValY,\
        interpFlux,veloUBound,veloLBound)
    #Compute the reduced chi-squared (degrees of freedom set to length of params)
    bestRedChi2 = (np.sum(((obsValYCut - interpFluxCut)**2 / (st_dev)**2.)))\
        /(len(interpFluxCut)-len(params))
    print('Best Fitting Model - Reduced Chi-squared:', str('{0:.2f}'\
        .format(bestRedChi2)))

    #Write the best fitting line's flux and wavelength to a file if not replotting
    if not replotting:
        writeBestFit(filename, bestIncl, fac_e, v_h, v_e, interpFluxCut,\
         obsValXCut, ew_fit, bestChi2, bestRedChi2)

    plt.figure(num=None, figsize=(11, 8), dpi=100, facecolor='w', edgecolor='k')
    #Plot the original halpha line before convolution if desired
    if plotOrigLine:
        L = sorted(zip(origData[0],origData[1]), key=operator.itemgetter(0))
        origData[0], origData[1] = zip(*L)
        plt.plot(origData[0],origData[1], color='lightsteelblue', linestyle='--',\
        label='Simulated\nOriginal', linewidth=1.0)
    #Plot the observed observ set to compare
    if plotOrigLine:
        plt.plot(obsValX, obsValY, color='black', label='\nObserved\n1998 (HEROS)'\
            +'\nEW='+str('{0:.2f}'.format(ew_obs))+' nm', linewidth=2.0)
    else:
        plt.plot(obsValX, obsValY, color='black', label='Observed\n1998 (HEROS)'\
            +'\nEW='+str('{0:.2f}'.format(ew_obs))+' nm', linewidth=2.0)
    #Plot the best fitting observ
    plt.plot(obsValX, interpFlux, color='royalblue', label='\nSimulated'\
        +'\n'+r'$i=$ '+str('{0:.2f}'.format(bestIncl))+r'$^{\circ}$'\
        +'\n'+r'$f_e=$'+str('{0:.2f}'.format(fac_e))\
        +'\n'+r'$v_h=$'+str('{0:.2f}'.format(v_h))+' km/s'\
        +'\n'+r'$v_e=$'+str('{0:.2f}'.format(v_e))+' km/s'\
        +'\nEW='+str('{0:.2f}'.format(ew_fit))+' nm'\
        +'\n'+r'$\chi^{2}=$'+str('{0:.2f}'.format(bestChi2*-1)))
    #Plot the boundaries of the line fitting
    plt.plot([veloUBound, veloUBound], [0.5, 1.5], color='black', linestyle='--')
    plt.plot([veloLBound, veloLBound], [0.5, 1.5], color='black', linestyle='--')
    plt.xlim(-1250, 1250)
    #plt.ylim(0.75, 7.5)
    plt.ylim(ymin=0.75)
    plt.xlabel("Velocity [km/s]",fontsize='x-large')
    plt.ylabel("Relative Flux",fontsize='x-large')
    plt.xticks(size='x-large')
    plt.yticks(size='x-large')
    plt.legend(fontsize='x-large')

    plt.savefig(filename + '.png')

#Plots the convergence of the walkers as they step for each parameter
def plotConvergence(npy, filename, ranges, inclFlag):
    converged_idx = 0

    if inclFlag: #If multiple inclinations are given
        linspace = [np.linspace(ranges[0][0], ranges[0][1], 5),
                    np.linspace(ranges[1][0], ranges[1][1], 5),
                    np.linspace(ranges[2][0], ranges[2][1], 5),
                    np.linspace(ranges[3][0], ranges[3][1], 5)]

        param_to_latex = dict(inc=r'$i [^{\circ}$]', f_e=r'$f_{e}$',
                              v_h=r'$v_{h} [km/s]$', v_e=r'$v_{e}$ [km/s]')
        params = ["inc", "f_e", "v_h", "v_e"]
        fig = plt.figure(num=None, figsize=(6, 8), dpi=100, facecolor='w',\
         edgecolor='k')

    else: #If only one inclination is given
        linspace = [np.linspace(ranges[0][0], ranges[0][1], 5),
                    np.linspace(ranges[1][0], ranges[1][1], 5),
                    np.linspace(ranges[2][0], ranges[2][1], 5)]

        param_to_latex = dict(f_e=r'$f_{e}$', v_h=r'$v_{h} [km/s]$',\
         v_e=r'$v_{e} [km/s]$')
        params = ["f_e", "v_h", "v_e"]
        fig = plt.figure(num=None, figsize=(6, 8), dpi=100, facecolor='w',\
         edgecolor='k')

    chain = np.load(npy)

    gs = gridspec.GridSpec(len(params), 3)
    gs.update(hspace=0.25)

    for ii, param in enumerate(params):
        these_chains = chain[:, :, ii]

        max_var = max(np.var(these_chains[:, converged_idx:], axis=1))

        ax1 = plt.subplot(gs[ii, :2])

        ax1.axvline(0, color="#67A9CF", alpha=0.7, linewidth=2)

        for walker in these_chains:
            ax1.plot(np.arange(len(walker)) - converged_idx, walker,
                     drawstyle="steps",
                     color=cm.Blues_r(np.var(walker[converged_idx:]) /max_var),
                     alpha=0.5)

        ax1.set_ylabel(param_to_latex[param], fontsize='xx-large', labelpad=18,
                       rotation="vertical", color=font_color)

        # Don't show ticks on the y-axis
        ax1.yaxis.set_ticks([])

        # For the plot on the bottom, add an x-axis label. Hide all others
        if ii == len(params) - 1:
            ax1.set_xlabel("step number", fontsize='x-large', labelpad=18,
                           color=font_color)
        else:
            ax1.xaxis.set_visible(False)

        ax2 = plt.subplot(gs[ii, 2])

        ax2.hist(np.ravel(these_chains[:, converged_idx:]),
                 bins=np.linspace(ax1.get_ylim()[0], ax1.get_ylim()[1], 20),
                 orientation='horizontal',
                 facecolor="#67A9CF",
                 edgecolor="none",
                 normed=True, histtype='barstacked')

        ax2.xaxis.set_visible(False)
        ax2.yaxis.tick_right()

        ax2.set_yticks(linspace[ii])
        ax1.set_ylim(ax2.get_ylim())

        if ii == 0:
            t = ax1.set_title("Walkers", fontsize='x-large', color=font_color)
            t.set_y(1.01)
            t = ax2.set_title("Posterior", fontsize='x-large', color=font_color)
            t.set_y(1.01)

        ax1.tick_params(axis='x', pad=2, direction='out',
                        colors=tick_color, labelsize='large')
        ax2.tick_params(axis='y', pad=2, direction='out',
                        colors=tick_color, labelsize='large')

        ax1.get_xaxis().tick_bottom()

    fig.subplots_adjust(hspace=0.0, wspace=0.0, bottom=0.10, top=0.93,
                        left=0.12, right=0.87)
    #plt.show()
    plt.savefig(filename + '.png')

#This function is what emcee runs
def lnprob(params, obsValX, obsValY, inclAngles, ranges, inclFlag, reddeningFiles,
            luminosity, distance, plotWave, normFlux, subtractCont, veloUBound,
            veloLBound, *inclSpacing):
    count = 0
    inside_ranges = True
    #This ensures that only values within the given parameter ranges are used
    while inside_ranges * (count < len(params)):
        inside_ranges = (params[count] >= ranges[count, 0]) *\
            (params[count] <= ranges[count, 1])
        count += 1
    if inside_ranges:
        #Simulation observ
        if inclFlag:
            inclAngles, fac_e, v_h, v_e = params
        else:
            fac_e, v_h, v_e = params

        simX, simY, origData = getSim(reddeningFiles[0], inclAngles, ranges,
                            luminosity[0], distance, fac_e, v_h, v_e, inclFlag,
                            plotWave, normFlux, subtractCont, inclSpacing)

        #Interpolate the flux to match x array of sim to obs
        interpFlux = griddata(np.array(simX),simY,np.array(obsValX),\
            method='linear',fill_value=1)

        #All chi2 are divided equally by this value
        st_dev = 1

        #Cut the velocity range over which the chi-squared is being computed
        obsValX, obsValY, interpFlux = veloWindow(obsValX,obsValY,interpFlux,\
            veloUBound,veloLBound)
        chi2 = np.sum(((obsValY - interpFlux)**2 / (st_dev)**2.))

        return -1 * chi2

    else:
        return -np.inf

# MAIN PART OF THE SCRIPT-------------------------------------------------------
def run(filename, a_parameter, nwalk, nstep, nburn, fac_e, v_e, v_h, inclFlag,
    inclAngles, reddeningFiles, plot_Rivi, luminosity, distance,
    plotWave, normFlux, subtractCont, veloUBound, veloLBound, plotOrigLine,
    *inclSpacing):

    # Getting the observed observ-----------------------------------------------
    obsValX, obsValY = plotRiviData() #x = velo y = flux

    # emcee stuff beyond here---------------------------------------------------
    if inclFlag:
        ranges = np.array([inclAngles, fac_e, v_h, v_e])
        ndim = 4
    else:
        ranges = np.array([fac_e, v_h, v_e])
        ndim=3

    #First guess of parameters
    p0 = [np.random.rand(ndim) * (ranges[:, 1] - ranges[:, 0]) +
            ranges[:, 0] for i in range(nwalk)]
    start_time = time.time()

    with Pool() as pool:
        if inclFlag:
            sampler = emcee.EnsembleSampler(nwalk, ndim, lnprob, args=[obsValX,
            obsValY, inclAngles, ranges, inclFlag, reddeningFiles, luminosity,
            distance, plotWave, normFlux, subtractCont, veloUBound, veloLBound,
            inclSpacing], a=a_parameter, pool=pool)
        else:
            sampler = emcee.EnsembleSampler(nwalk, ndim, lnprob, args=[obsValX,
            obsValY, inclAngles, ranges, inclFlag, reddeningFiles, luminosity,
            distance, plotWave, normFlux, subtractCont, veloUBound, veloLBound],
            a=a_parameter, pool=pool)

        # Running the Burn-In---------------------------------------------------
        print("Running burn-in with " + str(nburn) + " walkers ################")

        pos, prob, state = sampler.run_mcmc(p0, nburn, progress=True)

        print("--- Completed in %s minutes ---" % (str('{0:.2f}'.format((time\
            .time() - start_time) / 60))))
        af_bi = np.mean(sampler.acceptance_fraction)
        print("Mean acceptance fraction (Burn-In): ", str('{0:.2f}'\
            .format(af_bi)))
        sampler.reset()

        # Running MCMC----------------------------------------------------------
        print("Running MCMC ############################################")
        sampler.run_mcmc(pos, nstep, rstate0=state, progress=True)

        print("--- Completed in %s minutes ---" % (str('{0:.2f}'.format((time\
            .time() - start_time) / 60))))
        af = np.mean(sampler.acceptance_fraction)
        print("Mean acceptance fraction (MCMC): ", str('{0:.2f}'.format(af)))
        #print("Mean autocorrelation time: {0:.3f} steps"\
        #.format(np.mean(sampler.get_autocorr_time())))

    #Getting the chain and flattening
    chain = sampler.chain
    flatchain = chain.reshape((-1, ndim))

    #best fit parameters
    maxprob_index = np.argmax(prob)

    #Get the best parameters and their respective errors
    params_fit = pos[maxprob_index]
    errors_fit = [sampler.flatchain[:, i].std() for i in range(ndim)]

    # Saving the chain----------------------------------------------------------
    dir0 = os.getcwd()
    savepath = dir0+'/vars/chains/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    chain = sampler.chain
    chain_npy = savepath+filename+'_af'+str('{0:.2f}'.format(af))+"_chain.npy"
    np.save(chain_npy, chain)

    # Saving the prob and pos af------------------------------------------------
    savepath = dir0+'/vars/probs/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    probs_npy = savepath+filename+'_af'+str('{0:.2f}'.format(af))+"_prob.npy"
    np.save(probs_npy, prob)

    savepath = dir0+'/vars/pos/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    pos_npy = savepath+filename+'_af'+str('{0:.2f}'.format(af))+"_pos.npy"
    np.save(pos_npy, pos)

    savepath = dir0+'/vars/af/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)
    af_npy = savepath+filename+'_af'+str('{0:.2f}'.format(af))+"_af.npy"
    np.save(af_npy, af)

    # Corner Plotting-----------------------------------------------------------
    savepath = dir0+'/figures/'
    if not os.path.exists(savepath):
        os.makedirs(savepath)

    if inclFlag:
        labels = [r'$i$', r'$f_e$', r'$v_h$', r'$v_e$']
    else:
        labels = [r'$f_e$', r'$v_h$', r'$v_e$']
    quantiles = [0.16, 0.5, 0.84]
    figure = corner(flatchain, labels=labels, range=ranges, quantiles=quantiles,
            plot_contours=True, smooth=2., smooth1d=False, plot_datapoints=True,
            label_kwargs={'fontsize': 17},title_kwargs={'fontsize': 17},
            truths=None, show_titles=True, color_hist='black', plot_density=True,
            fill_contours=False, no_fill_contours=False, normed=True)
    figure.savefig(savepath+filename+'_af'+str('{0:.2f}'\
        .format(af))+"_corner.png")

    # Convergence Plotting-----------------------------------------------------------
    plotConvergence(chain_npy, savepath+filename+'_af'+str('{0:.2f}'.format(af))\
        +'_convergence', ranges, inclFlag)

    # Halpha Plotting----------------------------------------------------------------
    replotting=False
    if inclFlag:
        pltBestFit(params_fit, inclAngles, ranges, obsValX, obsValY, inclFlag,
                reddeningFiles, luminosity, distance, plotWave, normFlux,
                subtractCont, savepath+filename+'_af'+str('{0:.2f}'.format(af))\
                +'_halpha', veloUBound, veloLBound, np.max(prob), plotOrigLine,
                replotting, inclSpacing)
    else:
        pltBestFit(params_fit, inclAngles, ranges, obsValX, obsValY, inclFlag,
                reddeningFiles, luminosity, distance, plotWave, normFlux,
                subtractCont, savepath+filename+'_af'+str('{0:.2f}'.format(af))\
                +'_halpha', veloUBound, veloLBound, np.max(prob), plotOrigLine,
                replotting)

    print("Fitting complete ########################################")
    print("--- Completed in %s minutes ---" % (str('{0:.2f}'.format((time.time()\
     - start_time) / 60))))


import requests

locations = ('London', 'SVO', 'Cherepovets')

params = {
    "nMTq": "",
    "lang": "ru"
}

for loc in locations:
    url = f"https://wttr.in/{loc}"
    response = requests.get(url, params=params)
    response.raise_for_status()
    print(response.text)


#!/usr/bin/python3

from subprocess import Popen, PIPE
from datetime import date, datetime

# {{{ Only for poezio plugin
try:
    from plugin import BasePlugin
    import common
    import tabs
except:
    pass
else:
    class Plugin(BasePlugin):
        """Plugin for poezio"""
        def init(self):
            self.add_tab_command(
                tabs.MucTab,
                'np',
                self.command_np,
                "Отправляет в конфу сообщение о прослушиваемой композиции"
            )

        def command_np(self, args):
            args = " ".join(common.shell_split(args))  # костыль
            mes = get_np_message(get_np_info())
            if not args:
                r = "{}.".format(mes)
            else:
                a = args.strip()
                if a[0] not in ('.,!:;?…'):
                    a = " " + a
                r = "{}{}".format(mes, a)
            self.core.send_message(r)
# }}} Only for poezio plugin

def isfeminine(word):
    if word in ("антологии", "песню",
                "композицию", "инструментальную композицию"):
        return True
    else:
        return False

def get_np_info():
    # TODO: use dbus here except of runnig a shell command
    cmd = 'deadbeef --nowplaying-tf "{}"'
    OPTIONS = ("artist", "title", "year", "genre", "albumartist",
               "album", "composer", "comment", "releasetype",
               "playback_time_remaining_seconds", "length_seconds",
               "releasedate")
    DELIMITER = " -=- "
    fmt = DELIMITER.join("%{}%".format(x) for x in OPTIONS)
    out, err = Popen(cmd.format(fmt), shell=True,
                     stdout=PIPE, stderr=PIPE).communicate()
    x = out.decode("utf-8").split(DELIMITER)
    t = {}
    for field in OPTIONS:
        t[field] = x.pop(0)
    t["reltype"] = t["releasetype"]
    return t

def istracknoname(t):
    title = t["title"].lower().strip()
    if title in ("intro", "outro", "instrumental", "untitled") or not title:
        return True
    else:
        return False

def istracksamename(t):
    if t['title'].lower() == t['artist'].lower():
        return True
    else:
        return False

def get_what(t):
    genre = t["genre"].lower().strip()
    title = t["title"].lower().strip()
    x = title.split() or ['']
    firstword, lastword = x[0].strip("()[]"), x[-1].strip("()[]")

    if 'clas' in genre:
        st = "композицию"
    elif any(x in genre for x in ('ambient', 'noise', 'drone', "instrumental")):
        st = "трек"
    elif lastword == 'instrumental' or "instrumental" in t["comment"].lower():
        st = "инструментальную композицию"
    elif "intro" in (lastword, firstword):
        st = "интро"
    elif "outro" in (lastword, firstword):
        st = "аутро"
    else:
        st = "песню"

    if istracknoname(t):
        if st not in ("интро", "аутро"):
            nn = "безымянную " if isfeminine(st) else "безымянный "
        else:
            nn = ""
        return nn + st
    elif istracksamename(t):
        nn = "одноименную " if isfeminine(st) else "одноименный "
        return nn + st
    else:
        return " ".join((st, "«{}»".format(t["title"])))

def isalbumnoname(t):
    if t['album'].lower() in ('demo', "split"):
        return True
    else:
        return False

def isalbumsamename(t):
    if t['title'].lower() == t['album'].lower():
        return True
    else:
        return False

def guess_reltype(t):
    if t['albumartist'].lower() == "va" \
            or 'various' in t['albumartist'].lower() \
            or t['albumartist'].count(" & ") > 4:
        return "Compilation"
    if " & " in t["albumartist"] and t['artist'] == t['albumartist']:
        return "Collaboration"
    if 0 < t['albumartist'].count(" & ") < 5:
        return "Split"
    if "class" in t['genre'].lower():
        return "None"
    return "Album"

def get_from(t):
    RTYPES = {"demo": "демо",
              "anthology": "антологии",
              "ep": "EP",
              "album": "альбома",
              "compilation": "сборника",
              "split": "сплита",
              "collaboration": "совместного альбома",
              "single": "сингла"}

    if t["reltype"]:
        reltype = t["reltype"].lower()
    else:
        reltype = guess_reltype(t).lower()

    if reltype in RTYPES:
        relstring = RTYPES[reltype]
    elif t["reltype"]:
        relstring = t["reltype"]

    noname = isalbumnoname(t)
    samename = isalbumsamename(t)

    result = []

    # Предлог
    if reltype in ("split", "compilation") and not noname and not samename:
        result.append("со")
    else:
        result.append("с")

    # Прилагательные
    if samename:
        result.append("одноименной" if isfeminine(relstring)
                      else "одноименного")
    if noname:
        result.append("безымянной" if isfeminine(relstring)
                      else "безымянного")

    # Существительное
    result.append(relstring)

    # Дополнение (для сплитов)
    if reltype == "split":
        artists = t['albumartist'].split(' & ')
        artist_is_on_split = t['artist'] in artists
        if artist_is_on_split:
            artists.remove(t['artist'])
        s = " и ".join(artists)
        if s:
            result.append("с " + s)

    # Название
    if not noname and not samename:
        if reltype == "split":
            result.append("под названием")
        result.append("«{}»".format(t["album"]))

    return " ".join(result)

def get_when(t):
    # FIXME: this function is too complex and ugly
    cur_year = date.today().year
    try:
        albyear = int(t["year"])
    except:
        pass
    else:
        if albyear == cur_year - 1:
            t["year"] = "прошлого"
        elif albyear == cur_year - 2:
            t["year"] = "позапрошлого"

    when = " {} года".format(t["year"])
    reldate = t.get("releasedate")
    if reldate:
        try:
            reldate = datetime.strptime(reldate, "%Y-%m-%d")
        except:
            reldate = None
    if reldate:
        today = date.today()
        if today.month == reldate.month:
            if today.day < reldate.day:
                when = ", который ещё не вышел"
            elif today.day - reldate.day == 0:
                when = ", вышедшего сегодня"
            elif today.day - reldate.day == 1:
                when = ", вышедшего вчера"
            elif today.day - reldate.day == 2:
                when = ", вышедшего позавчера"
            else:
                _, thisweek, _ = today.isocalendar()
                _, relweek, _ = reldate.isocalendar()
                if thisweek == relweek:
                    when = ", вышедшего на этой неделе"
                elif thisweek - relweek == 1:
                    when = ", вышедшего на прошлой неделе"
    return when

def get_np_message(t):
    if t is None:
        return "/me ничего не слушает"
    if 'clas' in t['genre'].lower():
        res = ("{action} {composer}, " +
               "композицию «{title}» в исполнении {artist} {year} года")
    else:
        res = "{action} {artist}, {what} {from}{when}"

    t["action"] = "слушает"
    t["what"] = get_what(t)
    t["from"] = get_from(t)
    t["when"] = get_when(t)

    # TODO:
    # if float(t["playback_time_remaining_seconds"]) < 30 \
    #         and float(t["length_seconds"]) > 120:
    #     t["action"] = "дослушивает"

    return "/me " + res.format(**t)

if __name__ == "__main__":
    print(get_np_message(get_np_info()))


import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib, Gdk
from random import shuffle

def gtk_populate_threaded_treeview(tracks, treeview, liststore):

    Gdk.threads_enter()
    treeview.set_sensitive(False)
    Gdk.threads_leave()

    Gdk.threads_enter()
    treeview.set_model(None)
    Gdk.threads_leave()

    Gdk.threads_enter()
    treeview.freeze_child_notify()
    Gdk.threads_leave()

    liststore.clear()
    liststore.set_default_sort_func(lambda *unused: 0)
    liststore.set_sort_column_id(-1, Gtk.SortType.ASCENDING)

    for track in tracks:
        liststore.append(track)

    Gdk.threads_enter()
    treeview.set_model(liststore)
    Gdk.threads_leave()

    Gdk.threads_enter()
    treeview.thaw_child_notify()
    Gdk.threads_leave()

    Gdk.threads_enter()
    treeview.set_sensitive(True)
    Gdk.threads_leave()

def gtk_dialog_info(parent, text1, text2=None, icon=None):

    dialog = Gtk.MessageDialog(parent,
                               Gtk.DialogFlags.MODAL,
                               Gtk.MessageType.INFO,
                               Gtk.ButtonsType.CLOSE,
                               text1)

    if icon is not None:
        dialog.set_icon_from_file(icon)

    if text2 is not None:
        dialog.format_secondary_text(text2)

    dialog.run()
    dialog.destroy()

def gtk_get_selected_cells_from_selection(gtk_selection, column=0):
    model, treepaths = gtk_selection.get_selected_rows()
    return [model[treepath][column] for treepath in treepaths]

def gtk_get_first_selected_cell_from_selection(gtk_selection, column=0):

    model, treepaths = gtk_selection.get_selected_rows()

    if treepaths==[]:
        return None

    return model[treepaths[0]][column]

def gtk_get_iter_from_liststore_cell(gtk_liststore, cell_value, column=0):

    treeiter = gtk_liststore.get_iter_first()
    while treeiter != None:
        if gtk_liststore.get_value(treeiter, column) == cell_value:
            return treeiter

        treeiter=gtk_liststore.iter_next(treeiter)

    return None

def gtk_liststore_has_value(gtk_liststore, cell_value, column=0):

    for row in gtk_liststore:
        if row[column]==cell_value:
            return True

    return False

def gtk_select_row_from_cell(gtk_treeview, column, cellvalue, safe_thread=False):

    gtk_liststore=gtk_treeview.get_model()
    gtk_selection=gtk_treeview.get_selection()

    if cellvalue is None:
        liststore_iter=gtk_liststore.get_iter_first()
    else:
        liststore_iter=gtk_get_iter_from_liststore_cell(gtk_liststore, cellvalue, column)

        if liststore_iter is None:
            liststore_iter=gtk_liststore.get_iter_first()

    if liststore_iter is not None: # when a liststore is empty
        if not safe_thread:
            GLib.idle_add(gtk_selection.select_iter, liststore_iter)
        else:
            gtk_selection.select_iter(liststore_iter)

def gtk_shuffle_treeview(gtk_treeview):
    """
        It is not possible to use `liststore.reorder()` because
        the treeview is sorted.
    """

    gtk_treeview.set_sensitive(False)
    gtk_treeview.freeze_child_notify()

    gtk_liststore=gtk_treeview.get_model()
    gtk_treeview.set_model(None)

    gtk_liststore.set_default_sort_func(lambda *unused: 0)
    gtk_liststore.set_sort_column_id(-1, Gtk.SortType.ASCENDING)

    rows=[tuple(row) for row in gtk_liststore]
    shuffle(rows)

    gtk_liststore.clear()
    for row in rows:
        gtk_liststore.append(row)

    gtk_treeview.set_model(gtk_liststore)
    gtk_treeview.set_sensitive(True)
    gtk_treeview.thaw_child_notify()

def gtk_treeview_selection_is_okay(treeview, event):
    """
        When an user do a right click on a treeview, if click
        was not inside the selection, the selection will change.
    """

    try:
        pointing_treepath=treeview.get_path_at_pos(event.x, event.y)[0]
    except:
        return True

    treeview_selection=treeview.get_selection()

    # if the iter is not in the selected iters, remove the previous selection
    _, treepaths = treeview_selection.get_selected_rows()

    if not pointing_treepath in treepaths:
        treeview_selection.unselect_all()
        treeview_selection.select_path(pointing_treepath)

def gtk_get_selected_cells_from_iconview_selection(gtk_iconview, row=0):

    cells_data=[]
    liststore=gtk_iconview.get_model()

    for item in gtk_iconview.get_selected_items():
        treeiter = liststore.get_iter(item)
        if treeiter is not None:
            cells_data.append(liststore.get_value(treeiter, row))

    return cells_data


import mock
import pickle
import unittest

from soundwave import dashboard_api

class TestRequestErrors(unittest.TestCase):
  def testClientErrorPickleable(self):
    error = dashboard_api.ClientError(
        'api', {'status': '400'}, 'You made a bad request!')
    error = pickle.loads(pickle.dumps(error))
    self.assertIsInstance(error, dashboard_api.ClientError)
    self.assertEqual(error.request, 'api')
    self.assertEqual(error.response, {'status': '400'})
    self.assertEqual(error.content, 'You made a bad request!')

  def testServerErrorPickleable(self):
    error = dashboard_api.ServerError(
        'api', {'status': '500'}, 'Oops, I had a problem!')
    error = pickle.loads(pickle.dumps(error))
    self.assertIsInstance(error, dashboard_api.ServerError)
    self.assertEqual(error.request, 'api')
    self.assertEqual(error.response, {'status': '500'})
    self.assertEqual(error.content, 'Oops, I had a problem!')

class _FakeCommunicator(dashboard_api.PerfDashboardCommunicator):
  def __init__(self):
    # pylint: disable=super-init-not-called
    # Intentionally not calling parent's __init__ to skip API authorization.
    mock.patch.object(self, '_MakeApiRequest').start()

class TestDashboardCommunicator(unittest.TestCase):
  def setUp(self):
    self.api = _FakeCommunicator()

  def testGetTimeseries_success(self):
    self.api._MakeApiRequest.return_value = {'some': 'data'}
    self.assertEqual(self.api.GetTimeseries('test_path'), {'some': 'data'})

  def testGetTimeseries_missingPathReturnsNone(self):
    self.api._MakeApiRequest.side_effect = dashboard_api.ClientError(
        'api', {'status': '400'}, '{"error": "Invalid test_path foo"}')
    self.assertIsNone(self.api.GetTimeseries('foo'))

  def testGetTimeseries_serverErrorRaises(self):
    self.api._MakeApiRequest.side_effect = dashboard_api.ServerError(
        'api', {'status': '500'}, 'Something went wrong. :-(')
    with self.assertRaises(dashboard_api.ServerError):
      self.api.GetTimeseries('bar')

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


"""
A class representing a block in the game.

	Attributes:
		id (int): The unique ID of the block.
		cells (dict): A dictionary of cell positions for each rotation state of the block.
		cell_size (int): The size of each cell in the block.
		row_offset (int): The row offset of the block from the top of the screen.
		column_offset (int): The column offset of the block from the left of the screen.
		rotation_state (int): The current rotation state of the block.
		colors (dict): A dictionary of colors for each block ID.
"""

import pygame
from colors import Colors
from position import Position

class Block:
	def __init__(self, id):
		self.id = id
		self.cells = {}
		self.cell_size = 30
		self.row_offset = 0
		self.column_offset = 0
		self.rotation_state = 0
		self.colors = Colors.get_cell_colors()

	def move(self, rows, columns):
		self.row_offset += rows
		self.column_offset += columns

	def get_cell_positions(self):
		tiles = self.cells[self.rotation_state]
		moved_tiles = []
		for position in tiles:
			position = Position(position.row + self.row_offset, position.column + self.column_offset)
			moved_tiles.append(position)
		return moved_tiles

	def rotate(self):
		self.rotation_state += 1
		if self.rotation_state == len(self.cells):
			self.rotation_state = 0

	def undo_rotation(self):
		self.rotation_state -= 1
		if self.rotation_state == -1:
			self.rotation_state = len(self.cells) - 1

	def draw(self, screen, offset_x, offset_y):
		tiles = self.get_cell_positions()
		for tile in tiles:
			tile_rect = pygame.Rect(offset_x + tile.column * self.cell_size,
				offset_y + tile.row * self.cell_size, self.cell_size -1, self.cell_size -1)
			pygame.draw.rect(screen, self.colors[self.id], tile_rect)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Sep  9 20:18:21 2018

@author: sadra
"""

import numpy as np

import matplotlib
matplotlib.use('Agg')

import pylab

from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.collections import PatchCollection

### Internal imports
import sys
sys.path.append('..')

def visualize_X_hull_eps(s,iteration,xmin=-0.12,xmax=0.12,ymin=-1,ymax=1,xlabel='angle',ylabel='angular velocity',title="inverted pendulum with wall"):
    fig,ax1 = plt.subplots()
    ax1.set_xlabel(xlabel)
    ax1.set_ylabel(ylabel)
    ax1.set_xlim([xmin,xmax])
    ax1.set_ylim([ymin,ymax])
    p_list=[]
    for state in s.X[0:s.tree_size[iteration]]:
        p_list.append(patches.Polygon(vertices_hull_eps(s,[state]+[state.successor[0]]), True))
    p=PatchCollection(p_list,color=(0.4,0.4,0.4))
    ax1.add_collection(p)
    ax1.grid(color=(0,0,0), linestyle='--', linewidth=0.3)
    ax1.set_title(title+" tree iteration: %d"%iteration)
    fig.savefig('figures/ptree_%d.png'%iteration, dpi=100)
    return plt

def vertices_hull_eps(s,list_of_states):
    """
    Convex hull computation of list of states
    """
    PV=np.empty((0,s.n))
    for p in list_of_states:
        PV=np.vstack((PV,p.vertices_eps+p.x.T))
    hull=ConvexHull(PV)
    return PV[hull.vertices,:]

def visualize_push_box(x,t,xmin=0,xmax=10,ymin=-3,ymax=3,xlabel='x',ylabel='y',title="planar pushing"):
    fig,ax1 = plt.subplots()
    #fig=plt.figure(figsize=(8,5),dpi=80, facecolor='w', edgecolor='k')
    ax1.set_xlabel(xlabel)
    ax1.set_ylabel(ylabel)
    ax1.set_xlim([xmin,xmax])
    ax1.set_ylim([ymin,ymax])
    v=np.array([[-0.2, -0.2],[-0.2,  0.2],[0.2, 0.2],[0.2,  -0.2]])*3
    theta=x[2]
    R=np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]]).reshape((2,2))
    v_box=np.dot(R,v.T)+x[0:2,:]
    # Trajectories
    p=patches.Polygon(v_box[:,:].T, True)
    p=PatchCollection([p],color=(0.9,0.4,0.3))
    ax1.add_collection(p)
    ax1.grid(color=(0,0,0), linestyle='--', linewidth=0.3)
    ax1.set_title(title)
    alpha=2
    c_point=x[0:2,:]+np.dot(R,np.array([-0.7,6*np.asscalar(x[3])]).reshape((2,1)))
    f_point=x[4:,:]*alpha
    ax1.arrow(np.asscalar(c_point[0]-f_point[0]),np.asscalar(c_point[1]-f_point[1]),np.asscalar(f_point[0]),np.asscalar(f_point[1]),head_width=0.2)
    fig.savefig('figures/planar_pushing_%d.png'%t, dpi=100)
    return fig

for iteration in range(1,s.tree_iterations):
    fig=visualize_X_hull_eps(s,iteration)
    #fig.savefig('planar_pushing_bizim_%d.png'%t, dpi=100)


import os#import os
import cv2#import opencv
import numpy as np #import numpy
from PIL import Image#import pillow
from pathlib import Path#require read path
p = Path()

absolutepath =  str(p.absolute()).replace('\\', '/')+'/python'
recognizer = cv2.face.LBPHFaceRecognizer_create()#define opencv LBPH recognizer
path = absolutepath +'/dataset'
if not os.path.exists(absolutepath +'/lbph_recognizer'):#check if the file exist
    os.makedirs(absolutepath +'/lbph_recognizer')

#train image with with align the macth with its label name pattern
def getImagesWithID(path):
	imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
	faces = []#init variable
	IDs = []#init variable
	for imagePath in imagePaths:#read all existing image
		faceImg = Image.open(imagePath).convert('L')#converting image to greyscale
		faceNp = np.array(faceImg,'uint8')#encode face image to unit8 array
		ID = int(os.path.split(imagePath)[-1].split('.')[1])
		#split the name pattern from User.1.12 take the middle value(id)
		faces.append(faceNp)#take the encoded value push into the faces array
		IDs.append(ID)#take the extracted id from image files name push to IDs array
		#cv2.imshow("training",faceNp)
		cv2.waitKey(10)
	return np.array(IDs), faces

Ids, faces = getImagesWithID(path)#call to extract image data from dataset folder
recognizer.train(faces,Ids)#LBPH Training process
recognizer.save(absolutepath + '/lbph_recognizer/trainingData.yml')#save trained file as yml
print("data trained")
cv2.destroyAllWindows()#exit cv


from nltk.probability import HeldoutProbDist
from pandas.io.parsers import read_csv
from sklearn.utils.validation import check_non_negative
import tweepy
from textblob import TextBlob
from wordcloud import WordCloud
import pandas as pd
import numpy as np
import re
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

df = pd.read_csv('cleaned_combined_df.csv')
df.head()

tweetText_df = df.drop('User', 1).drop('Handle', 1).drop('LikeCount', 1).drop('Crypto', 1).drop('PostDates', 1).drop('PostTimes', 1)
tweetText_df.head()

def getSubjectivity(text):
    return TextBlob(text).sentiment.subjectivity

def getPolarity(text):
    return TextBlob(text).sentiment.polarity

tweetText_df['Subjectivity'] = tweetText_df['TweetText'].apply(getSubjectivity)
tweetText_df['Polarity'] = tweetText_df['TweetText'].apply(getPolarity)

tweetText_df.head(50)

#create function to compute positive, neutral and negative analysis

def getAnalysis(score):
    if score < 0:
         return 'Negative'
    elif score == 0:
        return 'Neutral'
    else:
        return 'Positive'

tweetText_df['Analysis'] = tweetText_df['Polarity'].apply(getAnalysis)
tweetText_df.head(50)

# percentage negative tweets
ntweets = tweetText_df[tweetText_df.Analysis == 'Negative']
ntweets = ntweets['TweetText']
ntweets

round( (ntweets.shape[0] / df.shape[0]) * 100, 1)

# percentage positive tweets
ptweets = tweetText_df[tweetText_df.Analysis == 'Positive']
ptweets = ptweets['TweetText']
ptweets

round( (ptweets.shape[0] / df.shape[0]) * 100 , 1)

# percentage neutral tweets
ptweets = tweetText_df[tweetText_df.Analysis == 'Neutral']
ptweets = ptweets['TweetText']
ptweets

round( (ptweets.shape[0] / df.shape[0]) * 100 , 1)

# Plotting and visualizing the counts
plt.title('Sentiment Analysis')
plt.xlabel('Sentiment')
plt.ylabel('Counts')
tweetText_df['Analysis'].value_counts().plot(kind = 'bar')
plt.show()

tweetText_df['Analysis'].value_counts()

# make a csv file of sentiment analysis
tweetText_df = tweetText_df.to_csv('Tweet_sentiment_analysis.csv', index=False, encoding='utf8')


import sqlite3
import http

from __init__ import *

from Database import Database
from home.HomeController import HomeController

def getWindows(room):
	db = Database()
	cursor = db.getCursor()
	windows = []
	cursor.execute('''
	SELECT
		name as name,
		ipaddress as ipaddress,
		upcommand as upcommand,
		downcommand as downcommand,
		stopcommand as stopcommand
	FROM window
	WHERE room_id=:room_id
	''', { 'room_id': room.getId() })
	for row in cursor:
		windows.append(Window(row, room))

	return windows

class EditWindowView:
	def __init__(self, room, window=None):
		self.room = room
		self.window = window

	def addToBox(self, box):
		name = None
		ipaddress = None
		up = None
		down = None
		stop = None
		if self.window is not None:
			name = self.window.name
			ipaddress = self.window.ipaddress
			up = self.window.upCommand
			down = self.window.downCommand
			stop = self.window.stopCommand

		addWindowForm = gz.Box(box, layout='grid', width='fill', height='fill')
		gz.Text(addWindowForm, text='Name:', grid=[0,0], align='right')
		self.name = gz.TextBox(addWindowForm, grid=[1,0], align='left', text=name, width=15)
		gz.Text(addWindowForm, text='IP Address:', grid=[0,1], align='right')
		self.ipaddress = gz.TextBox(addWindowForm, grid=[1,1], align='left', text=ipaddress, width=15)
		gz.Text(addWindowForm, text='Up Command:', grid=[0,2], align='right')
		self.up = gz.TextBox(addWindowForm, grid=[1,2], align='left', text=up, width=15)
		gz.Text(addWindowForm, text='Down Command:', grid=[0,3], align='right')
		self.down = gz.TextBox(addWindowForm, grid=[1,3], align='left', text=down, width=15)
		gz.Text(addWindowForm, text='Stop Command:', grid=[0,4], align='right')
		self.stop = gz.TextBox(addWindowForm, grid=[1,4], align='left', text=stop, width=15)
		gz.PushButton(addWindowForm, text='Save', grid=[0,5,2,1], command=self.saveWindow)

	def saveWindow(self):
		db = Database()
		cursor = db.getCursor()
		values = {
			'name': self.name.value,
			'ipaddress': self.ipaddress.value,
			'upcommand': self.up.value,
			'downcommand': self.down.value,
			'stopcommand': self.stop.value,
			'room_id': self.room.getId()
		}
		if self.window is not None:
			values['original_name'] = self.window.name
			cursor.execute('''
				UPDATE window
				SET
					name=:name,
					ipaddress=:ipaddress,
					upcommand=:upcommand,
					downcommand=:downcommand,
					stopcommand=:stopcommand
				WHERE
					room_id=:room_id AND
					name=:original_name
				''', values)
		else:
			cursor.execute('''
				INSERT INTO window
				(room_id, name, ipaddress, upcommand, downcommand, stopcommand)
				VALUES
				(:room_id, :name, :ipaddress, :upcommand, :downcommand, :stopcommand)
			''', values)
		cursor.connection.commit()
		self.room.view()

class Window:
	def __init__(self, row, room):
		self.seconds = 200
		self.room = room
		self.name = row['name']
		self.ipaddress = row['ipaddress']
		self.upCommand = row['upcommand']
		self.downCommand = row['downcommand']
		self.stopCommand = row['stopcommand']

	def postToBlindsController(self,command,seconds=None):
		conn = http.client.HTTPConnection(self.ipaddress)
		path = '/%d'%command
		if seconds is not None: path += '/%d'%seconds
		print('Carlos, sending: %s'%path)
		conn.request("POST", path)
		res = conn.getresponse()
		if res.status != 200:
			print("Bad response: %d"%res.status)
		else:
			print('Successfully performed the command!')

	def up(self): self.postToBlindsController(self.upCommand, self.seconds)
	def down(self): self.postToBlindsController(self.downCommand, self.seconds)
	def stop(self): self.postToBlindsController(self.stopCommand)
	def edit(self):
		HomeController().changeView(EditWindowView(self.room, self))
	def delete(self): print('not implemented')


import requests
from bs4 import BeautifulSoup
import os
import re
import time

last_page = int(input("请输入不要爬的页数："))
for i in range(1, last_page+1):
    if i == 1:
        # 主页地址
        url = "https://www.53pic.com/bizhi/dongman/"
        # print(url)
    else:
        url = "https://www.53pic.com/bizhi/dongman/index_%s.html" % str(i)
        # url.replace("2", str(i))
        # print(url)
        i += 1

# url = "https://www.53pic.com/bizhi/dongman/index_3.html"
# -----------------1、拿到主页面源代码，找到href提取子链接----------------------
gain_home = requests.get(url)
# 处理解析后的乱码
gain_home.encoding = "utf-8"
# print(gain_home.text)

# -------2、通过herf拿到子页面内容，从子页面中找到图片下载地址   <img src=”“>------

son_link = BeautifulSoup(gain_home.text, "html.parser")
son_link_list = son_link.find_all(name="a", attrs={"class": "title-content"})
for a in son_link_list:
    # print(son_link_list)  测试代码
    # ---------------------------------3、下载图片------------------------------
    # 获取到子页面链接
    son_link = "https://www.53pic.com" + a.get("href")
    # print(son_link)
    # 从子页面中拿到页面源代码
    son_code = requests.get(son_link)
    # 处理解析后的乱码
    son_code.encoding = "utf-8"
    son_code_text = son_code.text
    # print(son_code_text)
    wallpaper_link = BeautifulSoup(son_code_text, features="html.parser")
    ing_url_info = wallpaper_link.find(name="div", attrs={"id": "showimgXFL", "class": "cl mbv"})
    ing_url = ing_url_info.find("img")
    img = ing_url.get("src")  # 获取src属性值
    print(img)
    bz = requests.get(img)
    name = img.split("/")[-1]
    os.chdir(r"C:\Users\崔泽\Desktop\mig")
with open(name, mode='wb+') as file:
    file.write(bz.content)
    time.sleep(1)
# a = os.getcwd()
# print(a)
print("%s下载成功！" % img)

爬虫/爬取没图库壁纸.py


from os import walk
import logging
from typing import List

import json

from pathlib import Path

def isProjectFile(filename: Path) -> bool:
    return filename.suffix in [".py", ".ui", ".qss", ".qrc"]

def regenerateProject():
    fl = open("MatCal.pyproject", 'w')
    filesList: List[str] = ["MatCal.py"]
    # for dir in ["compilers", "designer", "generators", "resources", "src", "utils"]:
    for dir in ["resources", "src"]:
        for root, dirs, files in walk(dir):
            if len(files):
                for i in files:
                    if isProjectFile(Path(i)):
                        filesList.append(root + '/' + i)
    contents = json.dumps({"files": filesList})
    # print(filesList)
    # print(contents)
    # print(logging.getLogger())
    logging.info(f"Regenerating project contents: {contents}")
    fl.write(contents)


# -*- coding: utf-8 -*-0
"""
Created on Fri Dec 18 05:47:36 2020

@author: Piotr.Idzik and Maria Paszkiewicz
Puzzle 18 from https://adventofcode.com/2020/day/18

Part 1:
Rather than evaluating multiplication before addition, the operators have the
same precedence, and are evaluated left-to-right regardless of the order in which
they appear.

Part 2:
Now, addition and multiplication have different precedence levels, but they're not
the ones you're familiar with. Instead, addition is evaluated before multiplication.

Before you can help with the homework, you need to understand it yourself.
Evaluate the expression on each line of the homework; what is the sum of the
resulting values?
"""

def get_data():
    with open('input.txt', 'r') as in_file:
        data_str = in_file.read()
    return data_str.split('\n')

def get_val(in_str):
    def is_number(in_str):
        res = True
        try:
            int(in_str)
        except ValueError:
            res = False
        return res
    piece_list = in_str.split(' ')
    res_val = 0
    op_dict = {'+': lambda a, b: a+b, '*': lambda a, b: a*b}
    cur_val = None
    cur_op = None
    res_val = None
    piece_num = 0
    while piece_num < len(piece_list):
        cur_piece = piece_list[piece_num]
        if is_number(cur_piece):
            cur_val = int(cur_piece)
            piece_num += 1
        elif cur_piece in op_dict:
            cur_op = op_dict[cur_piece]
            piece_num += 1
        elif cur_piece[0] == '(':
            tmp_piece_num = piece_num
            tmp_count = 0
            while tmp_piece_num < len(piece_list):
                tmp_count += piece_list[tmp_piece_num].count('(')
                tmp_count -= piece_list[tmp_piece_num].count(')')
                if ')' in piece_list[tmp_piece_num]:
                    if tmp_count == 0:
                        break
                tmp_piece_num += 1
            assert tmp_piece_num < len(piece_list)
            tmp_str = ' '.join(piece_list[piece_num:tmp_piece_num+1])
            cur_val = get_val(tmp_str[1:-1])
            piece_num = tmp_piece_num+1
        if cur_val and cur_op:
            res_val = cur_op(res_val, cur_val)
            cur_op = None
            cur_val = None
        elif cur_val and not res_val and not cur_op:
            res_val = cur_val
            cur_val = None
    return res_val

def get_val_2(in_str):
    piece_list = in_str.split(' ')
    for cur_piece_num in range(1, len(piece_list)-1):
        if '+' in piece_list[cur_piece_num]:
            piece_list[cur_piece_num-1] = '(' + piece_list[cur_piece_num-1]
            piece_list[cur_piece_num+1] = piece_list[cur_piece_num+1] + ')'
    tmp_str = ' '.join(piece_list)
    return eval(tmp_str)

assert get_val('5 + 6') == 11
assert get_val('1 + (2 * 3) + (4 * (5 + 6))') == 51
assert get_val('2 * 3 + (4 * 5)') == 26
assert get_val('((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2') == 13632
assert get_val_2('((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2') == 23340

# Part 1
RES1 = sum(get_val(_) for _ in get_data())
print(RES1)

# Part 2
RES2 = sum(get_val_2(_) for _ in get_data())
print(RES2)