from neural_network import create_model_cnn
from neural_network import predict
from neural_network import cluster_data
from neural_network import create_scatter_plot
from spectrogram_creation import load_audio
from spectrogram_creation import get_spectrogram
import numpy as np

import sys
import os
import joblib
import pickle
import matplotlib.pyplot as plt
import random

def save_model_cnn(model, model_path):
    # Save the model to disk
    sys.stdout = open('NUL', 'w')
    joblib.dump(model, model_path)
    sys.stdout = sys.__stdout__

def load_model_cnn(model_path):
    print("Loading Model CNN...")
    # Load the model from disk
    sys.stdout = open('NUL', 'w')
    model = joblib.load(model_path)
    sys.stdout = sys.__stdout__
    print("Done!")

    return model

def create_and_save_predictions(filename:str):
    features_no = predict_all_in_directory('./data/no', './data/no/myvoice', 'no', 'dense_layer')
    features_yes = predict_all_in_directory('./data/yes', './data/yes/myvoice', 'yes', 'dense_layer')
    features = {**features_no, **features_yes}
    #print(features["0a9f9af7_nohash_0.wav"])

    # Save the dictionary to the file
    with open(filename, 'wb') as f:
        pickle.dump(features, f)
    return features

def load_predictions(filename:str):
    print("Loading Predictions...")
    # Load the dictionary from the file
    with open(filename, 'rb') as f:
        features = pickle.load(f)
    print("Done!")
    return features

def predict_by_wav(audio_path:str, img_path:str, output_layer=None):
    waveform, sample_rate = load_audio(audio_path)
    spectrogram, spect = get_spectrogram(waveform)

    plt.imsave(img_path, spectrogram.numpy(), cmap='gray')

    prediction = predict(model, img_path, output_layer)

    return prediction

def predict_all_in_directory(input_directory, output_directory, prefix:str, output_layer=None):
    # Make sure the output directory exists
    os.makedirs(output_directory, exist_ok=True)

    features = {}

    count = 0
    max_files = 100

    # Loop over all files in the input directory
    for filename in os.listdir(input_directory):
        # Ignore any files that aren't wav files
        if not filename.endswith('.wav'):
            continue

        # Construct the input and output file paths
        input_path = os.path.join(input_directory, filename)
        output_path = os.path.join(output_directory, f'{prefix}_{os.path.splitext(filename)[0]}.png')

        # Call the predict_by_wav function
        prediction = predict_by_wav(input_path, output_path, output_layer)
        features[prefix + "_" + filename] = prediction

        count += 1
        if max_files is not None and count >= max_files:
            break

    return features

# MAIN METHOD
if __name__ == '__main__':

    createCNN = True
    doPrediction = True
    doClustering = True

    model_path = 'model.joblib'

    # Step 0: PreProcess Data

    # Step 1: Create/Load the Convolutional Neural Network
    if (createCNN):
        # Create Model and save it
        model = create_model_cnn()
        save_model_cnn(model, model_path)
    else:
        # Load Model
        model = load_model_cnn(model_path)

    return

    # Step 2: Extract Features out of CNN for Clustering
    if (doPrediction):
        # Create Predictions and save them
        features = create_and_save_predictions("features.pickle")
    else:
        # Load Predictions
        features = load_predictions("features.pickle")
    # Get a random key from the dictionary
    random_key = random.choice(list(features.keys()))
    print(features[random_key])

    # Dictionary to List of values
    features = list(features.values())
    # Convert the features to a NumPy array
    features = np.array(features)
    # Reshape the array to have 2 dimensions
    features = features.reshape(features.shape[0], -1)

    # Step 3: Cluster Data
    if (doClustering):
        # Cluster Data
        cluster_data(features, 2)
        print("")
    else:
        # Load Model
        print("")


import numpy as np
import pandas as pd
import os
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import math
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input as preprocess_input_vgg16
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.applications.resnet50 import preprocess_input as preprocess_input_resnet50
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.applications.inception_v3 import preprocess_input as preprocess_input_inception_v3
from tensorflow.keras import Model

def load_df(path):
    """
    Loads the csv as a dataframe which contains the captions

    path: path of csv file
    """
    df = pd.read_csv(path)

    return df

def preprocess_df(df):
    """
    Select the english captions and extract only the desired columns from the dataframe like 'Name' and 'Description'

    df: dataframe which contains the captions
    """
    df = df[df['Language'] == 'English'].copy()
    df['Name'] = df[['VideoID', 'Start', 'End']].apply(lambda x: x['VideoID'] + '_' + str(x['Start']) + '_' + str(x['End']), axis = 1)
    data = df[['Name', 'Description']]

    return data

def get_final_list(videos_path, data):
    """
    Returns the list of videos which have captions available.

    videos_path: path to the folder which contains the videos
    data: preprocessed dataframe
    """
    videos_list = os.listdir(videos_path)
    num_videos = len(videos_list)

    for i in range(num_videos):
        videos_list[i] = videos_list[i][:-4]

    captioned_videos = set(data['Name'])
    videos = set(videos_list)
    videos_final = list(videos.intersection(captioned_videos)) #These have both video and caption

    return videos_final

def extract_frames(videos_final, source_path, target_path):
    """
    Extract the frames from the videos and store the extracted frames as images in jpg format

    videos_final: list of video names whose frames are to be extracted
    source_path: path to the videos folder
    target_path: path to the target folder where frames are stored
    """
    for video_name in videos_final:
        print("Extracting from", video_name)
        count = 0
        video_captured = cv2.VideoCapture(source_path + video_name + '.avi')
        path = target_path + video_name + '/'
        os.mkdir(path)

        while(video_captured.isOpened()):
            frameId = video_captured.get(1)
            ret, frame = video_captured.read()

            if ret != True:
                break

            if frameId % 10 == 0:
                filename = "frame" + str(count) + ".jpg"
                count += 1
                cv2.imwrite(path + filename, frame)

        video_captured.release()

    print("All frames extracted")

def select_videos(videos_final, frames_path, min_frames):
    """
    Select videos based on the threshold of the min frames

    videos_final: list of videos with captions
    frames_path: path where frames are stored
    min_frames: min threshold for selection
    """
    videos_selected = []

    for video_name in videos_final:
        if len(os.listdir(frames_path + video_name + '/')) >= min_frames:
            videos_selected.append(video_name)

    return videos_selected

def view_frames(video_path):
    """
    View the frames given the video path.
    """
    frames = os.listdir(video_path)
    n = len(frames)
    frames = os.listdir(video_path)
    n = len(frames)
    f = plt.figure()
    for i in range(n):
        # Debug, plot figure
        img = mpimg.imread(video_path+'/frame'+str(i)+'.jpg')
        plt.imshow(img)
        plt.figure()

def load_video_frames(frames_path, videos_selected):
    """
    Loading the frames into numpy array

    frames_path: path to the folder which contains the frames
    videos_selected: list of final video names which meet the min frames threshold
    """
    X = []
    for video_name in videos_selected:
        l = []
        count = 0

        for img_name in os.listdir(frames_path+video_name):
            if count==15:
                break

            img = plt.imread('dataset/msvd_videos/frames/' + video_name +"/"+ img_name)
            img = cv2.resize(img, (224, 224)) #Resize to 224x224
            l.append(img)
            count+=1

        print("Loading for", video_name)
        X.append(l)

    X = np.array(X)
    return X

def extract_features(frames_path, videos_selected):
    """
    Extracting features from the Frames using VGG16 pretrained model. Output is of shape (n, 15, 25088): For n videos and 15 frames for each video

    frames_path: path to the folder which contains the frames
    videos_selected: list of final video names which meet the min frames threshold
    """
    model = VGG16(weights='imagenet', include_top=True)
    feature_extractor = Model(model.input, model.get_layer('fc2').output)

    X = []
    for video_name in videos_selected:
        l = []
        count = 0

        for img_name in os.listdir(frames_path+video_name):
            if count==15:
                break

            img_path = 'dataset/msvd_videos/frames/' + video_name + "/"+img_name
            img = image.load_img(img_path, target_size=(224, 224))
            img_data = image.img_to_array(img)
            img_data = np.expand_dims(img_data, axis=0)
            img_data = preprocess_input_vgg16(img_data)

            features = feature_extractor.predict(img_data)
            features = features.flatten()
            l.append(features)
            count+=1

        print("Loading for", video_name)
        X.append(l)

    X = np.array(X)
    return X

def extract_features_resnet50(frames_path, videos_selected):
    """
    Extracting features from the Frames using ResNet50 pretrained model. Output is of shape (n, 15, 2048): For n videos and 15 frames for each video

    frames_path: path to the folder which contains the frames
    videos_selected: list of final video names which meet the min frames threshold
    """
    model = ResNet50(weights='imagenet', include_top=True)
    feature_extractor = Model(model.input, model.get_layer('avg_pool').output)

    X = []
    for video_name in videos_selected:
        l = []
        count = 0

        for img_name in os.listdir(frames_path+video_name):
            if count==15:
                break

            img_path = 'dataset/msvd_videos/frames/' + video_name + "/"+img_name
            img = image.load_img(img_path, target_size=(224, 224))
            img_data = image.img_to_array(img)
            img_data = np.expand_dims(img_data, axis=0)
            img_data = preprocess_input_resnet50(img_data)

            features = feature_extractor.predict(img_data)
            features = features.flatten()
            l.append(features)
            count+=1

        print("Loading for", video_name)
        X.append(l)

    X = np.array(X)
    return X

def extract_features_inception_v3(frames_path, videos_selected):
    """
    Extracting features from the Frames using InceptionV3 pretrained model. Output is of shape (n, 15, 2048): For n videos and 15 frames for each video

    frames_path: path to the folder which contains the frames
    videos_selected: list of final video names which meet the min frames threshold
    """
    model = InceptionV3(weights='imagenet', include_top=True)
    feature_extractor = Model(model.input, model.get_layer('avg_pool').output)

    X = []
    for video_name in videos_selected:
        l = []
        count = 0

        for img_name in os.listdir(frames_path+video_name):
            if count==15:
                break

            img_path = 'dataset/msvd_videos/frames/' + video_name + "/"+img_name
            img = image.load_img(img_path, target_size=(299, 299))
            img_data = image.img_to_array(img)
            img_data = np.expand_dims(img_data, axis=0)
            img_data = preprocess_input_inception_v3(img_data)

            features = feature_extractor.predict(img_data)
            features = features.flatten()
            l.append(features)
            count+=1

        print("Loading for", video_name)
        X.append(l)

    X = np.array(X)
    return X


import os.path
import os, time

key = 121 #kunci hexa
####kunci = random.randint(0,1000) #random integer
def toHex(d):
    return f"{d:0{2}X}".upper() #return to hexa

def decode(text):
    decoded = []
    for line in text.split('\n'):
        if "=" in line:
            i = line.index("=")
            decoded_text = ""
            for enc in [line[i+1:][j:j+2] for j in range(0,len(line[i+1:]),2)]:
                try:
                    decoded_text += chr(int(enc,16)^key)
                except ValueError:
                    decoded_text += '.'
            decoded.append(line[:i] + "=" + decoded_text)
        else:
            decoded.append(line)
    return "\n".join(decoded)
