import csv
import time
from datetime import datetime, timezone
from pathlib import Path

import inverters

class DataRecorder:
    def __init__(self, inverter: inverters.Inverter, interval=10, path='./'):
        self.inverter = inverter
        self.interval = interval
        self.path = path

        self._init_paths()
        self._run()

    def _init_paths(self) -> None:
        """
        Initialize the paths where the collected data from the inverters is saved.
        Later there should be a logic if two prevent collision if two inverters have the same name
        :return:
        """
        path_data_dir = Path(self.path) / 'data'

        if not path_data_dir.exists():
            path_data_dir.mkdir(parents=True)

        self.path_csv = path_data_dir / f'{self.inverter.name.lower()}.csv'

    def _run(self) -> None:
        # Open the CSV file in append mode with newline='' to avoid extra line breaks
        with open(self.path_csv, mode='a', newline='') as file:
            writer = csv.writer(file)
            print('checking file headers')

            # Write header if the file is empty
            if file.tell() == 0:
                print('no header found in file, catch first data')
                while True:
                    data = self.inverter.get_data()
                    if data != None:
                        csv_columns = ['time'] + list(data.keys())
                        print(f'new header: {csv_columns}')
                        writer.writerow(csv_columns)
                        break

        print('file headers found, started recording')
        while True:
            # Get the current time
            format_string = '%Y-%m-%d %H:%M:%S %Z'
            current_time = datetime.now(timezone.utc).strftime(format_string)

            # Get data from the get_data() function
            data = self.inverter.get_data()

            # Create a tuple with current time and data
            row = (current_time,) + tuple(data.values())

            with open(self.path_csv, mode='a', newline='') as file:
                writer = csv.writer(file)

                # Write the tuple to the CSV file
                writer.writerow(row)

                # Flush the file to make sure the data is written immediately
                file.flush()

            time.sleep(self.interval)


# Python program to print all permutations with
# duplicates allowed
def toString(List):
    return ''.join(List)

# Function to print permutations of string
# This function takes three parameters:
# 1. String
# 2. Starting index of the string
# 3. Ending index of the string.
def permutation(a, l, r):
    if l == r:
        print(toString(a))
    else:
        for i in range(l, r + 1):
            a[l], a[i] = a[i], a[l]
            permutation(a, l + 1, r)
            a[l], a[i] = a[i], a[l] # backtrack

# Driver program to test the above function
string = input("Enter the string: ")
n = len(string)
arr = list(string)
permutation(arr, 0, n-1)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Threat conditioning of tones using a loud white noise

Author: Santiago Munoz
Universite Libre de Bruxelles
smunozmo@ulb.ac.be
"""

#========================
# Importing used modules
#========================

from __future__ import division
from psychopy import monitors, gui, visual, core, data, event, logging
import numpy as np
from numpy.random import random, randint, normal, shuffle, uniform
from math import ceil, floor
import glob, os
from pyo import *

#==========================================
# Store info about the experiment session
#==========================================
#------------------------------
# Experiment session GUI dialog
#------------------------------

#get values from dialog
expName='WhiteNoise'
myDlg = gui.Dlg(title=expName, pos = (860,340))
myDlg.addField(label='participant',initial=0, tip='Participant name or code'),
myDlg.addField(label='age',initial=0, tip='Participant age'),
myDlg.addField(label='sex', choices=('female','male', 'non-binary'))
myDlg.addField(label='session',initial='', choices=['test', 1, 2], tip='Session Nr'),
myDlg.addField(label='screen', choices=(144, 60), tip='Refresh Rate')
myDlg.addField(label='triggers', initial='Yes', choices=['Yes', 'No'], tip='Send Parallel Port Triggers')
dlg_data = myDlg.show()
if myDlg.OK==False: core.quit()  #user pressed cancel

#store values from dialog
expInfo = {
    'participant':dlg_data[0],
    'age':dlg_data[1],
    'sex':dlg_data[2],
    'session':dlg_data[3],
    'screen':dlg_data[4],
    'triggers':dlg_data[5]
    }

expInfo['date']=data.getDateStr()  #add a simple timestamp
expInfo['expName']=expName

#-----------------------
#setup files for saving
#-----------------------

if not os.path.isdir('data'):
    os.makedirs('data') #if this fails (e.g. permissions) we will get error
filename='data' + os.path.sep + '%s_%s' %(expInfo['participant'], expInfo['date'])
logFile=logging.LogFile(filename+'.log', level=logging.EXP)
logging.console.setLevel(logging.WARNING)#this outputs to the screen, not a file

#====================================================================
# Setting some static variables that we might want to tweak later on
#====================================================================

#number of repetitions of each condition
nReps = 60

#determine screen's refresh rate
hz = int(expInfo['screen'])

#experiment time durations in seconds
times= {"REST" : 1., "CS" : 5.5, "UCS" : 0.5, "ITI" : 5.}

#adjust times in seconds to frames depending on screen's refresh rate
#choose 'ceil' for rounding up, 'floor' for rounding down (no half frames)
timeInFrames= {  # choose 'ceil' for rounding up, 'floor' for rounding down
        "REST" : int(ceil(hz * times["REST"])),
        "CS" : int(ceil(hz * times["CS"])),
        "UCS" : int(ceil(hz * times["UCS"])),
        "ITI" : int(ceil(hz * times["ITI"])),
        }

#=====================
# Open parallel port
#=====================
# Parallel port drivers need to be installed
# Note: the file inpout32.dll needs to be in the same folder

#triggers can be turned On or Off
if expInfo['triggers']=='Yes': triggers = True
else: triggers = False

if triggers:

    from psychopy import parallel

    port = parallel.ParallelPort(address=0xDEFC) #0xB010 in new Stim PC, 0xDEFC in Personal PC

    #create function to use shorter trigger commands
    def sendTrigger(code):
        port.setData(code)  #sets combination of pins high/low (0-255)
        core.wait(0.002)
        port.setData(0)  #sets all pins low again

    # TRIGGERS:
    triggerList = {
        'iti':10,  # ITI, first screen flip
        'CS-':11,  # fixation cross, first flip
        'CS+':12,  # fixation cross, first flip
        'UCSStart':13,  # fixation cross, first flip
        'resp':20,  # rating click response
        'restStart':100,  # rest Start
        'restEnd':101,  # rest Stop
        'eegStart':254,  # eeg rec start (set in biosemi config file)
        'eegStop':255   # eeg rec stop (set in biosemi config file)
        }

    sendTrigger(0) #sets all pins low to start
    sendTrigger(triggerList["eegStart"]) #start recording EEG

#===============================
# Creation of window and stimuli
#===============================

#-------------------
# Monitor and screen
#-------------------

# Monitor ('iiyama 144 Hz')
widthPix = 1920  #screen width in px
heightPix = 1080  #screen height in px
monitorwidth = 53.1  #monitor width in cm
viewdist = 60.  #viewing distance in cm
monitorname = 'iiyama'
scrn = 0  #0 to use main screen, 1 to use external screen
mon = monitors.Monitor(monitorname, width=monitorwidth, distance=viewdist)
mon.setSizePix((widthPix, heightPix))
mon.save()

# Initialize window
win = visual.Window(
    monitor=mon,
    size=(widthPix,heightPix),
    color=[0,0,.7255],  #'#B9B9B9' in hex
    colorSpace='hsv',  # !
    units='deg',
    screen=scrn,
    allowGUI=False,
    fullscr=True)

# win = visual.Window([800, 600], color='Gray', units='pix')  # For testing only

#-------
# MOUSE
#-------

mouse = event.Mouse(visible=True, win=win)

#---------------
# TEXT ELEMENTS
#---------------

# Instructions text
instruction_list = []
text_size = .6  #in degrees of visual angle (dva)
text_color = 'black'
text_font = 'Georgia'
restMessage = visual.TextStim(win,
    text=u"""Bienvenue. Nous allons commencer par une période de repos de trois minutes.
Vous ne devrez rien faire de particulier: trouvez simplement une position confortable et
laissez vos pensées divaguer. Evitez autant que possible les mouvements du corps.

Appuyez sur la touche « espace » pour démarrer la période de repos.""",
    color=text_color ,
    height=text_size,
    font=text_font)
OK = visual.TextStim(win,
    text=u"OK!",
    color=text_color ,
    height=text_size,
    font=text_font)
Merci = visual.TextStim(win,
    text=u"Merci!",
    color=text_color ,
    height=text_size,
    font=text_font)
start_message = visual.TextStim(win,
    text=u"""Bienvenue! Merci de participer à cette expérience.\
    Appuyez sur la barre d'espace pour lire les instructions.""",
    color=text_color ,
    height=text_size,
    font=text_font)
run_message = visual.TextStim(win,
    text=u"""Dès que vous appuyerez sur la barre d'espace, nous commencerons \
avec la vraie expérience.
    A vous de jouer!""",
    color=text_color ,
    height=text_size,
    font=text_font)
pause_message = visual.TextStim(win,
    text=u"",
    color=text_color ,
    height=text_size,
    font=text_font)

instruction_list.append(start_message)

#--------
# SOUNDS
#--------

# Create and boot a server
sv = Server(sr=44100, nchnls=2, buffersize=128, duplex=0, winhost="asio")
sv.verbosity = 0
sv.boot()   #initialize audio stream
sv.start()  #activates server processing loop

#frequencies for the sine tones in Hz
if int(expInfo['participant']) % 2 == 0: #even number
    toneFreqs = {"CS-" : 700, "CS+" : 1300}
else:  #odd number
    toneFreqs = {"CS-" : 1300, "CS+" : 700}

#starting volume
# UCS volume: 0.1275 = 95 dB; 0.1 = 91.8 dB
# CS volume: 0.0005 = 40 dB
volumes = {"CS-" : .0001, "CS+" : .0001, "UCS" : .1275}

#list with created sounds
sounds = {
    "CS-": Sine(freq=toneFreqs["CS-"], mul=volumes["CS-"]),
    "CS+": Sine(freq=toneFreqs["CS+"], mul=volumes["CS+"]),
    "UCS": Noise(mul=volumes["UCS"]).mix(2)  #mix(2) for dual-channel
}

#staircase paremeters
volumeRatioStart = 0.812  #volume reduction is done by dividing by this value (corresponds to -3dB decrease in perceived loudness)
volumeRatioChange = 0.05  #value that will be added to volumeRatio to change step size (will never go above 1.0)
volumeRatio = volumeRatioStart
#running average
running_perf = np.array([])  #running average of performance
window_length = 10  #change vol unit if 3 non-detections in the last 6 trials
perf_threshold = 0.6  #XX% performance

#--------
# IMAGES
#--------

restScreen = visual.ImageStim(win=win,
    image="imgs/landscape-1920x1080.jpg", units="deg", size= (32, 18))

#--------------
# RATING SCALE
#--------------

# Creating my own rating scale for full flexibility.
# I follow guidelines from Matejka 2016: No ticks, 2 labels, dynamic text
# feedback

#------------- You can adjust these
scale_max = 100 #maximum rating in the rating scale (int)
rs_max = 7  #scale upper limit in degrees of visual angle
rs_col = '#373F51'  #charcoal color
rs_txt_col = rs_col
rs_txt_size = .7
labelsYPos = -1
dynTxtYPos = 1
_rs_min = (-1 * rs_max)
labelsXPos = [x * rs_max for x in [-1, 1]]
labels = ["0 %", "100 %"]

#------------- No need to adjust these
dyn_txt = visual.TextStim(win, text=u"", height=rs_txt_size, color = rs_txt_col)
#scale stimuli: horizontal bar, labels, ticks/bands
rs_stims = []
rs_stims += [visual.Rect(win, width=rs_max*2, height=.1, fillColor = rs_col,
             lineColor = rs_col)]
for nr, thisXPos in enumerate(labelsXPos):  #text
    rs_stims += [visual.TextStim(win, text=labels[nr], height=rs_txt_size,
                 pos = [thisXPos, labelsYPos], color = rs_txt_col)]
#moving slider
rs_slider = visual.Rect(win, width=.25, height=1., fillColor = rs_col,
                        lineColor = rs_col)

#initialize some variables
ratings_allTrials = []  #all ratings matrix

#======================================================
# Create conditions list and trialhandler to run trials
#======================================================

trialTypes = ["CS-", "CS+"]

