import datetime
import threading
import tkinter as tk
import os
from config import SpectraConfig
from pybaselines import Baseline
from matplotlib import gridspec
from scipy.signal import find_peaks
import pvlib
import pytz
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, \
    NavigationToolbar2Tk
# Implement the default Matplotlib key bindings.
from matplotlib.figure import Figure
from jsonparser import JsonParser
from calibration import Calibrator
from tkinter.messagebox import showerror, showinfo
import matplotlib.pyplot as plt

class CaliApp(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.create_widgets()
        self.peaks_detected = False
        self.data = []
        self.pixel_xvals = []
        self.threadnm = ""
        self.savepath = ""
        self.active = ""
        self.threadnm = "digi"
        self.ax1_lines = []
        self.ax2_lines = []
        self.cal_wv = []
        self.cal_pix = []
        self.wave_range = []
        self.peak_is_found = False
        self.spectra = []
        self.wavelength = []
        plt.rcParams['xtick.major.size'] = 0
        plt.rcParams['ytick.major.size'] = 0
        plt.rcParams['xtick.minor.size'] = 0
        plt.rcParams['ytick.minor.size'] = 0

    def create_widgets(self):
        self.top_frame = tk.Frame(self)
        self.tbframe = tk.LabelFrame(self.top_frame, padx = 0, pady = 0)
        self.tbframe.grid(row=0, column=0)

        self.plotframe = tk.LabelFrame(self.top_frame, padx=3, pady=10)
        self.plotframe.grid(row=1, column=0)
        screen_dpi = 350
        self.parent.update()
        plot_width = int(0.9 * (self.parent.winfo_width() / screen_dpi))
        plot_height = int(0.9 * (self.parent.winfo_height() / screen_dpi))
        self.fig = Figure(figsize=(plot_width, plot_height), dpi=screen_dpi)
        gs = gridspec.GridSpec(nrows=4, ncols=5, figure=self.fig)

        self.ax = self.fig.add_subplot(gs[0:2, :4], picker=True)

        self.calax = self.fig.add_subplot(gs[1:3, 4:5])
        self.calax.tick_params(labelsize=3, labelrotation = 45)
        self.ax.tick_params(labelsize=5)
        self.mwax = self.fig.add_subplot(gs[2:4, :4], picker=True)
        self.ax.tick_params(labelsize=5, axis='x')
        self.ax.xaxis.set_ticks_position('top')

        self.calax.yaxis.set_ticks_position('right')
        self.mwax.tick_params(labelsize=5)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.plotframe)
        self.canvas.get_tk_widget().grid(row=0, column=0)
        self.cid = self.canvas.mpl_connect('button_press_event', self.onclick)
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.tbframe)
        self.toolbar.update()
        self.listframe = tk.LabelFrame(self.top_frame, padx=20, pady=16)
        self.listframe.grid(row=1, column=1)
        self.spectralist = tk.Listbox( self.listframe, height=plot_height * 10, font=( "Helvetica", 12))
        self.spectralist.pack(side="left", fill="x")
        self.scrollbar = tk.Scrollbar(self.listframe, orient="vertical")
        self.scrollbar.config(command=self.spectralist.yview)
        self.scrollbar.pack(side="left", fill="y")
        # self.populate_list()
        self.spectralist.bind('<Double-1>', self.on_list_select)

        ####

        self.commandframe = tk.LabelFrame(self.top_frame, padx=15, pady=15)
        self.commandframe.grid(row=2, column=0)
        # Plot
        self.pbutton = tk.Button( self.commandframe, text="Show", command=lambda: self.plot_spectra(), \
                                 padx=10, pady=4, font=( "Helvetica", 16))
        self.pbutton.grid(row=0, column=1)
        self.orig_pcolor = self.pbutton.cget("background")
        # self.pbutton['state'] = tk.DISABLED

       # Calibrate
        self.cbutton = tk.Button( self.commandframe, text="Calibrate", command=self.calibrate_sp,\
                                  padx=10, pady=4, font=( "Helvetica", 16))
        self.cbutton.grid(row=0, column=2)

        self.hscale_var = tk.DoubleVar()
        self.hscale_var.set(50)
        self.hscaler = tk.Scale( self.plotframe, from_=1, to=100, resolution = 0.0001, command=self.scaleSpectra, \
                                variable=self.hscale_var, orient=tk.HORIZONTAL, length=300)
        self.hscaler.grid(row=1, column=0)

        self.sbutton = tk.Button( self.commandframe, text="Save", command=self.save_adjusted_sp, padx=5, pady=4, font=( "Helvetica", 16))
        self.sbutton.grid(row=0, column=3)
        self.szabutton = tk.Button( self.commandframe, text="showSZA", command=self.showSZA, padx=5, pady=4, font=( "Helvetica", 16))
        self.szabutton.grid(row=0, column=0)
       # Quit
        self.qbutton = tk.Button( self.commandframe, text="Quit", command=self.quit, padx=5, pady=4, font=( "Helvetica", 16))
        self.qbutton.grid(row=0, column=4)
        # Progress
        self.settingframe = tk.LabelFrame(self.commandframe, padx=5, pady=5)
        self.settingframe.grid(row=0, column=5)
        self.peakframe = tk.LabelFrame(self.settingframe, padx=5, pady=5)
        self.peakframe.grid(row=0, column=0)
        self.peakbutton = tk.Button( self.peakframe, text="Peaks", command=self.find_peaks,\
                                     padx=5, pady=4, font=( "Helvetica", 16))
        self.peakbutton.grid(row=0, column=0)
        self.checkvar3 = tk.IntVar()
        self.checkvar3.set(0)
        self.picks_max = tk.Checkbutton( self.peakframe, text='Detect maximas   ', \
                                        variable=self.checkvar3, onvalue=1, offvalue=0, command=self.peak_mode)
        self.picks_max.grid(row=0, column = 1)

        self.baselineframe = tk.LabelFrame(self.settingframe, padx=5, pady=5)
        self.baselineframe.grid(row=1, column=0)
        self.sbutton = tk.Button( self.baselineframe, text="Baseline",\
                                  command=self.detect_baseline, padx=5, pady=4, font=( "Helvetica", 16))
        self.sbutton.grid(row=0, column=0)
        self.checkvar1 = tk.IntVar()
        self.poly_checkbtn = tk.Radiobutton( self.baselineframe, text='Poly', variable=self.checkvar1, value=1)
        self.checkvar1.set(0)
        self.poly_checkbtn.grid(row=0, column=1)
        self.morpth_checkbtn = tk.Radiobutton( self.baselineframe, text='Morph', variable=self.checkvar1, value=0)
        self.morpth_checkbtn.grid(row=0, column=2)
        self.top_frame.pack()
        # self.span_select = SpanSelector( self.mwax, self.on_pltselect, 'horizontal', useblit=True, rectprops=dict( alpha=0.5, facecolor='red'), button=3)

    def quit(self):
        self.parent.quit()     # stops mainloop
        self.parent.destroy()  # this is necessary on Windows to prevent crash

    def calibrate_sp(self):
        config = SpectraConfig.read_conf()
        self.sp_date = datetime.datetime.strptime(config['spectra.conf']['Date'], '%d/%m/%Y')
        self.stime = datetime.datetime.strptime(config['spectra.conf']['Starttime'], '%H:%M')
        self.etime = datetime.datetime.strptime(config['spectra.conf']['Endtime'], '%H:%M')
        self.start_dt = datetime.datetime.combine(self.sp_date.date(), self.stime.time())
        self.end_dt = datetime.datetime.combine(self.sp_date.date(), self.etime.time())
        self.latlon = np.array(config['spectra.conf']['Latitude/Longitude'].split(','), dtype=float)
        current_datetime = datetime.datetime.combine(self.sp_date.date(), self.stime.time())
        end_datetime = datetime.datetime.combine(self.sp_date.date(), self.etime.time())
        time_increment = datetime.timedelta(minutes=1)
        datetime_array = []
        print(current_datetime)
        timezone = 'Europe/Zurich'

        # Determine if daylight saving time is in effect for the given date
        tz = pytz.timezone(timezone)
        is_dst = tz.localize(current_datetime).dst() != datetime.timedelta(0)

        # Set tcorr based on whether it's daylight saving time
        tcorr = +2 if is_dst else +1

        while current_datetime <= end_datetime:
            tz = pytz.timezone(timezone)
            localized_datetime = tz.localize(current_datetime)
            datetime_array.append(localized_datetime + datetime.timedelta(hours=tcorr))
            current_datetime += time_increment

        nlat, wlon = (46.55, -7.98)
        latitude = nlat
        longitude = wlon
        altitude = 3580  # meters
        sza = pvlib.solarposition.get_solarposition(datetime_array, latitude, longitude, altitude)

        self.aimass_selec = pvlib.location.Location(latitude = latitude, longitude = longitude, altitude = altitude)\
                .get_airmass(datetime_array,solar_position=sza, model='kastenyoung1989')
        self.sza_selec = sza.zenith.values
        self.spectrum = (self.spectrum - np.min(self.morph_baseline)) / (np.max(self.morph_baseline) - np.min(self.morph_baseline))
        #self.spectrum = (self.spectrum) / (self.img_shape[0])
        cl_fname = f'{self.sp_range[0]}_{self.sp_range[1]}' + '_cal_lines.dat'
        cl_path = os.path.join(self.savepath, cl_fname)
        self.threadnm = "cali"
        #peaks_detected = False  # Flag to track if peak detection has been done
        try:
            if not self.peaks_detected and os.path.isfile(cl_path) and os.path.getsize(cl_path) > 0:
                self.calibrator = Calibrator(cl_path, self.spectrum)
                self.spec = self.calibrator.y2
                self.spectra = self.calibrator.y2
                self.wavelength = self.calibrator.xcal
                self.plot_spectra()
            elif self.peaks_detected or len(self.ax1_lines) != 0:
                self.cal_wv = self.ax1_lines
                self.cal_pix = self.ax2_lines
                if len(self.cal_wv) == len(self.cal_pix) and len(self.cal_pix) > 0:
                    with open(cl_path, 'w') as f:
                        for i, j in zip(self.cal_wv, self.cal_pix):
                            f.write('%4.2f %4.1f\n' % (i, j))
                        f.close()
                    self.calibrator = Calibrator(cl_path, self.spectrum)
                    self.spec = self.calibrator.y2
                    self.spectra = self.calibrator.y2
                    self.wavelength = self.calibrator.xcal
                    self.plot_spectra()
                elif len(self.cal_wv) != len(self.cal_pix):
                    showerror(title='Error', message=f'Calibration data size \
                              mismatch (sim {len(self.cal_wv)} != dig \
                              {len(self.cal_pix)}). Please ensure the detected\
                              peaks match.')
        except IOError:
            print('No calibration file found')

    def start_multip_thread(self, threadnm):

        self.threadnm = threadnm
        if threadnm == "cali":
            self.g_thread = threading.Thread(target=self.calibrate_sp)
            self.cbutton['state'] = tk.DISABLED
        self.g_thread.daemon = True
        # self.progressbar.start()
        self.g_thread.start()
        self.parent.after(20, self.check_g_thread)

    def check_g_thread(self):
        if self.g_thread.is_alive():
            self.parent.after(20, self.check_g_thread)
        else:
            # self.progressbar.stop()
            self.populate_list()

    def populate_list(self):

        jsparser = JsonParser(self.savepath, [])
        try:
            self.data = jsparser.read_json('spectra_file.json')
        except FileNotFoundError:
            self.data = []
        if self.threadnm == "cali":
            self.spectralist.delete(0, tk.END)
            self.cbutton['state'] = tk.DISABLED
            for dx in self.data:
                self.spectralist.insert(tk.END, dx.calsp_name)
            self.ax.clear()
            self.canvas.draw()

        if self.threadnm == "digi":
            self.spectralist.delete(0, tk.END)
            for dx in self.data:
                self.spectralist.insert(tk.END, dx.img_name)

    def on_list_select(self, event):

        self.active = self.spectralist.get(tk.ACTIVE)
        self.threadnm = "digi"
        if self.data:
            for od in self.data:
                if self.active == od.calsp_name and self.threadnm == "cali":
                    self.sp_selected = od.calsp_name
                    self.sp_range = od.sp_range
                    print(img_size)
                if self.active == od.img_name and self.threadnm == "digi":
                    self.sp_digi = od.sp_name
                    self.sp_range = od.sp_range
                    self.img_shape = od.img_shape
            if self.threadnm == "cali":
                self.pbutton['state'] = "normal"

                self.ax.clear()
                self.mwax.clear()
                self.calax.clear()
                self.ax1_lines = []
                self.ax2_lines = []
                self.canvas.draw_idle()
            elif self.threadnm == "digi":
                self.threadnm = "digi"
                # self.populate_list()
                self.ax.clear()
                self.mwax.clear()
                self.calax.clear()
                self.ax1_lines = []
                self.ax2_lines = []
                self.ini_plot()

    def ini_plot(self):
        self.threadnm = "digi"
        self.mwax.clear()
        self.ax.clear()
        try:
            simulated_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),'simulated.npz')
            simulated_data = np.load(simulated_path)
            self.ftir_wv= simulated_data['simulated_wn']
            self.ftir_in= simulated_data['simulated_in']
            self.selectedftir_wv = self.ftir_wv[(self.ftir_wv > ( self.sp_range[0] )) & (self.ftir_wv < (self.sp_range[1] ))]
            self.selectedftir_in = self.ftir_in[(self.ftir_wv < ( self.sp_range[1] )) & (self.ftir_wv > (self.sp_range[0] ))]
            self.savepath = SpectraConfig.read_conf()['spectra.conf']['spectrapath']

            self.spectrum = np.loadtxt( os.path.join( self.savepath, self.sp_digi), skiprows=0)
            self.pixel_xvals = np.arange(len(self.spectrum))

            self.ax.plot( self.selectedftir_wv, self.selectedftir_in, 'r', linewidth=0.7)
            self.ax.set_ylim(self.mwax.get_ylim()[::-1])
            self.mwaxline, = self.mwax.plot(self.pixel_xvals, self.spectrum, linewidth=0.7)
            #self.mwax.set_ylim(self.mwax.get_ylim()[::-1])
            self.mwax.set_ylim(0, self.img_shape[0])
            self.ax.invert_yaxis()
            #self.mwax.invert_yaxis()
            label_fontsize = 4
            self.ax.set_xlabel('Wavenumber $cm^{-1}$', fontsize = label_fontsize)
            self.ax.xaxis.set_label_position("top")
            self.mwax.set_xlabel('Pixel index', fontsize = label_fontsize)
            self.calax.set_xlabel('Pixel index', fontsize = label_fontsize)
            self.ax.set_ylabel('Intensity', fontsize = label_fontsize, rotation = 90)
            self.mwax.set_ylabel('Pixel index', fontsize = label_fontsize, rotation = 90)
            self.calax.set_ylabel('Wavenumber $cm^{-1}$', fontsize = label_fontsize, rotation = 90)
            self.calax.yaxis.set_label_position("right")

            self.canvas.draw_idle()
        except FileNotFoundError as fne:
            print(f"File Not found {fne}")

    def plot_spectra(self):
        self.ax.clear()
        self.calax.clear()
        self.pbutton.config(bg=self.orig_pcolor)
        if self.threadnm == "digi":
            self.populate_list()
        # get selected spectra and plot
        elif self.threadnm == "cali":
            try:
                self.ax.plot(self.selectedftir_wv, self.selectedftir_in, 'r', linewidth=0.7)
                self.axline, = self.ax.plot( self.wavelength, self.spec, linewidth=0.7)
                self.hscaler.configure( from_=np.min( self.wavelength), to=np.max( self.wavelength), resolution=0.001)
                self.mean_wv = (np.min(self.wavelength) +
                                np.max(self.wavelength)) / 2
                self.hscale_var.set(int(self.mean_wv))
                self.calax.plot(self.cal_pix, self.cal_wv, '.', picker = 3, markersize = 3)
                self.canvas.draw_idle()
            except FileNotFoundError:
                print('File not found')
    def showSZA(self):
        self.ax.clear()
        try:
            cal_wn,calibrated = np.load(os.path.join('Calibrated.npy'), allow_pickle = True)
            sim_wn,simulated = np.load(os.path.join('Simulated.npy'), allow_pickle = True)
            sza_range = np.load(os.path.join('SZA_range.npy'), allow_pickle = True)
            #air_range = np.load(os.path.join('AirMass.npy'), allow_pickle = True)
            cal_wn, calibrated = self.reduce_points(cal_wn, calibrated)
            posx =[cal_wn[int(i)] for i in np.arange(0, len(cal_wn),len(cal_wn)/len(sza_range))]
            xSza = [str(round(sza, 2)) for sza in np.flip(sza_range)]
            #xAir = [str(round(air, 2)) for air in np.flip(air_range)]
            #self.szax.set_xticks(posx, xSza)
            self.ax.plot(cal_wn, calibrated, label = 'calibrated' , linewidth=0.7)
            self.ax.plot(sim_wn, simulated, label = 'simulated', linewidth=0.7)
            #ax.set_xticks(cal_wn,xcal_wn, rotation=55)
            [self.ax.annotate(sza, (px, 1.01), size=2, rotation = 65) for sza,px in zip(xSza, posx)]
            #[self.ax.annotate(air, (px, 0.01), size=2, rotation = 65) for air,px in zip(xAir, posx)]
            [self.ax.axvline(x=px, color='lightgray', linewidth = 0.5) for px in posx]
            self.ax.set_ylim(0,1.2)
            #self.canvas.draw_idle()
            self.canvas.draw()
        except FileNotFoundError as fnf:
            showerror(title='Error', message='Files not found!')
            print(f"error is {fnf}") # details in console

    def detect_baseline(self):
        try:
            baseline_fitter = Baseline(np.arange(len(self.spectrum)))
            if (self.checkvar1.get() == 1):
                self.poly_baseline = baseline_fitter.modpoly(self.spectrum, poly_order=3)[0]
                print(np.min(self.selected_baseline))
            elif (self.checkvar1.get() == 0):
                self.morph_baseline = baseline_fitter.mor(self.spectrum, half_window=30)[0]
            else:
                pass
            #self.mwax.clear()
            self.mwax.plot(self.morph_baseline, linewidth=0.7, color = 'black')
            self.canvas.draw_idle()
        except AttributeError:
            self.pbutton.config(bg='light blue')

    def peak_mode(self):
        if self.checkvar3.get() == 0:
            print('Mode: detect minimas')
        elif self.checkvar3.get() == 1:
            print('Mode : detect maximas')
        else:
            pass
    def find_peaks(self):
        self.index = 0
        try:
            if self.checkvar3.get() == 0:
                self.digi_peaks, _ = find_peaks((-1)*self.spectrum + np.max(self.spectrum), prominence=self.digi_prom, distance =100)
                self.sim_peaks, _ = find_peaks((-1)*self.selectedftir_in + np.max(self.selectedftir_in), prominence=self.sim_prom)
            elif self.checkvar3.get() == 1:
                self.digi_peaks, _ = find_peaks(self.spectrum, prominence=self.digi_prom)
                self.sim_peaks, _ = find_peaks(self.selectedftir_in, prominence=self.sim_prom)
            self.sim_xpeaks = [self.sim_peaks, self.selectedftir_wv[self.sim_peaks]]
            self.digi_xpeaks = [self.digi_peaks, self.pixel_xvals[self.digi_peaks]]
            self.smax, = self.ax.plot(self.sim_xpeaks[1], self.selectedftir_in[self.sim_peaks], 'x', picker=3, markersize=3)
            self.dgax, = self.mwax.plot(self.digi_xpeaks[1], self.spectrum[self.digi_peaks], 'x', picker=3, markersize=3)
            self.ax1_lines = np.asarray(self.sim_xpeaks[1])
            self.ax2_lines = np.asarray(self.digi_xpeaks[1])
            self.peak_is_found = True

            # Plotting peak indices
            #for i, peak_wavenumber in enumerate(self.sim_xpeaks[1]):
            #    self.ax.text(peak_wavenumber, self.selectedftir_in[self.sim_peaks[i]], str(i), fontsize=3, verticalalignment='bottom', horizontalalignment='center')

           # for i, peak_pixel in enumerate(self.digi_xpeaks[1]):
           #     self.mwax.text(peak_pixel, self.spectrum[self.digi_peaks[i]], str(i), fontsize=3, verticalalignment='bottom', horizontalalignment='center')

        except AttributeError:
            showerror(title='Error', message='Define detection boundary -> Right click')

        self.peaks_detected = True
        self.canvas.draw_idle()

    def show_selected(self):
        try:
            baseline_fitter = Baseline(np.arange(len(self.spectrum)))
            if (self.checkvar1.get() == 1):
                self.selected_baseline = baseline_fitter.modpoly(self.spectrum, poly_order=3)[0]
            elif (self.checkvar1.get() == 0):
                self.selected_baseline = baseline_fitter.mor(self.spectrum, half_window=30)[0]
            else:
                pass
        except:
            pass

    def onclick(self, event):
        if event.dblclick:
            self.peak_is_found = True
            if event.inaxes == self.ax:
                self.ax1_lines = np.append(self.ax1_lines, event.xdata)
                self.ax1l = self.ax.vlines(self.ax1_lines, 0, 1, linestyle='solid', linewidth=0.5)
                self.canvas.draw_idle()
            elif event.inaxes == self.mwax:
                self.ax2_lines = np.append(self.ax2_lines,event.xdata)
                self.ax2l = self.mwax.vlines( self.ax2_lines, 0, 1, transform=self.mwax.get_xaxis_transform(), linestyles='solid', linewidth=0.5)
                self.canvas.draw_idle()
            else:
                pass
        else:
            if event.button == 3:
                if event.inaxes == self.ax:
                    self.sim_prom = event.ydata
                    self.ay1l = self.ax.axhline(y=self.sim_prom, linestyle='solid', linewidth=0.5)
                    self.canvas.draw_idle()
                elif event.inaxes == self.mwax:
                    self.digi_prom = event.ydata
                    self.ay2l = self.mwax.axhline(y=self.digi_prom, linestyle='solid', linewidth=0.5)
                    self.canvas.draw_idle()

            if event.button == 2:
                if event.inaxes == self.ax:
                    idx_1 = self.find_nearest_peak(self.sim_xpeaks[1], event.xdata)
                    self.sim_xpeaks[0] = np.delete(self.sim_xpeaks[0], idx_1)
                    self.sim_xpeaks[1] = np.delete(self.sim_xpeaks[1], idx_1)
                    self.smax.set_data(self.sim_xpeaks[1], self.selectedftir_in[self.sim_xpeaks[0]])
                    self.canvas.draw_idle()
                    self.ax1_lines = self.sim_xpeaks[1]
                elif event.inaxes == self.mwax:
                    idx_2 = self.find_nearest_peak(self.digi_xpeaks[1], event.xdata)
                    self.digi_xpeaks[0] = np.delete(self.digi_xpeaks[0], idx_2)
                    self.digi_xpeaks[1] = np.delete(self.digi_xpeaks[1], idx_2)
                    self.dgax.set_data(self.digi_xpeaks[1], self.spectrum[self.digi_xpeaks[0]])
                    self.canvas.draw_idle()
                    self.ax2_lines = self.digi_xpeaks[1]
            else:
                pass
    def scaleSpectra(self, dummy):
        if self.threadnm == "cali":
            hscale_value = self.hscaler.get()
            x_vals = self.wavelength * (hscale_value / self.mean_wv) #+ hscale_value_p / self.mean_wv
            self.axline.set_xdata(x_vals)
            self.canvas.draw_idle()
        else:
            print("First plot spectra to scale")

    def find_nearest_peak(self, arr, val):
        arr = np.asarray(arr)
        idx = (np.abs(arr - val)).argmin()
        return idx

    def reduce_points(self, xo, yo,res=0.0258):
        yn = []
        xmin, xmax = np.min(xo), np.max(xo)
        xn = np.linspace(xmin, xmax, int((xmax-xmin)/res))
        for x in xn:
            yn.append(np.median(yo[(xo > x-res/2) & (xo < x+res/2)]))
        return xn, yn

    def save_adjusted_sp(self):
        self.date_time_obj = (datetime.datetime.combine(self.sp_date.date(),self.stime.time()))

        #self.sza = float(90) - get_altitude(float(self.latlon[0]), float(self.latlon[1]), self.date_time_obj)
        self.print_sfit_readable_spectrum(self.sza_selec[0], d = self.date_time_obj)

    def print_sfit_readable_spectrum(self, sza=63.0, latlon=(46.55, 7.98), d=datetime.datetime(1951, 4, 15, 7, 30, 0),\
                                     res=0.25, apo='TRI', sn=100.0, rearth=6377.9857):
        #try:
        new_line = np.hstack(self.axline.get_xdata())
        spc = np.hstack(self.spectra)
        new_line, spc = self.reduce_points(new_line, spc)
        wvn_bounds = [np.min(new_line), np.max(new_line)]
        dt_str = d.strftime('%d%m%Y%H%M%S')
        #fname = os.path.join(self.savepath, '{:.2f}_{:.2f}_calibrated.dat'.format(wvn_bounds[0],wvn_bounds[1]))
        fname = os.path.join(self.savepath, 'jfj_{}_calibrated.dat'.format(dt_str))
        #pdb.set_trace()
        s = ' %4.2f  %8.4f  %4.2f  %5.2f  %5i\n'%(sza, rearth, 46.55, 7.89 , sn)
        s = s + d.strftime(' %Y %m %d %H %M %S\n')
        s = s + d.strftime(' %d/%m/%Y, %H:%M:%S')+', RES=%5.4f  APOD FN = %3s\n'%(res, apo)
        s = s + ' %7.3f %7.3f %11.10f %7i'%(wvn_bounds[0], wvn_bounds[1], (wvn_bounds[1]-wvn_bounds[0])/float(len(spc)), len(spc))
        for i in spc:
            s+='\n %8.5f'%(i)
            with open(fname, 'w') as f:
                f.write(s)
        showinfo(title='Saved', message= f'Successfully saved {fname}')
        np.save('Calibrated', [new_line, spc])
        np.save('SZA_range', self.sza_selec)
        self.aimass_selec.to_csv('AIRMASS.dat')
        #np.save('AirMass', self.sza_selec.AirMass)
        np.save('Simulated', [self.selectedftir_wv,self.selectedftir_in])
        #except:
        #    showerror(title='Save Error', message='Can\'t save file')