def encrypt(text):
    encoded = []
    for line in text.split('\n'):
        try:
            i = line.index("=")
            encoded.append(line[:i] + "="+ "".join(toHex(ord(dec)^key) for dec in line[i + 1:]))
        except ValueError:
            encoded.append(line)
    return "\n".join(encoded)

"""def writeFile(text, selfpath):
    file = f"{kunci}_{selfpath}.ini"
    if not os.path.exists(file):
        with open(file, "w") as fn:
            fn.write(f"{text}")
            fn.close()
            print(f"{file} Created!")
    else:
        with open(file, "w") as fn:
            fn.write(f"{text}")
            fn.close()
            print(f"{file} Created!")"""

def main():
    print("\n[S] SkyUniverse PUBG Encryptor and Decryptor Tools")
    print(">> Menu's are availables\n[1] Encrypt\n[2] Decrypt")
    menu = input("Choose menu you want to use => ")
    if menu in ["1",1,"Encrypt"]:
        enc = input("Masukan teks yang ingin di Enkripsi: ")
        if enc.startswith("+CVars="):
            print(encrypt(enc))
            repeatOnMenu()
        else:
            print("Please starswith `+CVars=`!")
    elif menu in ["2", 2, "Decrypt"]:
        dec = input("Masukan teks yang ingin di Enkripsi: ")
        if dec.startswith("+CVars="):
            print(decode(dec))
            repeatOnMenu()
        else:
            print("Please starswith `+CVars=`!")
    else:
        print("[System Warning] Select valid menu!")
        repeatOnMenu()

def repeatOnMenu():
    repeat = input("[S] You want use this program? (YES/NO)? ")
    if repeat == "YES":
        os.system("clear")
        main()
    else:
        os.system("exit")

if __name__ == "__main__":
    main()


import sys
import adventurer
import item
import consumable
import usable
import safe
import room

def show_inventory(player):
    if not player.inventory:
        print("Your bag is empty.")
    else:
        print("You have: ")
        for invlist in player.inventory:
            print(f"{invlist}")
    player.hunger += 1
    player.thirst += 1

def show_health(player):
    print(
        f"Energy: {player.rest}, Hunger: {player.hunger}, Thirst: {player.thirst}")

def movement(player, cmd):
    if cmd in (player.location.validdirection):
        player.location = player.location.validdirection[cmd]
        print(
            f"You are now in {player.location.name}, {player.location.description}")
    else:
        print("You can't go that way, please choose from: ", end="")
        for key in player.location.validdirection.keys():
            print(f"{key} ", sep=" ", end="")
        print("\n")
    player.hunger += 1
    player.thirst += 1
    player.rest -= 1

def look_room(player):
    print(f"{player.location.name}: {player.location.description}")
    print(f"Hint: {player.location.helptext}\n")
    for stuff in player.location.items:
        print("You see ", end="")
        print(f"{stuff.name}", sep=" ", end="")
        print(f" in the {player.location.name}.")
    player.hunger += 1
    player.thirst += 1

def open_item(player):
    if player.location.name == "Dining Room":
        if not player.location.items[0].state:
            print(safe.FruitBowl.openaction)
            player.inventory.update({usable.Key.name: usable.Key})
            player.location.items[0].state = True
        else:
            print("The bowl is empty.")
    elif player.location.name == "Kitchen":
        if not player.location.items[0].state:
            if 'Key' in player.inventory:
                print(safe.Cabinet.openaction)
                player.inventory.update({usable.Card.name: usable.Card})
                player.inventory.update(
                    {consumable.SnackBar.name: consumable.SnackBar})
                player.location.items[0].state = True
            else:
                print("You need a key to open this.")
        else:
            print("The Cabinet is already open and empty.")
    elif player.location.name == "Bedroom":
        if not player.location.items[0].state:
            if 'Card' in player.inventory:
                print(safe.Nightstand.openaction)
                player.inventory.update(
                    {usable.PassPaper.name: usable.PassPaper})
                player.location.items[0].state = True
            else:
                print("You need a magnetic swipe card to open this.")
        else:
            print("The Nightstand is already open and empty.")
    elif player.location.name == "Living Room":
        if not player.location.items[0].state:
            if 'Paper' in player.inventory:
                print(safe.Computer.openaction)
                player.inventory.update(
                    {usable.DoorCode.name: usable.DoorCode})
                player.location.items[0].state = True
            else:
                print("You need a PIN to access the login.")
        else:
            print("The computer is of no more use to you.")
    elif player.location.name == "Foyer":
        if not player.location.items[0].state:
            if 'Code' in player.inventory:
                print(safe.FrontDoor.openaction)
                player.location.items[0].state = True
                player.escaped = True
            else:
                print(
                    f"""Come on, {player.name}, you didn't think it would be this easy...
                did you?""")
    else:
        print("Nothing in here to open.")

def look_item(player):
    for stuff in player.location.items:
        print(f"You see {stuff.name}, {stuff.description}")
    player.hunger += 1
    player.thirst += 1

def use_item(player):
    if 'Granola' in player.inventory:
        if consumable.SnackBar.state:
            chooseeat = input(
                f"""\nDo you want to eat your snacks now, {player.name}?
You are {player.hunger}% hungry. (Y/N)""")
            if str.upper(chooseeat) == "Y":
                consumable.SnackBar.state = False
                player.hunger = 0
                print("Yummy!  You are 0 % hungry\n")
            else:
                print("Good idea, save it for  when you really need it.\n")
        else:
            print("You already ate your snack bar.")
    if 'Bottle' in player.inventory:
        if consumable.WaterBottle.state:
            choosedrink = input(
                f"""\nDo you want to drink you water now, {player.name}?
You are {player.thirst}% thirsty. (Y/N) """)
            if str.upper(choosedrink) == "Y":
                consumable.WaterBottle.state = False
                player.thirst = 0
                print("Hydrate!  You are 0 % thirsty.\n")
            else:
                print("Good idea, save it for  when you really need it.\n")
        else:
            print("You've already drank your water.")
    else:
        print(f"You don't nave anything I can use.")

def take_item(player):
    if len(player.location.items) > 0:
        try:
            tempdict = {}
            k = 1
            for v in player.location.items:
                tempdict.update({k: v})
                print(f"{k}: {v.name}")
                k += 1
            invitem = input("What item number you like to take? ")
            invdict = tempdict[int(invitem)]
            if invdict.name in ('Cabinet', 'Nightstand', 'Computer', 'Door'):
                print("\nYou can't take that.")
            elif invdict.name == ('FruitBowl'):
                print(
                    "\nWhy would you want wax fruit... ew?  Maybe there's something inside.")
            else:
                player.inventory.update({invdict.name: invdict})
                player.location.items.pop(int(invitem) - 1)
                print(f"You took {invdict.name}")
        except KeyError:
            print("Invalid selection, try again.")
    else:
        print("There are no items to take.")
    player.hunger += 1
    player.thirst += 1

def quit_game(player):
    print(f"""Suicide, eh?  Just couldn't take it any more?
Zeroing your energy level, and.....

    You died.
    Energy: 0, Hunger: {player.hunger}, Thirst: {player.thirst}

    """)
    sys.exit()

def show_menu():
    menu = """
          Inventory........... I or i | Health.............. H or h
          Move North.......... N or n | Move East........... E or e
          Move South.......... S or s | Move West........... W or w
          Take Item........... T or t | Use (eat|drink)..... U or u
          Look at items....... L or l | Look around Room.....R or r
          Open Item............O or o | Quit................ Q or q
        """
    print(menu)

def show_loc(room):
    print(f"\nYou're in the {room.name}: {room.description}")

def main():
    choosename = input("\n\nWould you like to create your name? (Y/N) ")
    name = "Meatbag"
    if str.upper(choosename) == "Y":
        name = input("What is your name? ")

    player = adventurer.Adventurer(name, 100, 0, 0, {}, room.Foyer)

    print("\n\nWelcome to Zork Escape!")
    print("You've entered a room and the door slammed behind you.")
    print("It's up to you to figure out how to get out.")
    print(f"Check your health, watch your stats.  Good luck, {player.name}!")
    show_loc(player.location)

    room.Kitchen.validdirection = {"S": room.Dining_Room}
    room.Dining_Room.validdirection = {"W": room.Foyer,
                                       "N": room.Kitchen}
    room.Foyer.validdirection = {"W": room.Living_Room,
                                 "N": room.Bedroom,
                                 "E": room.Dining_Room}
    room.Bathroom.validdirection = {"E": room.Bedroom}
    room.Bedroom.validdirection = {"S": room.Foyer,
                                   "W": room.Bathroom}
    room.Living_Room.validdirection = {"E": room.Foyer}

    room.Kitchen.items = [safe.Cabinet]
    room.Dining_Room.items = [safe.FruitBowl]
    room.Foyer.items = [safe.FrontDoor, item.DoorStop, item.WoodBlock]
    room.Bathroom.items = [item.ToiletBrush, consumable.WaterBottle]
    room.Bedroom.items = [safe.Nightstand]
    room.Living_Room.items = [safe.Computer]

    safe.FruitBowl.contains = [usable.Key]
    safe.Cabinet.contains = [consumable.SnackBar, usable.Card]
    safe.Nightstand.contains = [usable.PassPaper]

    menu_items = {
        'I': show_inventory,
        'H': show_health,
        'R': look_room,
        'L': look_item,
        'U': use_item,
        'T': take_item,
        "O": open_item,
        'N': movement,
        'S': movement,
        'E': movement,
        'W': movement,
        'Q': quit_game}

    while (player.escaped == False
           and player.rest > 0
           and player.hunger < 101
           and player.thirst < 101):

        show_menu()
        cmd = str.upper(input("Enter Command: ")[:1])
        print()
        if cmd == 'Q':
            quit_game(player)

        func = menu_items.get(cmd)
        if func is None:
            print("Invalid Command!!", file=sys.stderr)
            continue
        elif cmd in ("H", "I", "L", "T", "R", "U", "O"):
            func(player)
        elif cmd in ("N", "S", "E", "W"):
            func(player, cmd)
        else:
            func()

    if player.escaped:
        print(f"\nCongratulations, {name}, you made it!")
        print(f"Energy: {player.rest}, Hunger: {100 - player.hunger}, Thirst: {100 - player.thirst} remaining.\n")
    elif player.rest == 0:
        print("\n\nToo many moves used, try again!")
        print(f"Energy: {player.rest}, Hunger: {player.hunger}, Thirst: {player.thirst}")
    elif player.hunger >= 100:
        print("\n\nSnickers satisfies... you should try one some time.  You died of Hunger.")
        print(f"Energy: {player.rest}, Hunger: {player.hunger}, Thirst: {player.thirst}")
    else:
        print("\n\nYou should really look into r/HydroHomies.  You died of Thirst.")
        print(f"Energy: {player.rest}, Hunger: {player.hunger}, Thirst: {player.thirst}")

if __name__ == "__main__":
    main()


import sys
from random import random
import math
from math import pi
import operator
import numpy as np

from OpenGL.GLUT import *
from OpenGL.GL import *

NAME = "Test Display"

W, H = 500, 500

R1 = 0
R2 = 0
S = 1