trialList = []
for trialType in trialTypes:
    trialList.append({"trialType": trialType, "toneFreq": toneFreqs[trialType]})

#organize trials
trials = data.TrialHandler(trialList, nReps, method = 'random', extraInfo=expInfo)

#============
# INITIALIZE
#============
#------------------
# Resting period
#------------------

#message before rest
restMessage.draw()
win.flip()
keypress= event.waitKeys(keyList=['space', 'escape'])
if keypress[0] == 'escape': core.quit()

#start rest period
if triggers: sendTrigger(triggerList["restStart"])
for thisFrame in range(timeInFrames["REST"]):
    restScreen.draw() #landscape picture
    win.flip()
core.wait(.5)
if triggers: sendTrigger(triggerList["restEnd"])

#show 'OK!' message
OK.draw()
win.flip()
core.wait(1)

#----------------------------------
# Instructions screens and training
#----------------------------------

run_message.draw()
win.flip()
keypress= event.waitKeys(keyList=['space', 'escape'])
if keypress[0] == 'escape': core.quit()

#============================================
# Start main loop that goes through all trials
#============================================

for thisTrial in trials:

    #is this trial CS- or CS+?
    cond = thisTrial["trialType"]

    #wait for inter-trial interval
    if triggers: win.callOnFlip(sendTrigger, triggerList["iti"])
    for thisFrame in range(timeInFrames["ITI"]):
        win.flip()

    #--------------
    # Play CS sound
    #--------------

    #set sound
    cs = sounds[cond]  # CS- or CS+

    #set volume for this trial (updated at each trial)
    cs.setMul(volumes[cond])

    #play sound (Start processing and sending samples out)
    # cs.out(dur=times["CS"])
    cs.out()

    #send a trigger at next window flip
    if triggers: win.callOnFlip(sendTrigger, triggerList[cond])
    win.flip()

    #---------------------------
    # Rating Scale during sound
    #---------------------------

    #prepare and reset between repeated uses of the same scale
    event.clearEvents()
    detected = False
    detectedRT = None
    RATING = None
    ratings_thisTrial = []  #continuous rating
    ratings_thisTrial.append(trials.thisN)
    rs_slider.setFillColor('#FEFFFA')
    mouse.setPos([0,0])
    mouse.clickReset()
    #start showing the scale
    for thisFrame in range(timeInFrames["CS"]):
        #draw all components of the rating scale
        for stim in rs_stims:
            stim.draw()
        #set slider and dynamic text position to follow mouse (with limits)
        m_x, m_y = mouse.getPos()
        if m_x < _rs_min: m_x = _rs_min
        if m_x > rs_max: m_x = rs_max
        rs_slider.setPos([m_x, 0])
        rs_slider.draw()
        #re-scale rating value to new range
        RATING = int(((m_x+rs_max)/rs_max)*(scale_max/2))
        dyn_txt.setPos([m_x, dynTxtYPos])
        dyn_txt.setText(str(RATING)+ " %")
        dyn_txt.draw()
        win.flip()
        #listen to keyboard and mouse
        buttons, RT = mouse.getPressed(getTime=True)  #returns 3-item list and time since reset
        if not detected and buttons[0]:  #first click detected
            detected = True
            detectedRT = round(RT[0], 2)
            if triggers: sendTrigger(triggerList["resp"])
            rs_slider.setFillColor('#1A7AF8')
            mouse.clickReset()
        if event.getKeys(['escape']): core.quit()
        #save continuous rating sampled at each frame in a vector
        ratings_thisTrial.append(RATING)

    #stop sound
    cs.stop()

    #blank screen
    win.flip()

    #----------------
    # Play UCS sound
    #----------------

    if cond is "CS+":
        #set sound
        ucs = sounds["UCS"]

        #play sound
        ucs.out()

        #send trigger at next window flip
        if triggers: win.callOnFlip(sendTrigger, triggerList["UCSStart"])
        win.flip()

    #wait during sound
    for thisFrame in range(timeInFrames["UCS"]):
        win.flip()

    #stop sound
    if cond is "CS+": ucs.stop()

    #======================
    # Some data processing
    #======================

    #add this trial ratings to all trials ratings
    ratings_allTrials.append(ratings_thisTrial)

    #--------------------------------------
    # 1. Calculate running average of perf
    #--------------------------------------

    #add last detection responses to running average
    if len(running_perf)<window_length:  #add new value only
        running_perf = np.concatenate((running_perf[:], [detected]))
    elif len(running_perf)==window_length:  #add a new value and remove first value
        running_perf = np.concatenate((running_perf[1:], [detected]))

    #calculate running average of performance
    running_perf_mean = np.count_nonzero(running_perf)/len(running_perf)

    goodperformance = running_perf_mean==1.0
    badperformance = running_perf_mean <= perf_threshold
    enoughtrials =  len(running_perf)==window_length
    room4change = (volumeRatio + volumeRatioChange) < 1  #3 decrements of unit
    #if random performance and enough trials
    if badperformance and enoughtrials and room4change:
        #make the steps smaller
        volumeRatio += volumeRatioChange
        running_perf = np.array([])  #restart running average

    #if perfomance is good, return to previous ratios of change
    if goodperformance and enoughtrials and volumeRatio>volumeRatioStart:
        #make the steps bigger
        volumeRatio -= volumeRatioChange
        running_perf = np.array([])  #restart running average

    #--------------------------------
    # 2. Modify volume for next trial
    #--------------------------------

    if detected:
        volumes[cond] *= volumeRatio
    elif not detected:
        volumes[cond] /= volumeRatio

    #----------------------------------
    # Add the data to the trialHandler
    #----------------------------------

    #add response to trialHandler
    trials.addData('detected', detected)
    trials.addData('detectedRT', detectedRT)
    trials.addData('lastRating', RATING)
    trials.addData('volume', volumes[cond])
    trials.addData('volUnit', volumeRatio)
    trials.addData('averagePerformance', running_perf_mean)

    #========================
    # Allow for short breaks
    #========================

    if trials.thisN%10==0 and trials.thisN is not 0: #inform participant of the progress
        progText=u"{0:.0f}% des essais complétés!".format(100*((trials.thisN)/float(trials.nTotal)))
        pause_message.setText(progText)
        pause_message.draw()
        win.flip()
        keypress= event.waitKeys(keyList=['space', 'escape'])
        if keypress[0] == 'escape': core.quit()

#======
# Save
#======

# Stop Biosemi EEG recording
if triggers: sendTrigger(triggerList["eegStop"])

# Save response data
trials.saveAsWideText(filename+'.csv')

# Save continuous ratings in a file (1 trial per row, 1 sample per column)
# Add trial Nr and participant number

arr = np.array(ratings_allTrials)
np.savetxt(filename+'_ratings.csv', arr, delimiter=",", fmt = '%.0f')

#=======
# Close
#=======

# Show 'Merci!' message
Merci.draw()
win.flip()
core.wait(4)

sv.stop()
win.close()
core.quit()


import socket
import sys
import struct

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography import x509
from cryptography.x509.oid import NameOID

CA_ADDR = ("140.113.194.88", 20000)
GAME_DOWNLOADER_ADDR = ("140.113.194.88", 20500)
STUID = "0556518"
BLOCK_SIZE = 16

my_padding = lambda s: s + (BLOCK_SIZE * int(len(s) / BLOCK_SIZE + 1) - len(s) % BLOCK_SIZE) * '\0'

# recv exactly n bytes
def recvall(sock, n):

    data = b''

    while len(data) < n:
        packet = sock.recv(n - len(data))
        if not packet:
            return None
        data += packet

    return data

# send size of message and message to destination
def sendmsg(sock, message):

    msg_size = len(message)
    byte_msg_size = struct.pack("i", msg_size)

    if type(message) == str:
        message = bytes(message, 'utf-8')

    sock.sendall(byte_msg_size)
    sock.sendall(message)

# receive size of message and message from destination
def recvmsg(sock):

    msg_size = struct.unpack("i", sock.recv(4))
    return recvall(sock, int(msg_size[0]))

def rsa_decrypt(ciphertext, key):

    return key.decrypt(
        ciphertext,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA1()),
            algorithm=hashes.SHA1(),
            label=None
        )
    )

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as ca_sock, \
     socket.socket(socket.AF_INET, socket.SOCK_STREAM) as game_downloader_sock:

    # connect to CA
    ca_sock.connect(CA_ADDR)

    # send student ID to CA
    sendmsg(ca_sock, STUID)

    # receive "hello" from CA
    recvmsg(ca_sock)

    # generate my public key and private key
    my_private_key = rsa.generate_private_key(
        public_exponent=3,
        key_size=1024,
        backend=default_backend()
    )
    my_public_key = my_private_key.public_key()

    # generate certificate signing request
    csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, STUID)
    ])).sign(
        my_private_key, hashes.SHA256(), default_backend()
    )

    # send CSR to CA in pem foramat
    sendmsg(ca_sock, csr.public_bytes(serialization.Encoding.PEM))

    # receive certificate from CA
    cert_pem = recvmsg(ca_sock)

    # receive bye from CA
    recvmsg(ca_sock)

    # connect to GameDownloader
    game_downloader_sock.connect(GAME_DOWNLOADER_ADDR)

    # send student ID to GameDownloader
    sendmsg(game_downloader_sock, STUID)

    # receive "hello" from GameDownloader
    recvmsg(game_downloader_sock)

    # send certificate to GameDownloader in pem format
    sendmsg(game_downloader_sock, cert_pem)

    # receive "PASS" from GameDownloader
    recvmsg(game_downloader_sock)

    # receive GameDownloader's encrypted AES Session Key, Initial Vector and use my private key to decrypt
    aes_seesion_key = rsa_decrypt(recvmsg(game_downloader_sock), my_private_key)
    initial_vector = rsa_decrypt(recvmsg(game_downloader_sock), my_private_key)

    # create AES decryptor
    cipher = Cipher(algorithms.AES(aes_seesion_key), modes.CBC(initial_vector), backend=default_backend())
    aes_decryptor = cipher.decryptor()

    # receive Game Binary and use Aes Session Key to decrypt
    encrypted_game = recvmsg(game_downloader_sock)
    game = aes_decryptor.update(encrypted_game) + aes_decryptor.finalize()

    with open("game", "wb") as f:
        f.write(game)

    print('Download Complete. File named "game" is in the current working directory')

    # send "bye" to GameDownloader
    sendmsg(game_downloader_sock, "bye")


#Código de @arthurbarcala.
#Por favor não roube :)
import random

#Escolher uma palavra
bancoPalavras = ("instituto", "empresa", "escola", "programação", "python", "linguagem", "computador", "teclado", "pneumoultramicroscopicossilicovulcanoconiótico", "café", "depressão", "suicídio", "morte", "insanidade")
palavra = bancoPalavras[random.randint(0, len(bancoPalavras))]
palavraOculta = []
letrasInvalidas = []
vidas = 6
acertos = 0

#do (isso seria o do/while se tivesse no python)
for yay in range(0, len(palavra)):
    palavraOculta.append("_")
# fazer o usuário inserir uma letra
print(f"vidas: {vidas}, acertos: {acertos}")
print(f"Palavra: {palavraOculta}")
print(f"Letras inválidas: {letrasInvalidas}")
letra = input("Insira uma letra:\n")
# verificar se a letra inserida está na palavra
if letra in palavra and letra not in letrasInvalidas:
    for x in range(0, len(palavra)):
        if palavra[x] == letra:
            palavraOculta[x] = letra
            acertos += 1
    letrasInvalidas.append(letra)
    # Se não estiver, perde uma vida.
elif letra in letrasInvalidas:
    print("Essa letra ja foi!!")
else:
    vidas -= 1
    letrasInvalidas.append(letra)

while vidas > 0 and acertos < len(palavra):
    # fazer o usuário inserir uma letra
    print(f"vidas: {vidas}, acertos: {acertos}")
    print(f"Palavra: {palavraOculta}")
    print(f"Letras inválidas: {letrasInvalidas}")
    letra = input("Insira uma letra:\n")
    # verificar se a letra inserida está na palavra
    if letra in palavra and letra not in letrasInvalidas:
        for x in range(0, len(palavra)):
            if palavra[x] == letra:
                palavraOculta[x] = letra
                acertos += 1
        letrasInvalidas.append(letra)
        # Se não estiver, perde uma vida.
    elif letra in letrasInvalidas:
        print("Essa letra ja foi!!")
    else:
        vidas -= 1
        letrasInvalidas.append(letra)