if __name__ == "__main__":
    root = tk.Tk()
    width = root.winfo_screenwidth()
    height = root.winfo_screenheight()
    root.resizable(False, False)
    root.title("Spectra Digitizer")
    root.geometry("{}x{}".format(
        int(width - 0.2 * width), int(height - 0.2 * height)))
    CaliApp(root).pack()
    root.mainloop()


# 显示原始图像和增强后的图像
import tensorflow as tf
from matplotlib import pyplot as plt
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import numpy as np

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)

image_gen_train = ImageDataGenerator(
    rescale=1. / 255,
    rotation_range=45,
    width_shift_range=.15,
    height_shift_range=.15,
    horizontal_flip=False,
    zoom_range=0.5
)
image_gen_train.fit(x_train)
print("xtrain",x_train.shape)
x_train_subset1 = np.squeeze(x_train[:12])
print("xtrain_subset1",x_train_subset1.shape)
print("xtrain",x_train.shape)
x_train_subset2 = x_train[:12]  # 一次显示12张图片
print("xtrain_subset2",x_train_subset2.shape)

fig = plt.figure(figsize=(20, 2))
plt.set_cmap('gray')
# 显示原始图片
for i in range(0, len(x_train_subset1)):
    ax = fig.add_subplot(1, 12, i + 1)
    ax.imshow(x_train_subset1[i])