def display():
    # init
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    # transformations
    glPushMatrix(); glRotatef(R2*180.0/pi,1,0,0)
    glPushMatrix(); glRotatef(R1*180.0/pi,0,1,0)
    # glPushMatrix(); glScale3f(S,S,S)

    # draw
    glBegin(GL_TRIANGLES)
    glVertex3f(-1,-1, 0)
    glVertex3f( 1,-1, 0)
    glVertex3f( 0, 1, 0)
    glEnd()

    # pop
    glPopMatrix()
    glPopMatrix()
    # glPopMatrix()

    # Render the scene.
    glFlush()

def keyboard(key, x, y):
    # Handle ESC key.
    if key == b'\033':
    # "\033" is the Escape key
        sys.exit(1)

def special(key, x, y): pass

def initRendering():
    """ Initialize aspects of the GL scene rendering.  """
    glEnable (GL_DEPTH_TEST)

def reshape(w, h):
    """ Register a window resize by changing the viewport.  """
    glViewport(0, 0, w, h)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    if w > h:
        glOrtho(-w/h*2.0, w/h*2.0, -2.0, 2.0, -2.0, 2.0)
    else:
        glOrtho(-2.0, 2.0, -h/w * 2.0, h/w * 2.0, -2.0, 2.0)

def main(argc, argv):

    """ The main procedure, sets up GL and GLUT. """

    glutInit(argv)
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)

    glutInitWindowPosition(
        int(glutGet(GLUT_SCREEN_WIDTH)/2 - W/2),
        int(glutGet(GLUT_SCREEN_HEIGHT)/2 - H/2)
    )
    glutInitWindowSize(W, H)
    glutCreateWindow(NAME)
    initRendering()

    # Register interaction callbacks.

    glutKeyboardFunc(keyboard)
    glutSpecialFunc(special)
    glutReshapeFunc(reshape)
    glutDisplayFunc(display)

    glutMainLoop()

    return 0


import tweepy
from textblob import TextBlob
import pandas as pd
import numpy as np
import re
import matplotlib.pyplot as plt
import sys
plt.style.use('fivethirtyeight')

api_key = ""
api_secret_key = ""
access_token = ""
access_token_secret = ""

auth_handler = tweepy.OAuthHandler(consumer_key = api_key, consumer_secret = api_secret_key)
auth_handler.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth_handler)

search_term = "Google"
tweet_amount = 100

tweets = tweepy.Cursor(api.search, q=search_term, lang='en').items(tweet_amount)

polarity = 0

for tweet in tweets:
    final_text = tweet.text.replace('RT', '')
    if final_text.startswith(' @'):
        position = final_text.index(':')
        final_text = final_text[position+2:]
    if final_text.startswith('@'):
        position = final_text.index(' ')
        final_text = final_text[position+2]
    analysis = TextBlob(final_text)
    polarity += analysis.polarity

print(polarity)


from typing import List

class Solution:
    def rankTeams(self, votes: List[str]) -> str:
        count = { v: [0] * len(votes[0]) + [v] for v in votes[0] }

        for vote in votes:
            for i, v in enumerate(vote):
                count[v][i] -= 1

        return ''.join(sorted(votes[0], key=count.get))

def main():
    sol = Solution()
    print(sol.rankTeams(["FVSHJIEMNGYPTQOURLWCZKAX","AITFQORCEHPVJMXGKSLNZWUY","OTERVXFZUMHNIYSCQAWGPKJL",
                         "VMSERIJYLZNWCPQTOKFUHAXG","VNHOZWKQCEFYPSGLAMXJIUTR","ANPHQIJMXCWOSKTYGULFVERZ",
                         "RFYUXJEWCKQOMGATHZVILNSP","SCPYUMQJTVEXKRNLIOWGHAFZ","VIKTSJCEYQGLOMPZWAHFXURN",
                         "SVJICLXKHQZTFWNPYRGMEUAO","JRCTHYKIGSXPOZLUQAVNEWFM","NGMSWJITREHFZVQCUKXYAPOL",
                         "WUXJOQKGNSYLHEZAFIPMRCVT","PKYQIOLXFCRGHZNAMJVUTWES","FERSGNMJVZXWAYLIKCPUQHTO",
                         "HPLRIUQMTSGYJVAXWNOCZEKF","JUVWPTEGCOFYSKXNRMHQALIZ","MWPIAZCNSLEYRTHFKQXUOVGJ",
                         "EZXLUNFVCMORSIWKTYHJAQPG","HRQNLTKJFIEGMCSXAZPYOVUW","LOHXVYGWRIJMCPSQENUAKTZF",
                         "XKUTWPRGHOAQFLVYMJSNEIZC","WTCRQMVKPHOSLGAXZUEFYNJI"]))
    print(sol.rankTeams(["BCA","CAB","CBA","ABC","ACB","BAC"]))
    print(sol.rankTeams(["ABC","ACB","ABC","ACB","ACB"]))
    print(sol.rankTeams(["WXYZ","XYZW"]))
    print(sol.rankTeams(["ZMNAGUEDSJYLBOPHRQICWFXTVK"]))

if __name__ == '__main__':
    main()


import collections
from typing import Union, Optional, Set, List, Dict, Tuple

from blspy import AugSchemeMPL
from chiabip158 import PyBIP158
from clvm.casts import int_from_bytes

from src.consensus.block_rewards import (
    calculate_pool_reward,
    calculate_base_farmer_reward,
)
from src.consensus.blockchain_interface import BlockchainInterface
from src.consensus.coinbase import create_pool_coin, create_farmer_coin
from src.consensus.constants import ConsensusConstants
from src.consensus.find_fork_point import find_fork_point_in_chain
from src.consensus.block_root_validation import validate_block_merkle_roots
from src.consensus.network_type import NetworkType
from src.full_node.block_store import BlockStore
from src.consensus.blockchain_check_conditions import blockchain_check_conditions_dict
from src.full_node.coin_store import CoinStore
from src.consensus.cost_calculator import calculate_cost_of_program, CostResult
from src.consensus.block_record import BlockRecord
from src.types.blockchain_format.coin import Coin
from src.types.coin_record import CoinRecord
from src.types.announcement import Announcement
from src.types.condition_opcodes import ConditionOpcode
from src.types.condition_var_pair import ConditionVarPair
from src.types.full_block import FullBlock, additions_for_npc, announcements_for_npc
from src.types.name_puzzle_condition import NPC
from src.types.blockchain_format.sized_bytes import bytes32
from src.types.unfinished_block import UnfinishedBlock
from src.util.condition_tools import pkm_pairs_for_conditions_dict
from src.util.errors import Err
from src.util.hash import std_hash
from src.util.ints import uint64, uint32

import logging

log = logging.getLogger(__name__)