#Se revelar todas as letras ganha o jogo
if acertos == len(palavra):
    print("Parabéns!! Você acertou a palavra!")
    print(f"A palavra é {palavra}")
if vidas == 0:
    print("Você perdeu!!")
    print(f"A palavra era {palavra}")
#Se perder todas as vidas perde!


import subprocess
import sys

try:
	infile = sys.argv[1]
	outfile = sys.argv[2]
except:
	print("Provide input wav file and name for output file")
	sys.exit(0);

encodecmd = ["lame",infile,outfile]

subprocess.call(encodecmd)


import sys

# 무조건 3개 선택이고
# N은 카드 개수 M은 우리가 만들고자 하는 수

input=sys.stdin.readline

def black_jack(N,M,list_):
    sum_list=[]
    for i in range(0,N-2):
        for k in range(i+1,N-1):
            for j in range(k+1,N):
                sum_=list_[i]+list_[k]+list_[j]
                if sum_<=M:
                    sum_list.append(sum_)
    print(max(sum_list))

def main():
    N,M = map(int, input().split())
    list_=list(map(int,input().split()))
    black_jack(N,M,list_)

if __name__=="__main__":
    main()


import scipy.io as sio
import networkx as nx
import numpy as np
import os

def find_subgraph(file_name):

    G = nx.read_gml(file_name,label='id,label,value')
    temp_list = None
    max = 0
    sum_num = 0
    temp_list =[]
    for c in sorted(nx.connected_components(G),key=len,reverse=True):

        lenc = len(c)
        # print(type(c))      #类型是set
        # print("len" ,len(c))

        num = get_value(G,c)
        sum_num = sum_num + num
        if lenc< 100 and lenc >2:

            # print (c)
            # sub_graph = nx.Graph(c)
        # num = get_value(G,c)
            if max < num :
                max = num
                temp_list = c
            # print(lenc, num)

        print(sum_num,len(temp_list),max,num)

    return temp_list

def get_value(G,c):
    num = 0
    for n in c:
        if G.node[n]['value'] == '1':
            num = num + 1
    return num

if __name__ == '__main__':
#dir_name = 'temp_data_91_1_40_25'

    path = "/mnt/f/test/task2/GraphRicciCurvature/data=0.2/"
    top_name = 'temp_data_'
    bot_name = '_1_30_15/'
#-------------------------------------
    start_id = 80
    end_id = 91
    name_list = ['3surgery','4surgery','4_1_new_surgery','2_1_new_surgery','4surgery','4surgery','save_grad_3surgery(best)','save_grad_3surgery','save_grad_2surgery','save_grad_4surgery','4surgery']
#------------------------------------
    for i,id in enumerate(range(start_id,end_id)):
        id = str(id)
        file_dir = path+ top_name + id + bot_name+name_list[i]+'.gml'
        # name = '4surgery'

        if os.path.exists(file_dir):
            print(file_dir)
        else :
            print("file not exists")
        sub_graph =find_subgraph(file_dir)

        # os.system("pause")
        input()


import open3d as o3d
import cv2 as cv
import numpy as np
from argparse import ArgumentParser

class SphericalVisualizer:
    def __init__(self):
        '''
        Creates a visualization for 360 (spherical) image
        from equirectangular image.
        '''
        self.load_view_point()

    def equi_to_spherical(self, image, Z = 3):
        '''
        Converts equirectagular image to
        360 image which can be visualized.

        :type image: numpy array
        :param image: image to be converted into mesh
        '''
        height, width, n_channels = image.shape
        image = image[...,::-1]

        mesh_x, mesh_y, mesh_z = np.meshgrid(np.linspace(0, width-1, width), np.linspace(0, height-1, height), Z)

        theta = mesh_x / width * (2*np.pi)
        phi = mesh_y / height * (np.pi)
        r = 3.5

        mesh_x = r * np.sin(phi) * np.cos(-theta)
        mesh_y = r * np.sin(phi) * np.sin(-theta)
        mesh_z = r * np.cos(phi)

        XYZ = np.stack((mesh_x, mesh_y, mesh_z), axis = -1)
        XYZ = np.squeeze(XYZ)
        XYZ = np.reshape(XYZ, (height * width, -1))
        colors = (np.reshape(image, (width * height, n_channels))) / 256
        pcd = o3d.geometry.PointCloud()

        pcd.points = o3d.utility.Vector3dVector(XYZ)
        pcd.colors = o3d.utility.Vector3dVector(colors)

        return pcd

    def load_view_point(self):
        '''
        Creates a pinhole camera parameter such that
        the default view is directed toward front face.
        '''
        self.param = o3d.camera.PinholeCameraParameters()
        self.param.intrinsic.set_intrinsics(1920, 1016, 879.88181024498977,
                                            879.88181024498977,959.5,507.5)
        self.param.extrinsic = np.array([[0, 1, 0, 0],
                                         [0, 0, -1, 0],
                                         [-1, 0, 0, 0],
                                         [0, 0, 0, 1]])

    def visualization(self, image_path):
        '''
        Creates the visualiation.

        :type image_path: string
        :param image_path: Path to input image.
        '''
        self.image360 = cv.imread(image_path)
        self.sph = self.equi_to_spherical(self.image360)

        vis = o3d.visualization.Visualizer()
        vis.create_window()
        vis.get_render_option().background_color = np.asarray([0, 0, 0])
        ctr = vis.get_view_control()

        vis.add_geometry(self.sph)
        ctr.convert_from_pinhole_camera_parameters(self.param)

        vis.run()
        vis.destroy_window()

if __name__ == '__main__':
    parser = ArgumentParser('Spherical image visualizer.')
    parser.add_argument('--image', help='Path to 360 image to be visualized.')
    args = parser.parse_args()

    image_path = str(args.image)
    SphericalVisualizer().visualization(image_path)


from textblob import TextBlob
# import pyttsx3

# engine = pyttsx3.init()
# engine.say("Hello Employee Number 123510905960124. We hope you had a great day of work. It's time to submit your employee wellness statement")
# engine.runAndWait()

print("Enter your wellness statement: ")
phrase = input("> ")

blob = TextBlob(phrase)

while blob.sentiment.polarity < 0.5:
    print("More positive please: ")
    phrase = input("> ")
    blob = TextBlob(phrase)

print("We appreciate you too!")


from ToolCommand import ToolCommand
import sys
from fn_qradar_advisor.lib.qradar_advisor_client import QRadarAdvisorClient
import logging
logging.basicConfig(filename="testing.log", level=logging.DEBUG)

HELP_STR = """
	Usage:\n
	\t quick_search.py -i app_id -s search_value
	"""
arg_str = "hi:s:"
arg_list = ["help", "app_id", "search"]

class SampleCmd(ToolCommand):

    def do_command(self):
        client = QRadarAdvisorClient(qradar_host=self.system_host,
                                     qradar_token=self.system_token,
                                     advisor_app_id=self.opts_dict["app_id"],
                                     cafile=False, log=logging,
                                     opts={}, function_opts=self.opts_dict)
        resp = client.quick_search(self.opts_dict["search"])
        print(str(resp))

if __name__ == "__main__":
	sample_cmd = SampleCmd(HELP_STR)
	sample_cmd.run_command(sys.argv[1:], arg_str, arg_list)


from flask import Flask, request, jsonify
from flask_cors import CORS
import json
import os
import pandas as pd
from PIL import Image
import base64
import io

FILE_ABS_PATH = os.path.dirname(__file__)

app = Flask(__name__)
CORS(app)

FILE_ABS_PATH = os.path.dirname(__file__)
PROCESS_DATA_FOLDER = os.path.join(FILE_ABS_PATH, 'data/ImageNet_SR')
DATA_FOLDER = "E:\imageNet\\"
RESULT_FOLDER = os.path.join(DATA_FOLDER, 'sr')

RAW_FOLDER =  os.path.join(DATA_FOLDER, '50000_N_N_224')
BICUBIC_FOLDER = os.path.join(RESULT_FOLDER, '50000_DS-bicubic_N_224')
VDSR_FOLDER = os.path.join(RESULT_FOLDER, '50000_DS-bicubic_VDSR-1_224')
SRResnet_FOLDER = os.path.join(RESULT_FOLDER, '50000_DS-bicubic_SRResNet-4_224')
HCFlow_FOLDER = os.path.join(RESULT_FOLDER, '50000_DS-bicubic_HCFlow-4_224')
N = 5000
data_configs = [
    {'model': 'bicubic', 'folder': BICUBIC_FOLDER},
    {'model': 'vdsr', 'folder': VDSR_FOLDER},
    {'model': 'srresnet', 'folder': SRResnet_FOLDER},
    {'model': 'hcflow', 'folder': HCFlow_FOLDER},
    {'model': 'raw', 'folder': RAW_FOLDER}
]
DATA_PATH = os.path.abspath(os.path.join(FILE_ABS_PATH, 'data'))

def generate_nested_dict_from_df(df):
    re_names = []
    for column in df.columns:
        if column in  ['imnames', 'label']:
            re_names.append((column, column))
        else:
            re_names.append(tuple(column.split('%')))
    df.columns = pd.MultiIndex.from_tuples(re_names)
    l = df.to_dict('records')
    two_level_array = []
    for record in l:
        _dict = {}
        for (k1, k2) in record:
            if k1 == k2:
                _dict[k1] = record[(k1, k2)]
            else:
                if k1 not in _dict:
                    _dict[k1] = {}
                _dict[k1][k2] = record[(k1, k2)]
        two_level_array.append(_dict)
    return two_level_array

@app.route('/api/SR/loadSRMetrics/', methods=['POST'])
def fetch_sr_metrics():
    label_df = pd.read_csv(os.path.join(PROCESS_DATA_FOLDER,  'ImageNet_label.csv'))
    metric_df = pd.read_csv(os.path.join(PROCESS_DATA_FOLDER, 'metrics.csv'))
    merge_df = metric_df.merge(label_df, on='imnames')
    nested_array = generate_nested_dict_from_df(merge_df.head(N))
    return jsonify(nested_array), 200, {"Content-Type": "application/json"}

@app.route('/api/SR/loadSRModels/', methods=['POST'])
def load_sr_models():
    return jsonify(['vdsr', 'srResNet', 'hcflow']), 200, {"Content-Type": "application/json"}

@app.route('/api/SR/loadMetricNames/', methods=['POST'])
def load_metric_names():
    return jsonify(['lpips', 'ssims', 'psnrs']), 200, {"Content-Type": "application/json"}

@app.route('/api/SR/loadClassificationModels/', methods=['POST'])
def load_classification_models():
    return jsonify(['googlenet', 'alexnet', 'vgg19', 'resnet50', 'swin_b', 'convnext_large']), 200, {"Content-Type": "application/json"}
#
@app.route('/api/SR/loadDatasetIds/', methods=['POST'])
def load_dataset_ids():
    return jsonify(['bicubic_224', 'vdsr', 'srResNet', 'hcflow']), 200, {"Content-Type": "application/json"}

def process_classification_results(dataset_ids, classification_id):
    all_df = None
    label_df = pd.read_csv(os.path.join(PROCESS_DATA_FOLDER, 'ImageNet_label.csv')).head(N)
    for dataset_id in dataset_ids:
        data_path = os.path.join(PROCESS_DATA_FOLDER, "{}%{}.csv".format(dataset_id, 'all'))
        print(dataset_id, "{}%{}.csv".format(dataset_id, 'all'))
        df = pd.read_csv(data_path).head(N)
        columns = ['imnames', '{}%top1_id'.format(classification_id), '{}%top1_prob'.format(classification_id) ]
        df = df[columns]
        update_column = {}
        for column in columns:
            if column == 'imnames': continue
            update_column[column] = "{}%{}".format(dataset_id, column)
        df = df.rename(columns=update_column)
        if all_df is None:
            all_df = df
        else:
            all_df = all_df.merge(df, on='imnames')
    all_df = all_df.merge(label_df, on='imnames')
    all_dicts = all_df.to_dict('records')
    update_records = []
    def to_nest_attr(dict):
        _dict = {}
        for attr in dict:
            if attr in ['imnames', 'label']:
                _dict[attr] = dict[attr]
            else:
                l1, l2, l3 = attr.split('%')
                if l1 not in _dict:
                    _dict[l1] = {}
                _dict[l1][l3] = dict[attr]
        return _dict
    for dict in all_dicts:
        update_records.append(to_nest_attr(dict))

    return update_records