fig.suptitle('Subset of Original Training Images', fontsize=20)
plt.show()

# 显示增强后的图片
fig = plt.figure(figsize=(20, 2))
for x_batch in image_gen_train.flow(x_train_subset2, batch_size=12, shuffle=False):
    for i in range(0, 12):
        ax = fig.add_subplot(1, 12, i + 1)
        ax.imshow(np.squeeze(x_batch[i]))
    fig.suptitle('Augmented Images', fontsize=20)
    plt.show()
    break;


#!/usr/bin/env python
import shelve
import os
import sys
from itertools import chain
from doze import url
import json
import logging
import requests
import requests_cache
import json
from wsgiref.simple_server import make_server
from webob.dec import wsgify
from webob import Response
import webbrowser

requests_cache.install_cache()

USERNAME=os.environ['USERNAME']
PLAYLIST=os.environ['PLAYLIST']
CLIENT_ID=os.environ['CLIENT_ID']
CLIENT_SECRET=os.environ['CLIENT_SECRET']
REDIRECT_URI='http://local.ericmoritz.name:8000/'

STATE=shelve.open('.state')

logging.basicConfig(level=logging.INFO)

accounts_service = url('https://accounts.spotify.com')
spotify_service = url('https://api.spotify.com/v1')
playlist_resource = spotify_service.users(USERNAME).playlists(PLAYLIST).tracks

def lines(filenames):
    return chain.from_iterable(
        open(fn)
        for fn in filenames
    )

def _spotify_get(url, *args, **kwargs):
    logging.info("Getting {}".format(url))
    kwargs['headers'] = dict(auth_headers(), **kwargs.get('headers', {}))
    return json.loads(
        requests.get(
            str(url),
            *args, **kwargs
        ).content
    )

def _spotify_put(url, *args, **kwargs):
    logging.info("PUT {} with {!r}".format(url, kwargs.get('data')))
    kwargs['headers'] = dict(auth_headers(), **kwargs.get('headers', {}))
    r = requests.put(
        url,
        *args, **kwargs
    )
    r.raise_for_status()
    return r

def _spotify_post(url, *args, **kwargs):
    logging.info("POST {} with {!r}".format(url, kwargs.get('data')))
    kwargs['headers'] = dict(auth_headers(), **kwargs.get('headers', {}))
    r = requests.post(
        url,
        *args, **kwargs
    )
    r.raise_for_status()
    return r

def are_tokens_still_ok():
    tokens = STATE.get('tokens', {})
    return bool(tokens)

def io_oauth_dance():
    webbrowser.open(str(
        accounts_service.authorize(
            client_id=CLIENT_ID,
            response_type='code',
            scope='playlist-modify-public playlist-modify-private',
            redirect_uri=REDIRECT_URI,
        )
    ))

    @wsgify
    def callback(req):
        r = requests.post(
            str(accounts_service.api.token),
            data={
                "grant_type": 'authorization_code',
                "code": req.GET['code'],
                "redirect_uri": REDIRECT_URI,
                "client_id": CLIENT_ID,
                "client_secret": CLIENT_SECRET,
            }
        )
        STATE['tokens']=json.loads(r.content)
        STATE.sync()
        return Response("authorized, go back to the terminal")

    httpd = make_server('', 8000, callback)
    httpd.handle_request()

def auth_headers():
    return (
        ('Authorization', 'Bearer {}'.format(STATE['tokens']['access_token'])),
    )

def test_tokens():
    if not are_tokens_still_ok():
        return False

    data = _spotify_get(spotify_service.me)
    logging.info("Hello {display_name}".format(**data))
    return True

def chunk(s, n):
    return [s[x:x+n] for x in range(0,len(s),n)]

def io_find_album(albumName):
    logging.info(u"Searching for {}".format(albumName))
    return _spotify_get(
        spotify_service.search(
            q=albumName.encode('utf-8'),
            type='album'
        )
    ).get('albums', {}).get('items', [])

while not test_tokens():
    io_oauth_dance()

if len(sys.argv) > 1:
    source = lines(sys.argv[1:])
else:
    source = sys.stdin

album_urls = [
    album['href']
    for line in source
    for album in io_find_album(
        json.loads(line)['fullAlbumName']
    )
]

tracks = [
    track['uri']
    for url in album_urls
    for track in _spotify_get(url).get('tracks', {}).get('items', [])
]

_spotify_put(
    str(playlist_resource),
    data=json.dumps({'uris': []}),
    headers={'Content-Type': 'application/json'}
)

for c in chunk(tracks, 100):
    _spotify_post(
        str(playlist_resource),
        data=json.dumps({'uris': c}),
        headers={'Content-Type': 'application/json'}
    )


"""1514. Path with Maximum Probability (Difficulty: Medium).
https://leetcode.com/problems/path-with-maximum-probability/

You are given an undirected weighted graph of n nodes (0-indexed), represented by an edge list
where edges[i] = [a, b] is an undirected edge connecting the nodes a and b with a probability
of success of traversing that edge succProb[i].

Given two nodes start and end, find the path with the maximum probability of success to go from start to end
and return its success probability.

If there is no path from start to end, return 0.
Your answer will be accepted if it differs from the correct answer by at most 1e-5.

Example 1:
https://assets.leetcode.com/uploads/2019/09/20/1558_ex1.png
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
Output: 0.25000
Explanation: There are two paths from start to end,
one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25.

Example 2:
https://assets.leetcode.com/uploads/2019/09/20/1558_ex2.png
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
Output: 0.30000

Example 3:
https://assets.leetcode.com/uploads/2019/09/20/1558_ex2.png
Input: n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
Output: 0.00000
Explanation: There is no path between 0 and 2.

Constraints:
    2 <= n <= 10^4
    0 <= start, end < n
    start != end
    0 <= a, b < n
    a != b
    0 <= succProb.length == edges.length <= 2*10^4
    0 <= succProb[i] <= 1
    There is at most one edge between every two nodes."""
import collections
import heapq

class Solution1514:
    def maxProbability(self, n: int, edges: list[list[int]], succProb: list[float], start_node: int,
                       end_node: int) -> float:              # Dijkstra's Algorithm
        adjacency = collections.defaultdict(list)
        for i in range(len(edges)):
            source, distance = edges[i]
            adjacency[source].append([distance, succProb[i]])
            adjacency[distance].append([source, succProb[i]])

        visited = set()
        max_heap = [(-1, start_node)]

        while max_heap:
            probability, node = heapq.heappop(max_heap)
            visited.add(node)

            if node == end_node:
                return probability * -1
            for neighbour, edge_probability in adjacency[node]:
                if neighbour not in visited:
                    heapq.heappush(max_heap, (probability * edge_probability, neighbour))

        return 0

solution = Solution1514()
print(solution.maxProbability(n=3, edges=[[0, 1], [1, 2], [0, 2]], succProb=[0.5, 0.5, 0.2], start_node=0, end_node=2))
print(solution.maxProbability(n=3, edges=[[0, 1], [1, 2], [0, 2]], succProb=[0.5, 0.5, 0.3], start_node=0, end_node=2))
print(solution.maxProbability(n=3, edges=[[0, 1]], succProb=[0.5], start_node=0, end_node=2))

Graphs/Problem 1514 Path with Maximum Probability.py


# -*- coding: utf-8 -*-
"""
Created on Sat Sep 14 09:46:25 2019

@author: Agung Perdananto
"""
# import Library
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# Import Data
salary_data = pd.read_csv('Salary_Data.csv')

# separate dependent variable and independent variable
X = salary_data.iloc[:, :-1].values

y = salary_data.iloc[:, -1].values

#splitting the dataset into the training set dan Test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state = 0)

# Fitting Seimple Linear Regression to training set
regressor = LinearRegression()
regressor.fit(X_train, y_train)

y_pred = regressor.predict(X_test)

# Visualizing training results
plt.scatter(X_train, y_train, c='r')
plt.plot(X_train, regressor.predict(X_train), c='g')
plt.title('Salary vs Experience (Training data)')
plt.xlabel('expeience (years)')
plt.ylabel('salary ($K)')
plt.show()

# Visualizing test results
plt.scatter(X_test, y_test, c='r')
plt.plot(X_test, y_pred, c='g')
plt.title('Salary vs Experience (Test data)')
plt.xlabel('expeience (years)')
plt.ylabel('salary ($K)')
plt.show()


import talib
import numpy as np
import math
import pandas
import time
import datetime
from datetime import *
from functools import reduce
from sklearn import svm
from sklearn.cluster import KMeans
from collections import Counter
# todo
# 2.优化svm特征
# 1.修改选点策略
# 方案二
# 通过成交量超过60日均线，找波段
# 方案三
# 通过斜率找波段