async def validate_block_body(
    constants: ConsensusConstants,
    blocks: BlockchainInterface,
    block_store: BlockStore,
    coin_store: CoinStore,
    peak: Optional[BlockRecord],
    block: Union[FullBlock, UnfinishedBlock],
    height: uint32,
    cached_cost_result: Optional[CostResult] = None,
    fork_point_with_peak: Optional[uint32] = None,
) -> Tuple[Optional[Err], Optional[CostResult]]:
    """
    This assumes the header block has been completely validated.
    Validates the transactions and body of the block. Returns None for the first value if everything
    validates correctly, or an Err if something does not validate. For the second value, returns a CostResult
    if validation succeeded, and there are transactions
    """
    if isinstance(block, FullBlock):
        assert height == block.height
    prev_transaction_block_height: uint32 = uint32(0)

    # 1. For non block blocks, foliage block, transaction filter, transactions info, and generator must be empty
    # If it is a block but not a transaction block, there is no body to validate. Check that all fields are None
    if block.foliage.foliage_transaction_block_hash is None:
        if (
            block.foliage_transaction_block is not None
            or block.transactions_info is not None
            or block.transactions_generator is not None
        ):
            return Err.NOT_BLOCK_BUT_HAS_DATA, None
        return None, None  # This means the block is valid

    # 2. For blocks, foliage block, transaction filter, transactions info must not be empty
    if (
        block.foliage_transaction_block is None
        or block.foliage_transaction_block.filter_hash is None
        or block.transactions_info is None
    ):
        return Err.IS_TRANSACTION_BLOCK_BUT_NO_DATA, None

    # keeps track of the reward coins that need to be incorporated
    expected_reward_coins: Set[Coin] = set()

    # 3. The transaction info hash in the Foliage block must match the transaction info
    if block.foliage_transaction_block.transactions_info_hash != std_hash(block.transactions_info):
        return Err.INVALID_TRANSACTIONS_INFO_HASH, None

    # 4. The foliage block hash in the foliage block must match the foliage block
    if block.foliage.foliage_transaction_block_hash != std_hash(block.foliage_transaction_block):
        return Err.INVALID_FOLIAGE_BLOCK_HASH, None

    # 5. The prev generators root must be valid
    # TODO(straya): implement prev generators

    # 4. The foliage block hash in the foliage block must match the foliage block
    if block.foliage.foliage_transaction_block_hash != std_hash(block.foliage_transaction_block):
        return Err.INVALID_FOLIAGE_BLOCK_HASH, None

    # 7. The reward claims must be valid for the previous blocks, and current block fees
    if height > 0:
        # Add reward claims for all blocks from the prev prev block, until the prev block (including the latter)
        prev_transaction_block = blocks.block_record(block.foliage_transaction_block.prev_transaction_block_hash)
        prev_transaction_block_height = prev_transaction_block.height

        assert prev_transaction_block.fees is not None
        pool_coin = create_pool_coin(
            prev_transaction_block.height,
            prev_transaction_block.pool_puzzle_hash,
            calculate_pool_reward(prev_transaction_block.height),
        )
        farmer_coin = create_farmer_coin(
            prev_transaction_block.height,
            prev_transaction_block.farmer_puzzle_hash,
            uint64(calculate_base_farmer_reward(prev_transaction_block.height) + prev_transaction_block.fees),
        )
        # Adds the previous block
        expected_reward_coins.add(pool_coin)
        expected_reward_coins.add(farmer_coin)

        # For the second block in the chain, don't go back further
        if prev_transaction_block.height > 0:
            curr_b = blocks.block_record(prev_transaction_block.prev_hash)
            while not curr_b.is_transaction_block:
                expected_reward_coins.add(
                    create_pool_coin(
                        curr_b.height,
                        curr_b.pool_puzzle_hash,
                        calculate_pool_reward(curr_b.height),
                    )
                )
                expected_reward_coins.add(
                    create_farmer_coin(
                        curr_b.height,
                        curr_b.farmer_puzzle_hash,
                        calculate_base_farmer_reward(curr_b.height),
                    )
                )
                curr_b = blocks.block_record(curr_b.prev_hash)

    if set(block.transactions_info.reward_claims_incorporated) != expected_reward_coins:
        return Err.INVALID_REWARD_COINS, None

    removals: List[bytes32] = []
    coinbase_additions: List[Coin] = list(expected_reward_coins)
    additions: List[Coin] = []
    announcements: List[Announcement] = []
    npc_list: List[NPC] = []
    removals_puzzle_dic: Dict[bytes32, bytes32] = {}
    cost: uint64 = uint64(0)

    if height <= constants.INITIAL_FREEZE_PERIOD and block.transactions_generator is not None:
        return Err.INITIAL_TRANSACTION_FREEZE, None

    if constants.NETWORK_TYPE == NetworkType.MAINNET:
        if block.transactions_generator is not None:
            if len(bytes(block.transactions_generator)) > constants.MAX_GENERATOR_SIZE:
                return Err.PRE_SOFT_FORK_MAX_GENERATOR_SIZE, None
            else:
                return None, None
        return None, None
    else:
        # 6. The generator root must be the tree-hash of the generator (or zeroes if no generator)
        if block.transactions_generator is not None:
            if block.transactions_generator.get_tree_hash() != block.transactions_info.generator_root:
                return Err.INVALID_TRANSACTIONS_GENERATOR_ROOT, None
        else:
            if block.transactions_info.generator_root != bytes([0] * 32):
                return Err.INVALID_TRANSACTIONS_GENERATOR_ROOT, None

        if block.transactions_generator is not None:
            # Get List of names removed, puzzles hashes for removed coins and conditions crated
            if cached_cost_result is not None:
                result: Optional[CostResult] = cached_cost_result
            else:
                result = calculate_cost_of_program(block.transactions_generator, constants.CLVM_COST_RATIO_CONSTANT)
            assert result is not None
            cost = result.cost
            npc_list = result.npc_list

            # 8. Check that cost <= MAX_BLOCK_COST_CLVM
            if cost > constants.MAX_BLOCK_COST_CLVM:
                return Err.BLOCK_COST_EXCEEDS_MAX, None
            if result.error is not None:
                return Err(result.error), None

            for npc in npc_list:
                removals.append(npc.coin_name)
                removals_puzzle_dic[npc.coin_name] = npc.puzzle_hash

            additions = additions_for_npc(npc_list)
            announcements = announcements_for_npc(npc_list)
        else:
            result = None

        # 9. Check that the correct cost is in the transactions info
        if block.transactions_info.cost != cost:
            return Err.INVALID_BLOCK_COST, None

        additions_dic: Dict[bytes32, Coin] = {}
        # 10. Check additions for max coin amount
        # Be careful to check for 64 bit overflows in other languages. This is the max 64 bit unsigned integer
        for coin in additions + coinbase_additions:
            additions_dic[coin.name()] = coin
            if coin.amount > constants.MAX_COIN_AMOUNT:
                return Err.COIN_AMOUNT_EXCEEDS_MAXIMUM, None

        # 11. Validate addition and removal roots
        root_error = validate_block_merkle_roots(
            block.foliage_transaction_block.additions_root,
            block.foliage_transaction_block.removals_root,
            additions + coinbase_additions,
            removals,
        )
        if root_error:
            return root_error, None

        # 12. The additions and removals must result in the correct filter
        byte_array_tx: List[bytes32] = []

        for coin in additions + coinbase_additions:
            byte_array_tx.append(bytearray(coin.puzzle_hash))
        for coin_name in removals:
            byte_array_tx.append(bytearray(coin_name))

        bip158: PyBIP158 = PyBIP158(byte_array_tx)
        encoded_filter = bytes(bip158.GetEncoded())
        filter_hash = std_hash(encoded_filter)

        if filter_hash != block.foliage_transaction_block.filter_hash:
            return Err.INVALID_TRANSACTIONS_FILTER_HASH, None

        # 13. Check for duplicate outputs in additions
        addition_counter = collections.Counter(_.name() for _ in additions + coinbase_additions)
        for k, v in addition_counter.items():
            if v > 1:
                return Err.DUPLICATE_OUTPUT, None

        # 14. Check for duplicate spends inside block
        removal_counter = collections.Counter(removals)
        for k, v in removal_counter.items():
            if v > 1:
                return Err.DOUBLE_SPEND, None

        # 15. Check if removals exist and were not previously spent. (unspent_db + diff_store + this_block)
        if peak is None or height == 0:
            fork_h: int = -1
        elif fork_point_with_peak is not None:
            fork_h = fork_point_with_peak
        else:
            fork_h = find_fork_point_in_chain(blocks, peak, blocks.block_record(block.prev_header_hash))

        if fork_h == -1:
            coin_store_reorg_height = -1
        else:
            last_block_in_common = await blocks.get_block_record_from_db(blocks.height_to_hash(uint32(fork_h)))
            assert last_block_in_common is not None
            coin_store_reorg_height = last_block_in_common.height

        # Get additions and removals since (after) fork_h but not including this block
        additions_since_fork: Dict[bytes32, Tuple[Coin, uint32]] = {}
        removals_since_fork: Set[bytes32] = set()
        coinbases_since_fork: Dict[bytes32, uint32] = {}

        if height > 0:
            curr: Optional[FullBlock] = await block_store.get_full_block(block.prev_header_hash)
            assert curr is not None

            while curr.height > fork_h:
                removals_in_curr, additions_in_curr = curr.tx_removals_and_additions()
                for c_name in removals_in_curr:
                    removals_since_fork.add(c_name)
                for c in additions_in_curr:
                    additions_since_fork[c.name()] = (c, curr.height)

                for coinbase_coin in curr.get_included_reward_coins():
                    additions_since_fork[coinbase_coin.name()] = (coinbase_coin, curr.height)
                    coinbases_since_fork[coinbase_coin.name()] = curr.height
                if curr.height == 0:
                    break
                curr = await block_store.get_full_block(curr.prev_header_hash)
                assert curr is not None

        removal_coin_records: Dict[bytes32, CoinRecord] = {}
        for rem in removals:
            if rem in additions_dic:
                # Ephemeral coin
                rem_coin: Coin = additions_dic[rem]
                new_unspent: CoinRecord = CoinRecord(
                    rem_coin,
                    height,
                    uint32(0),
                    False,
                    (rem in coinbases_since_fork),
                    block.foliage_transaction_block.timestamp,
                )
                removal_coin_records[new_unspent.name] = new_unspent
            else:
                unspent = await coin_store.get_coin_record(rem)
                if unspent is not None and unspent.confirmed_block_index <= coin_store_reorg_height:
                    # Spending something in the current chain, confirmed before fork
                    # (We ignore all coins confirmed after fork)
                    if unspent.spent == 1 and unspent.spent_block_index <= coin_store_reorg_height:
                        # Check for coins spent in an ancestor block
                        return Err.DOUBLE_SPEND, None
                    removal_coin_records[unspent.name] = unspent
                else:
                    # This coin is not in the current heaviest chain, so it must be in the fork
                    if rem not in additions_since_fork:
                        # Check for spending a coin that does not exist in this fork
                        # TODO: fix this, there is a consensus bug here
                        return Err.UNKNOWN_UNSPENT, None
                    new_coin, confirmed_height = additions_since_fork[rem]
                    new_coin_record: CoinRecord = CoinRecord(
                        new_coin,
                        confirmed_height,
                        uint32(0),
                        False,
                        (rem in coinbases_since_fork),
                        block.foliage_transaction_block.timestamp,
                    )
                    removal_coin_records[new_coin_record.name] = new_coin_record

                # This check applies to both coins created before fork (pulled from coin_store),
                # and coins created after fork (additions_since_fork)>
                if rem in removals_since_fork:
                    # This coin was spent in the fork
                    return Err.DOUBLE_SPEND, None

        removed = 0
        for unspent in removal_coin_records.values():
            removed += unspent.coin.amount

        added = 0
        for coin in additions:
            added += coin.amount

        # 16. Check that the total coin amount for added is <= removed
        if removed < added:
            return Err.MINTING_COIN, None

        fees = removed - added
        assert_fee_sum: uint64 = uint64(0)

        for npc in npc_list:
            if ConditionOpcode.RESERVE_FEE in npc.condition_dict:
                fee_list: List[ConditionVarPair] = npc.condition_dict[ConditionOpcode.RESERVE_FEE]
                for cvp in fee_list:
                    fee = int_from_bytes(cvp.vars[0])
                    assert_fee_sum = assert_fee_sum + fee

        # 17. Check that the assert fee sum <= fees
        if fees < assert_fee_sum:
            return Err.RESERVE_FEE_CONDITION_FAILED, None

        # 18. Check that the assert fee amount < maximum coin amount
        if fees > constants.MAX_COIN_AMOUNT:
            return Err.COIN_AMOUNT_EXCEEDS_MAXIMUM, None

        # 19. Check that the computed fees are equal to the fees in the block header
        if block.transactions_info.fees != fees:
            return Err.INVALID_BLOCK_FEE_AMOUNT, None

        # 20. Verify that removed coin puzzle_hashes match with calculated puzzle_hashes
        for unspent in removal_coin_records.values():
            if unspent.coin.puzzle_hash != removals_puzzle_dic[unspent.name]:
                return Err.WRONG_PUZZLE_HASH, None

        # 21. Verify conditions
        # create hash_key list for aggsig check
        pairs_pks = []
        pairs_msgs = []
        for npc in npc_list:
            assert height is not None
            unspent = removal_coin_records[npc.coin_name]
            error = blockchain_check_conditions_dict(
                unspent,
                announcements,
                npc.condition_dict,
                prev_transaction_block_height,
                block.foliage_transaction_block.timestamp,
            )
            if error:
                return error, None
            for pk, m in pkm_pairs_for_conditions_dict(npc.condition_dict, npc.coin_name):
                pairs_pks.append(pk)
                pairs_msgs.append(m)

        # 22. Verify aggregated signature
        # TODO: move this to pre_validate_blocks_multiprocessing so we can sync faster
        if not block.transactions_info.aggregated_signature:
            return Err.BAD_AGGREGATE_SIGNATURE, None

            # noinspection PyTypeChecker
        if not AugSchemeMPL.aggregate_verify(pairs_pks, pairs_msgs, block.transactions_info.aggregated_signature):
            return Err.BAD_AGGREGATE_SIGNATURE, None

        return None, result


import torch
import heat as ht