@app.route('/api/SR/jointlyAnalysis/', methods=['POST'])
def jointly_analysis():
    print(request.json)
    dataset_ids = request.json['firstAttributes']
    classification_id = request.json['classificationIds'][0]
    print(dataset_ids, classification_id)
    results = process_classification_results(dataset_ids=dataset_ids,
                                             classification_id=classification_id)
    return jsonify(results), 200, {"Content-Type": "application/json"}

# jointlyAnalysis
def load_model_performance():
    return ['vdsr', 'srResNet', 'hcflow']
    data_path = os.path.join(DATA_PATH, 'classification.csv')
    df = pd.read_csv(data_path)
    resp = df.to_dict('records')
    # resp = resp[:100]
    for r in resp:
        r['id'] = int(r['imname'].split('.')[0].split('_')[-1])
    print("Total number records: ", len(resp))

    map_path = os.path.join(DATA_PATH, 'label2name.json')
    with open(map_path, 'r') as input_file:
        label2Name = json.load(input_file)
    return jsonify({
        'results': resp,
        'label2Name': label2Name
    }), 200, {"Content-Type": "application/json"}

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


import os
import csv

csvpath = os.path.join('..', 'PyPoll', 'election_data.csv')

total_votes = 0
candidates = []
unique_candidates = []
O_Tooley_votes = 0
Khan_votes = 0
Correy_votes = 0
Li_votes = 0

with open(csvpath, newline="") as csvfile:
    csvreader = csv.reader(csvfile, delimiter=",")

    csv_header = next(csvreader)

    for row in csvreader:

        total_votes += 1

        candidates.append(row[2])

        if row[2] == "O'Tooley":
            O_Tooley_votes += 1

        elif row[2] == "Khan":
            Khan_votes += 1

        elif row[2] == "Correy":
            Correy_votes += 1

        else:
            Li_votes += 1

O_Tooley_Pct = round(O_Tooley_votes/total_votes*100,2)

Khan_Pct = round(Khan_votes/total_votes*100,2)

Correy_Pct = round(Correy_votes/total_votes*100,2)

Li_Pct = round(Li_votes/total_votes*100,2)

Winner = max(O_Tooley_votes, Khan_votes, Correy_votes, Li_votes)

print("Election Results")
print("-------------------------")
print("Total Votes: " + str(total_votes))
print("-------------------------")
print("Here is a list of the candidates that received votes: " + str(set(candidates)))
print("-------------------------")
print("Khan: " + str(Khan_Pct) + "% " + "(" + str(Khan_votes) + ")")
print("Correy: " + str(Correy_Pct) + "% " + "(" + str(Correy_votes) + ")")
print("Li: " + str(Li_Pct) + "% " + "(" + str(Li_votes) + ")")
print("O'Tooley: " + str(O_Tooley_Pct) + "% " + "(" + str(O_Tooley_votes) + ")")
print("-------------------------")

if Winner == Correy_votes:
    print("Winner: Correy with " + str(Correy_votes) + " votes")
elif Winner == Khan_votes:
    print("Winner: Khan with " + str(Khan_votes) + " votes")
elif Winner == Li_votes:
    print("Winner: Li with " + str(Li_votes) + " votes")
else:
    print("Winner: O'Tooley with " + str(O_Tooley_votes) + " votes")

with open("Election_Results.txt", "w") as results:

    results.write("Election Results\n")
    results.write("-------------------------\n")
    results.write("Total Votes: " + str(total_votes) + "\n")
    results.write("-------------------------\n")
    results.write("Here is a list of the candidates that received votes: " + str(set(candidates)) + "\n")
    results.write("-------------------------\n")
    results.write("Khan: " + str(Khan_Pct) + "% " + "(" + str(Khan_votes) + ")\n")
    results.write("Correy: " + str(Correy_Pct) + "% " + "(" + str(Correy_votes) + ")\n")
    results.write("Li: " + str(Li_Pct) + "% " + "(" + str(Li_votes) + ")\n")
    results.write("O'Tooley: " + str(O_Tooley_Pct) + "% " + "(" + str(O_Tooley_votes) + ")\n")
    results.write("-------------------------\n")

    if Winner == Correy_votes:
        results.write("Winner: Correy with " + str(Correy_votes) + " votes")
    elif Winner == Khan_votes:
        results.write("Winner: Khan with " + str(Khan_votes) + " votes")
    elif Winner == Li_votes:
        results.write("Winner: Li with " + str(Li_votes) + " votes")
    else:
        results.write("Winner: O'Tooley with " + str(O_Tooley_votes) + " votes")


import requests
import json
import os
from glob import glob
from datetime import date

# -- Method to read your zenodo token from a file
def readtoken(fn='/home/jonah.kanner/.zenodo'):
    """
    fn should be the FILENAME of a file containing your zenodo token
    Keep your token secret!
    See: https://zenodo.org/account/settings/applications/tokens/new/
    """
    with open(fn, 'r') as fp:
        token = fp.read()
    return token

def pubdate(token, response, describe=None):
    """
    Update the published date to today
    """

    draft_url = response.json()['links']['latest_draft']
    data = {}
    data['metadata'] = response.json()["metadata"]
    params = {'access_token': token}
    headers = {"Content-Type": "application/json"}
    today = date.today().isoformat()

    data['metadata']['publication_date'] = today
    if describe is not None:
        data['metadata']['description'] = describe

    r = requests.put(draft_url, params=params, data=json.dumps(data), headers = {"Content-Type": "application/json"})
    return r

# -- Makes a new data set
def make_dataset(token, server='https://sandbox.zenodo.org'):
    """
    Creates a new dataset, and returns the zenodo response
    """

    # -- Make new entry on sandbox server
    headers = {"Content-Type": "application/json"}
    params = {'access_token': token}
    r = requests.post('{0}/api/deposit/depositions'.format(server),
                      params=params,
                      json={},
                      headers=headers)

    id = r.json()['id']
    print("Created new entry with id {}".format(id))
    return r

def push_file(path, token, response, scope='IGWN', project='GWTC2', version='1'):
    """
    Method to push a file to zenodo

    PATH should be the path to the file

    TOKEN should be your token

    RESPONSE should be the zenodo response for a data set, as aquired from MAKE_DATASET or RETRIEVE methods
    """

    # -- Set up basic info about request
    bucket_url = response.json()["links"]["bucket"]
    params = {'access_token': token}

    # -- Construct file name to be used in zenodo
    filename = os.path.basename(path)
    #filename = '{0}-{1}-v{2}-'.format(scope, project, version) + filename
    filename = '{0}-{1}-'.format(scope, project, version) + filename
    print(filename)

    # The target URL is a combination of the bucket link with the
    # desired filename seperated by a slash.
    with open(path, "rb") as fp:
        r = requests.put(
            "%s/%s" % (bucket_url, filename),
            data=fp,
            params=params,
        )
    return r

# NOTE
# Need to do this:  https://developers.zenodo.org/#new-version

def publish(token, response):
    url = response.json()['links']['publish']
    params = {'access_token': token}
    r = requests.post(
            url,
            params=params,
        )
    return r

def newversion(token, response, desc=None):
    """
    Creates a new version of a deposit
    """
    url = response.json()['links']["newversion"]
    print("url:", url)

    params = {'access_token': token}
    r = requests.post(
            url,
            params=params,
        )
    print("New Version response:")
    print(r.json())

    # -- Get response for new version
    draft_url = r.json()['links']['latest_draft']
    draft = requests.get(draft_url, params=params)
    return draft

def retrieve(recid, token, server='https://sandbox.zenodo.org'):
    """
    Retrieve the response for an existing zenodo record

    RECID should be the record ID for an existing zenodo record

    TOKEN should be your token
    """
    r = requests.get("{0}/api/deposit/depositions/{1}?access_token={2}".format(server, recid, token))
    print(json.dumps(r.json(), indent=2))
    return r

def delete_files(token, response):
    """
    Deletes all files from a draft zenodo deposit
    """
    fileurl = response.json()['links']['files']
    filelist = requests.get(fileurl, params={'access_token':token})

    for item in filelist.json():
        url = item['links']['self']
        requests.delete(url, params={'access_token':token})

    print("Deleted files from draft")
    return filelist

"""
Example use case

from zenodozen import *

# -- List of files you want to add
filelist = glob('./all_posterior_samples/GW*')

#-- Read token
token = readtoken(fn='/home/jonah.kanner/.zenodo-sandbox')

#-- Get record of existing Zenodo entry
response = retrieve('748570', token)

# -- Add a bunch of files
for fn in filelist:
    r =  push_file(fn, token, response, scope='IGWN', project='GWTC2', version='1')

"""


'''
Change History
2022/12/13 - use the revised test_rl_macd_v2, default params to (3,7,19), 0, 0

Change History
2023/03/03  add cwh check
'''
from datetime import datetime
from datetime import timedelta

import json
import numpy as np
import traceback
from test_mongo import MongoExplorer
import pandas as pd
from pandas import json_normalize
from test_yahoo import QuoteExplorer
from test_g20_v2 import StockScore
from test_stockstats import StockStats
from openpyxl import load_workbook
from pathlib import Path
from copy import copy
from typing import Union, Optional
#import numpy as np
#import pandas as pd
import openpyxl
#from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
#import time
from test_cup_with_handle import Rule_Cup_with_Handle