def calcSection(close, date = []):
    if len(date) < len(close):
        date += [''] * (len(close) - len(date))
    # 计算波段
    # 预处理，把走势分为向上或向下的波段
    secList = []
    # 划分自然波段
    start, startPr = date[0], close[0]
    i = 1
    while i < len(close):
        end, endPr = date[i], close[i]
        uod = 1
        if startPr > endPr:
            uod = -1
        # sec = [uod, start, startPr, end, endPr]
        sec = {'uod': uod, 'start': [start, i-1, startPr], 'end': [end, i, endPr]}
        if len(secList) == 0:
            secList.append(sec)
        else:
            lastSec = secList[-1]
            if lastSec['uod'] == uod:
                lastSec['end'] = [end, i, endPr]
            else:
                secList.append(sec)
        start = end
        startPr = endPr
        i+=1
    # 把自然波段进行容忍合并
    upAdj = 0.5 # 上涨回调幅度严格
    dwAdj = 0.8 # 下跌反弹幅度宽松
    cnt = 0
    while cnt != len(secList):
        cnt = len(secList)
        i = 1
        while i < len(secList)-1:
            preSec = secList[i-1]
            midSec = secList[i]
            nxtSec = secList[i+1]
            # 若整体向上or向下，则合并波段
            if nxtSec['uod'] == preSec['uod'] and \
            nxtSec['uod'] * (nxtSec['end'][2] - preSec['end'][2]) >= 0 and \
            nxtSec['uod'] * (nxtSec['start'][2] - preSec['start'][2]) >= 0:
                preSub = abs(preSec['end'][2] - preSec['start'][2])
                midSub = abs(midSec['end'][2] - midSec['start'][2])
                adj = dwAdj
                if nxtSec['uod'] == 1:
                    adj = upAdj
                # 回调只有一天则直接合并
                # 前波段涨跌幅小于8％则直接合并
                # 不然回调幅度要小于要求值才合并
                if midSec['end'][1] - midSec['start'][1] < 10 or\
                midSub / preSub < adj:
                    preSec['end'] = nxtSec['end']
                    del(secList[i:i+2])
                else:
                    i+=1
            else:
                i+=1
    # 最后价格缺失，易导致波段过短
    # 最后三个波段如果总天数少于20天，则强行合并
    if len(secList) > 3:
        if secList[-1]['end'][1] - secList[-3]['start'][1] < 10:
            secList[-3]['end'] = secList[-1]['end']
            del(secList[-2:])

    return secList

# 获取超过某些条件的波段
# 去掉下降波段
def getHighSec(secList):
    doorsill = 50
    highSec = []
    for sec in secList:
        if sec['end'][2] < sec['start'][2]:
            continue
        rate = (sec['end'][2] / sec['start'][2] - 1) * 100
        if rate < doorsill:
            continue
        # 计算平均涨跌幅 大概范围在0.5～5
        avg_rate = rate / (sec['end'][1] - sec['start'][1])
        if avg_rate < 0.5: # 去掉涨幅太慢的
            continue
        sec['rate'] = avg_rate
        highSec.append(sec)
        # print(sec['rate'])
    return highSec

# 获取标准原始数据
def getSample(stock, num, now):
    his = get_history(num, '1d', 'close')[stock]
    date_his = his.keys()
    close_his = his.values
    volume_his = get_history(num, '1d', 'volume')[stock].values
    close = []
    volume = []
    date = []
    for i in range(0, len(close_his)):
        # 删除价格为0的点
        # 删除停盘日
        if close_his[i] < 0.1 or volume_his[i] < 1:
            continue
        if i+1 < len(date_his):
            t = date_his[i+1]
            t = str(t.date())
        else:
            t = now - timedelta(days=1)
            t = str(t.date())
        date.append(t)
        close.append(close_his[i])
        volume.append(volume_his[i])
    return [date, close, volume]

max_span = 150
# 计算k-means聚类样本
def getKmsX(close, volume):
    pma = IMa(np.array(close), 10, 0, 3).avgs
    # vma = IMa(np.array(volume), max_span, 0, 1).avgs
    vma = MA(volume, 30)
    kmsX = []
    for i in range(max_span, len(close)):
        up = close[i] / close[i-1] - 1
        yup = close[i-1] / close[i-2] -1
        pr = close[i] / pma[i]
        vol = volume[i] / vma[i]
        yvol = volume[i-1] / vma[i-1]
        kmsX.append([up, yup, pr, vol, yvol])
    return kmsX

# 计算信号样本, 并生成svm的原始标签
def getOrgSvmY(highSec, kmsX):
    upX = []
    svmY = [0] * len(kmsX)
    for sec in highSec:
        # kmsX比close短max_span
        start = sec['start'][1] - max_span
        if start < 0:
            continue
        # for i in range(start-1, start+4):
        #     svmY[i] = 1
        #     upX.append(kmsX[i])
        # 前面跌幅小的，后面涨幅小的都算买点
        # dw = 0
        # for i in range(start, start-5, -1):
        #     dw += kmsX[i][0]
        #     if dw > -0.02:
        #         svmY[i] = 1
        #         upX.append(kmsX[i])
        #     else:
        #         break
        up = 0
        for i in range(start+1, start+10):
            up += kmsX[i][0]
            if up < 0.095:
                svmY[i] = 1
                upX.append(kmsX[i])
            else:
                break
    return [svmY, upX]

# 强制把过短的波段合并
def forceMerge(secList):
    i = 1
    while i < len(secList)-1:
        if secList[i+1]['end'][1] - secList[i-1]['start'][1] < 30:
            secList[i-1]['end'] = secList[i+1]['end']
            del(secList[i:i+2])
        else:
            i+=1