class Laplacian:
    def __init__(
        self,
        similarity,
        weighted=True,
        definition="norm_sym",
        mode="fully_connected",
        threshold_key="upper",
        threshold_value=1.0,
        neighbours=10,
    ):
        """
        Graph Laplacians from a dataset

        Parameters
        ----------
        similarity : function f(X) --> similarity matrix
            Metric function that defines similarity between vertices. Should accept a data matrix (n,f) as input and return an (n,n) similarity matrix.
            Additional required parameters can be passed via a lambda function.
        definition : string
            Type of Laplacian
            'simple': Laplacian matrix for simple graphs L = D - A
            'norm_sym': Symmetric normalized Laplacian L^sym = D^{-1/2} L D^{-1/2} = I - D^{-1/2} A D^{-1/2}
            'norm_rw': L^rw = D^{-1} L = I - D^{-1} A
        mode : "fc", "eNeighbour"
            How to calculate adjacency from the similarity matrix
            "fully_connected" is fully-connected, so A = S
            "eNeighbour" is the epsilon neighbourhood, with A_ji = 0 if S_ij </> lower/upper; for eNeighbour an upper or lower boundary needs to be set
        threshold_key : string
            "upper" or "lower", defining the type of threshold for the epsilon-neighrborhood
        threshold_value : float
            Boundary value for the epsilon-neighrborhood
        neighbours : int
            Number of neirest neighbors to be considered for adjacency definition. Currently not implemented
        Returns
        -------
        L : ht.DNDarray

        """
        self.similarity_metric = similarity
        self.weighted = weighted
        if definition not in ["simple", "norm_sym"]:
            raise NotImplementedError(
                "Currently only simple and normalized symmetric graph laplacians are supported"
            )
        else:
            self.definition = definition
        if mode not in ["eNeighbour", "fully_connected"]:
            raise NotImplementedError(
                "Only eNeighborhood and fully-connected graphs supported at the moment."
            )
        else:
            self.mode = mode

        if threshold_key not in ["upper", "lower"]:
            raise ValueError(
                "Only 'upper' and 'lower' threshold types supported for eNeighbouhood graph construction"
            )
        else:
            self.epsilon = (threshold_key, threshold_value)

        self.neighbours = neighbours

    def _normalized_symmetric_L(self, A):
        degree = ht.sum(A, axis=1)
        degree.resplit_(axis=None)
        # Find stand-alone vertices with no connections
        temp = torch.ones(
            degree.shape, dtype=degree.larray.dtype, device=degree.device.torch_device
        )
        degree.larray = torch.where(degree.larray == 0, temp, degree.larray)
        L = A / ht.sqrt(ht.expand_dims(degree, axis=1))
        L = L / ht.sqrt(ht.expand_dims(degree, axis=0))
        L = L * (-1.0)
        L.fill_diagonal(1.0)
        return L

    def _simple_L(self, A):
        degree = ht.sum(A, axis=1)
        L = ht.diag(degree) - A
        return L

    def construct(self, X):
        S = self.similarity_metric(X)
        S.fill_diagonal(0.0)

        if self.mode == "eNeighbour":
            if self.epsilon[0] == "upper":
                if self.weighted:
                    S = ht.where(S < self.epsilon[1], S, 0)
                else:
                    S = ht.int(S < self.epsilon[1])
            else:
                if self.weighted:
                    S = ht.where(S > self.epsilon[1], S, 0)
                else:
                    S = ht.int(S > self.epsilon[1])

        if self.definition == "simple":
            L = self._simple_L(S)
        elif self.definition == "norm_sym":
            L = self._normalized_symmetric_L(S)

        return L


class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        res = [0] * len(temperatures)
        stack = [] # we
        LEN = len(temperatures)
        for i in range(LEN-1, -1, -1):
            while stack and stack[-1][0] < temperatures[i]:
                stack.pop()
            if not stack:
                res[i] = 0  # lets check if there are any elements
                stack.append([temperatures[i], i])  # add current element to stack
            else:
                res[i] = stack[-1][1] - i
                stack.append([temperatures[i], i])
        return res


import math
from random import randrange, uniform

import numpy as np
import OpenGL
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

from cluster_aabb import Cluster_AABB
from cluster_sphere import ClusterSphere
from camera import Camera
from cylinder import Cylinder
from cone import Cone
from plane import Plane
from point import Point
from raycasting import Raycasting
from sphere import Sphere
from material import Material
from ambient_light import AmbientLight
from point_light import PointLight
from directionoal_point_light import DirectionalPointLight
from spot_light import SpotLight

from utils import *
from matrix_transformation import *
from obj_reader import *

def square():
    glBegin(GL_QUADS)
    glVertex2f(100, 100)
    glVertex2f(200, 100)
    glVertex2f(200, 200)
    glVertex2f(100, 200)
    glEnd()

def draw_scene(width, height, nlines, ncols, matrix):
    width_frame = width/ncols
    height_frame = height/nlines
    init_width = -width * 0.5
    init_height = height * 0.5
    for line in range(0, nlines):
        y1 = init_height - height_frame*line
        y2 = init_height - height_frame*(line+1)
        for col in range(0, ncols):
            glColor3f(matrix[line][col][0], matrix[line]
                      [col][1], matrix[line][col][2])
            x1 = init_width + width_frame*col
            x2 = init_width + width_frame*(col+1)
            glBegin(GL_QUADS)
            glVertex2f(x1, y1)
            glVertex2f(x1, y2)
            glVertex2f(x2, y2)
            glVertex2f(x2, y1)
            glEnd()