class RLDailyTrader:
    def __init__(self, options):
        self.mongo = MongoExplorer()
        self.runDate = options['AAOD']
        self.aaod = options['AAOD']
        #self.symbol = options['symbol']
        #self.long = options['long']
        #self.short = options['short']
        #self.signal = options['signal']
        #self.macd_threshold = options['macd_threshold']
        #self.macd_min_len = options['macd_min_len']
        #self.today = datetime.now()

        self.list = ['MSFT', 'SPY', 'SHOP', 'TWLO', 'ROKU', 'OKTA', 'PAYC', 'GOOGL', 'LYFT', 'TTD', 'AYX', 'ISRG', 'CRM',
                     'ATVI', 'MDB', 'SQ', 'BABA', 'AAPL', 'TCEHY', 'META', 'AMZN', 'TSLA', 'ELV', 'COST', 'GS',
                     'GE', 'DELL', 'AZO', 'POOL', 'NOW', 'BKNG', 'ORLY', 'ALGN', 'HUM', 'LIN', 'PCTY',
                     'ETSY', 'DECK', 'FIVE', 'NEO', 'PODD', 'TXG', 'CABO', 'NET', 'TW', 'SNOW', 'CHK',
                     'ASML', 'TEAM', 'DDOG', 'PANW', 'CZR', 'CTSH', 'MTCH', 'SBSW', 'JD', 'IQV',
                     'OPEN', 'UPWK', 'EXPI', 'JBHT', 'CLH', 'TYL', 'MSCI', 'AXON', 'FND', 'GNRC', 'PEN',
                     'TPL', 'FANG', 'WK', 'CDAY', 'SMAR', 'WMG', 'AMBA', 'GLOB', 'EPAM', 'CACC', 'REXR', 'EXPO',
                     'ACHC', 'ANSS', 'ATKR', 'FOXF', 'IIPR', 'LKQ', 'QLYS', 'RCM', 'WDAY', 'ULTA', 'DT',
                     'MEDP', 'DPZ', 'TNET', 'UTHR', 'DKS','RPD', 'ASAN', 'SAIA', 'TREX', 'BJ',
                     'CYBR', 'ADBE', 'ESI', 'HLI', 'CHPT', 'KRNT', 'KEYS', 'ARES', 'UPST', 'ONTO', 'AMT', 'SBAC',
                     'MUSA', 'LNG', 'VAC', 'PLNT', 'AIRC', 'ALGM', 'HII', 'WSC', 'TDG', 'BYDDF', 'ABBV',
                     'NVO', 'CHK', 'UNH', 'REGN', 'EXR', 'ENPH', 'ELV', 'BYDDY', 'SCI', 'ARGX', 'BAH', 'PWR',
                     'KNSL', 'AZPN', 'DTM', 'ALNY', 'YZCAY', 'ON', 'WMB', 'RSG', 'WCN', 'ADP', 'CVS',
                     'VRTX', 'DOX', 'LLY', 'HUBB', 'FWONK', 'ALB', 'FSLR', 'GGB', 'RRX', 'HOMB', 'SYM',
                     'OZK', 'TECK', 'VLO', 'NUE', 'PXD', 'STLD', 'GDDY', 'NXST', 'BIIB', 'BMRN', 'HES',
                     'IRDM', 'WRB', 'GL', 'CQP', 'AMN', 'ELP', 'GLPI', 'MCK', 'MOH', 'CB', 'CW', 'GD', 'DUK',
                     'EIX', 'GMED', 'H', 'IRTC', 'LKFN', 'MMSI', 'NJR', 'ORA', 'PRTA', 'PTC', 'RHP', 'TH',
                     'URI', 'VIPS', 'VST', 'WING', 'XENE', 'FMX', 'PDD', 'FIZZ', 'RRC', 'RYI', 'PECO', 'PWSC', 'PXD',
                     'AEIS', 'WHD', 'INSW', 'OKE', 'RES', 'TRGP', 'A', 'AIN', 'AME', 'APOG', 'ANET', 'CWST',
                     'CAT', 'CDW', 'GIB', 'CHDN', 'CI', 'CR', 'DRI', 'EMR', 'FCFS', 'FLS', 'HSIC', 'HXL', 'INST',
                     'ITCI', 'OHI', 'PAYX', 'RBC', 'SPXC', 'VICI', 'WAB', 'WEX', 'DINO', 'NFE', 'BIPC', 'WFRD',
                     'ASIX', 'CRC', 'CVE', 'CSWI', 'ESTE', 'ENS', 'EQNR', 'OXY', 'PARR', 'SNDX', 'WLK', 'DEN',
                     'LNW', 'CHRD', 'DECK', 'ACHC', 'ALNY', 'ALB', 'FSLR', 'TECK', 'BMRN', 'GATX',
                     'GEF', 'KRYS', 'MLI', 'NE', 'OGE', 'SYBT', 'TGLS', 'TKR', 'VAL', 'TCOM', 'ASO', 'DG',
                     'JAZZ', 'JKS', 'MGY', 'MTDR', 'PDCE', 'DCP', 'SMCI', 'AES', 'AGYS', 'BMI', 'CALX',
                     'CASY', 'CBZ', 'WIRE', 'NSP', 'IHG', 'IRM', 'MCD', 'NXGN', 'TRTN', 'XLU', 'WEC', 'XEL', 'APD',
                     'ARLP', 'CCEP', 'CTRA', 'PSX', 'HWM', 'NVO', 'GLPI', 'RETA', 'TXRH', 'DKL', 'LOPE', 'USAC',
                     'CVX', 'SUN', 'SUPN', 'MGRC', 'HPK', 'ASAI', 'BOWL', 'SUBCY', 'ET', 'HQY', 'HUBG',
                     'LNTH', 'LMT', 'SPTN', 'SNEX', 'AMR', 'AFG', 'ACGL', 'CEIX', 'DMLP', 'ERIE', 'RLI', 'SAFT',
                     'SIGI', 'HCC', 'CBOE', 'PI', 'IPAR', 'LPLA', 'PJT', 'AGCO', 'ALG', 'NGLOY', 'NLY', 'AIT',
                     'BANF', 'DDS', 'EME', 'EXLS', 'FN', 'FIBK', 'PAC', 'ASR', 'IDA', 'IMKTA', 'ITA', 'KR',
                     'LNN', 'MSM', 'NOC', 'NVT', 'ROL', 'SJW', 'TEX', 'TRN', 'VMI', 'WCC', 'ATI', 'AMPH',
                     'APLS', 'ARCH', 'ASH', 'CF', 'CFR', 'THG', 'NGVT', 'IOSP', 'MTRN', 'RS', 'SCCO', 'RYAN',
                     'AXON', 'RJF', 'OMAB', 'FICO', 'HAE', 'OGS', 'ACA', 'ABG', 'BKE', 'CNP', 'CMS', 'FIX',
                     'JKHY', 'NNN', 'NVEE', 'OXM', 'SLGN', 'TTC', 'TWO', 'GWW', 'FMC', 'GLP', 'LXU', 'TAL',
                     'AIR', 'AMAL', 'BDC', 'ELF', 'GPC', 'IEP', 'EDU', 'SAIC', 'SRE', 'VC', 'RTX', 'IBN', 'MGPI',
                     'RPM', 'ADC', 'HEI', 'MRTN', 'PCAR', 'CRS', 'ACT', 'NUE', 'AEP', 'CLFD', 'IT', 'HOLX', 'NSSC',
                     'PAG', 'SPLP', 'TJX', 'PSN', 'FOUR', 'AON', 'UTZ', 'RSG', 'CNXN', 'BDX', 'BWXT', 'CTAS',
                     'DGII', 'GILD', 'MCRI', 'TRV', 'ANCTF', 'ATKR', 'LLY', 'GL', 'PBT', 'ADUS', 'IEX', 'LTC',
                     'ROST', 'AFL', 'MPC', 'SBR', 'CMI', 'HTHT', 'ENSG', 'UHS', 'MURGY', 'NI', 'WPM', 'SLVM', 'GGB',
                     'AVA', 'INCY', 'NVCR', 'COP', 'CSGP', 'DCI', 'PFGC', 'TWI', 'UOVEY', 'WPC', 'GMAB', 'MDRX', 'NDSN',
                     'SPSC', 'ABC', 'EDPFY', 'HALO', 'VRTV', 'GEO', 'UNF', 'AXSM', 'YUM', 'GES', 'YUMC', 'AMGN', 'OLN',
                     'EPD', 'KLAC', 'MMP', 'BURL', 'CWT', 'CSL', 'DLTR', 'DY', 'MA', 'MSI', 'NTCT', 'NEE', 'ORCL', 'SNA',
                     'SBUX', 'WYNN', 'XYL', 'AIG', 'CCI', 'CMC', 'RIO', 'STLD', 'AMP', 'ASX', 'LSCC', 'PLXS', 'COLD',
                     'APPF', 'BRKR', 'CROX', 'DSGX', 'AQUA', 'FCPT', 'GMS', 'HCA', 'NSIT', 'LMAT', 'NEP', 'OLLI',
                     'PTCT', 'TPR', 'RL', 'GEL', 'EWZ', 'KNX', 'FWONA', 'MTD', 'COOP', 'ODFL', 'WAT',
                     'XPEL', 'MEG', 'CCJ', 'MEOH', 'PRI', 'PLMR', 'CEG', 'ADI', 'KLIC', 'MTSI', 'MCHP', 'MPWR', 'OCSL',
                     'TXN', 'ATRI', 'BCC', 'CRHKY', 'CCOI', 'CTS', 'DXCM', 'DFIN', 'FELE', 'LSTR', 'MBUU', 'O', 'RBA',
                     'SBRA', 'SGEN', 'SKX', 'VHT', 'WM', 'PII', 'AVGO', 'FRHC', 'CAR', 'CACI', 'ETN', 'NPO',
                     'FDS', 'PPA', 'ROP', 'STRL', 'TMO', 'OWL', 'MKTX', 'POWI', 'ROAD', 'DHI', 'PLUS', 'GPI', 'ICFI',
                     'MEI', 'PRIM', 'R', 'TDY', 'XLE', 'FCX', 'PEP', 'HPE', 'ABB', 'AMX', 'EQIX', 'IBP', 'IYH',
                     'LECO', 'NRC', 'PKG', 'DGX', 'TSCO', 'VRSN', 'WSO', 'ZTO', 'UI', 'VOYA', 'CRUS', 'GOLF', 'ASND',
                     'EPRT', 'HGV', 'ITW', 'PFSI', 'SXI', 'WWD', 'IIJIY', 'PHR', 'WTRG', 'QSR', 'TPX', 'ASMIY', 'PLL',
                     'ATSG', 'NEU', 'CRDO', 'SPT', 'DORM', 'APG', 'HOMB', 'RWWI', 'DHCC', 'IE', 'ACDC', 'GPLB', 'AAMC',
                     'USLM', 'KNIT', 'DPSI', 'CHKR', 'UFPT', 'LNKB', 'VWFB', 'HLNE', 'OTIS', 'SSBK', 'BBSI', 'EVI', 'FC',
                     'FUTU', 'KRUS', 'KRMD', 'RGEN', 'TCBC', 'XPOF', 'JXN', 'ZGN', 'CCSI', 'LCFY', 'ATAT', 'PLTNU', 'RICK',
                     'IBEX', 'ESQ', 'TRNS', 'WIX', 'APHE', 'LKST', 'NVDA', 'BLD', 'RXMD', 'ALTR', 'CLMB', 'BWMN',
                     'SVMB', 'VCTR', 'AERG', 'AURX', 'ERLFF', 'ESAB', 'MLTX', 'CMG', 'GWOX', 'MMS', 'MXF', 'VSEC', 'FLUX',
                     'RCL', 'SAP', 'SIEGY', 'SYK', 'RRX', 'AAON', 'AYI', 'PLOW', 'HEES', 'JBT', 'NVEC', 'ELA', 'ANIK', 'BLX',
                     'JPM', 'MOS', 'GBFH', 'CCRD', 'HVRRY', 'EVR', 'EEFT', 'FL', 'ROK', 'BESIY', 'IFNNY', 'IDCC', 'FAST',
                     'EWD', 'ADRNY', 'KTB', 'BA', 'VATE', 'GFS', 'ITT', 'SDXAY', 'CASH', 'ARW', 'V', 'MBLY', 'HSTM',
                     'LVMUY', 'FSBW', 'NTES', 'URBN', 'EADSY', 'CDNS', 'CASS', 'LFUS', 'WT', 'IR', 'ARCAY', 'LRCX', 'FTNT',
                     'MANH', 'SCTH', 'DO', 'ARNC', 'NVR', 'INTA', 'BWA', 'TJBH', 'AGM', 'MTZ', 'COCO', 'CARR', 'PH',
                     'FTCO', 'GSHD', 'HUBS', 'LMPX', 'MRTI', 'NGLD', 'DKNG', 'NFLX', 'UHAL', 'CTVA', 'KIDS', 'RADI', 'RIOT',
                     'AMRX', 'IDXX', 'INSP', 'WST', 'CPRT', 'RMD', 'CRSP', 'ICG']

        #self.list = ['SHOP', 'COUP', 'TWLO', 'ROKU', 'OKTA', 'PAYC', 'GOOGL', 'LYFT', 'TTD', 'AYX', 'ISRG', 'CRM',
        #             'ATVI', 'MDB', 'SQ', 'BABA', 'AAPL', 'TCEHY', 'FB', 'AMZN', 'TSLA', 'ANTM', 'COST', 'GS',
        #             'GE', 'CDLX', 'APPN', 'RNG', 'DELL', 'AZO', 'CHTR', 'FTNT', 'POOL', 'NOW', 'BKNG', 'ORLY',
        #             'ALGN', 'HUM', 'IAC', 'LIN', 'SNAP', 'PCTY', 'IDXX', 'NVCR', 'ETSY', 'EW', 'CNC', 'MASI', 'CMG',
        #             'TTNDY', 'ILMN', 'DECK', 'FIVE', 'ANET', 'HUBS', 'EQIX', 'MPWR']
        #   'SPSC', 'CHTR', 'UI', 'CTLT', 'XLRN','SPPT','MIME', 'MLYBY','SWCH', 'SRD','COUP','MYOV','EVOP','STOR', 'SJI', 'IBB',
        #self.list = ['BKNG'] 'WIX', 'BILI','MA', 'HCA', 'PRAH', 'NFLX', 'ZTS','VEEV', 'PYPL', 'AVGO', 'ZM', 'CRWD',
        # 'CVNA', 'DOCU', 'PINS', 'V', 'AIMC', 'SLYV', 'MDY',
        self.exclusionList = ['PENN', 'JCOM', 'GKOS', 'EYE', 'BURL', 'W', 'GOLF', 'DG', 'TRU', 'SSNC', 'TSCO', 'FLT', 'PDD',
                              'ZS', 'ROST','DXCM', 'NTES', 'NIO', 'LI', 'ODFL', 'XPO', 'SAM','FRC']

    def copy_excel_cell_range(
            self,
            src_ws: openpyxl.worksheet.worksheet.Worksheet,
            min_row: int = None,
            max_row: int = None,
            min_col: int = None,
            max_col: int = None,
            tgt_ws: openpyxl.worksheet.worksheet.Worksheet = None,
            tgt_min_row: int = 1,
            tgt_min_col: int = 1,
            with_style: bool = True
    ) -> openpyxl.worksheet.worksheet.Worksheet:
        """
        copies all cells from the source worksheet [src_ws] starting from [min_row] row
        and [min_col] column up to [max_row] row and [max_col] column
        to target worksheet [tgt_ws] starting from [tgt_min_row] row
        and [tgt_min_col] column.

        @param src_ws:  source worksheet
        @param min_row: smallest row index in the source worksheet (1-based index)
        @param max_row: largest row index in the source worksheet (1-based index)
        @param min_col: smallest column index in the source worksheet (1-based index)
        @param max_col: largest column index in the source worksheet (1-based index)
        @param tgt_ws:  target worksheet.
                        If None, then the copy will be done to the same (source) worksheet.
        @param tgt_min_row: target row index (1-based index)
        @param tgt_min_col: target column index (1-based index)
        @param with_style:  whether to copy cell style. Default: True

        @return: target worksheet object
        """
        if tgt_ws is None:
            tgt_ws = src_ws

        # https://stackoverflow.com/a/34838233/5741205
        for row in src_ws.iter_rows(min_row=min_row, max_row=max_row,
                                    min_col=min_col, max_col=max_col):
            for cell in row:
                tgt_cell = tgt_ws.cell(
                    row=cell.row + tgt_min_row - 1,
                    column=cell.col_idx + tgt_min_col - 1,
                    value=cell.value
                )
                if with_style and cell.has_style:
                    # tgt_cell._style = copy(cell._style)
                    tgt_cell.font = copy(cell.font)
                    tgt_cell.border = copy(cell.border)
                    tgt_cell.fill = copy(cell.fill)
                    tgt_cell.number_format = copy(cell.number_format)
                    tgt_cell.protection = copy(cell.protection)
                    tgt_cell.alignment = copy(cell.alignment)
        return tgt_ws

    def append_df_to_excel(
            self,
            filename: Union[str, Path],
            df: pd.DataFrame,
            sheet_name: str = 'Sheet1',
            startrow: Optional[int] = None,
            max_col_width: int = 30,
            autofilter: bool = False,
            fmt_int: str = "#,##0",
            fmt_float: str = "#,##0.00",
            fmt_date: str = "yyyy-mm-dd",
            fmt_datetime: str = "yyyy-mm-dd hh:mm",
            truncate_sheet: bool = False,
            storage_options: Optional[dict] = None,
            **to_excel_kwargs
    ) -> None:
        """
        Append a DataFrame [df] to existing Excel file [filename]
        into [sheet_name] Sheet.
        If [filename] doesn't exist, then this function will create it.

        @param filename: File path or existing ExcelWriter
                         (Example: '/path/to/file.xlsx')
        @param df: DataFrame to save to workbook
        @param sheet_name: Name of sheet which will contain DataFrame.
                           (default: 'Sheet1')
        @param startrow: upper left cell row to dump data frame.
                         Per default (startrow=None) calculate the last row
                         in the existing DF and write to the next row...
        @param max_col_width: maximum column width in Excel. Default: 40
        @param autofilter: boolean - whether add Excel autofilter or not. Default: False
        @param fmt_int: Excel format for integer numbers
        @param fmt_float: Excel format for float numbers
        @param fmt_date: Excel format for dates
        @param fmt_datetime: Excel format for datetime's
        @param truncate_sheet: truncate (remove and recreate) [sheet_name]
                               before writing DataFrame to Excel file
        @param storage_options: dict, optional
            Extra options that make sense for a particular storage connection, e.g. host, port,
            username, password, etc., if using a URL that will be parsed by fsspec, e.g.,
            starting “s3://”, “gcs://”.
        @param to_excel_kwargs: arguments which will be passed to `DataFrame.to_excel()`
                                [can be a dictionary]
        @return: None

        Usage examples:

        >>> append_df_to_excel('/tmp/test.xlsx', df, autofilter=True,
                               freeze_panes=(1,0))

        >>> append_df_to_excel('/tmp/test.xlsx', df, header=None, index=False)

        >>> append_df_to_excel('/tmp/test.xlsx', df, sheet_name='Sheet2',
                               index=False)

        >>> append_df_to_excel('/tmp/test.xlsx', df, sheet_name='Sheet2',
                               index=False, startrow=25)

        >>> append_df_to_excel('/tmp/test.xlsx', df, index=False,
                               fmt_datetime="dd.mm.yyyy hh:mm")

        (c) [MaxU](https://stackoverflow.com/users/5741205/maxu?tab=profile)
        """
        def set_column_format(ws, column_letter, fmt):
            for cell in ws[column_letter]:
                cell.number_format = fmt
        filename = Path(filename)
        file_exists = filename.is_file()
        # process parameters
        # calculate first column number
        # if the DF will be written using `index=True`, then `first_col = 2`, else `first_col = 1`
        first_col = int(to_excel_kwargs.get("index", True)) + 1
        # ignore [engine] parameter if it was passed
        if 'engine' in to_excel_kwargs:
            to_excel_kwargs.pop('engine')
        # save content of existing sheets
        if file_exists:
            wb = load_workbook(filename)
            sheet_names = wb.sheetnames
            sheet_exists = sheet_name in sheet_names
            sheets = {ws.title: ws for ws in wb.worksheets}

        with pd.ExcelWriter(
            filename.with_suffix(".xlsx"),
            engine="openpyxl",
            mode="a" if file_exists else "w",
            if_sheet_exists="new" if file_exists else None,
            date_format=fmt_date,
            datetime_format=fmt_datetime,
            storage_options=storage_options
        ) as writer:
            if file_exists:
                # try to open an existing workbook
                writer.book = wb
                # get the last row in the existing Excel sheet
                # if it was not specified explicitly
                if startrow is None and sheet_name in writer.book.sheetnames:
                    startrow = writer.book[sheet_name].max_row
                # truncate sheet
                if truncate_sheet and sheet_name in writer.book.sheetnames:
                    # index of [sheet_name] sheet
                    idx = writer.book.sheetnames.index(sheet_name)
                    # remove [sheet_name]
                    writer.book.remove(writer.book.worksheets[idx])
                    # create an empty sheet [sheet_name] using old index
                    writer.book.create_sheet(sheet_name, idx)
                # copy existing sheets
                writer.sheets = sheets
            else:
                # file doesn't exist, we are creating a new one
                startrow = 0

            # write out the DataFrame to an ExcelWriter
            df.to_excel(writer, sheet_name=sheet_name, **to_excel_kwargs)
            worksheet = writer.sheets[sheet_name]

            if autofilter:
                worksheet.auto_filter.ref = worksheet.dimensions

            for xl_col_no, dtyp in enumerate(df.dtypes, first_col):
                col_no = xl_col_no - first_col
                width = max(df.iloc[:, col_no].astype(str).str.len().max(),
                            len(df.columns[col_no]) + 6)
                width = min(max_col_width, width)
                column_letter = get_column_letter(xl_col_no)
                worksheet.column_dimensions[column_letter].width = width
                if np.issubdtype(dtyp, np.integer):
                    set_column_format(worksheet, column_letter, fmt_int)
                if np.issubdtype(dtyp, np.floating):
                    set_column_format(worksheet, column_letter, fmt_float)

        if file_exists and sheet_exists:
            # move (append) rows from new worksheet to the `sheet_name` worksheet
            wb = load_workbook(filename)
            # retrieve generated worksheet name
            new_sheet_name = set(wb.sheetnames) - set(sheet_names)
            if new_sheet_name:
                new_sheet_name = list(new_sheet_name)[0]
            # copy rows written by `df.to_excel(...)` to
            self.copy_excel_cell_range(
                src_ws=wb[new_sheet_name],
                tgt_ws=wb[sheet_name],
                tgt_min_row=startrow + 1,
                with_style=True
            )
            # remove new (generated by Pandas) worksheet
            del wb[new_sheet_name]
            wb.save(filename)
            wb.close()

    #def run(self, ticker, always_run_rl=False):
    def run(self, ticker, run_rl=1, g20_threshold=20):
        result = None
        try:
            #print(self.aaod)
            q = QuoteExplorer()
            q.get_quotes(ticker, self.aaod)

            # default
            short = 3
            long = 7
            signal = 19
            macd_threshold = 0
            macd_min_len = 0

            mongo_rl_param = self.mongo.mongoDB['test_rl_macd_param']
            mongo_query_param = {"symbol": ticker}
            quote_param = mongo_rl_param.find(mongo_query_param)
            if mongo_rl_param.count_documents(mongo_query_param) > 0:
                short = quote_param[0]['short']
                long = quote_param[0]['long']
                signal = quote_param[0]['signal']
                macd_threshold = quote_param[0]['macd_threshold']
                macd_min_len = quote_param[0]['macd_min_len']

            #g20 = StockScore({'AAOD': self.aaod, 'symbol': ticker})
            #if g20.run_fundamentals() == True:
            ss = StockStats(ticker)
            #ss.macd(self.short, self.long, self.signal)
            #print(ss.stock)
            #self.c2 = ss.macd_crossing_by_threshold()
            #last_macd_date = self.c2.loc[len(self.c2)-1, 'date']
            #date_diff = self.today - last_macd_date
            #last_macd_len = self.c2.loc[len(self.c2)-1, 'len']
            m = ss.macd_by_date(self.aaod, short, long, signal)
            #print(m)

            #s = ss.stock
            #s = s.reset_index()
            #last_macd_date = s.iloc[-1]['date'].strftime("%Y-%m-%d")
            #last_macd_cross = s.iloc[-1]['macd_cross']
            #last_macd_r = s.iloc[-1]['r']
            #last_macd_len = s.iloc[-1]['len']
            #print(last_macd_date, last_macd_cross, last_macd_r)

            #if last_macd_date == self.aaod and (last_macd_cross == 1 or last_macd_cross == -1 or last_macd_r < 0.2) and last_macd_len >= 5:
            #if date_diff.days <= 2 and last_macd_len >= 5:
            #if (m['r'] < 0.2 and m['len'] >= 5) or (m['len'] == 1 and m['pre_len'] >= 5):
            #if (m['r'] < 0.2 and m['len'] >= 5) or m['len'] == 1:
            if (m['r'] < macd_threshold and m['len'] >= macd_min_len) or m['len'] == 1:
                print('check g20')
                g20 = StockScore({'AAOD': self.aaod, 'symbol': ticker})
                g20.run(save_rl=True, run_rl=run_rl, retrain_rl=True, g20_threshold=g20_threshold)
                if g20.result.get('rl_result') is not None:
                    #print(self.c2)
                    #print(json.dumps(g20.result, indent=4))
                    print(g20.result)
                    g20.save_g20()
                    result = g20.result
        except Exception as error:
            # print(error)
            print(traceback.format_exc())
            pass
        return result

    def run_all(self, g20_threshold=20):
        #symbol = 'PUMP'  # 'MTDR'     #'CDLX' #'APPN' #'EYE'  #'RNG'     #'GOOGL'     #'EVBG'     #'BAND'     #'NFLX' #'GRWG'     #'ACMR'     #'MDB'     #'RCM'     #'FB'     #'AAPL'     #'ANTM'     #'AMZN'     #'TSLA'   #'BAND'     #'ROKU'     #'SHOP'     #'TWLO'

        mongoDB = self.mongo.mongoDB
        mongo_col = mongoDB['etrade_companies']
        # mongo_query = {"Yahoo_Symbol": 'BRK-A'}
        # mongo_query = {"Yahoo_Symbol": 'APG'}
        # mongo_query = {"Yahoo_Symbol": 'FOE'}
        # mongo_query = {"Yahoo_Symbol": 'AMD'}
        # mongo_query = {"Yahoo_Symbol": 'TSLA'}
        # mongo_query = {"Yahoo_Symbol": 'BILL'}
        #mongo_query = {"Yahoo_Symbol": 'SHOP'}
        #mongo_query = {"Yahoo_Symbol": 'AAPL'}
        #mongo_query = {"Yahoo_Symbol": 'V'}
        #mongo_query = {"Yahoo_Symbol": 'TLND'}
        #mongo_query = {"Yahoo_Symbol": 'XME'}
        # mongo_query = {"Yahoo_Symbol": 'KOD'}
        #mongo_query = {"Yahoo_Symbol": 'NFLX'}
        #mongo_query = {"Yahoo_Symbol": 'NFLX'}
        #mongo_query = {"Yahoo_Symbol": 'AYX'}
        #mongo_query = {"Yahoo_Symbol": 'YUMC'}
        mongo_query = {'status': 'active'}
        com = mongo_col.find(mongo_query, no_cursor_timeout=True)

        #aaod = datetime.now().strftime("%Y-%m-%d")
        #today = datetime.now()

        index = 1
        restartIndex = 1        #5200        #964        #2282        #8074        #2118        #8057        #1568      # 3752
        stopIndex = 1000000  # 3753
        for i in com:
            print(str(index) + "	" + i['Yahoo_Symbol'])
            if index > stopIndex:
                break
            if index >= restartIndex:
                try:
                    if i['Yahoo_Symbol'] not in self.list:      # and i['Yahoo_Symbol'] not in self.exclusionList:
                        cwh = Rule_Cup_with_Handle(self.aaod)
                        cwh_result = cwh.trade_with_cwh(ticker=i['Yahoo_Symbol'], aaod=self.aaod, look_back=20, cwh_back=20, db_look_back=30)
                        #print(cwh_result)

                        self.run(ticker=i['Yahoo_Symbol'], run_rl=1, g20_threshold=g20_threshold)
                except Exception as error:
                    #print(error)
                    print(traceback.format_exc())
                    pass

            #time.sleep(1.00)
            index += 1

    def run_portfolio(self, g20_threshold=20):
        index = 1
        restartIndex = 1        #1568      # 3752
        stopIndex = 1000000  # 3753
        for ticker in self.list:
            print(str(index) + "	" + ticker)
            if index > stopIndex:
                break
            if index >= restartIndex:
                try:
                    cwh = Rule_Cup_with_Handle(self.aaod)
                    cwh_result = cwh.trade_with_cwh(ticker=ticker, aaod=self.aaod, look_back=30, cwh_back=20, db_look_back=30)
                    #print(cwh_result)

                    self.run(ticker=ticker, run_rl=2, g20_threshold=g20_threshold)
                except Exception as error:
                    #print(error)
                    print(traceback.format_exc())
                    pass
            index += 1

    def to_excel(self):
        mongo = MongoExplorer()
        mongo_col = mongo.mongoDB['stock_g_score']
        mongo_query = {"runDate": self.aaod, "$or": [{"Recommendation": ""}, {"symbol": {"$in": self.list}}]}
        g = mongo_col.find(mongo_query, no_cursor_timeout=True)

        #pd.set_option('display.max_rows', None)
        #pd.set_option('display.max_columns', None)
        #pd.set_option('display.width', None)
        #pd.set_option('display.max_colwidth', None)
        df = pd.DataFrame(list(g))

        macd = json_normalize(df.get('MACD'))
        df = df.join(macd)

        rl_result = json_normalize(df.get('rl_result'))
        df = df.join(rl_result)

        excel_file_name = 'test_rl_macd_daily_20221214.xlsx'
        self.append_df_to_excel(excel_file_name, df,
                startcol=17, header=False,
                columns=[
                    'symbol',
                    'Reason',
                    'Recommendation',
                    'model_run_date',
                    'start_date',
                    'end_date',
                    'duration',
                    'model_gain',
                    'model_perf',
                    'buy_and_hold_gain',
                    'buy_and_hold_perf',
                    'model_score',
                    'predict_date',
                    'predict_macd_accum',
                    'predict_macd_len',
                    'predict_action',
                    'predict_vol',
                    'AAOD',
                    'close',
                    'Score',
                    'CAP',
                    'CapScore',
                    'PEScore',
                    'AveragePE',
                    'PE',
                    'EPS',
                    'IndustryRank',
                    'Rev Growth',
                    'Gross Margin',
                    'G20',
                    'SR20',
                    'G20Close',
                    'G20Date',
                    'G20Total',
                    'G10',
                    'SR10',
                    'G10Close',
                    'G10Date',
                    'G10Total',
                    'G5',
                    'SR5',
                    'G5Close',
                    'G5Date',
                    'G5Total',
                    'G1',
                    'SR1',
                    'G1Close',
                    'G1Date',
                    'G1Total',
                    'runDate',
                    'macd_sign',
                    'peak',
                    'peak_date',
                    'accum',
                    'len',
                    'r',
                    'pre_macd_sign',
                    'pre_peak',
                    'pre_peak_date',
                    'pre_accum',
                    'pre_len'
                ])
        #get cwh results
        aaod_2 = (datetime(*(int(s) for s in self.aaod.split('-'))) + timedelta(days=(-1) * 5)).strftime("%Y-%m-%d")
        query1 = {'$and': [{'end_date': {'$lte': self.aaod}}, {'end_date': {'$gte': aaod_2}}]}
        #print(query1)
        cwh = mongo.mongoDB['stock_cwh_results'].find(query1, no_cursor_timeout=True)
        #pd.set_option('display.max_rows', None)
        #pd.set_option('display.max_columns', None)
        #pd.set_option('display.width', None)
        #pd.set_option('display.max_colwidth', None)
        cd = pd.DataFrame(list(cwh))

        cwh_df = pd.DataFrame(columns=['_id', 'symbol', 'cwh_sign', 'cwh_end', 'pearson', 'sigma', 'end_date', 'perf', 'perf_date'])

        for i, c in cd.iterrows():
            if c['cwh_sign'] == 1:
                try:
                    g20 = StockScore({'AAOD': self.aaod, 'symbol': c['symbol']})
                    g20.run(save_rl=True, run_rl=0)
                    if g20.result['Recommendation'] == '':
                        #print(c)
                        cwh_df = pd.concat([cwh_df, cd.iloc[[i]]])
                        #print(cwh_df)
                except:
                    pass
            elif c['cwh_sign'] == 2 and c['symbol'] in self.list:
                cwh_df = pd.concat([cwh_df, cd.iloc[[i]]])

        if not cwh_df.empty:
            cwh_df['Reason'] = cwh_df['cwh_sign']
            cwh_df['Recommendation'] = ''
            cwh_df['model_run_date'] = self.aaod
            cwh_df['start_date'] = ''
            #cwh_df['end_date'] = cwh_df['end-date']
            cwh_df['duration'] = cwh_df['sigma']
            cwh_df['model_gain'] = ''
            cwh_df['model_perf'] = ''
            cwh_df['buy_and_hold_gain'] = ''
            cwh_df['buy_and_hold_perf'] = ''
            cwh_df['model_score'] = cwh_df['pearson']
            #print(cwh_df)

            cwh_df = cwh_df.reset_index()

            self.append_df_to_excel(excel_file_name, cwh_df,
                    startcol=17, header=False,
                    columns=[
                        'symbol',
                        'Reason',
                        'Recommendation',
                        'model_run_date',
                        'start_date',
                        'end_date',
                        'duration',
                        'model_gain',
                        'model_perf',
                        'buy_and_hold_gain',
                        'buy_and_hold_perf',
                        'model_score'
                    ])