# 计算svm的样本
def getSvmX(close, volume, kmsY, target = [0]):
    dis_len = len(close) - len(kmsY)
    svmX = []
    for cle_idx in range(dis_len, len(close)):
        kms_idx = cle_idx - dis_len
        if kmsY[kms_idx] not in target:
            continue
        secList = calcSection(close[:cle_idx+1])
        if len(secList) < 4: #前面数据量过小，少于3个波段
            svmX.append([]) #加个占位符，方便后面过滤Y
            continue
        part = []
        itrSt, itrEd= -4, -1
        # 只有三个波段,或最后波段够长则取后三段
        # sec = secList[-1]
        # if len(secList) == 3 or sec['end'][1] - sec['start'][1] > 5:
        #     itrSt, itrEd = -3, 0
        # 量化三个波段的特征信息
        vma = MA(volume[:cle_idx], cle_idx)[-1]
        for k in range(itrSt, itrEd):
            sec = secList[k]
            # x轴偏移，方便计算
            dis = sec['start'][1]
            y1 = sec['start'][2]
            x1 = 0
            y2 = sec['end'][2]
            x2 = sec['end'][1] - dis
            b = y1
            k = (y2 - b) / x2
            x3 = (x2 // 2)
            y3 = k * x3 + b
            mid = close[x3 + dis]
            # 中间点的偏差
            dev = mid / y3 - 1
            # 波段涨跌幅
            up = sec['end'][2] / sec['start'][2] - 1
            # 时间跨度
            scope = x2
            secVma = MA(volume[dis:dis+scope], scope)[-1]
            rate = secVma / vma
            part += [up, scope, rate, dev]
        svmX.append(part)
    return svmX

def trimSvmY(orgSvmY, kmsY, svmX, target = [0]):
    svmY = []
    for i in range(0, len(kmsY)):
        if kmsY[i] in target:
            svmY.append(orgSvmY[i])
    if len(svmX) != len(svmY):
        return svmY
    i = len(svmX)
    while i > 0:
        i -= 1
        if len(svmX[i]) == 0:
            del(svmX[i], svmY[i])
    return svmY

def getTarget(sigY):
    stat = Counter(sigY)
    print(stat)
    target = []
    t1, t2 = 0,0
    m1, m2 = 0,0
    for t, n in stat.items():
        if n > m1:
            m2 = m1
            t2 = t1
            m1 = n
            t1 = t
    target = [t1, t2]
    print(target)
    return target

def train(context, stockList):
    allKmsX = []
    allUpX = []
    cache = {}
    validLIst = []
    for stock in stockList:
        date, close, vol = getSample(stock, 1000, context.now)
        if len(close) < 600: # 次新股不做为样本
            continue
        secList = calcSection(close, date)
        highSec = getHighSec(secList)
        if len(highSec) < 1:
            continue
        # print(stock, highSec)
        kmsX = getKmsX(close, vol)
        svmY, upX = getOrgSvmY(highSec, kmsX)
        if len(upX) < 1:
            continue
        allKmsX += kmsX
        allUpX += upX
        validLIst.append(stock)
        cache[stock] = [close, vol, svmY, kmsX]
    kms = KMeans(n_clusters=6, random_state=0).fit(allKmsX)
    upY = kms.predict(allUpX)
    context.kms = kms
    target = getTarget(upY)
    allSvmX = []
    allSvmY = []
    for stock in validLIst:
        close, vol, svmY, kmsX = cache[stock]
        kmsY = kms.predict(kmsX)
        svmX = getSvmX(close, vol, kmsY, target)
        leftY = trimSvmY(svmY, kmsY, svmX, target)
        allSvmX += svmX
        allSvmY += leftY
    context.svc = 0
    if len(allSvmX) < 1:
        print('empty sample')
        return

    print(Counter(allSvmY))
    svc = svm.SVC(class_weight={1:90})
    svc.fit(allSvmX, allSvmY)
    context.svc = svc
    context.kms_target = target

def predict(context, stock):
    if context.svc == 0:
        return 0
    date, close, vol = getSample(stock, 600, context.now)
    if len(date) < 300: # 属性计算条件不足忽略
        return 0
    dis = - 1 - max_span
    kmsX = getKmsX(close[dis:], vol[dis:])
    kmsY = context.kms.predict(kmsX)
    svmX = getSvmX(close, vol, kmsY, context.kms_target)
    if len(svmX) < 1 or len(svmX[0]) < 1:
        return 0
    y = context.svc.predict(svmX)[0]
    return y

def getMaxMin(val_list):
    mx, mn = 0, 9999
    max_idx, min_idx = 0, 0
    for i in range(0, len(val_list)):
        if val_list[i] > mx:
            mx = val_list[i]
            max_idx = i
        if val_list[i] < mn:
            mn = val_list[i]
            min_idx = i
    return [min_idx, mn, max_idx, mx]

#init方法是您的初始化逻辑，context对象可以在任何函数之间传递
def init(context):
    #滑点默认值为2‰
    context.set_slippage(0.002)
    #交易费默认值为0.25‰
    context.set_commission(0.00025)
    #基准默认为沪深300
    context.set_benchmark("399102.SZ")
    #最多买入股票数量
    context.stock_num = 2
    context.stockList = []
    task.daily(daily_check, time_rule=market_close(minute=15))  #每天收盘前5分钟运行
    task.weekly(option_stock, weekday=2, time_rule=market_open(minute=15))  #每周周二开盘后5分钟运行
    # task.monthly(option_stock, tradingday=1 ,time_rule=market_open(minute=5))  #每月第1个交易日开盘后5分运行

    stockList = chooseStock(60)
    train(context, stockList)

def sell_stock(context):
    if len(context.portfolio.positions) > 0:
        for stock in context.portfolio.positions.keys():
            if isFastDown(stock):
                print('卖出', stock)
                order_target_value(stock,0)

#每天检查
def daily_check(context, data_dict):
    sell_stock(context)
    buy_stock(context)  #买入股票

#操作股票
def option_stock(context,data_dict):
    stockPack = chooseStock(60)
    stockList = []
    for stock in stockPack:
        if stock in list(context.portfolio.positions.keys()):
            continue
        if isFastDown(stock):
            continue
        y = predict(context, stock)
        if y > 0:
            stockList.append(stock)
    context.stockList = stockList
    print('left cash', context.portfolio.cash)

#策略买入信号函数
def buy_stock(context):
    stockList = context.stockList
    stock_buy_num = context.stock_num
    left_num = stock_buy_num - len(context.portfolio.positions)
    if left_num <= 0:
        return
    stock_cash = context.portfolio.cash/left_num*1.02  #每支股票买入的最大仓位
    i = 0
    while i < left_num and i < len(stockList):
        stock = stockList[i]
        succ = len(context.portfolio.positions)
        if i == left_num-1:
            stock_cash = context.portfolio.cash
        print('买入', stock)
        order_value(stock, stock_cash)     #买入股票
        if succ != len(context.portfolio.positions): #购买成功
            del(stockList[i])
        i+=1

#选股函数
def chooseStock(need = 10):
    dataframe = get_fundamentals(
        query(
        # ).filter(
        #     fundamentals.ma.twine
        ).order_by(
            fundamentals.equity_valuation_indicator.market_cap_2.asc()
        ).limit(
            need
        )
    )
    stockList = dataframe.columns.values

    return stockList

def isFastDown(stock):
    his = get_history(10, '1d', 'close')[stock].values
    if len(his) < 10:
        return True
    # 先找最近最高值
    mx = -1
    idx = 0
    for i in range(0, len(his)):
        if his[i] > mx:
            idx = i
            mx = his[i]
    # 再从最高点往后找最小值
    mn = mx
    for i in range(i, len(his)):
        if his[i] < mn:
            mn = his[i]
    if (mx / mn - 1) > 0.1: #回调超过10％则卖出
        return True
    return False

#每天开盘前进行选股
def before_trade(context):
    pass

#日或分钟或实时数据更新，将会调用这个函数
def handle_data(context,data_dict):
    pass


import pandas as pd
import matplotlib
matplotlib.use('tkAgg')
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from pandas.plotting import scatter_matrix
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.metrics import roc_curve, roc_auc_score

df= pd.read_csv('census_income_learn.csv')
df.columns=range(1,43)
df.rename(columns={42: 'income'}, inplace=True)

weights=df[25]
y_train=pd.get_dummies(df['income'])
y_train.drop(columns=' - 50000.',inplace=True) #this column is now redundant

df2= pd.read_csv('census_income_test.csv')
df2.columns=range(1,43)
y_test=pd.get_dummies(df2[42])
y_test.drop(columns=' - 50000.',inplace=True)

plt.xlabel('age')
df.loc[df['income']==' - 50000.', 1].plot.hist(color='chocolate',bins=40,title='Histogram of Age')
df.loc[df['income']==' 50000+.', 1].plot.hist(color='darkmagenta',bins=40)
plt.legend(['Under 50k income','Over 50k income'])
plt.show()
df.groupby('income').hist(alpha=0.4) #_plot of the histograms of the numerical variable

# data correlation now !!
scatter_matrix(df, alpha=0.2, figsize=(6, 6), diagonal='kde')
df[3]=df[3].astype('object')
df[4]=df[4].astype('object')
df[37]=df[37].astype('object')
df[39]=df[39].astype('object')

df2[3]=df2[3].astype('object')
df2[4]=df2[4].astype('object')
df2[37]=df2[37].astype('object')
df2[39]=df2[39].astype('object')

corr=pd.get_dummies(df[[3,9]],drop_first=True).corr(method='pearson', min_periods=1) #correlation() matrix

#data cleaning
df[17]=df[17]-df[18]
df2[17]=df2[17]-df2[18]#net capital
x_train=df.drop(columns=[6,7,9,10,15,18,21,22,23,25,26,27,28,30,32,33,34,35,36,38,41,'income'])
x_test=df2.drop(columns=[6,7,9,10,15,18,21,22,23,25,26,27,28,30,32,33,34,35,36,38,41,42])
print(df.isnull().sum())#non are equal to zero
print(df2.isnull().sum())# none are equal to zero

x_train=pd.get_dummies(x_train,drop_first=True)#171 columns
x_test=pd.get_dummies(x_test,drop_first=True)#171 columns
x_train.info()

print(cross_val_score(LogisticRegression(n_jobs=-1),x_train, y_train, cv=10, scoring='accuracy'))#10 folds cross validation scores
print(cross_val_score(RandomForestClassifier(n_jobs=-1,n_estimators=20),x_train, y_train, cv=10, scoring='accuracy'))

model1=LogisticRegression(n_jobs=-1)
model2=RandomForestClassifier(n_estimators=100,n_jobs=-1)

model1.fit(x_train,y_train)
model2.fit(x_train,y_train)

predictions1=model1.predict(x_test)
predictions2=model2.predict(x_test)

print(confusion_matrix(y_test,predictions1))
print(classification_report(y_test, predictions1))
print(confusion_matrix(y_test,predictions1))
print(classification_report(y_test, predictions1))

fpr,tpr,thresholds=roc_curve(y_train,model1.predict_proba(x_train)[:,1]) #roc_auc_score curves

associatedprediction=[ 1 if (predictions1[k]==1 or predictions2[k]==1) else 0 for k in range(len(predictions2))] #easy ensembling  of the two models in order to increase the number of true positives
print(confusion_matrix(y_test,associatedprediction))
print(classification_report(y_test, associatedprediction))

#best f1 score :
probas=model1.predict_proba(x_train)[:,1]
threshbest,f1best=0,0
for i in range(10):
    print(i)
    thresh=0.2+i/100
    true_pos = sum([(probas[k] > thresh) * (y_train.values[k] == 1) for k in range(len(probas))])
    false_pos = sum([(probas[k] > thresh) * (y_train.values[k] == 0) for k in range(len(probas))])
    false_neg = sum([(probas[k] <= thresh) * (y_train.values[k] == 1) for k in range(len(probas))])
    true_neg = sum([(probas[k] <= thresh) * (y_train.values[k] == 0) for k in range(len(probas))])

    recall = true_pos / (true_pos + false_neg)
    precision = true_pos / (true_pos + false_pos)
    f1 = 2 * precision * recall / (precision + recall)
    if f1>f1best:
        f1best=f1
        threshbest=thresh
print(f1best,threshbest)
probastest=model1.predict_proba(x_test)[:,1]
true_pos = sum([(probastest[k] > threshbest) * (y_test.values[k] == 1) for k in range(len(probastest))])
false_pos = sum([(probastest[k] > threshbest) * (y_test.values[k] == 0) for k in range(len(probastest))])
false_neg = sum([(probastest[k] <= threshbest) * (y_test.values[k] == 1) for k in range(len(probastest))])
true_neg = sum([(probastest[k] <= threshbest) * (y_test.values[k] == 0) for k in range(len(probastest))])

recall = true_pos / (true_pos + false_neg)
precision = true_pos / (true_pos + false_pos)
f1 = 2 * precision * recall / (precision + recall)
print(f1)


import os
import cv2
import numpy as np
import pandas as pd
import albumentations
import torch
from tqdm import tqdm
from torch.utils.data import Dataset

def get_dataframe(k_fold, data_dir, data_folder, out_dim = 1):

    # data 읽어오기 (pd.read_csv / DataFrame으로 저장)
    data_folder = 'images/'
    df_train = pd.read_csv(os.path.join(data_dir, data_folder, 'train.csv'))

    # 비어있는 데이터 버리고 데이터 인덱스를 재지정함
    # df_train = df_train[df_train['인덱스 이름'] != -1].reset_index(drop=True)

    # 이미지 이름을 경로로 변환하기 (pd.DataFrame / apply, map, applymap에 대해 공부)
    df_train['filepath'] = df_train['image_name'].apply(lambda x: os.path.join(data_dir, f'{data_folder}train', x))  # f'{x}.jpg'

    # 원본데이터=0, 외부데이터=1
    df_train['is_ext'] = 0

    '''
    ####################################################
    교차 검증 구현 (k-fold cross-validation)
    ####################################################
    '''
    # 교차 검증을 위해 이미지 리스트들에 분리된 번호를 매김
    img_ids = len(df_train['img_id'].unique())
    print(f'Original dataset의 이미지수 : {img_ids}')

    # 데이터 인덱스 : fold 번호. (fold)번 분할뭉치로 간다
    # train.py input arg에서 k-fold를 수정해줘야함 (default:5)
    print(f'Dataset: {k_fold}-fold cross-validation')
    img_id2fold = {i: i % k_fold for i in range(img_ids)}
    df_train['fold'] = df_train['img_id'].map(img_id2fold)

    # test data (학습이랑 똑같게 함)
    df_test = pd.read_csv(os.path.join(data_dir, data_folder, 'test.csv'))
    df_test['filepath'] = df_test['image_name'].apply(lambda x: os.path.join(data_dir, f'{data_folder}test', x)) # f'{x}.jpg'

    return df_train, df_test

class resamplingDataset(Dataset):
    def __init__(self, csv, mode, image_size=1024, transform=None):
        self.csv = pd.concat([csv]*10, ignore_index=True).reset_index(drop=True)
        self.mode = mode # train / valid
        self.transform = transform

        self.r_test_delta = 180.0 # 테스트가 필요없다면 180, 아니면 1
        self.s_test_delta = 0.01 # 0.01 단위로 변경
        self.s_test_low = 0.5
        self.s_test_high = 2.0
        self.image_size = image_size

        # 시간 절약을 위해 메모리에 데이터셋 미리 읽어들임
        self.image_list = []
        print('데이터 로딩 시작')
        for i in tqdm(range(len(self.csv))):
            # 이미지 읽어들임
            temp_img = cv2.cvtColor(cv2.imread(self.csv.iloc[i].filepath), cv2.COLOR_RGB2BGR)

            # Color filter array 영향을 줄이기 위해 0.5배로 리사이징
            temp_img = cv2.resize(temp_img, dsize=(0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)

            # center crop
            h, w, _ = temp_img.shape
            h_half, w_half = int(h/2), int(w/2)
            temp_img = temp_img[h_half-self.image_size:h_half+self.image_size, w_half-self.image_size:w_half+self.image_size, :]

            # append image list
            self.image_list.append(temp_img)
        print('데이터 로딩 끝')

    def __len__(self):
        return self.csv.shape[0]

    def __getitem__(self, index):
        image = self.image_list[index]

        # 변형 값 얻어내기
        r_test_value = np.random.uniform(low=0, high=180, size=(1,)) // self.r_test_delta
        s_test_value = np.random.uniform(low=self.s_test_low, high=self.s_test_high, size=(1,))
        s_test_value -= (s_test_value % self.s_test_delta)

        # 변형
        matrix = cv2.getRotationMatrix2D((int(self.image_size/2), int(self.image_size/2)), float(r_test_value), float(s_test_value))
        image = cv2.warpAffine(image, matrix, (self.image_size, self.image_size), cv2.INTER_LINEAR)

        # albumentation 적용
        res = self.transform(image=image)
        image = res['image'].astype(np.float32)

        # 흑백 이미지 변환 후 차원 변경 [1, 1024, 1024]
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        image = np.expand_dims(image, axis=0)

        # 학습용 데이터 리턴
        data = torch.tensor(image).float()

        # 변경 값 리턴하기
        target_list = [r_test_value, s_test_value*100]

        return data, torch.tensor(target_list).float()

def get_transforms(image_size):
    transforms_train = albumentations.Compose([
        albumentations.RandomBrightness(limit=0.1, p=0.75),
        albumentations.RandomContrast(limit=0.1, p=0.75),
        # albumentations.CLAHE(clip_limit=2.0, p=0.3),
        # albumentations.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=20, val_shift_limit=10, p=0.5),
        # albumentations.Cutout(max_h_size=int(image_size * 0.1), max_w_size=int(image_size * 0.1), num_holes=1, p=0.7),
        albumentations.Normalize()
    ])

    transforms_val = albumentations.Compose([
        # albumentations.Resize(image_size, image_size),
        albumentations.Normalize()
    ])

    return transforms_train, transforms_val

def get_meta_data_stoneproject(df_train, df_test):
    '''
    ####################################################
                        안씀
    ####################################################
    '''

    return 0,0,0,0


import datetime

import requests

url = 'https://apps.fedoraproject.org/datagrepper/raw'

ignored_badges = [
    'origin',
]

def badge_id(msg):
    return msg['msg'].get('badge', {}).get('badge_id')

def grep(tries=0, **kwargs):
    response = requests.get(url, params=kwargs)
    if not bool(response):
        if tries > 7:
            raise IOError("Failed to %r %r" % (response.url, response))
        for item in grep(tries=tries + 1, **kwargs):
            yield item

    data = response.json()
    pages = data['pages']

    for message in data['raw_messages']:
        if badge_id(message) in ignored_badges:
            continue
        yield message

    for page in range(1, pages):
        kwargs['page'] = page
        response = requests.get(url, params=kwargs)
        try:
            data = response.json()
        except Exception as e:
            if "Expecting value" in str(e):
                continue
            else:
                raise

        for message in data.get('raw_messages', []):
            if badge_id(message) in ignored_badges:
                continue
            yield message

def monthly_timebucket(timestamp):
    then = datetime.datetime.fromtimestamp(timestamp)
    date = datetime.date(then.year, then.month, 1)
    return date

def daily_timebucket(timestamp):
    then = datetime.datetime.fromtimestamp(timestamp)
    return then.date()

def weekly_timebucket(timestamp):
    then = datetime.datetime.fromtimestamp(timestamp)
    calendar = then.isocalendar()
    return str(calendar[0]) + "-" + ("%i" % calendar[1]).zfill(2)

badge_tags_cache = {}
def badge2tags(badge_id):
    if badge_id not in badge_tags_cache:
        url = 'https://badges.fedoraproject.org/badge/%s/json' % badge_id
        response = requests.get(url)
        data = response.json()
        if 'tags' in data:
            tags = (data['tags'] or '').strip(',').split(',')
            badge_tags_cache[badge_id] = tags
        else:
            badge_tags_cache[badge_id] = []

    return badge_tags_cache[badge_id]


import twilio, flask
from twilio.rest import Client
import os
# import dotenv
# from dotenv import load_dotenv
# Import requests and Python's core JSON library.
import requests
import json
from flask import Flask, request, redirect, url_for, render_template
from twilio.twiml.messaging_response import MessagingResponse
# from twilio.twiml import Response

# BASEDIR = os.path.abspath(os.path.dirname(__file__))

# load_dotenv(os.path.join(BASEDIR, '.env'))

account_id = os.getenv('twilio_account_sid')
token = os.getenv('twilio_account_authtoken')

# Account Sid and Auth Token from twilio.com/console

twilio_account_sid = account_id
twilio_auth_token = token

# Creating an instance of Flask
app = Flask(__name__)
BASE_URL = 'http://pokeapi.co'

def query_pokeapi(resource_url):
    url = '{0}{1}'.format(BASE_URL, resource_url)
    response = requests.get(url)

    if response.status_code == 200:
        return json.loads(response.text)
    return None

def pokedex_description(pokemon_species):
    url = '{0}{1}'.format(BASE_URL, pokemon_species)
    response_two = requests.get(url)

    if response_two.status_code == 200:
        return json.loads(response_two.text)
    return None

# Render home()
@app.route("/")
def home():
    return render_template("home.html")

# Render incoming message
# -------------------------------
@app.route("/sms", methods=["GET", "POST"])
def incoming_message():
    twiml = MessagingResponse()

    client = Client(twilio_account_sid, twilio_auth_token)

    body = request.values.get("Body", "").lower().strip().replace(" ","")

    pokemon_url = "/api/v2/pokemon/{0}/".format(body)
    pokemon_json = query_pokeapi(pokemon_url)

    # pokemon_index = pokemon_json['game_indices'][0]['game_index']

    pokemon_url_two = "/api/v2/pokemon-species/{0}/".format(body)
    pokemon_json_two = pokedex_description(pokemon_url_two)

    if pokemon_json == None:
        msg = twiml.message ("Oops try again")
        return str(twiml)
    elif pokemon_json:

        # description = pokemon_json_two['flavor_text_entries'][1]['flavor_text']

        # Look for English pokedex description
        for i in pokemon_json_two['flavor_text_entries']:
            if i["language"]["name"] == "en":
                description = i["flavor_text"]
                break

        sprite = pokemon_json['sprites']['front_default']

        msg = twiml.message(description)

        msg.media(sprite)

        # client.messages.create(
        #     body = description,
        #     from_ = '+0000000000',
        #     to = '',
        #     media_url = sprite
        # )
        return str(twiml)

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

# incoming_message()


#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Authors :
#       James Goodger <james@evofetch.org>

from os import EX_OK

from evo.cdif2rsf.objects.AttributeEntity import AttributeEntity
from evo.cdif2rsf.objects.AttributeVersionEntity import AttributeVersionEntity
from evo.common.objects.AttributeVersion import AttributeVersion
from evo.common.processing.Utils import requestNewRSFId

def buildAttributeChanges(cdifFile, changeDict):

    """ Reads attributes from a CDIF file into a dictionary """
    for line in cdifFile:
        line = line.strip()

        # if the line is the start of an entity
        if line.startswith("(AttributeVersion FM"):

            revision = None
            attributeChange = None

            for line in cdifFile:
                line = line.strip()
                if line.startswith("(revision "):
                    revision = line.split("\"")[1]
                elif line.startswith("(versionOfAttribute "):
                    attributeName = line.split("\"")[1]
                    attributeChange = AttributeVersion(revision, attributeName)
                elif line.startswith("(isCreation "):
                    boolValue = (line.split("-")[1] == "TRUE")
                    attributeChange.setCreation(boolValue)
                elif line.startswith("(isModification "):
                    boolValue = (line.split("-")[1] == "TRUE")
                    attributeChange.setModification(boolValue)
                elif line.startswith("(isDeletion "):
                    boolValue = (line.split("-")[1] == "TRUE")
                    attributeChange.setDeletion(boolValue)
                elif line.startswith(")"):
                    changeDict[attributeName] = attributeChange
                    break

def buildAttributes(cdifFile, changeDict, dictionaries, versionDict, containmentDict):

    for line in cdifFile:
        line = line.strip()

        # if the line is the start of an entity
        if line.startswith("(Attribute FM"):

            for line in cdifFile:
                line = line.strip()
                if line.startswith("(uniqueName "):
                    uniqueAttributeName = line.split("\"")[1]
                elif line.startswith("(belongsTo "):
                    parentClass = line.split("\"")[1]
                elif line.startswith("(declaredType "):
                    declaredType = line.split("\"")[1]
                elif line.startswith("(declaredClass "):
                    declaredClass = line.split("\"")[1]
                elif line.startswith("(accessControlQualifier "):
                    accessControlQualifier = line.split("\"")[1]
                elif line.startswith("(hasClassScope "):
                    hasClassScope = (line.split("-")[1] == "TRUE")
                elif line.startswith("(revision "):
                    revision = line.split("\"")[1]
                elif line.startswith(")"):
                    latestClassVersion = dictionaries.getLatestClassVersion(parentClass)
                    if uniqueAttributeName in changeDict:
                        attribute = dictionaries.getAttributeEntity(uniqueAttributeName)
                        if attribute is None:
                            attribute = AttributeEntity()
                            attribute.setIdentifier(requestNewRSFId())
                            attribute.setUniqueName(uniqueAttributeName)
                            attribute.setClassIdentifier(dictionaries.getClassId(parentClass))
                        attributeVersion = AttributeVersionEntity()
                        attributeVersion.setIdentifier(requestNewRSFId())
                        attributeVersion.setUniqueName(uniqueAttributeName)
                        attributeVersion.setAttributeIdentifier(attribute.getIdentifier())
                        attributeVersion.setAccessControlQualifier(accessControlQualifier)
                        attributeVersion.setDeclaredType(declaredType)
                        if declaredClass != "":
                            attributeVersion.setDeclaredClassIdentifier( \
                                             dictionaries.getClassId(declaredClass))
                        attributeVersion.setClassScope(hasClassScope)
                        attributeVersion.setRevision(revision)
                        attributeVersion.setClassVersion(latestClassVersion)
                        versionDict[uniqueAttributeName] = attributeVersion
                        dictionaries.storeAttributeVersion(uniqueAttributeName, attribute, attributeVersion)
                    else:
                        attributeRevisionId = dictionaries.getRevision(revision)
                        classRevisionId = dictionaries.getRevision(latestClassVersion.getRevision())
                        if classRevisionId > attributeRevisionId:
                            attributeVersion = dictionaries.getLatestAttributeVersion(uniqueAttributeName)
                            attributeVersion.setRevision(revision)
                            attributeVersion.setClassVersion(latestClassVersion)
                            containmentDict[uniqueAttributeName] = attributeVersion
                    break

def writeAttributes(inputFile, dictionaries):

    changes = {}

    fileHandle = open(inputFile, 'r')
    buildAttributeChanges(fileHandle, changes)
    fileHandle.close()

    versions = {}
    containment = {}

    fileHandle = open(inputFile, 'r')
    buildAttributes(fileHandle, changes, dictionaries, versions, containment)
    fileHandle.close()

    attributeChangedByRevision = {}
    attributeCreatedByRevision = {}
    attributeModifiedByRevision = {}
    attributeDeletedByRevision = {}
    attributeVersions = {}
    attributeVersionBelongsToClassVersion = {}

    for change in changes.values():
        attribute = dictionaries.getAttributeEntity(change.getAttributeName())
        attributeId = attribute.getIdentifier()
        revisionId = dictionaries.getRevision(change.getRevision())
        attributeChangedByRevision[attributeId] = revisionId
        if change.isCreation():
            attributeCreatedByRevision[attributeId] = revisionId
        if change.isModification():
            attributeModifiedByRevision[attributeId] = revisionId
        if change.isDeletion():
            attributeDeletedByRevision[attributeId] = revisionId

    for version in versions.values():
        versionId = version.getIdentifier()
        attributeVersions[versionId] = version

    for version in containment.values():
        versionId = version.getIdentifier()
        attributeVersionBelongsToClassVersion[versionId] = version

    changeFile = open("attributeChangedByRevision.txt", 'a')
    creationFile = open("attributeCreatedByRevision.txt", 'a')
    modificationFile = open("attributeModifiedByRevision.txt", 'a')
    deletionFile = open("attributeDeletedByRevision.txt", 'a')
    attributeVersionFile = open("attributeVersions.txt", 'a')
    attributeTypeFile = open("attributeVersionHasClassAsType.txt", 'a')
    attributeVisibilityFile = open("attributeVersionVisibility.txt", 'a')
    containmentFile = open("attributeVersionBelongsToClassVersion.txt", 'a')

    indices = attributeChangedByRevision.keys()
    indices.sort()
    for attributeId in indices:
        revisionId = attributeChangedByRevision[attributeId]
        attributeChangedByRevisionInfo = str(attributeId) + "\t" + str(revisionId) + "\n"
        changeFile.write(attributeChangedByRevisionInfo)
    changeFile.close()

    indices = attributeCreatedByRevision.keys()
    indices.sort()
    for attributeId in indices:
        revisionId = attributeCreatedByRevision[attributeId]
        attributeCreatedByRevisionInfo = str(attributeId) + "\t" + str(revisionId) + "\n"
        creationFile.write(attributeCreatedByRevisionInfo)
    creationFile.close()

    indices = attributeModifiedByRevision.keys()
    indices.sort()
    for attributeId in indices:
        revisionId = attributeModifiedByRevision[attributeId]
        attributeModifiedByRevisionInfo = str(attributeId) + "\t" + str(revisionId) + "\n"
        modificationFile.write(attributeModifiedByRevisionInfo)
    modificationFile.close()

    indices = attributeDeletedByRevision.keys()
    indices.sort()
    for attributeId in indices:
        revisionId = attributeDeletedByRevision[attributeId]
        attributeDeletedByRevisionInfo = str(attributeId) + "\t" + str(revisionId) + "\n"
        deletionFile.write(attributeDeletedByRevisionInfo)
    deletionFile.close()

    indices = attributeVersions.keys()
    indices.sort()
    for identifier in indices:
        version = attributeVersions[identifier]
        attributeId = version.getAttributeIdentifier()
        revisionId = dictionaries.getRevision(version.getRevision())
        attributeVersionInfo = str(identifier) + "\t" + str(attributeId) + \
                               "\t" + str(revisionId) + "\n"
        attributeVersionFile.write(attributeVersionInfo)
        typeClassId = version.getDeclaredClassIdentifier()
        if not (typeClassId is None):
            typeClassInfo = str(identifier) + "\t" + str(typeClassId) + "\n"
            attributeTypeFile.write(typeClassInfo)
        visibility = version.getAccessControlQualifier()
        if visibility != "":
            visibilityInfo = str(identifier) + "\t\"" + visibility + "\"\n"
            attributeVisibilityFile.write(visibilityInfo)
    attributeVersionFile.close()
    attributeTypeFile.close()
    attributeVisibilityFile.close()

    indices = attributeVersionBelongsToClassVersion.keys()
    indices.sort()
    for identifier in indices:
        version = attributeVersionBelongsToClassVersion[identifier]
        classVersion = version.getClassVersion()
        classVersionId = classVersion.getIdentifier()
        containmentInfo = str(identifier) + "\t" + str(classVersionId) + "\n"
        containmentFile.write(containmentInfo)
    containmentFile.close()

    return EX_OK

def writeAttributeEntities(dictionaries):

    attributes = {}

    for uniqueAttributeName in dictionaries.attributeDict:
        attribute = dictionaries.getAttributeEntity(uniqueAttributeName)
        attributes[attribute.getIdentifier()] = attribute

    attributesFile = open("attributesWithIDs.txt", 'w')
    attributeContainmentFile = open("attributeBelongsToClass.txt", 'w')

    indices = attributes.keys()
    indices.sort()
    for identifier in indices:
        attribute = attributes[identifier]
        attributeInfo = str(identifier) + "\t" + attribute.getUniqueName() + "\n"
        attributesFile.write(attributeInfo)
        containmentInfo = str(identifier) + "\t" + str(attribute.getClassIdentifier()) + "\n"
        attributeContainmentFile.write(containmentInfo)

    attributesFile.close()
    attributeContainmentFile.close()

    return EX_OK


from django.template import loader
from django.http import HttpResponse
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
#from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required, permission_required
from django import forms
from django.shortcuts import redirect
from .models import Gathering, Gathering_Belong, Gathering_Witness, Location, UserHome, Organization
import io

import csv
import datetime as dateTime

def to_fff(self, dataset, title, params, debug=False):
  print(f"TOWM Web Map delivery of {len(dataset)} records")
  title += " generated on "+now_minute()
  payload = {"title":title, "csv": dataset.get_csv([title])}
  self._send_to_fff_web_server(payload)

def _send_to_fff_web_server(self,payload,files=None):
  url = "https://map.fridaysforfuture.org/admin/inactive_upload/"
  cred = open(Env.get_or_die(Env.FFF_WEB_TOKEN_FILENAME), encoding="utf-8").read()
  payload["password"] = cred
  result = requests.post(url, data=payload, files=files)
  if(result.status_code == 200):
    print("UPFF Uploaded to fff.org.")
  else:
    print("NOFF Problem uploading to fff.org:\n%s"%result)
    raise (result.status_code, result.text)

def coffer_data():
  with io.StringIO() as csvfile:
    datawriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    data_rows = dict()

    locations = list(Location.objects.filter(lat__isnull=False)[:]) #remove [:num] for full list
    for location in locations:
      eventmap_data = Eventmap_Data()
      eventmap_data.object_location = location

      gatherings = list(Gathering.objects.filter(location=location))
      gatherings.sort(key=lambda gathering: gathering.start_date if gathering.start_date else datetime.datetime(1970,1,1), reverse=True)
      if (len(gatherings) > 0):
        for gathering in gatherings:
          eventmap_data.object_gathering = gathering
          #data_rows.update({eventmap_data.key: eventmap_data.data_format_coffer()})

          witnesses = list(Gathering_Witness.objects.filter(gathering=gathering))
          witnesses.sort(key=lambda witness: witness.date if witness.date else datetime.datetime(1970,1,1), reverse=True)
          if (len(witnesses) > 0):
            for witness in witnesses:
              eventmap_data.object_witness = witness
              data_rows.update({eventmap_data.regid: eventmap_data.data_format_coffer()})
              #print(f"TESV {eventmap_data.data_format_coffer()} \n \n")

    #print(f"EDDR {data_rows}")
    datawriter.writerows(data_rows.values())

    #print(f"CSVO {csvfile}")
    return csvfile.getvalue()

def eventmap_data():
  with io.StringIO(newline='') as csvfile:
    datawriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    datawriter.writerow(['FFF Global Map generated on ' + dateTime.datetime.today().strftime('%Y-%m-%d %H:%M')]+['']*16)
    datawriter.writerow([
      'Country',
      'Town',
      'Address',
      'Time',
      'Date',
      'End Date',
      "Link to event (URL), e.g. Facebook, Instagram, Twitter, web",
      'Event Type',
      'Lat',
      'Lon',
      'Your name',
      'Email Address',
      'Phone number in international format (optional)',
      'Notes (optional)',
      'Organization that you represent (optional)',
      'Organizational Color',
      'regid'
    ])

    data_rows = dict()

    locations = list(Location.objects.filter(lat__isnull=False)[:]) #remove [:num] for full list
    for location in locations:
      eventmap_data = Eventmap_Data()
      eventmap_data.object_location = location

      gatherings = list(Gathering.objects.filter(location=location))
      gatherings.sort(key=lambda gathering: gathering.start_date if gathering.start_date else datetime.datetime(1970,1,1), reverse=True)
      if (len(gatherings) > 0):
        for gathering in gatherings:
          eventmap_data.object_gathering = gathering

          witnesses = list(Gathering_Witness.objects.filter(gathering=gathering))
          witnesses.sort(key=lambda witness: witness.date if witness.date else datetime.datetime(1970,1,1), reverse=True)
          if (len(witnesses) > 0):
            for witness in witnesses:
              eventmap_data.object_witness = witness

              data_rows.update({eventmap_data.regid: eventmap_data.data_format_map()})
          else:
            data_rows.update({eventmap_data.regid: eventmap_data.data_format_map()()})

    print(f"EDDR {data_rows}")
    datawriter.writerows(data_rows.values())

  return csvfile

def eventmap_data_view(request):
  eventlist = []
  datareader = csv.reader(open(eventmap_data(), newline=''), delimiter=',', quotechar='"')
  for row in datareader:
    eventlist.append(row)

  context = {
    'eventlist_length': (len(eventlist)-2),
    'eventlist': eventlist,
  }

  template = loader.get_template('action/eventmap_data.html')
  return HttpResponse(template.render(context, request))

class Eventmap_Data():
  object_location = None
  object_gathering = None
  object_witness = None

  source = 'Gamechanger' #C

  #LOCATION
  country = '' #CM
  town = '' #CM
  lat = '' #CM
  lon = '' #CM
  location_google_name = '' #C

  #GATHERING; WITNESS
  create_time = '' #C
  update_time = '' #C
  organization = '' #CM
  participants = '' #CM
  date = '' #CM

  #GATHERING
  #create_time = '' #C
  #update_time = '' #C
  regid = '' #CM
  gathering_type = '' #CM
  #participants = '' #CM
  #organization = '' #CM
  organization_color = '' #M
  #date = '' #CM
  date_end = '' #M
  frequency = 'once' #C : 'once', 'weekly', 'every friday'
  time = '' #CM
  address = '' #CM
  contact_approval = 'y' #C
  contact_accsess_level = '' #Private, Press, Public
  contact_name = '' # CM
  contact_email = '' # CM
  contact_phone = ''  #M
  contact_notes = '' #M

  #WITNESS
  #create_time = '' #C
  #update_time = '' #C
  #date = '' #CM
  #participants = '' #CM
  #organization = '' #CM
  proof_url = '' #CM

  def data_process_location(self):
    #LOCATION; country, town, lat, lon, location_google_name
    if self.object_location:
      self.country = self.object_location.country()
      self.town = self.object_location.name
      self.lat = self.object_location.lat
      self.lon = self.object_location.lon
      #self.location_google_name = self.object_location.google_name

  def data_process_gathering(self):
    #GATHERING; create_time, update_time,
    # regid, gathering_type, participants, organization, ?organization_color?, date, date_end, frequency, time, adress,
    # contact_approval, contact_name, contact_email, contact_phone, contact_notes
    if self.object_gathering:
      #self.create_time = self.object_gathering.creation_time
      #self.update_time = self.object_gathering.updated

      self.regid = self.object_gathering.regid

      self.date = self.object_gathering.start_date
      self.date_end = self.object_gathering.end_date
      if (self.date != self.date_end):
        self.frequency = 'weekly'

      self.gathering_type = self.object_gathering.get_gathering_type_str()
      if self.object_gathering.expected_participants:
        self.participants = self.object_gathering.expected_participants
      if self.object_gathering.address:
        self.address = self.object_gathering.address
      if self.object_gathering.time:
        self.time = self.object_gathering.time
      if len(self.object_gathering.organizations.all()) > 0:
        self.organization = ", ".join(str(elem) for elem in list(self.object_gathering.organizations.all()))

      if (self.contact_approval == 'y'):
        if self.object_gathering.contact_name:
          self.contact_name = self.object_gathering.contact_name
        if self.object_gathering.contact_email:
          self.contact_email = self.object_gathering.contact_email
        if self.object_gathering.contact_phone:
          self.contact_phone = self.object_gathering.contact_phone
        if self.object_gathering.contact_notes:
          self.contact_notes = self.object_gathering.contact_notes
      else:
        self.contact_name = self.object_gathering.contact_name = 'anonymus'
        self.contact_email = self.object_gathering.contact_email = 'map@fff'
        self.contact_notes = self.object_gathering.contact_notes = 'Anonymus registration'

  def data_process_witness(self):
    #WITNESS;
    # >create_time<, >update_time<,
    # >date<, *date_end*, *frequency*, participants, >organization<, organization_color
    if self.object_witness:
      self.create_time = self.object_witness.creation_time
      self.update_time = self.object_witness.updated

      self.date = self.object_witness.date
      self.date_end = self.object_witness.date
      #DEFAULT: self.frequency = 'Once'

      if self.object_witness.participants:
        self.participants = self.object_witness.participants

      if self.object_witness.proof_url:
        self.proof_url = self.object_witness.proof_url
      if self.object_witness.organization:
        self.organization = self.object_witness.organization
      else:
        self.organization = ''
      self.organization_color = self.object_witness.get_pin_color()

  def data_process_all(self):
    self.data_process_location()
    self.data_process_gathering()
    self.data_process_witness()

  def data_format_map(self):
    self.data_process_all()
    return [
      self.country,
      self.town,
      self.address,
      self.time,
      self.date,
      self.date_end,
      self.proof_url,
      self.gathering_type,
      self.lat,
      self.lon,
      self.contact_name,
      self.contact_email,
      self.contact_phone,
      self.contact_notes,
      self.organization,
      self.organization_color,
      self.regid,
    ]

  def data_format_coffer(self):
    self.data_process_all()
    return [
      'Witness',
      self.regid,
      self.date,
      self.participants,
      self.proof_url,
      self.create_time,
      self.update_time,
      self.organization,
    ]


import json
import requests
import logging
import asyncio

from stores.base import Store

logger = logging.getLogger(__name__)

PS5_PRODUCT_ID = 14962185
BASE_URL = (
    "https://bestbuy.ca/ecomm-api/availability/products",
    "?accept=application%2Fvnd.bestbuy.standardproduct.v1",
    f"%2Bjson&accept-language=en-CA&skus={PS5_PRODUCT_ID}",
)

class BestBuy(Store):
    def check(self) -> bool:
        self.found = False
        headers = {
            "User-Agent": (
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
                " (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",
            )
        }
        response = requests.get(BASE_URL, headers=headers, timeout=10)
        try:
            response.raise_for_status()
            raw_response = response.content.decode("utf-8")
            json_response = raw_response.replace("\ufeff", "")
            json_response = json_response.replace("\r\n", "")
            self.parse_payload(json.loads(json_response))
        except Exception as e:
            logger.error(e)
        print(f"Checked bestbuy.  Purchasable: {self.found}")

    def parse_payload(self, raw_json: dict) -> None:
        availabilities = raw_json.get("availabilities")
        for availability in availabilities:
            shipping_availability = availability.get("shipping")
            purchasable = shipping_availability.get("purchaseable")
            if purchasable:
                loop = asyncio.new_event_loop()
                asyncio.set_event_loop(loop)
                loop.run_until_complete(
                    self.stock_alert(
                        provider="Bestbuy",
                        link=(
                            "https://www.bestbuy.ca/en-ca/product/",
                            f"{PS5_PRODUCT_ID}",
                        ),
                    )
                )
                self.found = True


import pytest
from fastapi.testclient import TestClient
from main import app

# comment
testApp = TestClient(app)

lessthan50KPayload = {
  "age": 29,
  "workclass": "State-gov",
  "fnlgt": 77516,
  "education": "Bachelors",
  "education-num": 13,
  "marital-status": "Never-married",
  "occupation": "Adm-clerical",
  "relationship": "Not-in-family",
  "race": "White",
  "sex": "Male",
  "capital-gain": 2174,
  "capital-loss": 0,
  "hours-per-week": 40,
  "native-country": "United-States"
}

morethan50KPayload = {
          "age": 50,
          "workclass": "Federal-gov",
          "fnlgt": 251585,
          "education": "Bachelors",
          "education-num": 13,
          "marital-status": "Divorced",
          "occupation": "Exec-managerial",
          "relationship": "Not-in-family",
          "race": "White",
          "sex": "Male",
          "capital-gain": 0,
          "capital-loss": 0,
          "hours-per-week": 55,
          "native-country": "United-States"
}

badPayload = {}

@pytest.fixture
def lessthan50KPayload_fixture():
    return lessthan50KPayload

@pytest.fixture
def morethan50KPayload_fixture():
    return morethan50KPayload

def test_get():
    res = testApp.get("/")
    assert res.json()["result"] == "Welcome to Renee's CENSUS API. You can type in a JSON body containing 14 attributes to get back a salary prediction"
    assert res.status_code == 200

def test_post_correct(lessthan50KPayload_fixture):
    res = testApp.post("/predict", json=lessthan50KPayload_fixture)
    assert res.status_code == 200
    assert res.json()["prediction"] == "Income <= 50k"

def test_post_wrong(morethan50KPayload_fixture):
    res = testApp.post("/predict", json=morethan50KPayload_fixture)
    assert res.status_code == 200
    assert res.json()["prediction"] != "Income > 50k"


from django.urls import path
from Todolist import views

urlpatterns = [

    path('', views.TodO, name="TodO"),
    path('delete/<int:id>/',views.Delete, name="Delete"),
    path('edit/<int:id>/',views.Edit, name="Edit"),
    path('update/<int:id>',views.Update, name="Update")

]


from brownie import accounts, SideEntranceLenderPool
from web3 import Web3

ETHER_IN_POOL = Web3.toWei("1000", "ether")
ATTACKER_INITIAL_BALANCE = None

def before():
    # setup scenario
    deployer = accounts[0]
    attacker = accounts[1]
    pool = SideEntranceLenderPool.deploy({"from": deployer})
    pool.deposit({"from": deployer, "value": ETHER_IN_POOL})
    assert pool.balance() == ETHER_IN_POOL

    global ATTACKER_INITIAL_BALANCE
    ATTACKER_INITIAL_BALANCE = attacker.balance()

def run_exploit():
    # remove pass and add exploit code here
    # attacker = accounts[1] - account to be used for exploit
    pass

def after():
    attacker = accounts[1]
    assert SideEntranceLenderPool[-1].balance() == 0
    # Not checking exactly how much is the final balance of the attacker,
    # because it'll depend on how much gas the attacker spends in the attack
    # If there were no gas costs, it would be balance before attack + ETHER_IN_POOL
    assert attacker.balance() > ATTACKER_INITIAL_BALANCE

def test_side_entrance_challenge():
    before()
    run_exploit()
    after()


from flask import Flask,jsonify,request

import os

import requests

app=Flask(__name__)
app.secret_key=os.urandom(24)

def get_addr(ip):
    url = 'https://api.map.baidu.com/location/ip'
    data = {
        'ip': str(ip),
        'ak': 'kPQGVqe2bbc5wm1cB2nopX6s3R241gR9'
    }
    res = requests.post(url, data=data)
    addr = res.json()['address']
    return addr

@app.route('/get_ip')
def get_ip():
    try:
        ip = request.remote_addr
        address = get_addr(ip)
        return jsonify(msg='ok',ip=ip, address=address)
    except:
        return jsonify(msg='error')

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


#program to find last modified files and big files

import os
import datetime as dt

os.chdir("C:\\Users\\fnuj\\OneDrive - AMDOCS\\Backup Folders\\Desktop\\New folder")

inp=input("1: File modifed, 2:Big file, 3:Big Directory")
now = dt.datetime.now()
ago = now-dt.timedelta(minutes=300)
for root, dirs,files in os.walk('.'):
    dir_size=0
    for fname in files:
        path = os.path.join(root, fname)
        st = os.stat(path)
        mtime = dt.datetime.fromtimestamp(st.st_mtime)
        size = st.st_size
        if inp==1 and mtime > ago:
            print('%s modified %s'%(path, mtime))
        if inp==2 and size>524288:
            print('%s size is %s' %(path,size))
        dir_size=dir_size+size
        if inp==3 and dir_size>524288:
            print('%s Dir size is %s' %(path,dir_size1))

#to find the size of directory we haev to sum up the fixe size in above traversal
if inp == '3':
    for root, dirs,files in os.walk('.'):
        dsize=0
        for dname in dirs:
            path = os.path.join(root, dname)
            st = os.stat(path)
            dsize = dsize+st.st_size
            if dsize>1048576:
                print('%s Dir size is %s' %(path,size))


from flask import Flask
from config.config import getServerConfig
import logging
import os
from utils.Utils import Utils
from restapis.searchData import searchData

app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'some secret key'

app.add_url_rule("/", view_func=searchData.as_view("search_Data"))

serverConfig = getServerConfig()
logFileDir = serverConfig['logFileDir']

if os.path.exists(logFileDir) == False:
    print("LogFile Directory " + logFileDir +
          " does not exist. Exiting the app.")
    exit(-1)

print("LogFile Directory = " + logFileDir)
Utils.initLoggingConfig(logFileDir + "/app.log")

logging.info('serverConfig => %s', serverConfig)

port = serverConfig['port']

if __name__ == "__main__":
    app.run('localhost',port)


import cv2
from tkinter import *
from deepface import DeepFace
from PIL import Image, ImageTk

# Loading Cascade file from the directory
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')

url = "http://192.168.29.53:8080/video"
def openCam():

    cap = cv2.VideoCapture(url)

    while True:
        rat, frame = cap.read()

        # Reading Frame
        rat, frame = cap.read()

        # Flip the image horizontically

        # Converting RGB image to Gray Scale image
        gray = cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY)

        # Detecting faces in image
        faces = face_cascade.detectMultiScale(gray,1.1,4)

        # Draw Ractangle Box around faces
        for (x,y,w,h) in faces:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)

            # Image of each face (Region of Interest)
            ROI = frame[y:y+h,x:x+w]

            # Prediction of Emotion using DeepFace
            prediction = DeepFace.analyze(ROI,actions=['emotion'],enforce_detection=False)

            # Put Text in the image
            font = cv2.FONT_HERSHEY_PLAIN
            cv2.putText(frame,str(prediction[0]['dominant_emotion']),(x,y),font,2,(0,0,255),2,cv2.LINE_4)

        frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)

        photo = ImageTk.PhotoImage(Image.fromarray(frame))
        video_frame['image'] = photo

        root.update()