def iterate():
    glViewport(0, 0, w, h)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(-w * 0.5, w*0.5, -h*0.5, h*0.5, 0.0, 1.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

def showScreen():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    iterate()
    glColor3f(1.0, 0.0, 3.0)
    # square()
    draw_scene(w, h, lines, cols, teste_ray.create_matrix())
    glutSwapBuffers()

if __name__ == '__main__':

    w, h, lines, cols = 800, 800, 200, 200

    point_xyz = Point(-2, -2, 5)
    lookat = Point(0, 0, -0)
    view_up = Point(0, 1.0, 0.0)

    point_xyz1 = Point(0, 80, -50)
    lookat1 = Point(0, 1, -50)
    view_up1 = Point(0, 1.0, 0.1)

    view = Camera(point_xyz=point_xyz,
                  lookat=lookat, view_up=view_up)

    # Materials
    bronze = Material([0.2125, 0.1275, 0.054],[0.714, 0.4284, 0.18144],[0.393548, 0.271906, 0.166721],10)
    obsidian = Material([0.05375, 0.05, 0.06625],[0.18275, 0.17, 0.22525],[0.332741, 0.328634, 0.346435], 0)
    chrome = Material([0.25, 0.25, 0.25],[0.4, 0.4, 0.4],[0.774597, 0.774597, 0.774597],0)
    teste = Material([0.1, 0.1, 0.1],[0.1, 0.1, 0.1],[0.1, 0.1, 0.1],0)
    gold = Material([0.24725, 0.1995, 0.0745],[0.75164, 0.60648, 0.22648],[0.628281, 0.555802, 0.366065],8)
    silver = Material([0.19225, 0.19225, 0.19225], [0.50754, 0.50754, 0.50754], [0.508273, 0.508273, 0.508273], 0)
    ruby = Material([0.1745, 0.01175, 0.01175], [0.61424, 0.04136, 0.04136], [0.727811, 0.626959, 0.626959], 1)
    emerald = Material([0.0215, 0.1745, 0.0215], [0.07568, 0.61424, 0.07568], [0.633, 0.727811, 0.633], 0.6)
    brass = Material([0.329412, 0.223529, 0.027451], [0.780392, 0.568627, 0.113725], [0.992157, 0.941176, 0.807843], 0.21794872)
    red_rubber = Material([0.05, 0.0, 0.0], [0.5, 0.4, 0.4], [0.7, 0.04, 0.04], .078125)
    black_rubber = Material([0.02, 0.02, 0.02], [0.01, 0.01, 0.01], [0.4, 0.4, 0.4], .078125)
    yellow_rubber = Material([0.05, 0.05, 0.0], [0.0, 0.5, 0.4], [0.7, 0.07, 0.04], .078125)
    white_rubber = Material([0.05, 0.05, 0.05], [0.5, 0.5, 0.5], [0.7, 0.07, 0.07], .078125)
    green_rubber = Material([0.0,	0.05,	0.0],	[0.4,	0.5,	0.4],	[0.04,	0.7,	0.04],	0.078125)
    turquoise = Material([0.1, 0.18725, 0.1745], [0.396, 0.74151, 0.69102],  [0.297254, 0.30829, 0.306678], 0.1)
    cyan_plastic = Material([0.0,0.1,0.06],	[0.0,0.50980392,0.50980392],[0.50196078,0.50196078,0.50196078],	0.25)
    green_plastic = Material([0.0, 0.0, 0.0], [0.1, 0.35, 0.1],	[0.45, 0.55, 0.45],	0.25)
    red_plastic	= Material([0.0,0.0,0.0],	[0.5,0.0,0.0],	[0.7,0.6,0.6],	0.25)
    materials = [bronze, obsidian, chrome, teste, gold, silver, ruby, emerald, brass, red_rubber, black_rubber, yellow_rubber, white_rubber, green_rubber, turquoise, cyan_plastic, green_plastic, red_plastic]

    # Lights
    light_ambient = AmbientLight([0.0,0.0,0.8])

    point_light = PointLight(Point(-120.0,120.0,0.0), [0.3,0.3,0.3])
    point_light.get_point_camera(view)

    point_light1 = PointLight(Point(120.0,120.0,-50.0), [0.3,0.3,0.3])
    point_light1.get_point_camera(view)

    point_light2 = PointLight(Point(25.0,0.0,-30.0), [0.9,0.9,0.9])
    point_light2.get_point_camera(view)

    directional_point_light = DirectionalPointLight(Point(0,0,0), [0.3,0.3,0.3], Point(0.0,0.0,-1.0))
    directional_point_light.get_point_camera(view)

    spot_light = SpotLight(Point(-15.0,-10.0,-90.0), [1.0,1.0,0.0], Point(0.0,1.0, 0.0), 50)
    spot_light.get_point_camera(view)

    lights = [light_ambient,point_light, point_light1, point_light2, directional_point_light]

    # Objects
    cylinder = Cylinder(Point(30, 15, -50), 10, 15, Point(0.0, 1.0, 1.0), bronze)
    cylinder.get_center_camera(view)
    print(cylinder.center_camera.matrix)

    sphere = Sphere(Point(-15.0, 15.0, -50.0), 12, bronze)
    sphere.get_center_camera(view)
    # print(sphere.center_camera.matrix)

    # sphere1 = Sphere(Point(0.0, 10.0, -60), 9, ruby)
    # sphere1.get_center_camera(view)

    # cone = Cone(Point(0, 0, -50), 9, 18, Point(0.0, 1.0, 0.0), silver)
    # cone.get_center_camera(view)
    # print(cone.center_camera.matrix)
    # cone1 = Cone(Point(-25, 0, -50), 9, 18, Point(0.0, 1.0, 0.7), bronze)
    # cone1.get_center_camera(view)
    cone2 = Cone(Point(25, 0, -50), 9, 18, Point(0.0, 1.0, -0.7), bronze)
    cone2.get_center_camera(view)

    plane = Plane(Point(0,-370,-50), Point(0,1,0.0),silver)
    plane1 = Plane(Point(-370,0,-50), Point(1,0,0.0),chrome)
    plane2 = Plane(Point(370,0,-50), Point(-1,0,0.0),ruby)
    plane3 = Plane(Point(0,0,-450), Point(0,0,-1.0),obsidian)

    test_object = read_faces_from_obj('obj/1face.obj', bronze)
    for obj in test_object:
        obj.get_center_camera(view)
        print(obj.center_camera.matrix)
    # scene = [sphere1]
    # scene = [cone, cone1, cone2]
    objects_scene = [sphere]

    cluster1 = ClusterSphere(Point(30.0, 30.0, -50.0),25, [cone2, cylinder])
    cluster1.get_center_camera(view)

    cluster = ClusterSphere(Point(-15.0, 15.0, -50.0),15, objects_scene)
    cluster.get_center_camera(view)

    scene = [cluster, cluster1]
    # scene = [cylinder]

    # RayCast
    teste_ray = Raycasting(lights,scene, view, w/2, w, h, lines, cols,'perspective')

    # print(view.world_to_camera)

    # OpenGL main loop
    # Initialize a glut instance which will allow us to customize our window
    glutInit()
    glutInitDisplayMode(GLUT_RGBA)  # Set the display mode to be colored
    glutInitWindowSize(w, h)   # Set the width and height of your window
    # Set the position at which this windows should appear
    glutInitWindowPosition(1000, 100)
    # Give your window a title
    wind = glutCreateWindow("OpenGL Coding Practice")
    # Tell OpenGL to call the showScreen method continuously
    glutDisplayFunc(showScreen)
    # Draw any graphics or shapes in the showScreen function at all times
    # glutIdleFunc(showScreen)
    glutMainLoop()  # Keeps the window created above displaying/running in a loop


# @Time : 2022-10-02 10:53
# @Author : Phalange
# @File : 6193. 沙漏的最大总和.py
# @Software: PyCharm
# C'est la vie,enjoy it! :D
from typing import List

class Solution:
    def maxSum(self, grid: List[List[int]]) -> int:
        ans = 0
        m = len(grid)
        n = len(grid[0])
        for i in range(0,m-2):
            for j in range(0,n-2):
                tmp = sum(sum(rows[j:j+3]) for rows in grid[i:i+3]) - grid[i+1][j] - grid[i+1][j+2]
                ans = max(tmp,ans)

        return ans

grid = [[6,2,1,3],[4,2,1,5],[9,2,8,7],[4,1,2,9]]
print(Solution().maxSum(grid))


# https://www.hackerrank.com/challenges/itertools-product/problem

from itertools import product

a = list(input().split()) # [int(x) for x in input().split()]
num1 = [int(i) for i in a] #
b = list(input().split())
num2 = [int(i) for i in b]
c=list(product(num1,num2))
print(*c)


# encoding: utf-8
# Python2 support
from __future__ import unicode_literals

from quartier import Quartier

class Zone(object):
    def __init__(self, name):
        self.name = name
        self.nb_vehicule = 0
        self._start = Quartier("")

    def __str__(self):
        return self.name

    def ajouter_quartier(self, zip_code):
        """
        Ajoute un quartier (code postal) à la zone.
        Le quartier est décomposé en sous-quartiers de façon à former un automate à états finis.

        :param zip_code: Le code postal complet à ajouter.
        """
        current_state = self._start
        for char in zip_code:
            if current_state.get_noeud(char) is None:
                current_state.ajouter_arc(char)
            current_state = current_state.get_noeud(char)

    def contains(self, zip_code):
        """
        Détermine si le quartier est présent dans la zone.

        :param zip_code: Le code postal complet du quartier à chercher.
        :return: True si le quartier existe dans la zone, False sinon
        """
        current_state = self._start.get_noeud(zip_code[0])

        if current_state is not None:
            for char in zip_code[1:]:
                current_state = current_state.get_noeud(char)
                if current_state is None:
                    break

        return current_state is not None

    def select_random_quartier(self):
        """
        Sélectionne un quartier au hasard dans la zone.
        Utile pour initialiser le quartier de départ des véhicules.

        :return: Un quartier choisi au hasard.
        """
        return self._start.get_random_noeud()


"""Customized ProcessPoolExecutor."""
import concurrent.futures
import concurrent.futures.process
import multiprocessing

def _process_worker(initializer, call_queue, result_queue):
    """Runs initializer before _process_worker to set signal handlers."""
    initializer()
    concurrent.futures.process._process_worker(call_queue, result_queue)  # pylint: disable=protected-access

class ProcessPoolExecutorWithInit(concurrent.futures.ProcessPoolExecutor):
    """Process pool executor with initializer.

    Allows executing _initializer on each worker before processing tasks.
    """

    def __init__(self, *args, initializer=None, **kwargs):
        super().__init__(*args, **kwargs)
        self._initializer = initializer

    def _adjust_process_count(self):
        for _ in range(len(self._processes), self._max_workers):
            p = multiprocessing.Process(
                target=_process_worker,
                args=(self._initializer,
                      self._call_queue,
                      self._result_queue))
            p.start()
            self._processes[p.pid] = p


from sys import exit
"""This file implements utilities used for working with scheme I/O,
 scheme lists and using them together with python lists."""

CSE_EXECUTABLE_LIST = 0
CSE_NONEXECUTABLE_LIST = 1
CSE_STRING = 2
CSE_OTHER = 3

# Removes all the comments from the given command.
def removeComments(comm):
    pos = 0

    while True:
        if pos >= len(comm):
            break
        comPos = comm.find(';', pos)
        if comPos == -1:
            break
        uncomPos = comm.find('\n', comPos)
        if uncomPos == -1:
            uncomPos = len(comm)
        comm = comm[0:comPos] + comm[uncomPos + 1:]
        pos = comPos

    return comm

# Gets rid of extra whitespace.
# Returns the given command as being on one line,
# only whitespace being single spaces between lists and elements of lists.
def fixWhitespace(comm):
    comm = comm.replace('\n', ' ')
    comm = ' '.join(comm.split())
    comm = comm.replace('( ', '(')
    comm = comm.replace(' )', ')')
    comm = comm.replace('\' ', '\'')
    return comm

# Checks the start and end of string.
# Check for (...); '(...); '...'/"...".
def checkStartEnd(strn):
    if strn[len(strn) - 1] == ')' and strn[0] == '(':
        return CSE_EXECUTABLE_LIST
    if strn[len(strn) - 1] == ')' and strn[0:2] == '\'(':
        return CSE_NONEXECUTABLE_LIST
    if [strn[0], strn[len(strn) - 1]] in [['\'', '\''], ['\"', '\"']]:
        return CSE_STRING
    return CSE_OTHER

# Returns the first occurence after pos of a substring in strn being encased between leftC and rightC.
# leftC and rightC are included in the result
# leftC and rightC should be different
def getEncasedIn(strn, pos, leftC, rightC):
    if leftC == rightC:
        return ""

    stepL = len(leftC)
    stepR = len(rightC)

    # Get to the closest occurence of leftC
    startPos = strn.find(leftC, pos)
    pos = startPos

    leftCount = 0

    while pos < len(strn):
        if strn[pos:(pos + stepL)] == leftC:        # skip step characters if encountered leftC or rightC
            leftCount += 1
            pos += stepL
        elif strn[pos:(pos + stepR)] == rightC:
            leftCount -= 1
            pos += stepR
        else:                                       # skip only one character if encountered neither
            pos += 1

        if leftCount == 0:                          # return the desired substring if we found it
            return strn[startPos:pos]

    return ''                                       # return empty string if we got to the end of strn

# Returns the given command as a list. Assumes that the command is properly structured.
# First element of the returned list is whether the list should be evaluated,
# second element is the list of the list's elements
def getListFromCommand(comm):
    # make sure that the command is an actual scheme list
    if checkStartEnd(comm) not in [CSE_EXECUTABLE_LIST, CSE_NONEXECUTABLE_LIST]:
        print("Error: trying to parse a non-list as a list. Quitting.")
        exit()

    res = []
    comm = comm[:len(comm) - 1]         # remove ) at the end
    if comm[0] == '\'':                 # remove '( at the start
        comm = comm[2:]
        res.append(False)
    else:                               # remove ( at the start
        res.append(True)
        comm = comm[1:]

    elems = []
    pos = 0

    while pos < len(comm):
        if comm[pos] == '(':          # executable list
            newElem = getEncasedIn(comm, pos, '(', ')')
        elif (pos < len(comm) - 1) and comm[pos:pos + 2] == '\'(':           # non-executable list
            newElem = getEncasedIn(comm, pos, '\'(', ')')
        else:                           # just an element
            beforeNext = comm.find(' ', pos)
            if beforeNext == -1:
                beforeNext = len(comm)
            newElem = comm[pos:beforeNext]

        # append the new element and move the position forward
        elems.append(newElem)
        pos += len(newElem)
        pos += 1

    res.append(elems)
    return res

# Returns a string representation of the given python list(no quotes)
def listToSchemeList(lst):
    res = '('
    if len(lst) > 0:
        res += listToSchemeList(lst[0]) if isinstance(lst[0], list) else str(lst[0])
    for elem in lst[1:]:
        res += ' ' + (listToSchemeList(elem) if isinstance(elem, list) else str(elem))
    res += ')'
    return res

# Returns a string representation of the given python list, except that all lists are starting with quote
def listTononexList(lst):
    res = '\'('
    if len(lst) > 0:
        res += listTononexList(lst[0]) if isinstance(lst[0], list) else str(lst[0])
    for elem in lst[1:]:
        res += ' ' + (listTononexList(elem) if isinstance(elem, list) else str(elem))
    res += ')'
    return res

# Replaces every occurence of arg in lst with argVal. lst is a scheme list in string form.
def replaceInList(arg, argVal, lst):
    pos = 0
    while True:
        pos = lst.find(arg, pos)
        if pos == -1:
            break

        if lst[pos - 1] in ['(', ' '] and lst[pos + len(arg)] in [')', ' ']:
            lst = lst[0:pos] + str(argVal) + lst[pos + len(str(arg)):]

        pos += len(arg)

    return lst

# Used to output the result of a command
def output(result):
    if result is None:
        return
    if isinstance(result, list):
        result = listToSchemeList(result)
    result = str(result)
    result = result.replace('\'(', '(')
    result = fixWhitespace(result)
    print(result, end='')


#! /usr/bin/env python3
import numpy as np
from computeDifference import computeDifference

def computeStopCondFuncVal(ReconValues,MeasuredValues,StopCondParams,ImageType,StopCondFuncVal,MaxIdxsVect,NumSamples,IterNum,BatchSamplingParams):

    if BatchSamplingParams.Do=='N':
        Diff=computeDifference(ReconValues[MaxIdxsVect],MeasuredValues[NumSamples-1],ImageType)
        if IterNum == 0:
            StopCondFuncVal[IterNum,0] = StopCondParams.Beta*Diff
        else:
            StopCondFuncVal[IterNum,0] = ((1-StopCondParams.Beta)*StopCondFuncVal[IterNum-1,0] + StopCondParams.Beta*Diff)
        StopCondFuncVal[IterNum,1] = NumSamples

    else:
        Diff=0
        for i in range(0,BatchSamplingParams.NumSamplesPerIter):
            Diff=computeDifference(ReconValues[MaxIdxsVect[i]],MeasuredValues[NumSamples-1-(BatchSamplingParams.NumSamplesPerIter-i-1)],ImageType)+Diff
        Diff = Diff/BatchSamplingParams.NumSamplesPerIter
        if IterNum == 0:
            StopCondFuncVal[IterNum,0] = StopCondParams.Beta*Diff
        else:
            StopCondFuncVal[IterNum,0] = ((1-StopCondParams.Beta)*StopCondFuncVal[IterNum-1,0] + StopCondParams.Beta*Diff)
        StopCondFuncVal[IterNum,1] = NumSamples
    return StopCondFuncVal

def checkStopCondFuncThreshold(StopCondParams,StopCondFuncVal,NumSamples,IterNum,SizeImage):

    if StopCondParams.Threshold==0:
        if NumSamples>SizeImage[0]*SizeImage[1]*StopCondParams.MaxPercentage/100:
            Stop=1
        else:
            Stop=0

    else:
        if NumSamples>SizeImage[0]*SizeImage[1]*StopCondParams.MaxPercentage/100:
            Stop=1
        else:
            if np.logical_and(((SizeImage[0]*SizeImage[1])*StopCondParams.MinPercentage/100)<NumSamples,StopCondFuncVal[IterNum,0]<StopCondParams.Threshold):
                Stop=0
                GradStopCondFunc =np.mean(StopCondFuncVal[IterNum,0]-StopCondFuncVal[IterNum-StopCondParams.JforGradient:IterNum-1,0])
                if GradStopCondFunc<0:
                    Stop=1
            else:
                Stop=0
    return Stop

def computeBeta(SizeImage):
    import math
    if SizeImage[0]*SizeImage[1]<512**2+1:
        Beta = 0.001*(((18-math.log(SizeImage[0]*SizeImage[1],2))/2)+1)
    else:
        Beta = 0.001/(((math.log(SizeImage[0]*SizeImage[1],2)-18)/2)+1)
    return Beta


import os
import sys
import types
import weakref
import logging
import datetime
import warnings
import traceback
import functools

from . import _registered_callbacks
from .vendor import six

def inrange(number, base, offset=0.5):
    r"""Evaluate whether `number` is within `base` +- `offset`

    Lower bound is *included* whereas upper bound is *excluded*
    so as to allow for ranges to be stacked up against each other.
    For example, an offset of 0.5 and a base of 1 evenly stacks
    up against a base of 2 with identical offset.

    Arguments:
        number (float): Number to consider
        base (float): Center of range
        offset (float, optional): Amount of offset from base

    Usage:
        >>> inrange(0, base=1, offset=0.5)
        False
        >>> inrange(0.4, base=1, offset=0.5)
        False
        >>> inrange(1.4, base=1, offset=0.5)
        True
        >>> # Lower bound is included
        >>> inrange(0.5, base=1, offset=0.5)
        True
        >>> # Upper bound is excluded
        >>> inrange(1.5, base=1, offset=0.5)
        False

    """

    return (base - offset) <= number < (base + offset)

class MessageHandler(logging.Handler):
    def __init__(self, records, *args, **kwargs):
        # Not using super(), for compatibility with Python 2.6
        logging.Handler.__init__(self, *args, **kwargs)
        self.records = records

    def emit(self, record):
        self.records.append(record)

def extract_traceback(exception):
    """Inject current traceback and store in exception"""
    exc_type, exc_value, exc_traceback = sys.exc_info()
    exception.traceback = traceback.extract_tb(exc_traceback)[-1]
    del(exc_type, exc_value, exc_traceback)

def time():
    """Return ISO formatted string representation of current UTC time."""
    return '%sZ' % datetime.datetime.utcnow().isoformat()

class ItemList(list):
    """List with keys

    Raises:
        KeyError is item is not in list

    Example:
        >>> Obj = type("Object", (object,), {})
        >>> obj = Obj()
        >>> obj.name = "Test"
        >>> l = ItemList(key="name")
        >>> l.append(obj)
        >>> l[0] == obj
        True
        >>> l["Test"] == obj
        True
        >>> try:
        ...   l["NotInList"]
        ... except KeyError:
        ...   print(True)
        True
        >>> obj == l.get("Test")
        True
        >>> l.get("NotInList") == None
        True

    """

    def __init__(self, key, object=list()):
        super(ItemList, self).__init__(object)
        self.key = key

    def __getitem__(self, index):
        if isinstance(index, int):
            return super(ItemList, self).__getitem__(index)

        for item in self:
            if getattr(item, self.key) == index:
                return item

        raise KeyError("%s not in list" % index)

    def get(self, key, default=None):
        try:
            return self.__getitem__(key)
        except KeyError:
            return default

class classproperty(object):
    def __init__(self, getter):
        self.getter = getter

    def __get__(self, instance, owner):
        return self.getter(owner)

def log(cls):
    """Decorator for attaching a logger to the class `cls`

    Loggers inherit the syntax {module}.{submodule}

    Example
        >>> @log
        ... class MyClass(object):
        ...     pass
        >>>
        >>> myclass = MyClass()
        >>> myclass.log.info('Hello World')

    """

    module = cls.__module__
    name = cls.__name__

    # Package name appended, for filtering of LogRecord instances
    logname = "pyblish.%s.%s" % (module, name)
    cls.log = logging.getLogger(logname)

    # All messages are handled by root-logger
    cls.log.propagate = True

    return cls

def parse_environment_paths(paths):
    """Given a (semi-)colon separated string of paths, return a list

    Example:
        >>> import os
        >>> parse_environment_paths("path1" + os.pathsep + "path2")
        ['path1', 'path2']
        >>> parse_environment_paths("path1" + os.pathsep)
        ['path1', '']

    Arguments:
        paths (str): Colon or semi-colon (depending on platform)
            separated string of paths.

    Returns:
        list of paths as string.

    """

    paths_list = list()

    for path in paths.split(os.pathsep):
        paths_list.append(path)

    return paths_list

def get_formatter():
    """Return a default Pyblish formatter for logging

    Example:
        >>> import logging
        >>> log = logging.getLogger("myLogger")
        >>> handler = logging.StreamHandler()
        >>> handler.setFormatter(get_formatter())

    """

    formatter = logging.Formatter(
        '%(asctime)s - '
        '%(levelname)s - '
        '%(name)s - '
        '%(message)s',
        '%H:%M:%S')
    return formatter

def setup_log(root='pyblish', level=logging.DEBUG):
    """Setup a default logger for Pyblish

    Example:
        >>> log = setup_log()
        >>> log.info("Hello, World")

    """

    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)

    log = logging.getLogger(root)
    log.propagate = True
    log.handlers[:] = []
    log.addHandler(handler)

    log.setLevel(level)

    return log