if __name__ == '__main__':
    startTime = datetime.now()

    aaod = datetime.now().strftime("%Y-%m-%d")
    #aaod = (datetime.now() + timedelta(days=-1)).strftime("%Y-%m-%d")
    mongo = MongoExplorer()
    mongo_col_q = mongo.mongoDB.get_collection('AMZN')
    qDates = list(mongo_col_q.find().sort("Date", -1))

    max_date = datetime(*(int(s) for s in qDates[0]['Date'].split('-')))
    date_diff = (datetime.now() - max_date).days
    #print(aaod, max_date, max_date.weekday(), date_diff)

    #if date_diff > 1 and max_date.weekday() < 4: aaod = (max_date + timedelta(days=1)).strftime("%Y-%m-%d")
    if date_diff >= 1 and date_diff <= 2 and max_date.weekday() == 4: aaod = max_date.strftime("%Y-%m-%d")
    #if date_diff >= 3 and max_date.weekday() == 4: aaod = (max_date + timedelta(days=3)).strftime("%Y-%m-%d")
    aaod = '2023-05-17'

    print(aaod)

    #d = RLDailyTrader({'AAOD': aaod, 'short': 6, 'long': 13, 'signal': 9})
    d = RLDailyTrader({'AAOD': aaod})
    d.run_portfolio()
    endTime1 = datetime.now()
    runTime1 = endTime1 - startTime

    #d.to_excel()
    d.run_all()
    d.to_excel()

    endTime = datetime.now()
    runTime2 = endTime - endTime1
    runTime = endTime - startTime
    print('start:', startTime, 'portfolio end:', endTime1, 'portfolio run time: ', runTime1, 'all end: ', endTime, 'all run time: ', runTime2, 'run time: ', runTime)