root = Tk()
root.title("Emotion Detection App")
root.geometry('1200x700')

# Adding Video Frame
video_frame = Label(text='Image',bg="lightyellow")
video_frame.pack()

# Adding Button
button = Button(text="Open Camera",font=('','14'),bg='white',fg='black',borderwidth=2,padx=5,pady=5,command=openCam)
button.pack(pady=20)

root.mainloop()


import subprocess
import sys
from pathlib import Path

# Map genus to gram+/-

def extract_genus_id(record):
    return record.lstrip().rstrip().split(' ')[0]

def read_lists(config_dir) -> dict:
    taxon_to_gram_type = dict()

    for file in config_dir.glob('*_taxon_ids.txt'):
        gram_type = str(file.name).replace('_taxon_ids.txt', '')
        with open(file, 'r') as src_fh:
            for line in src_fh.readlines():
                taxon_to_gram_type[line.rstrip()] = gram_type

    return taxon_to_gram_type

# Genus example (one line from grep)
# mirko-air:bin coriny$ ./taxonkit list --ids 570 --show-rank --show-name | grep "\[genus\]"
# 570 [genus] Klebsiella
# Species example (no output from grep)
# mirko-air:bin coriny$ ./taxonkit list --ids 1280 --show-rank --show-name | grep "\[genus\]"
# mirko-air:bin coriny$
# High level example (lots of output)
# mirko-air:bin coriny$ ./taxonkit list --ids 1224 --show-rank --show-name | grep "\[genus\]" | head
# 262 [genus] Francisella
# 1234547 [genus] Candidatus Nebulobacter
# 1869285 [genus] Allofrancisella
# 330062 [genus] Candidatus Endoecteinascidia
def extract_genus_maps(taxid_dict):

    genus_to_gram_type = dict()

    for taxid in taxid_dict.keys():

        print(taxid, file=sys.stderr)
        command = [taxonkit_path, 'list', '--ids', taxid, '--show-rank', '--show-name']

        lookup_process = subprocess.Popen(command, stdout=subprocess.PIPE)

        genuses = list(filter(lambda x: '[genus]' in x,
                              [line.decode('UTF=8').lstrip().rstrip() for line in lookup_process.stdout.readlines()]))

        for line in genuses:
            print(line, file=sys.stderr)
            genus_id = extract_genus_id(line)
            genus_to_gram_type[genus_id] = taxid_dict[taxid]

    return genus_to_gram_type