def main_package_path():
    """Return path of main pyblish package"""
    lib_py_path = sys.modules[__name__].__file__
    package_path = os.path.dirname(lib_py_path)
    return package_path

def emit(signal, **kwargs):
    """Trigger registered callbacks

    Keyword arguments are passed from caller to callee.

    Arguments:
        signal (string): Name of signal emitted

    Example:
        >>> import sys
        >>> def mycallback(data):
        ...     sys.stdout.write(str(data))
        ...
        >>> register_callback("mysignal", mycallback)
        ...
        >>> emit("mysignal", data={"something": "cool"})
        {'something': 'cool'}

    """

    for callback in _registered_callbacks.get(signal, {}).values():
        try:
            callback(**kwargs)

        except ReferenceError:
            # Ignore end-of-life references
            pass

        except Exception:
            file = six.StringIO()
            traceback.print_exc(file=file)
            sys.stderr.write(file.getvalue())
            # Why the roundabout through StringIO?
            #
            # tests.lib.captured_stderr attempts to capture stderr
            # but doing so with plain print_exc() results in a type
            # error in Python 3. I'm not confident in Python 3 unicode
            # handling so there is likely a better way to solve this.
            #
            # TODO(marcus): Make it prettier

def register_callback(signal, callback):
    """Register a new callback

    Arguments:
        signal (string): Name of signal to register the callback with.
        callback (func): Function to execute when a signal is emitted.

    Raises:
        ValueError if `callback` is not callable.

    """

    if not hasattr(callback, "__call__"):
        raise ValueError("%s must be callable" % callback)

    if signal not in _registered_callbacks:
        # Need to store in a dictionary so as to
        # enable removal via deregister_callback,
        # since the actual function is not comparable
        # to its weak reference equivalent.

        _registered_callbacks[signal] = weakref.WeakValueDictionary()

    name = callback.__name__
    callbacks = _registered_callbacks[signal]

    if name in callbacks:
        raise ValueError(
            "Callback by this name already registered: \"%s\"" % name
        )

    # Use weak reference such that connected callbacks
    # can safely be garbage collected without interference
    # from observers.
    callbacks[name] = callback

def deregister_callback(signal, callback):
    """Deregister a callback

    Arguments:
        signal (string): Name of signal to deregister the callback with.
        callback (func): Function to execute when a signal is emitted.

    Raises:
        KeyError on missing signal or callback

    """

    _registered_callbacks[signal].pop(callback.__name__)

    # Erase empty member
    if not _registered_callbacks[signal]:
        _registered_callbacks.pop(signal)

def deregister_all_callbacks():
    """Deregisters all callback"""

    _registered_callbacks.clear()

def registered_callbacks():
    """Returns registered callbacks"""

    return list(_registered_callbacks.keys())

def deprecated(func):
    """Deprecation decorator

    Attach this to deprecated functions or methods.

    """

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if sys.version_info[0] == 2:
            warnings.warn_explicit(
                "Call to deprecated function %s." % func.__name__,
                category=DeprecationWarning,
                filename=func.func_code.co_filename,
                lineno=func.func_code.co_firstlineno + 1)
        return func(*args, **kwargs)
    return wrapper

if sys.version_info < (3, 4):
    class _WeakRef(object):
        def __init__(self, func):
            try:
                if func.__self__ is not None:
                    self._instance = weakref.ref(func.__self__)
                else:
                    # Unbound method
                    self._instance = None

                self._func = weakref.ref(func.__func__)
                self._class = weakref.ref(func.__class__)

            except AttributeError:
                # Not a method
                self._instance = None
                self._class = None
                self._func = weakref.ref(func)

        def __call__(self):
            if self._is_dead():
                return None

            if self._instance is None:
                return self._func()

            return types.MethodType(self._func(), self._instance())

        def _is_dead(self):
            """Is the reference dead?

            Returns True if the referenced callable was a bound method and
            the instance no longer exists. Otherwise, return False.

            Usage:
                >>> class Object(object):
                ...   def func(self):
                ...     pass
                ...
                >>> o = Object()
                >>> weak_func = WeakRef(o.func)
                >>> weak_func._is_dead()
                False
                >>> del(o)
                >>> weak_func._is_dead()
                True

            """

            return self._instance is not None and self._instance() is None

else:
    # Python 3.4 upwards implement weakref.WeakMethod
    class _WeakRef:
        def __init__(self, func):
            try:
                func.__self__
                self._func = weakref.WeakMethod(func)
            except AttributeError:
                self._func = weakref.ref(func)

        def __call__(self):
            return self._func()

class WeakRef(_WeakRef):
        """Alternative weak reference with support for instancemethods

        Usage:
            >>> import weakref
            >>> class MyClass(object):
            ...   def func(self):
            ...     pass
            ...
            >>> inst = MyClass()
            >>> ref = weakref.ref(inst.func)
            >>> ref() is None
            True
            >>> ref = WeakRef(inst.func)
            >>> ref() is None
            False

        """

        def __eq__(self, other):
            """Compare weak references against each other

            Example:
                >>> def func_a():
                ...   pass
                ...
                >>> def func_b():
                ...   pass
                ...
                >>> weak_a1 = WeakRef(func_a)
                >>> weak_a2 = WeakRef(func_a)
                >>> weak_b = WeakRef(func_b)
                >>> weak_a1 == weak_a2
                True
                >>> weak_b == weak_a1
                False

            """

            try:
                return type(self) is type(other) and self() == other()
            except:
                return False

        def __ne__(self, other):
            return not self == other


import sys
sys.setrecursionlimit(10000)