'''
        excel_file_name = 'stock_g_score_' + aaod.replace('-', '') + '.xlsx'
        w = pd.ExcelWriter(excel_file_name, engine='xlsxwriter')
        df.to_excel(w, sheet_name='Sheet1',
                    columns=[
                        'symbol',
                        'Reason',
                        'Recommendation',
                        'model_run_date',
                        'start_date',
                        'end_date',
                        'duration',
                        'model_gain',
                        'model_perf',
                        'buy_and_hold_gain',
                        'buy_and_hold_perf',
                        'model_score',
                        'predict_date',
                        'predict_macd_accum',
                        'predict_macd_len',
                        'predict_action',
                        'predict_vol',
                        'AAOD',
                        'close',
                        'Score',
                        'CAP',
                        'CapScore',
                        'PEScore',
                        'AveragePE',
                        'PE',
                        'EPS',
                        'IndustryRank',
                        'Rev Growth',
                        'Gross Margin',
                        'G20',
                        'SR20',
                        'G20Close',
                        'G20Date',
                        'G20Total',
                        'G10',
                        'SR10',
                        'G10Close',
                        'G10Date',
                        'G10Total',
                        'G5',
                        'SR5',
                        'G5Close',
                        'G5Date',
                        'G5Total',
                        'G1',
                        'SR1',
                        'G1Close',
                        'G1Date',
                        'G1Total',
                        'runDate',
                        'macd_sign',
                        'peak',
                        'peak_date',
                        'accum',
                        'len',
                        'r',
                        'pre_macd_sign',
                        'pre_peak',
                        'pre_peak_date',
                        'pre_accum',
                        'pre_len'
                    ])
        w.save()

        with pd.ExcelWriter(excel_file_name, engine='openpyxl', mode='a', if_sheet_exists='replace')as w:
            w.book = load_workbook(excel_file_name)
            w.sheets = {ws.title: ws for ws in w.book.worksheets}
            #df.to_excel(w, sheet_name='Sheet1', startrow=w.book['Sheet1'].max_row, startcol=17, header=False,
            df.to_excel(w, sheet_name='Sheet1', startcol=17,
                columns = [
                            'symbol',
                            'Reason',
                            'Recommendation',
                            'model_run_date',
                            'start_date',
                            'end_date',
                            'duration',
                            'model_gain',
                            'model_perf',
                            'buy_and_hold_gain',
                            'buy_and_hold_perf',
                            'model_score',
                            'predict_date',
                            'predict_macd_accum',
                            'predict_macd_len',
                            'predict_action',
                            'predict_vol',
                            'AAOD',
                            'close',
                            'Score',
                            'CAP',
                            'CapScore',
                            'PEScore',
                            'AveragePE',
                            'PE',
                            'EPS',
                            'IndustryRank',
                            'Rev Growth',
                            'Gross Margin',
                            'G20',
                            'SR20',
                            'G20Close',
                            'G20Date',
                            'G20Total',
                            'G10',
                            'SR10',
                            'G10Close',
                            'G10Date',
                            'G10Total',
                            'G5',
                            'SR5',
                            'G5Close',
                            'G5Date',
                            'G5Total',
                            'G1',
                            'SR1',
                            'G1Close',
                            'G1Date',
                            'G1Total',
                            'runDate',
                            'macd_sign',
                            'peak',
                            'peak_date',
                            'accum',
                            'len',
                            'r',
                            'pre_macd_sign',
                            'pre_peak',
                            'pre_peak_date',
                            'pre_accum',
                            'pre_len'
                        ])

'''

#   NET, PCTY, HUM, NOW


from scipy.stats import ks_2samp
from IKS import IKS
import numpy as np
from time import time