library_directory = Path(sys.argv[1])

taxonkit_path = sys.argv[2] if 2 < len(sys.argv) else 'taxonkit'

library_taxids = read_lists(library_directory)

id_map = extract_genus_maps(library_taxids)

with open('genus_to_db.map', 'w') as db_map:
    for taxid in id_map.keys():
        print(taxid, id_map[taxid], file=db_map)


import json
from functools import partial
from pathlib import Path

from katar.engine.io.base_interactor import BaseInteractor
from katar.engine.serializers import BaseSerializer
from katar.engine.utils import int_from_bytes, int_to_bytes
from katar.logger import logger

class KatarInteractor(BaseInteractor):
    def __init__(self) -> None:
        super().__init__()
        self.interactor_type = "katar"

    def get_current_offset(self):
        offset = 0
        with open(self.tracking_file, "rb") as log_reader:
            for chunk in iter(partial(log_reader.read, 4), b""):
                log_length = int_from_bytes(chunk)
                log_reader.read(log_length)
                offset += 1

        return offset

    def get_size_from_location(self, location):
        size = 0
        ignore_first = True
        with open(self.tracking_file, "rb") as log_reader:
            log_reader.seek(location)
            for chunk in iter(partial(log_reader.read, 4), b""):
                log_length = int_from_bytes(chunk)
                log_reader.read(log_length)
                if ignore_first:
                    ignore_first = False
                    continue
                else:
                    size += log_length
        return size

    def print(self):
        print("Printing contents of file -", self.tracking_file)
        with open(self.tracking_file, "rb") as reader:
            for chunk in iter(partial(reader.read, 4), b""):

                length = int_from_bytes(chunk)
                payload_bytes = reader.read(length)

                print(length, payload_bytes)

    def get(self, offset, base_offset, serializer: BaseSerializer, start=0):
        target = offset - base_offset
        with open(self.tracking_file, "rb") as log_reader:
            log_reader.seek(start)
            for chunk in iter(partial(log_reader.read, 4), b""):
                log_length = int_from_bytes(chunk)
                log_in_bytes = log_reader.read(log_length)
                log = serializer.deserialize(log_in_bytes)
                if log["offset"] == target:
                    return log["payload"]
        return None


import discord, json
from data import Gamoo

with open("token.json") as token:
    token = json.load(token)

client = discord.Client()

@client.event
async def on_ready():
    print(f'{client.user} is ready to get you free games!!!')

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content == '!help':
        await message.channel.send('list of commands goes in here')
        return
    if message.content == '!game':
        while True:
            retorno = Gamoo().search_game()
            if retorno != None:
                await message.channel.send(retorno)
            else:
                await message.channel.send("There is no more free games, come back tomorrow")
                break
        return

client.run(token)