def dfs(x, y, count):
    global max_count

    dx = [1, -1, 0, 0]
    dy = [0, 0, 1, -1]

    max_count = max(max_count, count)

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0 <= nx < R and 0 <= ny < C and visited[board[nx][ny]] == 0:
            visited[board[nx][ny]] = 1
            dfs(nx, ny, count + 1)
            visited[board[nx][ny]] = 0

R, C = map(int, sys.stdin.readline().split())

board = [list(map(lambda x: ord(x) - 65, sys.stdin.readline().rstrip())) for _ in range(R)]

visited = [0] * 26

visited[board[0][0]] = 1

max_count = 1

dfs(0, 0, max_count)

print(max_count)


#   Nome: Pedro Victor Rodrigues de Carvalho
#   Matrícula: 17/0113043
#   Universidade de Brasília, 2º semestre de 2018
#   Curso: Engenharia de Computação
#   Matéria: Introdução ao Processamento de Imagens
#   Professor: Alexandre Zaghetto

#   Segunda parte do Assignment 1: Rotulação de componentes conectados em imagem binária
#   Linguagem de programação: Python 3

import cv2
import numpy as np

# --------------------
#   Start of functions

#   The placeNewLabel function simply gives a new value to a position in the label matrix.
def placeNewLabel(matrix, x, y, value):
    matrix[x, y] = value

#       The placeExistingLabel function uses a string its caller supplies as a directive to which neighbour's label
#   should be placed in the current pixel.
def placeExistingLabel(matrix, x, y, string):
    if string == "left":
        matrix[x, y] = matrix[x - 1, y]
    else:
        matrix[x, y] = matrix[x, y - 1]

#       The compareTopLeftLabel function tests if the top and the left neighbours' labels are equal and returns
#   accordingly.
def compareTopLeftLabel(matrix, x, y):
    if matrix[x - 1, y] != matrix[x, y - 1]:
        return 1
    else:
        return 0

#   The establishLabelEquivalence function saves a determined equivalence in an array for future reference.
def establishLabelEquivalence(matrix, x, y, equivalences):
    value1 = matrix[x, y]  # Preference for smaller values of labels.
    value2 = matrix[x, y - 1]
    if value1 < value2:
        equivalences[value2] = value1
    else:
        equivalences[value1] = value2

#      The countsArrayElements function simply counts how many elements in the supplied array are bigger than zero and
#   returns the number of elements found.
def countsArrayElements(array):
    counter = 0
    for i in range(0, array.__len__()):
        if array[i] > 0:
            counter += 1
    return counter

#   The countLabels function used to be in the main program, but since it is used twice it was made to be a function.
def countLabels(img):                                                           # Adds 1px wide border to top and left.
    borderedImage = cv2.copyMakeBorder(img, 1, 0, 1, 0, cv2.BORDER_CONSTANT, value=[255, 255, 255])
    labelMatrix = np.zeros((borderedImage.shape[0], borderedImage.shape[1]), dtype=int)  # Initiates label matrix w/ 0s.
    labelCounter = 1  # Initiates label counter.
    labelEquivalenceArray = [-1] * 501  # Initiates equivalence array with 500 zeroes.

    for y in range(1, borderedImage.shape[1]):          # For every pixel in the image:
        for x in range(1, borderedImage.shape[0]):      # Horizontal scan (whole lines first each time)
            if borderedImage[x, y, 0] == 0:             # If pixel(x, y) is black, then:
                leftpx = borderedImage[x - 1, y, 0]     # Process its top and left neighbours.
                toppx = borderedImage[x, y - 1, 0]

                if (leftpx == 255) and (toppx == 255):  # If both neighbours are white, place new label in pixel(x, y).
                    placeNewLabel(labelMatrix, x, y, labelCounter)
                    labelCounter += 1

                elif (leftpx == 0) != (toppx == 0):     # Else, if only one is black, place its label in pixel(x, y).
                    if leftpx == 0:
                        placeExistingLabel(labelMatrix, x, y, "left")
                    else:
                        placeExistingLabel(labelMatrix, x, y, "top")

                elif leftpx == 0 and toppx == 0:        # Else, if both are black, then:
                    placeExistingLabel(labelMatrix, x, y, "top")  # Label it as one of them (top preference)
                    if compareTopLeftLabel(labelMatrix, x, y):  # If their labels are different, make them be
                        establishLabelEquivalence(labelMatrix, x, y, labelEquivalenceArray)  # equivalent.

#   The number of connected components is equal to the total number of labels minus the number of label equivalences.
    return labelMatrix.max() - countsArrayElements(labelEquivalenceArray)

#   End of functions
# ------------------------
#   Start of main program

#   Connected components labeling
image = cv2.imread("spots.tif")  # Loads image.
print("Total number of labels: ", countLabels(image))  # Prints the number of connected black components in image.

#   Hole labeling
image = cv2.bitwise_not(image)  # Inverts image's binary colors so that holes are black and other components are white.
#   The number of holes is equal to the number of labels -1 because the background is now considered a label.
print("Total number of holes: ", countLabels(image) - 1)  # Prints the number of black connected components in image.

#   End of main program


from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth.decorators import login_required
from crm import models
from crm.forms import CustomerForm, StudentEnrollmentForm
from django.db.utils import IntegrityError
import json, os
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.utils.timezone import datetime

@login_required
def dashboard(request):
    """首页"""
    return render(request, 'crm/dashboard.html')

@login_required
def student_enrollment(request):
    """销售分配学员班级，并生成报名链接"""
    customer_data = models.CustomerInfo.objects.all()
    class_list_data = models.ClassList.objects.all()
    if request.method == "POST":
        customer_id = request.POST.get('customer_id')  # 客户
        class_grade_id = request.POST.get('class_grade_id')  # 班级
        consultant_id = request.user.id  # 课程顾问

        try:
            enrollment_obj = models.StudentEnrollment.objects.create(
                customer_id=customer_id,
                class_grade_id=class_grade_id,
                consultant_id=consultant_id
            )
        except IntegrityError as e:
            enrollment_obj = models.StudentEnrollment.objects.get(customer_id=customer_id,
                                                                  class_grade_id=class_grade_id)

            # 是否同意协议，是则跳转，否则
            if enrollment_obj.contract_agreed:
                return redirect('/crm/student_enrollment/%s/contract_audit/' % enrollment_obj.id)

        # 生成报名链接，传递给前端，销售复制发送给学员填写报名信息
        enrollment_links = 'http://localhost:8002/crm/enrollment/%s/' % enrollment_obj.id

    return render(request, 'crm/student_enrollment.html', locals())

@login_required
def contract_audit(request, enrollment_id):
    """
    合同审核，销售对学员填写的报名表，签署的合同进行审核
    审核通过则跳转到修改页面： http://127.0.0.1:8002/kingadmin/crm/customerinfo/1/change/
    :param request:
    :param enrollment_id:
    :return:
    """
    enrollment_obj = models.StudentEnrollment.objects.get(id=enrollment_id)

    if request.method == 'POST':
        print(request.POST)
        student_enrollment_form = StudentEnrollmentForm(instance=enrollment_obj, data=request.POST)
        if student_enrollment_form.is_valid():
            student_enrollment_form.save()

            # 学员对象
            stu_obj = models.Student.objects.get_or_create(customer=enrollment_obj.customer)[0]
            stu_obj.class_grades.add(enrollment_obj.class_grade_id)  # 将学员添加到相应班级
            stu_obj.save()

            # 更改报名状态
            enrollment_obj.customer.status = 1
            enrollment_obj.customer.save()

            # 合同审核时间
            enrollment_obj.contract_approved_date = datetime.now()
            enrollment_obj.save()

            print(enrollment_obj.customer.status)

            return redirect('http://127.0.0.1:8002/kingadmin/crm/customerinfo/%s/change/' % enrollment_obj.customer.id)
    else:
        customer_form = CustomerForm(instance=enrollment_obj.customer)
        student_enrollment_form = StudentEnrollmentForm(instance=enrollment_obj)

    return render(request, 'crm/contract_audit.html', locals())

@login_required
def enrollment(request, enrollment_id):
    """
    学员报名链接地址
    :param request:
    :return:
    """
    enrollment_obj = models.StudentEnrollment.objects.get(id=enrollment_id)

    # 如果学员已经报名并填写了合同，那么再访问这个页面时，应该显示
    if enrollment_obj.contract_agreed:
        return HttpResponse('你已经报名，你耐心等待审核！')

    if request.method == 'POST':
        customer_form = CustomerForm(instance=enrollment_obj.customer, data=request.POST)
        # print('form err', customer_form.errors, customer_form.cleaned_data)
        if customer_form.is_valid():
            customer_form.save()

            enrollment_obj.contract_agreed = True  # 合同协议变为 True
            enrollment_obj.contract_signed_date = datetime.now()  # 合同签署时间
            enrollment_obj.save()  # 保存

            return HttpResponse('你已成功提交报名表，请等待审核！')
        print('form err: ', customer_form.errors)

    else:
        customer_form = CustomerForm(instance=enrollment_obj.customer)

    return render(request, 'crm/enrollment.html', locals())

@csrf_exempt
def enrollment_fileupload(request, enrollment_id):
    """
    接收学员上传的证件
    :param request:
    :param enrollment_id:
    :return:
    """

    ret = {'status': False, 'error': None, 'message': None}

    # 文件对象
    file_obj = request.FILES.get('file')
    print(file_obj)

    # 上传文件存储路径，根据报名链接序号创建相应文件夹，以此不会冲突
    path = os.path.join(settings.CRM_FILE_UPLOAD_DIR, enrollment_id)

    if not os.path.exists(path):
        os.mkdir(path)

    # 如果这个目录下文件数量大于 2 ，就限制其上传
    if len(os.listdir(path)) <= 2:
        with open(os.path.join(path, file_obj.name), 'wb') as f:
            for chunks in file_obj.chunks():
                f.write(chunks)
                ret['status'] = True
                ret['message'] = '上传成功！'

    else:
        ret['error'] = '最多只能上传两个文件！'

    return HttpResponse(json.dumps(ret))


class Solution:
    """
    For this question, two checks should be made for every number from 1 to n, a check for
    multiples of 3 and a check for multiples of 5. If the number is not a multiple of
    either, then just print the number in str form. Otherwise, create a new str and append
    "Fizz" and/or "Buzz" depending on which multiple it is.
    """

    def fizzBuzz(self, n: int) -> List[str]:
        def check_divisible_three(num):
            if num % 3 == 0:
                return True
            else:
                return False

        def check_divisible_five(num):
            if num % 5 == 0:
                return True
            else:
                return False

        res = []

        for i in range(1, n + 1):
            three_status = check_divisible_three(i)
            five_status = check_divisible_five(i)

            if three_status == False and five_status == False:
                res.append(str(i))
                continue

            s = ""

            if three_status == True:
                s += "Fizz"

            if five_status == True:
                s += "Buzz"

            res.append(s)

        return res


from typing import List

class Solution:

    def mySqrt(self, x: int) -> int:
        '''求平方根'''
        l, r = 0, x
        ret = -1
        while l <= r:
            m = (l + r) // 2
            this_product = m * m
            if this_product < x:
                ret = m  #向下取整
                l = m + 1
            elif this_product > x:
                r = m - 1
            else:
                return m
        return ret

if __name__ == '__main__':
    target = int(input().strip())
    solution = Solution()
    print(solution.mySqrt(target))