from collections import deque

initial_A = np.random.normal(loc = 0, scale = 1, size = 500)
initial_B = np.random.normal(loc = 1, scale = 1, size = 500)

stream_A = np.random.normal(loc = 0, scale = 1, size = 5000)
stream_B = np.random.normal(loc = 1, scale = 1, size = 5000)

######################
## TEST IKS
######################

start = time()

iks_statistics = [] # collect statistics generated by IKS
iks = IKS()
sliding_A = deque(initial_A) # sliding window
sliding_B = deque(initial_B) # sliding window
for a, b in zip(initial_A, initial_B):
  iks.Add(a, 0)
  iks.Add(b, 1)

# process sliding window
for a, b in zip(stream_A, stream_B):
  iks.Remove(sliding_A.popleft(), 0)
  iks.Remove(sliding_B.popleft(), 1)

  sliding_A.append(a)
  sliding_B.append(b)

  iks.Add(a, 0)
  iks.Add(b, 1)

  iks_statistics.append(iks.KS())

finish = time()
print(f'Elapsed time for IKS to process stream: {round(finish - start, 2)} sec')

######################
## TEST ks_2samp
######################

start = time()

ks_2samp_statistics = [] # gather all statistics generated by ks_2samp
sliding_A = deque(initial_A) # sliding window
sliding_B = deque(initial_B) # sliding window

for a, b in zip(stream_A, stream_B):
  sliding_A.popleft()
  sliding_B.popleft()
  sliding_A.append(a)
  sliding_B.append(b)

  ks_2samp_statistics.append(ks_2samp(sliding_A, sliding_B).statistic)

finish = time()
print(f'Elapsed time for ks_2samp to process stream: {round(finish - start, 2)} sec')

max_diff = np.max(np.abs(np.array(iks_statistics) - np.array(ks_2samp_statistics)))

print(f'Maximum difference between IKS and ks_2samp: {max_diff}')


import json
import os

from django_gcloud_storage import DjangoGCloudStorage, storage
from django.conf import settings
from google.oauth2 import service_account

from Maple.settings import base

class CustomGCS(DjangoGCloudStorage):
    def __init__(self, project=None, bucket=None, credentials=None):
        self._client = None
        self._bucket = None

        if bucket is not None:
            self.bucket_name = bucket
        else:
            self.bucket_name = settings.GCS_BUCKET

        if credentials is not None:
            self.credentials = credentials
        else:
            # 從Django setting中取得參數GCS_CREDENTAILS作為認證依據
            # 這個參數可以是JSON檔案路徑，或者是JSON字串
            self.credentials = settings.GCS_CREDENTIALS

        if project is not None:
            self.project_name = project
        else:
            self.project_name = settings.GCS_PROJECT

        self.bucket_subdir = ''
        self.use_unsigned_urls = True

    @property
    def client(self):
        if not self._client:
            # 認證的過程中，若認證字串是一個檔案的話
            # 則嘗試用JSON檔案認證的方式
            # 這是原本的認證方式
            if os.path.isfile(self.credentials):
                self._client = storage.Client.from_service_account_json(
                    self.credentials, project=self.project_name)
            else:
                # 若認證自傳不是檔案路徑的話，嘗試用json解成dictionary
                # 接著用oauth2client.service_account中的API嘗試認證
                cred_dict = json.loads(self.credentials)
                credentials = service_account.Credentials.from_service_account_info(cred_dict)
                self._client = storage.Client(project=self.project_name, credentials=credentials)
        return self._client

CUSTOM_GCS = CustomGCS()
CUSTOM_GCS_CLIENT = None
BUCKET = None
if base.GCS_CREDENTIALS:
    CUSTOM_GCS_CLIENT = CUSTOM_GCS.client
    BUCKET = CUSTOM_GCS_CLIENT.get_bucket(base.GCS_BUCKET)


print("Welcome to my quiz, Answer 10 simple questions to be the boss")

playing = input("Do you want to play? ")

if playing.lower() != "yes":
    quit()

print("Okay! Let's play :)")
score = 0

# Ques 1
answer = input("When was python first released? ")
if answer.lower() == "1991":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

# Ques 2
answer = input("When was javascript first released? ")
if answer.lower() == "1995":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

# Ques 3
answer = input("What does GPU stand for? ")
if answer.lower() == "graphics processing unit":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

# Ques 4
answer = input("Total number of islands comprising philipines?")
if answer.lower() == "7640":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

# Ques 5
answer = input("What does RAM stand for? ")
if answer.lower() == "random access memory":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

# Ques 1
answer = input("What does PSU stand for? ")
if answer.lower() == "power supply":
    print('Correct!')
    score += 1
else:
    print("Incorrect!")

print("You got " + str(score) + " questions correct!")
print("You got " + str((score / 4) * 100) + "%.")


#define a flatten list
def flatten(data):
# If data is empty then there is no work to do
    if data == []:
        return []
# If the first element in data is a list
    if type(data[0]) == list:
# Flatten the first element and flatten the remaining elements in the list
        return flatten(data[0]) + flatten(data[1:])
    else:
# The first element in data is not a list so only the remaining elements in the list need
# to be flattened
        return [data[0]] + flatten(data[1:])

# Demonstrate the flatten function
def main():
    print(flatten([1, [2, 3], [4, [5, [6, 7]]], [[[8], 9], [10]]]))
    print(flatten([1, [2, [3, [4, [5, [6, [7, [8, [9, \
                  [10]]]]]]]]]]))
    print(flatten([[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], \
                  10]))
    print(flatten([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
    print(flatten([]))

main()


import math

import requests

from config import APCA_API_KEY_ID, APCA_API_KEY_SECRET, APCA_ENDPOINT
from securities import get_current_price

def get_broker_headers(broker_api_key=APCA_API_KEY_ID, broker_api_secret=APCA_API_KEY_SECRET):
    return {
        "APCA-API-KEY-ID": broker_api_key,
        "APCA-API-SECRET-KEY": broker_api_secret
    }

def is_market_open(endpoint=APCA_ENDPOINT, broker_api_key=APCA_API_KEY_ID, broker_api_secret=APCA_API_KEY_SECRET):
    response = requests.get(f"{endpoint}/v2/clock", headers=get_broker_headers(broker_api_key, broker_api_secret))

    assert response.status_code == 200, (
        f"is_market_open request failed, code: {response.status_code}, reason: {response.text}"
    )

    return response.json()["is_open"]

def get_cash(endpoint=APCA_ENDPOINT, broker_api_key=APCA_API_KEY_ID, broker_api_secret=APCA_API_KEY_SECRET):
    response = requests.get(f"{endpoint}/v2/account", headers=get_broker_headers(broker_api_key, broker_api_secret))

    assert response.status_code == 200, (
        f"get_cash request failed, code: {response.status_code}, reason: {response.text}"
    )

    return float(response.json()["cash"])

def get_positions(endpoint=APCA_ENDPOINT, broker_api_key=APCA_API_KEY_ID, broker_api_secret=APCA_API_KEY_SECRET):
    response = requests.get(f"{endpoint}/v2/positions", headers=get_broker_headers(broker_api_key, broker_api_secret))

    assert response.status_code == 200, (
        f"get_positions request failed, code: {response.status_code}, reason: {response.text}"
    )

    return [
        {
            "symbol": pos["symbol"],
            "qty": int(pos["qty"]),
            "side": pos["side"],
            "market_value": float(pos["market_value"])
        }
        for pos in response.json()
    ]

def place_order(
    symbol,
    num_shares,
    endpoint=APCA_ENDPOINT,
    broker_api_key=APCA_API_KEY_ID,
    broker_api_secret=APCA_API_KEY_SECRET
):
    order = {
        "symbol": symbol.upper(),
        "qty": int(abs(num_shares)),
        "side": "sell" if num_shares < 0 else "buy",
        "type": "market",
        "time_in_force": "gtc"
    }

    response = requests.post(
        f"{endpoint}/v2/orders",
        json=order,
        headers=get_broker_headers(broker_api_key, broker_api_secret)
    )

    assert response.status_code == 200, (
        f"place_order request failed, code: {response.status_code}, reason: {response.text}"
    )

def get_buying_power(
    side="long",
    endpoint=APCA_ENDPOINT,
    broker_api_key=APCA_API_KEY_ID,
    broker_api_secret=APCA_API_KEY_SECRET
):
    positions = get_positions(endpoint, broker_api_key, broker_api_secret)
    cash = get_cash(endpoint, broker_api_key, broker_api_secret)

    #  cash + total long positions
    # (in short): cash + total short positions
    return cash + sum(pos["market_value"] for pos in positions if pos["side"] == side)

def reconcile_portfolio(
    target_symbols,
    side="long",
    endpoint=APCA_ENDPOINT,
    broker_api_key=APCA_API_KEY_ID,
    broker_api_secret=APCA_API_KEY_SECRET
):
    buying_power = get_buying_power(side, endpoint, broker_api_key, broker_api_secret)

    positions = {
        pos["symbol"]: pos
        for pos in get_positions(endpoint, broker_api_key, broker_api_secret)
    }

    target_symbols_set = set(target_symbols)
    combined_symbols = target_symbols_set | set(positions)
    num_target_symbols = len(target_symbols_set)

    if num_target_symbols < 1:
        target_symbol_value = 0
    else:
        target_symbol_value = buying_power / len(target_symbols_set)

    # TODO: also check open orders
    for symbol in combined_symbols:
        if symbol in target_symbols:
            quote = get_current_price(symbol)

            shares = math.floor(target_symbol_value / quote)

            if symbol in positions:
                # symbol desired and already held, but may need to adjust
                diff = shares - positions[symbol]["qty"]

                if diff != 0:
                    place_order(symbol, diff, endpoint, broker_api_key, broker_api_secret)

            else:
                # purchase shares
                place_order(symbol, shares, endpoint, broker_api_key, broker_api_secret)
        else:
            # sell position
            shares = -(positions[symbol]["qty"])
            place_order(symbol, shares, endpoint, broker_api_key, broker_api_secret)


import curses
from curses import wrapper
import time
import sys

# intro_screen function
def start_game(stdscr):
    stdscr.clear()
    stdscr.addstr("Welcome to the Speed Typing Test !")
    stdscr.addstr("\nPress any key to continue.....")
    stdscr.refresh()
    stdscr.getkey()

def wpn_test(stdscr):
    target_text = "This is a sample test for this game!"
    current_text = []
    words_check = 0

    start_time = time.time()
    while True:
        stdscr.clear()
        display_text(stdscr, target_text, current_text, start_time, words_check)
        stdscr.refresh()

        key = stdscr.getkey()

        if ord(key) == 27:
            break

        if key in ("KEY_BACKSPACE", '\b', "\x7f"):
            if len(current_text) > 0:
                current_text.pop()

        elif len(current_text) < len(target_text):
            current_text.append(key)

def check_result(stdscr, words_check, target, start_time):
    if words_check == len(target):
        elapsed_time = time.time() - start_time
        stdscr.clear()
        stdscr.addstr(0, 0, f"Congratulations !, Time taken: {round(elapsed_time, 3)} sec", curses.color_pair(1))
        stdscr.addstr(2, 0, f"Do you want to play again ? Press 'P' or 'Q:'")
        key = stdscr.getkey()
        if key == 'P' or key == 'p':
            wpn_test(stdscr)
        else:
            sys.exit()

def display_text(stdscr, target, current,start_time,words_check = 0):
    stdscr.addstr(target)

    for i, char in enumerate(current):
        if char != target[i]:
            stdscr.addstr(0, i, char, curses.color_pair(2))
        else:
            stdscr.addstr(0, i, char, curses.color_pair(1))
            words_check += 1
            stdscr.addstr(1, 0, f"Correct Char: {words_check}")
            check_result(stdscr, words_check, target, start_time)

def main(stdscr): # stdscr --> screen name

    # Initializing colors
    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
    curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
    curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLACK)

    start_game(stdscr)
    wpn_test(stdscr)

wrapper(main)


#base.html에 유저가 수강하고있는 과목 객체들을 항상 넘겨준다. 따로 view를 호출하지 않아도 됨 이를 contetxt processor라고 한다. setting에 TEMPLATE에 설정되어있음.

from .models import Subject_Assign

def default(request):
    qs = Subject_Assign.objects.all()
    return dict(
        subjects_ = qs,
    )