import streamlit as st
import openai
import os
from streamlit_extras.stoggle import stoggle

openai_api_key = st.secrets["openai_key"]

# Set the OpenAI API key
openai.api_key = openai_api_key

def generate_response(prompt, user_input):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": user_input},
        ],
    )

    return response.choices[0].message['content']

def app():
    st.title("The spoookiest time of the year!")
    st.subheader("ðŸ‘»ðŸŽƒðŸ’€")

    st.markdown("## History of Halloween")
    # Add a checkbox to show or hide the history section
    stoggle(
        "Show the History of Halloween!",
        """'<iframe src="https://blogs.loc.gov/headlinesandheroes/2021/10/the-origins-of-halloween-traditions/" width="100%" height="450"></iframe>', unsafe_allow_html=True)"""

    )
    st.markdown("---")  # Add horizontal line for separation
    st.markdown("## Halloween Recipe and Decoration Generator")
    # Dropdown menu for user to select recipe or decoration
    option = st.selectbox('What would you like help with?', ['Halloween Recipe', 'DIY Halloween Decoration'])
    user_prompt = st.text_input('Enter more specifics (optional)')

    if st.button('Get Ideas'):
        if option == 'Halloween Recipe':
            system_prompt = "You are an expert chef who specializes in creating fun and spooky Halloween recipes."
            with st.spinner("Cooking up the recipe..."):
                response = generate_response(system_prompt, user_prompt)
                st.write(response)
        else:
            system_prompt = "You are a skilled craftsman with a knack for DIY Halloween decorations."
            with st.spinner("Searching the craft box..."):
                response = generate_response(system_prompt, user_prompt)
                st.write(response)

app()


import sys
from math import *
from PyQt5 import QtCore, QtGui, QtWidgets

# Importa interfaces de usuário

import TelaInicial
import CalculadoraSimples
import CalculadoraCientifica

# Cria a classe do controlador

class controller:
    def __init__(self):
        self.TelaInicial_Window = QtWidgets.QMainWindow()
        self.TelaInicial_ui = TelaInicial.Ui_Dialog()
        self.TelaInicial_ui.setupUi(self.TelaInicial_Window)

        self.tradicional_Window = QtWidgets.QMainWindow()
        self.tradicional_ui = CalculadoraSimples.Ui_Dialog()
        self.tradicional_ui.setupUi(self.tradicional_Window)

        self.cientifica_Window = QtWidgets.QMainWindow()
        self.cientifica_ui = CalculadoraCientifica.Ui_Dialog()
        self.cientifica_ui.setupUi(self.cientifica_Window)

        self.TelaInicial_ui.pushButton.clicked.connect(self.show_calc)

        # Define os botões da Calculadora Simples

        self.tradicional_ui.pushButton_18.clicked.connect(self.numero)    # 0
        self.tradicional_ui.pushButton_15.clicked.connect(self.numero)    # 1
        self.tradicional_ui.pushButton_14.clicked.connect(self.numero)    # 2
        self.tradicional_ui.pushButton_16.clicked.connect(self.numero)    # 3
        self.tradicional_ui.pushButton_9.clicked.connect(self.numero)     # 4
        self.tradicional_ui.pushButton_11.clicked.connect(self.numero)    # 5
        self.tradicional_ui.pushButton_12.clicked.connect(self.numero)    # 6
        self.tradicional_ui.pushButton_5.clicked.connect(self.numero)     # 7
        self.tradicional_ui.pushButton_7.clicked.connect(self.numero)     # 8
        self.tradicional_ui.pushButton_8.clicked.connect(self.numero)     # 9
        self.tradicional_ui.pushButton_13.clicked.connect(self.operador)  # +
        self.tradicional_ui.pushButton_10.clicked.connect(self.operador)  # -
        self.tradicional_ui.pushButton_6.clicked.connect(self.operador)   # x
        self.tradicional_ui.pushButton_4.clicked.connect(self.operador)   # ÷
        self.tradicional_ui.pushButton_3.clicked.connect(self.operador)   # √
        self.tradicional_ui.pushButton_19.clicked.connect(self.virgula)   # ,
        self.tradicional_ui.pushButton_17.clicked.connect(self.igual)     # =
        self.tradicional_ui.pushButton.clicked.connect(self.ac)           # AC
        self.tradicional_ui.pushButton_2.clicked.connect(self.delete)     # DEL

        # Define os botões da Calculadora Científica

        self.cientifica_ui.pushButton_43.clicked.connect(self.numero)     # π
        self.cientifica_ui.pushButton_23.clicked.connect(self.numero)     # 0
        self.cientifica_ui.pushButton_27.clicked.connect(self.numero)     # 1
        self.cientifica_ui.pushButton_24.clicked.connect(self.numero)     # 2
        self.cientifica_ui.pushButton_25.clicked.connect(self.numero)     # 3
        self.cientifica_ui.pushButton_26.clicked.connect(self.numero)     # 4
        self.cientifica_ui.pushButton_32.clicked.connect(self.numero)     # 5
        self.cientifica_ui.pushButton_22.clicked.connect(self.numero)     # 6
        self.cientifica_ui.pushButton_21.clicked.connect(self.numero)     # 7
        self.cientifica_ui.pushButton_33.clicked.connect(self.numero)     # 8
        self.cientifica_ui.pushButton_29.clicked.connect(self.numero)     # 9
        self.cientifica_ui.pushButton_34.clicked.connect(self.operador)   # +
        self.cientifica_ui.pushButton_30.clicked.connect(self.operador)   # -
        self.cientifica_ui.pushButton_38.clicked.connect(self.operador)   # x
        self.cientifica_ui.pushButton_37.clicked.connect(self.operador)   # ÷
        self.cientifica_ui.pushButton_35.clicked.connect(self.operador)   # √
        self.cientifica_ui.pushButton_40.clicked.connect(self.operador)   # x^
        self.cientifica_ui.pushButton_42.clicked.connect(self.angulo)     # Seno
        self.cientifica_ui.pushButton_41.clicked.connect(self.angulo)     # Cosseno
        self.cientifica_ui.pushButton_39.clicked.connect(self.angulo)     # Tangente
        self.cientifica_ui.pushButton_20.clicked.connect(self.virgula)    # ,
        self.cientifica_ui.pushButton_28.clicked.connect(self.igual)      # =
        self.cientifica_ui.pushButton_36.clicked.connect(self.ac)         # AC
        self.cientifica_ui.pushButton_31.clicked.connect(self.delete)     # DEL

    # Métodos
    def porcentagem(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()

        # texto=str(float(texto)/100)
        if(texto == " " or texto.endswith(("+", "-", "*", "√", "÷", "(", " ", "%","a"))):
            envia = texto
        elif(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","π",")"))):
            envia = texto+"%"
        elif(texto.endswith(",")):
            envia = texto+"0%"
        else:
            envia = texto

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def operador(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
            sender = self.tradicional_Window.sender().text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()
            sender = self.cientifica_Window.sender().text()

        if(sender=="√"):
            if(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","π",")","%"))):
                envia = texto + "*√("
            elif(texto.endswith(("+", "-", "*", "÷", " ","("))):
                envia = texto + "√("
            elif(texto.endswith(",")):
                envia = texto + "0*√("
            elif(texto.endswith("a")):
                envia = texto
        elif(sender=="x^"):
            if(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","π",")","%"))):
                envia = texto + "^("
            elif(texto.endswith(("+", "-", "*", "÷", " ","("))):
                envia = texto
            elif(texto.endswith(",")):
                envia = texto + "0^("
            elif(texto.endswith("a")):
                envia = texto
        elif(texto.endswith(("+", "-", "*", "÷"))):
            if(texto[len(texto)-2]=="(" and sender in ["+","-"]):
                envia = texto[0:len(texto)-1]+sender
            elif(texto[:len(texto)-1].endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",")","π")) or texto[len(texto)-2]=="%"):
                envia = texto[0:len(texto)-1]+sender
            else:
                envia = texto
        elif(texto.endswith(",")):
            envia = texto + "0" + sender
        elif(texto.endswith("(")):
            if(sender in ["+", "-"]):
                envia = texto + sender
            else:
                envia = texto
        elif(texto == " " or texto.endswith("a")):
            envia = texto
        else:
            envia = texto + sender

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def virgula(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()
        if(texto == " " or texto.endswith(("+", "-", "*", "√", "÷", "("))):
            envia = texto+"0,"
        elif(texto.endswith("%")):
            envia = texto+"*0,"
        elif(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","π"))):
            index = max(texto.rfind("+"), texto.rfind("-"), texto.rfind("*"), texto.rfind("÷"), texto.rfind("√"), texto.rfind("^"))+1
            if(texto[index:].find(",")==-1):
                envia=texto+","
            else:
                envia=texto
        elif(texto.endswith(",")):
            envia = texto
        elif(texto.endswith("a")):
            envia = texto
        else:
            envia = texto

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def abre(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()

        if(texto.endswith(("+", "-", "*", "÷", "√", "(", " "))):
            envia = texto+"("
        elif(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ")","π"))):
            envia = texto+"*("
        elif(texto.endswith(",")):
            envia = texto+"0*("
        elif(texto.endswith("a")):
            envia = texto
        else:
            envia = texto

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def fecha(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()

        contab = texto.count("(")
        contfe = texto.count(")")
        if(contab-contfe == 0 or texto.endswith(("+", "-", "*", "÷", "(", " "))):
            envia = texto
        elif(texto.endswith(",")):
            envia = texto + "0)"
        elif(contab-contfe >= 1):
            envia = texto+")"
        elif(texto.endswith("a")):
            envia = texto
        else:
            envia = texto

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def angulo(self):
        texto = self.cientifica_ui.label.text()
        sender = self.cientifica_Window.sender().text()

        if(texto.endswith(("+", "-", "*", "÷", "(", " ", "a"))):
            envia = texto+sender+"("
        elif(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ")","π"))):
            envia = texto+"*"+sender+"("
        else:
            envia = texto+sender+"("

        self.cientifica_ui.label.setText(envia)

    def arco(self):
        texto = self.cientifica_ui.label.text()
        if(texto.endswith(("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ")","π"))):
            envia=texto+"*a"
        elif(texto.endswith(("+", "-", "*", "÷", "(", " "))):
            envia=texto+"a"
        elif(texto.endswith("a")):
            envia=texto
        self.cientifica_ui.label.setText(envia)

    def numero(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
            sender = self.tradicional_Window.sender().text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()
            sender = self.cientifica_Window.sender().text()

        if(texto.endswith(")")):
            envia = texto + "*" + sender
        elif(texto.endswith("a")):
            envia=texto
        else:
            envia = texto+sender

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def igual(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()

        contab = texto.count("(")
        contfe = texto.count(")")
        if(contab-contfe >= 1):
            texto = texto+")"*(contab-contfe)

        texto = texto.replace(",",".").replace("e","i").replace("√","sqrt").replace("^","**").replace("÷","/").replace("π","pi")
        try:
            aux = eval(texto)
            envia = str(float(f'{aux:.3f}')).replace(".",",")
        except (NameError, ValueError, SyntaxError):
            envia = texto.replace(".",",").replace("pi","π").replace("i","e").replace("sqrt","√").replace("**","^").replace("/","÷")
            QtWidgets.QMessageBox.about(self.cientifica_Window, "Math domain error", "Raízes negativas não são permitidas\nArcos (seno e cosseno) são calculados para valores entre -1 e +1")

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def delete(self):
        # Calculadora tradicional
        self.tradicional_ui.label.setText(" ")

        # Calculadora científica
        self.cientifica_ui.label.setText(" ")

    def ac(self):
        if(self.tradicional_Window.isActiveWindow()):
            texto = self.tradicional_ui.label.text()
        elif(self.cientifica_Window.isActiveWindow()):
            texto = self.cientifica_ui.label.text()

        envia = texto[0:len(texto)-1]
        if(texto == " "):
            envia = " "
        elif(texto.endswith("(") and texto[:len(texto)-1].endswith(("√", "^"))):
            envia = texto[0:len(texto)-2]
        elif(texto.endswith("(") and texto[:len(texto)-1].endswith(("n", "s"))):
            envia = texto[0:len(texto)-4]

        # Calculadora tradicional
        self.tradicional_ui.label.setText(envia)

        # Calculadora científica
        self.cientifica_ui.label.setText(envia)

    def show_TelaInicial(self):
        self.TelaInicial_Window.show()

    def show_calc(self):
        self.tradicional_ui.label.setText(" ")
        self.cientifica_ui.label.setText(" ")
        if self.TelaInicial_ui.radioButton.isChecked():
            self.tradicional_Window.show()
            self.TelaInicial_Window.close()

        if self.TelaInicial_ui.radioButton_2.isChecked():
            self.cientifica_Window.show()
            self.TelaInicial_Window.close()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    controller = controller()
    controller.show_TelaInicial()
    sys.exit(app.exec_())


from typing import List

class Solution:
    def countNegatives(self, grid: List[List[int]]) -> int:

        def bin_search(list):
            l = 0
            h = len(list) - 1
            boundary = -1
            while l <= h:
                m = ( l + h ) // 2
                if list[m] < 0:
                    boundary = m
                    h = m - 1
                else:
                    l = m + 1
            return boundary
        count = 0
        for lis in grid:
            # Returns -1 when there are no negative numbers in the list
            negInd = bin_search(lis)
            count += len(lis) - negInd if negInd >= 0 else 0
        return count

CP problems/Big-O/Binary search/Leet code/1351. Count Negative Numbers in a Sorted Matrix.py


#! /usr/bin/env python3
#
# Extract rows from database where qCSV is true
# and save into a CSV file.
#
# Ripped out of UW_SG.py
#
# July-2023, Pat Welch, pat@mousebrains.com

from argparse import ArgumentParser
from TPWUtils import Logger
import logging
import psycopg
import os

def openFile(fn:str, qForce:bool):
    if not qForce and os.path.isfile(fn):
        logging.info("Opening %s", fn)
        return open(fn, "a")

    dirname = os.path.dirname(fn)
    if not os.path.isdir(dirname):
        logging.info("Creating %s", dirname)
        os.makedirs(dirname, mode=0o755, exist_ok=True)

    logging.info("Creating %s", fn)
    fp = open(fn, "w")
    fp.write("id,t,lat,lon\n")
    return fp

parser = ArgumentParser()
Logger.addArgs(parser)
parser.add_argument("--grp", type=str, default="AUV", help="Group name")
parser.add_argument("--csv", type=str, default="~/Sync.ARCTERX/Shore/Gliders/UW.csv",
                    help="Where to CSV filename")
parser.add_argument("--db", type=str, default="arcterx", help="Which Postgresql DB to use")
parser.add_argument("--force", action="store_true", help="Rebuild the CSV file from scratch")
args = parser.parse_args()

Logger.mkLogger(args, fmt="%(asctime)s %(levelname)s: %(message)s")

args.csv = os.path.abspath(os.path.expanduser(args.csv))

sql0 = "CREATE TEMPORARY TABLE TPW (LIKE glider);"

sql1 = "WITH updated AS ("
sql1+= "UPDATE glider SET qCSV=TRUE"
sql1+= " WHERE grp=%s"
if not args.force: sql1+= " AND NOT qCSV"
sql1+= " RETURNING grp,id,t,lat,lon"
sql1+= ")"
sql1+= "INSERT INTO TPW SELECT * FROM updated;"

sql2 = "SELECT id,t,lat,lon FROM TPW ORDER BY t;"

fp = None

with psycopg.connect(f"dbname={args.db}") as db: # Get the last time stored in the database
    try:
        cur = db.cursor()
        cur.execute(sql0)
        cur.execute("BEGIN TRANSACTION;")
        cur.execute(sql1, (args.grp,))

        cnt = 0
        for row in cur.execute(sql2):
            if fp is None: fp = openFile(args.csv, args.force)
            fp.write(",".join(map(str, row)) + "\n")
            cnt += 1

        if fp: fp.close()
        db.commit()
        logging.info("Fetched %s CSV records into %s", cnt, args.csv)
    except:
        db.rollback()
        logging.exception("Unexpected error %s", args)


# Library
import uvicorn
from fastapi import FastAPI
from features import feature
import numpy as np
import pandas as pd
import pickle

# Create the app object
app = FastAPI()

# Model load
pickleIn = open('model.pkl','rb')
classifier = pickle.load(pickleIn)

# Create a index page
@app.get('/')
def index():
    return {'message':'Hello World!'}

# HTTP POST request is made to the "/predict" endpoint.
@app.post('/predict')

# This function handles the POST request to the "/predict" endpoint. It accepts data of type "feature" and assigns it to a variable named "data."
def predictDiabetes(data:feature):

    # Converts the incoming data into a Python dictionary. This makes it easier to work with the data later.
    data = data.dict()

    # Assign the data from the dictionary to relevant variables.
    Pregnancies=data['Pregnancies']
    Glucose=data['Glucose']
    BMI=data['BMI']
    DiabetesPedigreeFunction=data['DiabetesPedigreeFunction']

    # Stores the prediction result in a variable.
    prediction = classifier.predict([[Pregnancies,Glucose,BMI,DiabetesPedigreeFunction]])

    # If the prediction is 1, it is diabetes and if the prediction is 0, it is not diabetes.
    if(prediction[0]==1):
        prediction="Diabetes"
    else:
        prediction="Not-Diabetes"
    return {
        'prediction': prediction
    }

# Will run on http://127.0.0.1:8000
if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)


#Django
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.core.validators import RegexValidator

#abstract cride.util
from cride.utils.models import CRideModel

class User(CRideModel,AbstractUser):
    email=models.EmailField(
        "Email adress",
        unique=True,
        error_messages={
            "unique":"A user with  that email already exist."
        }
    )

    phone_regex=RegexValidator(regex=r'\+?1?\d{9,15}$',
    message="Phone number must be enteredin the  format +999999999. Up  to 15  digits allowed.")
    phone_number=models.CharField(validators=[phone_regex],max_length=17,blank=True)

    USERNAME_FIELD="email"

    REQUIRED_FIELDS=["username","first_name","last_name"]

    is_client=models.BooleanField(
        "Client status",
        default=True,
        help_text="help easily distinguish user"
    )

    is_verfied=models.BooleanField(
        "Verified",
        default=False,
        help_text="Set to true  when the user have verified its email adress"
    )

    def __str__(self):
        return self.username

    def get_short_name(self):
        return self.username


"""Shared functions for migrations"""
import flatdict
from yaml import dump

from lib.dekickrc import (
    dekickrc_tmpl_parse_value,
    get_dekickrc_flat,
    get_dekickrc_tmpl_flat,
)
from lib.fs import chown
from lib.settings import DEKICKRC_PATH

def dekickrc_save_flat(dekickrc_flat: flatdict.FlatDict):
    """Saves flat dict to .dekickrc.yml file"""
    with open(DEKICKRC_PATH, "w", encoding="utf-8") as yaml_file:
        dump(dekickrc_flat.as_dict(), yaml_file)
        chown(DEKICKRC_PATH)

def dekickrc_add_default_values():
    """Adds missing fields to the .dekickrk.yml file based on .dekickrc.tmpl.yml"""

    dekickrc_flat = get_dekickrc_flat()
    tmpl_flat = get_dekickrc_tmpl_flat()

    for path, value in tmpl_flat.items():
        if path not in dekickrc_flat:
            var = dekickrc_tmpl_parse_value(str(value))

            if var["default"] != "" and var["required"]:
                dekickrc_flat[path] = var["default"]

    dekickrc_save_flat(dekickrc_flat)

def dekickrc_remove_unused_values():
    """Removes unused fields from the .dekickrk.yml file"""

    dekickrc_flat = get_dekickrc_flat()
    tmpl_flat = get_dekickrc_tmpl_flat()

    for key in dekickrc_flat.keys():  # pylint: disable=consider-using-dict-items
        if key not in tmpl_flat:
            del dekickrc_flat[key]

    dekickrc_save_flat(dekickrc_flat)


import pandas as pd
import pkgutil
from io import BytesIO

def load_bank(classifier=True):
    bank = pd.read_csv(
        BytesIO(
            pkgutil.get_data('loadbank', 'bank/bank.csv')
        ),
        sep=';',
    )
    bank_category = (
        bank.select_dtypes(
            include=object
        ).apply(
            lambda x: x.astype('category'),
            axis=0
        )
    )
    bank_numeric = bank.select_dtypes(
        include=int
    )
    if classifier:
        y = bank_category.y
        X = pd.concat(
            [bank_category, bank_numeric],
            axis=1
        ).drop(
            ['y'], axis=1
        )
    else:
        y = bank_numeric.balance
        X = pd.concat(
            [bank_category, bank_numeric],
            axis=1
        ).drop(
            ['balance'], axis=1
        )
    return X, y

def load_bank_classifier():
    return load_bank(classifier=True)

def load_bank_regressor():
    return load_bank(classifier=False)


import re
from collections import Counter
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from io import StringIO
import spacy
import fitz
from spacy.matcher import Matcher

def extract_text_from_pdf(pdf_path):
    text = ""
    try:
        pdf_document = fitz.open(pdf_path)
        num_pages = pdf_document.page_count

        for page_num in range(num_pages):
            page = pdf_document.load_page(page_num)
            text += page.get_text()
    except Exception as e:
        print("Error extracting text from PDF:", e)

    return text

def extract_contact_number_from_resume(text):
    contact_number = None

    # Use regex pattern to find potential contact numbers
    patterns = [
        r"\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b",  # XXX-XXX-XXXX or (XXX) XXX-XXXX
        r"\b\d{10}\b",  # 10-digit numbers
        r"\b\d{3}[-.\s]?\d{4}[-.\s]?\d{3}\b",  # XXX-XXXX-XXX or XXX.XXXX.XXX
    ]

    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            contact_number = match.group()
            break

    return contact_number

def extract_email_from_resume(text):
    email = None

    # Use regex pattern to find a potential email address
    pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b"
    match = re.search(pattern, text)
    if match:
        email = match.group()

    return email

def extract_skills_from_resume(text, skills_list):
    skills = []

    for skill in skills_list:
        pattern = r"\b{}\b".format(re.escape(skill))
        match = re.search(pattern, text, re.IGNORECASE)
        if match:
            skills.append(skill)

    return skills
def get_skill_frequency(text, skills_list):
    skill_counts = Counter()

    for skill in skills_list:
        pattern = r"\b{}\b".format(re.escape(skill))
        matches = re.findall(pattern, text, re.IGNORECASE)
        skill_counts[skill] = len(matches)

    return skill_counts

def extract_education_from_resume(text):
    education = []

    # Use regex pattern to find education information
    pattern = r"(?i)(?:Bsc|\bB\.\w+|\bM\.\w+|\bPh\.D\.\w+|\bBachelor(?:'s)?|\bMaster(?:'s)?|\bPh\.D)\s(?:\w+\s)*\w+"
    matches = re.findall(pattern, text)
    for match in matches:
        education.append(match.strip())

    return education

def extract_name(resume_text):
    nlp = spacy.load('en_core_web_sm')
    matcher = Matcher(nlp.vocab)

    # Define name patterns
    patterns = [
        [{'POS': 'PROPN'}, {'POS': 'PROPN'}],  # First name and Last name
        [{'POS': 'PROPN'}, {'POS': 'PROPN'}, {'POS': 'PROPN'}],  # First name, Middle name, and Last name
        [{'POS': 'PROPN'}, {'POS': 'PROPN'}, {'POS': 'PROPN'}, {'POS': 'PROPN'}]  # First name, Middle name, Middle name, and Last name
        # Add more patterns as needed
    ]

    for pattern in patterns:
        matcher.add('NAME', patterns=[pattern])

    doc = nlp(resume_text)
    matches = matcher(doc)

    for match_id, start, end in matches:
        span = doc[start:end]
        return span.text

    return None


from django.db import models
from django.db import IntegrityError
from vereador.models import Vereador
from bs4 import BeautifulSoup
from urllib.request import urlopen
from django.db.models import Q
import re
from datetime import datetime

class ProjetoLei(models.Model):
    projeto = models.IntegerField(unique=True)
    protocolo = models.IntegerField(null=True, blank=True)
    assunto = models.TextField()
    observacao = models.TextField(null=True, blank=True)
    vereador = models.ForeignKey(
        Vereador,
        on_delete=models.PROTECT,
        related_name='projetos'
    )
    data_divulgacao = models.DateField(null=True, blank=True)
    data_aprovacao = models.DateField(null=True, blank=True)
    data_arquivamento = models.DateField(null=True, blank=True)

    def __str__(self):
        return self.assunto

    class Meta:
        verbose_name = "projeto de lei"
        verbose_name_plural = "projetos de lei"

    def buscar_dados(self):
        vereadores = Vereador.objects.all()
        for vereador in vereadores:
            link_projeto = vereador.links.all().filter(tipo=1).values()
            if link_projeto:
                link = link_projeto[0]['link']
                dados = self.buscar_html(link)
                for dado in dados:
                    try:
                        projeto_lei = ProjetoLei(
                            projeto=dado['projeto'],
                            protocolo=dado['protocolo'],
                            assunto=dado['assunto'],
                            observacao=dado['situacao'],
                            vereador=vereador
                        )
                        projeto_lei.save()
                    except IntegrityError:
                        projeto_lei = ProjetoLei.objects.get(
                            projeto=dado['projeto'])
                        projeto_lei.observacao = dado['situacao']
                        projeto_lei.save()
                        error = "Projeto ja existente - %s" % dado['projeto']
                        print(error)

    def buscar_dados_em_tramite(self):
        link = 'http://www.camaracolombo.pr.gov.br/projetos_legislativo1.asp'
        dados = self.buscar_html_em_tramite(link)
        for dado in dados:

            if (dado['vereador'] == 'Anderson da Silva'):
                dado['vereador'] = 'Anderson Ferreira da Silva'

            if (dado['vereador'] == 'Dolíria Strapasson'):
                dado['vereador'] = 'Dolíria Londregue Strapasson'

            if (dado['vereador'] == 'Marcos Antonio da Silva'):
                dado['vereador'] = 'Marcos Antônio da Silva'

            vereador = Vereador.objects.buscar_nome(dado['vereador'])
            if (vereador is None):
                continue

            try:
                projeto_lei = ProjetoLei(
                    projeto=dado['projeto'],
                    protocolo=dado['protocolo'],
                    assunto=dado['assunto'],
                    observacao=dado['situacao'],
                    vereador=vereador
                )
                projeto_lei.save()
            except IntegrityError:
                projeto_lei = ProjetoLei.objects.get(projeto=dado['projeto'])
                projeto_lei.observacao = dado['situacao']
                projeto_lei.save()
                error = "Projeto ja existente - %s" % dado['projeto']
                print(error)

    def buscar_html_em_tramite(self, link):
        html = urlopen(link)
        res = BeautifulSoup(html.read(), "html5lib")

        tables = res.find_all(
            "table",
            {
                "id": "table48"
            }
        )

        dados = []
        for table in tables:
            tds = table.find_all(
                "td"
            )

            protocolo = None

            projeto = tds[0].get_text().strip()
            projeto = projeto.split('/')
            projeto = projeto[0]

            vereador = tds[2].get_text().strip()

            assunto = tds[3].get_text().strip()
            situacao = str(tds[4])

            dados.append({
                'protocolo': protocolo,
                'projeto': projeto,
                'assunto': assunto,
                'situacao': situacao,
                'vereador': vereador
            })
        return dados

    def buscar_html(self, link):
        html = urlopen(link)
        res = BeautifulSoup(html.read(), "html5lib")

        tables = res.find_all(
            "table",
            {
                "id": "table48"
            }
        )

        dados = []
        for table in tables:
            tds = table.find_all(
                "td"
            )
            protocolo = tds[0].get_text().strip()

            projeto = tds[1].get_text().strip()
            projeto = projeto.split('/')
            projeto = projeto[0]

            assunto = tds[3].get_text().strip()
            situacao = str(tds[4])

            dados.append({
                'protocolo': protocolo,
                'projeto': projeto,
                'assunto': assunto,
                'situacao': situacao
            })
        return dados

    def remove_tupla(self, tuples):
        tuples = [t for t in tuples if t]
        return tuples

    def ajusta_data(self, data):
        if data is not None:
            data = str(data).replace('/', '-')
            padrao_data = '%d-%m-%Y'

            pattern = r"^[0-9]{2}-[0-9]{2}-[0-9]{2}$"
            result = re.match(pattern, data)
            if result is not None:
                padrao_data = '%d-%m-%y'
            data = datetime.strptime(data, padrao_data)
            return data
        return None

    def extrair_informacao(self):
        projetos = ProjetoLei.objects.all().order_by('-projeto').exclude(
            Q(data_aprovacao__isnull=False) | Q(
                data_arquivamento__isnull=False)
        ).values()

        for projeto in projetos:
            observacao = projeto['observacao']
            aprovado = self.ajusta_data(
                self.indentifica_aprovacao(observacao))
            divulgado = self.ajusta_data(
                self.indentifica_divulgacao(observacao))
            arquivado = self.ajusta_data(
                self.indentifica_arquivamento(observacao))

            projeto_lei = ProjetoLei.objects.get(projeto=projeto['projeto'])
            projeto_lei.data_divulgacao = divulgado
            projeto_lei.data_aprovacao = aprovado
            projeto_lei.data_arquivamento = arquivado
            projeto_lei.save()

    def indentifica_aprovacao(self, observacao):
        observacao = observacao.replace('  ', ' ')
        regex1 = "(?:Aprovado<br\/>)([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex2 = "([0-9]{2}\/[0-9]{2}\/[0-9]{2,4}) - Aprovado"
        regex3 = "Aprovado ([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex4 = "Aprovado - ([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex = r"%s|%s|%s|%s" % (regex1, regex2, regex3, regex4)

        matches = re.findall(regex, observacao, re.IGNORECASE)
        for match in matches:
            return self.remove_tupla(match)[0]

    def indentifica_divulgacao(self, observacao):
        observacao = observacao.replace('  ', ' ')
        regex1 = "([0-9]{2}\/[0-9]{2}\/[0-9]{2,4}) - Divulgado"
        regex2 = "Divulgado - ([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex = r"%s|%s" % (regex1, regex2)

        matches = re.findall(regex, observacao, re.IGNORECASE)
        for match in matches:
            return self.remove_tupla(match)[0]

    def indentifica_arquivamento(self, observacao):
        observacao = observacao.replace('  ', ' ')
        regex1 = "(?:Arquivado<br\/>)([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex2 = "([0-9]{2}\/[0-9]{2}\/[0-9]{4})<br\/>Arquivado"
        regex3 = "Arquivado - ([0-9]{2}\/[0-9]{2}\/[0-9]{2,4})"
        regex4 = "([0-9]{2}\/[0-9]{2}\/[0-9]{2,4}) - Arquivado"
        regex = r"%s|%s|%s|%s" % (regex1, regex2, regex3, regex4)

        matches = re.findall(regex, observacao, re.IGNORECASE)
        for match in matches:
            return self.remove_tupla(match)[0]


import albumentations as albu
import cv2
import numpy as np
from albumentations.pytorch import ToTensorV2
import torchvision.transforms as T

def otsu_thresholding(image):
    otsu_threshold, image_result = cv2.threshold(
        image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU,
    )
    return otsu_threshold

def auto_canny(image, o_threshold=0.2):
    # compute the median of the single channel pixel intensities
    v = np.median(image)
    # apply automatic Canny edge detection using the computed median
    upper = o_threshold
    lower = upper / 2
    edged = cv2.Canny(image, lower, upper)
    # return the edged image
    return edged

def canny_preprocess(img, **args):
    _preprocessing = T.Compose([
        T.ToPILImage(),
        T.Grayscale(),
        lambda x: np.array(x).astype(np.uint8),
        lambda x: auto_canny(x, otsu_thresholding(x)),
        # lambda x: cv2.dilate(x, np.ones((3, 3), np.uint8), iterations=1),
        #         lambda x: cv2.morphologyEx(x, cv2.MORPH_CLOSE, np.ones((3,3),np.uint8)),
        lambda x: cv2.bitwise_not(x),
        lambda x: cv2.cvtColor(x,cv2.COLOR_GRAY2RGB),
    ])

#     _postprocessing = T.Compose([
#         T.ToTensor(),
#         T.Resize((512, 512)),
#         T.Normalize(
#            mean=[0.485, 0.456, 0.406],
#            std=[0.229, 0.224, 0.225]
#        ),
#         T.ToPILImage(),
#     ])

    canny_mask = _preprocessing(img.astype(np.uint8))
    # print(img.shape, canny_mask.shape, img.dtype, canny_mask.dtype)
    applied_mask = cv2.bitwise_and(img, canny_mask)
    # result = _postprocessing(applied_mask)
    return applied_mask

def get_training_augmentation(is_preprocessing=False):
    train_transform = [

        albu.HorizontalFlip(p=0.5),
        #
        albu.ShiftScaleRotate(scale_limit=0.5, rotate_limit=5, shift_limit=0.2, p=0.2, border_mode=0),
        #
        # albu.PadIfNeeded(min_height=512, min_width=512, always_apply=True, border_mode=0),
        # albu.RandomCrop(height=512, width=512, p=0.2),
        albu.Resize(height=512, width=512),
        #
        albu.GaussNoise(p=0.1),
        albu.Perspective(p=0.1),
        #
        albu.OneOf(
            [
                albu.CLAHE(p=1),
                albu.RandomBrightness(p=1),
                albu.RandomGamma(p=1),
            ],
            p=0.1,
        ),
        #
        albu.OneOf(
            [
                albu.Sharpen(p=1),
                albu.Blur(blur_limit=3, p=1),
                albu.MotionBlur(blur_limit=3, p=1),
            ],
            p=0.1,
        ),
        #
        albu.OneOf(
            [
                albu.RandomContrast(p=1),
                albu.HueSaturationValue(p=1),
            ],
            p=0.1,
        ),

    ]
    if is_preprocessing:
        train_transform.extend([
            albu.Lambda(image=canny_preprocess)
        ])

    train_transform.extend([albu.Normalize(mean=[0.0, 0.0, 0.0], std=[1.0,1.0,1.0], max_pixel_value=255.0), ToTensorV2()])
    # train_transform.extend([ToTensorV2()])
    return albu.Compose(train_transform)

def get_validation_augmentation(is_preprocessing=False):
    """Add paddings to make image shape divisible by 32"""
    test_transform = [
        # albu.PadIfNeeded(512, 512),
        # albu.RandomCrop(height=512, width=512, always_apply=True),
        albu.Resize(height=512, width=512),

    ]
    if is_preprocessing:
        test_transform.extend([
            albu.Lambda(image=canny_preprocess)
        ])

    test_transform.extend([albu.Normalize(mean=[0.0, 0.0, 0.0], std=[1.0,1.0,1.0], max_pixel_value=255.0), ToTensorV2()])
    return albu.Compose(test_transform)

# def to_tensor(x, **kwargs):
#     return x.transpose(2, 0, 1).astype('float32')

def get_preprocessing(preprocessing_fn, is_preprocess):
    """Construct preprocessing transform

    Args:
        preprocessing_fn (callbale): data normalization function
            (can be specific for each pretrained neural network)
    Return:
        transform: albumentations.Compose

    """
    if is_preprocess:
        _transform = [
            albu.Lambda(image=canny_preprocess),
            ToTensorV2(),
        ]
    else:
        _transform = [
            ToTensorV2(),
        ]
    return albu.Compose(_transform)


# Задача 1.1. Вычислить методом Монте Карло payoff европейского колл опциона и сравнить с точной формулой Блэка-Шоулза
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from params import *

def MonteCarlo_payoff(s_0, r, sigma, dt, K, steps, paths, draw_plot=True):
    """
    :param r: The expected return
    :param sigma: The expected volatility
    :param dt: The increment of time, fraction of year
    :param K: Strike price,  dollars
    :param draw_plot:
    :return:
    """
    z = np.random.normal(size=(steps, paths))
    s = s_0 * np.exp(np.cumsum((r - np.power(sigma, 2) / 2) * dt + sigma * np.sqrt(dt) * z, axis=0))
    c = np.exp(-r * dt) * np.maximum(s[-1] - K, 0)

    print(c)

    payoff = np.sum(c) / paths

    print(payoff)

    # if draw_plot:
    #     plt.plot(s)
    #     plt.show()

    return payoff

def BlackSholes_payoff(s, r, sigma, dt, K):
    def N(x):
        return norm.cdf(x)

    # dt

    d1 = (np.log(s / K) + (r + np.power(sigma, 2) / 2) * dt) / (sigma * dt)
    d2 = d1 - sigma * dt

    return N(d1) * s - N(d2) * K * np.exp(-r * dt)

MonteCarlo_payoff = MonteCarlo_payoff(s_0, r, sigma, dt, K, steps, paths)

BlackSholes_payoff = BlackSholes_payoff(s_0, r, sigma, dt, K)

print(f'Вычисление payoff\'а европейского колл-опциона с параметрами:\n'
      f'Безрисковая процентная ставка: {r}, волатильность: {sigma}, срок исполнения опциона, месяцев: {dt * 12}, страйк-цена: {K}, начальная цена: {s_0},\n'
      f'количество временных отрезков: {steps}, количество симуляций: {paths}.\n'
      f'Вычисленный по методу Монте-Карло: {MonteCarlo_payoff}, по точной формуле Блэка-Шоулса: {BlackSholes_payoff}\n'
      f'Ошибка метода Монте-Карло составила {abs(MonteCarlo_payoff - BlackSholes_payoff)}')


import scipy.io

import tensorflow as tf
import numpy as np

VGG19_LAYERS = (
    'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1',

    'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',

    'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3',
    'relu3_3', 'conv3_4', 'relu3_4', 'pool3',

    'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3',
    'relu4_3', 'conv4_4', 'relu4_4', 'pool4',

    'conv5_1', 'relu5_1'
)

def load_net(data_path):

    """
    Loads parameters from data_path (path to .mat file)

    Args:
        data_path: (string) path to saved net
    """

    parameter_dict = scipy.io.loadmat(data_path)
    del parameter_dict['__version__']
    del parameter_dict['__globals__']
    del parameter_dict['__header__']

    return parameter_dict

def net_preloaded(parameter_dict, input_image, num_freeze=0):

    """
    Generates layers of VGG net. Returns a dictionary of the neural net

    Args:
        parameter_dict: (dict) Dictionary holding all the weights for the network
        input_image: (tf tensor) Placegolder tensor with shape of input image
        num_freeze: (int) number of layers to freeze in network
    """

    net = {}
    current = input_image

    for i, layer_name in enumerate(VGG19_LAYERS):

        if i < num_freeze:
            freeze = True
        else:
            freeze = False

        kind = layer_name[:4]

        if kind == 'conv':

            weights = parameter_dict['w' + layer_name]
            bias = parameter_dict['b' + layer_name].reshape(-1)
            current = _conv_layer(current, weights, bias, layer_name, freeze)

        elif kind == 'relu':
            current = tf.nn.relu(current)

        elif kind == 'pool':
            current = _pool_layer(current)

        net[layer_name] = current

    assert len(net) == len(VGG19_LAYERS)

    return net

def _conv_layer(input, weights, bias, layer_name, freeze):

    """
    Create a conv-layer from the input parameters and returns it.

    Args:
        input: (tensor) Input to the conv layer
        weights: (numpy array) Weight matrix for conv layer
        bias: (numpy array) Bais vector for layer
        layer_name: (string) Name of the layer
        freeze: (bool) tells whether layer should be constant or trainable
    """

    if freeze:
        conv = tf.nn.conv2d(input, tf.constant(weights, name="w" + layer_name), strides=(1, 1, 1, 1),
            padding='SAME')
        bias = tf.constant(bias, name="b" + layer_name)
        return tf.nn.bias_add(conv, bias)

    else:
        w = tf.get_variable("w" + layer_name, initializer=tf.Variable(weights))
        b = tf.get_variable("b" + layer_name, initializer=tf.Variable(bias))

        conv = tf.nn.conv2d(input, w, strides=(1, 1, 1, 1),
                padding='SAME')

        return tf.nn.bias_add(conv, b)

def _pool_layer(input):

    """
    Create a and returns a max pool layer

    Args:
        input: (tensor) Input to the max pool layer
    """

    return tf.nn.max_pool(input, ksize=(1, 2, 2, 1), strides=(1, 2, 2, 1),
            padding='SAME')

def preprocess(image, mean_pixel):

    """
    Subtract mean pixel value to an image

    Args:
        image: (numpy array) Image to subtract mean from
        mean_pixel: (int) mean pixel value to subtract
    """

    return image - mean_pixel

def unprocess(image, mean_pixel):

    """
    Subtract mean pixel value to an image

    Args:
        image: (numpy array) Image to subtract mean from
        mean_pixel: (int) mean pixel value to subtract
    """

    return image + mean_pixel

def save_parameters(sess, extra_parameters, file_name):

    """
    Saves the parameters trained in sess, in file 'trained_vgg_net.m'
    extra_parameters is a dictionary of additional parameters to save

    Args:
        sess: (tf session) Session to save computational graph from
        extra_parameters: (dict) Contains extra parameters neccessary for the network
        file_name: (string) Name of file
    """

    graph = tf.get_default_graph()
    parameter_dict = {}

    for i, layer_name in enumerate(VGG19_LAYERS):
        kind = layer_name[:4]
        if kind == 'conv':
            parameter_dict['w' + layer_name] = sess.run(graph.get_tensor_by_name('net/w' + layer_name + ':0'))
            parameter_dict['b' + layer_name] = sess.run(graph.get_tensor_by_name('net/b' + layer_name + ':0'))

    parameter_dict.update(extra_parameters)

    scipy.io.savemat(file_name, parameter_dict)

    return file_name


#Snake Tutorial Python

import math
import random
import pygame
import tkinter as tk
from tkinter import messagebox

class Cube(object):
    """Klasa dla kostki, która jest cześcią snake oraz snack"""
    rows = 20
    w = 500
    def __init__(self,start,direction_for_x =1,direction_for_y=0,color=(255,0,0)):
        self.position = start
        self.direction_for_x = 1
        self.direction_for_y = 0
        self.color = color

    def move(self, direction_for_x , direction_for_y):
        self.direction_for_x = direction_for_x
        self.direction_for_y = direction_for_y
        self.position = (self.position[0] + self.direction_for_x, self.position[1] + self.direction_for_y)

    def draw(self, surface, eyes=False):
        distance = self.w // self.rows
        i = self.position[0]
        j = self.position[1]

        pygame.draw.rect(surface, self.color, (i*distance+1, j*distance+1, distance-2, distance-2))
        if eyes:
            centre = distance//2
            radius =3
            circleMiddle1 = (i*distance+centre-radius, j*distance+8)
            circleMiddle2 = (i*distance + distance - radius*2, j*distance+8)
            pygame.draw.circle(surface, (0,0,0), circleMiddle1, radius)
            pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)

        # zostało dodane 1 do i oraz j by kostka nie rusowała się na liniach siatki, -2 dwa tak samo

class Snake(object):
    body = []
    turns = {}
    def __init__(self, color, position):
        self.color = color
        self.head = Cube(position)
        self.body.append(self.head)
        self.direction_for_x = 0
        self.direction_for_y = 1

    def move(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # run = False
                pygame.quit()

            keys = pygame.key.get_pressed()

            for key in keys:
                if keys[pygame.K_LEFT]:
                    self.direction_for_x = -1
                    self.direction_for_y = 0
                    self.turns[self.head.position[:]] = [self.direction_for_x, self.direction_for_y]
                elif keys[pygame.K_RIGHT]:
                    self.direction_for_x = 1
                    self.direction_for_y = 0
                    self.turns[self.head.position[:]] = [self.direction_for_x, self.direction_for_y]
                elif keys[pygame.K_DOWN]:
                    self.direction_for_x = 0
                    self.direction_for_y = 1
                    self.turns[self.head.position[:]] = [self.direction_for_x, self.direction_for_y]
                elif keys[pygame.K_UP]:
                    self.direction_for_x = 0
                    self.direction_for_y = -1
                    self.turns[self.head.position[:]] = [self.direction_for_x, self.direction_for_y]

        for index, element in enumerate(self.body):
            p = element.position[:]
            if p in self.turns:
                turn = self.turns[p]
                element.move(turn[0], turn[1])
                if index == len(self.body) - 1:
                    self.turns.pop(p)
            else:
                if element.direction_for_x == -1 and element.position[0] <= 0:
                    element.position = (element.rows - 1, element.position[1])
                elif element.direction_for_x == 1 and element.position[0] >= element.rows - 1:
                    element.position = (0, element.position[1])
                elif element.direction_for_y == 1 and element.position[1] >= element.rows - 1:
                    element.position = (element.position[0], 0)
                elif element.direction_for_y == -1 and element.position[1] <= 0:
                    element.position = (element.position[0], element.rows - 1)
                else:
                    element.move(element.direction_for_x, element.direction_for_y)

    def reset(self, position):
        self.head = Cube(position)
        self.body = []
        self.body.append(self.head)
        self.turns = {}
        self.direction_for_x = 0
        self.direction_for_y = 1

    def addCube(self):
        tail = self.body[-1]
        dx = tail.direction_for_x
        dy = tail.direction_for_y
        if dx == 1 and dy == 0:
            self.body.append(Cube((tail.position[0]-1,tail.position[1])))
        elif dx == -1 and dy == 0:
            self.body.append(Cube((tail.position[0]+1,tail.position[1])))
        elif dx == 0 and dy == 1:
            self.body.append(Cube((tail.position[0],tail.position[1]-1)))
        elif dx == 0 and dy == -1:
            self.body.append(Cube((tail.position[0],tail.position[1]+1)))

        self.body[-1].direction_for_x = dx
        self.body[-1].direction_for_y = dy

    def draw(self, surface):
        for i, element in enumerate(self.body):
            if i == 0:
                element.draw(surface, True)
            else:
                element.draw(surface)

def drawGrid(w, rows, surface):
    sizeBtwn = w // rows

    x = 0
    y = 0
    for l in range(rows):
        x = x + sizeBtwn
        y= y + sizeBtwn
        # rysowanie linii
        pygame.draw.line(surface, (255,255,255), (x,0), (x, w))
        pygame.draw.line(surface, (255,255,255), (0,y), (w, y))

def redrawWindow(surface):
    global rows, width, snake, snack
    surface.fill((120,120,160))
    snake.draw(surface)
    snack.draw(surface)
    drawGrid(width, rows, surface)
    pygame.display.update()

def randomSnack(rows, item):

    positions = item.body

    while True:
        x = random.randrange(rows)
        y = random.randrange(rows)
        if len(list(filter(lambda z: z.position == (x,y), positions))) > 0:
            continue
        else:
            break
    return (x, y)

def message_box(subject, content):
    root = tk.Tk()
    root.attributes("-topmost", True)
    root.withdraw()
    messagebox.showinfo(subject, content)
    try:
        root.destroy()
    except:
        pass

def main():
    global width, rows, snake, snack
    width = 500
    # height = 500
    rows = 20
    win = pygame.display.set_mode((width, width))
    snake = Snake((255,100,0), (10, 10))
    snack = Cube(randomSnack(rows, snake), color=(0, 255, 0))
    run = True

    clock = pygame.time.Clock()

    while run:

        pygame.time.delay(50)
        clock.tick(10)
        snake.move()
        if snake.body[0].position == snack.position:
            snake.addCube()
            snack = Cube(randomSnack(rows, snake), color=(0, 255, 0))

        for x in range(len(snake.body)):
            if snake.body[x].position in list(map(lambda z: z.position, snake.body[x+1:])):
                print('Score: ', len(snake.body))
                message_box('Game Over', 'Play again')
                snake.reset((10, 10))
                break

        redrawWindow(win)

main()


# import websocket
# import json
# import sys, getopt
# try:
#     import thread
# except ImportError:
#     import _thread as thread
# from collections import deque

# queue = deque()
# websocket_params = {
#     'type': 'unsubscribe',
#     'product_ids': ['BTC-USD'],
#     'channels': [
#         {
#             'name': 'ticker'
#         }
#     ]
# }

# def on_message(ws, message):
#     queue.append(message['price'])

# def on_error(ws, error):
#     print(error)

# def on_close(ws):
#     print("### closed ###")

# def on_open(ws):
#     def run(*args):
#         ws.send(json.dumps(websocket_params))
#     thread.start_new_thread(run, ())

# def run():
#     print('run')
#     ws.run_forever()

# websocket.enableTrace(True)
# ws = websocket.WebSocketApp("wss://ws-feed.pro.coinbase.com",
#                                 on_open = on_open,
#                                 on_message = on_message,
#                                 on_error = on_error,
#                                 on_close = on_close)
# ws.on_open = on_open

# run()

##########

# class A:
#     def printA(self):
#         print('A')
#         def printB():
#             print('B')
#         printB()
# a = A()
# a.printA()

############

# vals = [1,2,3]
# def get_val():
#     i = 0
#     while True:
#         i = (i+1) % 3
#         yield vals[i]

# count = 0
# for i in get_val():
#     print(i)
#     count += 1
#     if count >= 100:
#         break

#################

import json
import asyncio
import websockets
from websockets import WebSocketServerProtocol

# @asyncio.coroutine
# def hello():
#     websocket_params = {
#         'type': 'subscribe',
#         'product_ids': ['BTC-USD'],
#         'channels': ['ticker']
#     }
#     websocket = yield from websockets.connect('wss://ws-feed.pro.coinbase.com')
#     print('1')
#     yield from websocket.send(json.dumps(websocket_params))
#     print('2')
#     while True:
#         greeting = yield from websocket.recv()
#         print(greeting)

# asyncio.get_event_loop().run_until_complete(hello())

async def hello():
    websocket_params = {
        'type': 'subscribe',
        'product_ids': ['BTC-USD'],
        'channels': ['ticker']
    }
    async with websockets.connect('wss://ws-feed.pro.coinbase.com') as websocket:
        await websocket.send(json.dumps(websocket_params))
        while True:
            response = await websocket.recv()
            yield response

async def loop():
    async for i in hello():
        print(i)

asyncio.get_event_loop().run_until_complete(loop())


#!/usr/bin/env python3
"""sets-up user `environment`"""

import os
from pathlib import Path
import subprocess

def set_env():
    """
    Installs required modules
    checks if token file exists
    if false asks for required input and creates it
    """

    home_path = Path.home()
    to_conf = os.path.join(home_path, ".config")
    full_path = Path(to_conf, ".gh_config")
    if full_path.exists() is False:
        gh_username = input("Github username: ")
        gh_token = input("Github token: ")
        clone_option = input("Use ssh or https: (https | ssh)\n")
        if clone_option == "ssh":
            print("""
-----------------------------------------------------------------------------
                    You will need to setup the ssh keys
                            learn more here ⬇

    https://docs.github.com/en/authentication/connecting-to-github-with-ssh

-----------------------------------------------------------------------------
                  """)
        with open(full_path, "w") as file:
            file.write(f"{gh_username}\n{gh_token}\n{clone_option}")
    else:
        raise FileExistsError("File already exists")

    print("\n", "=" * 50, "\n")
    subprocess.run(["pip", "install", "-r", "requirements.txt"])
    print("================Everything is set====================")

if __name__ == "__main__":
    set_env()


from heapq import heappop, heappush
import itertools
import copy

from constants import CellState, Actions
dist = {
    "FORWARD": 1,
    "U_TURN": 1,
    "TURN_LEFT": 1,
    "TURN_RIGHT": 1
}

def __isAllowed(state, x, y):
    if x < 0 or x >= state.grid.height: return False
    if y < 0 or y >= state.grid.width: return False
    return True

def explore_new(state, x, y, direction):
    state.robot.set_robot(x, y, direction)

def virtual_explore(state, x, y, direction):
    state.robot.set_robot(x, y, direction)
    for sensor in state.robot.sensors:
        all_sensable_cells = sensor.get_all_cells(x, y, direction)
        for cell in all_sensable_cells:
            _x, _y = cell
            if not __isAllowed(state, _x, _y):
                break
            if state.explored_grid[_x][_y].is_same(CellState.FREE):
                continue
            elif state.explored_grid[_x][_y].is_same(CellState.OBSTACLE):
                break
            elif state.explored_grid[_x][_y].is_same(CellState.UNKNOWN):
                return True
    return False

def virtual_sense(state, action):
    # used to get a approximate next_state
    # virtual_sense won't change state
    x, y, direction = state.robot.next_state(action, state.x, state.y, state.direction)
    state_copy = copy.deepcopy(state)
    state_copy.robot.set_robot(x, y, direction)
    state_copy.x = x
    state_copy.y = y
    state_copy.direction = direction
    explored_grid_before_predict = copy.deepcopy(state.explored_grid)
    sensed_cells_state = {}
    for sensor in state_copy.robot.sensors:
        # predict and update state_copy.explored_map and num_explored
        sensed_cells_state.update(sensor.get_cells_state_with_explored_grid(x, y, direction, state_copy))
    for sensed_cell in sensed_cells_state.keys():
        x, y = sensed_cell
        if explored_grid_before_predict[x][y].is_same(CellState.UNKNOWN):
            state_copy.num_explored += 1
    if state_copy.num_explored == 300:
        state_copy.is_terminal = True
        # print("virtual sense:", next_state.num_explored)
    return state_copy

# def dijkstra(state):
#     # virtual wall can walk, but will stuck at corner, see case1.jpg
#     if state.num_explored == 300:
#         return 1
#     pq = []  # list of entries arranged in a heap
#     entry_finder = {}  # mapping of tasks to entries
#     REMOVED = '<removed-task>'  # placeholder for a removed task
#     counter = itertools.count()  # unique sequence count
#
#     def add_task(task, priority=0):
#         'Add a new task or update the priority of an existing task'
#         if task in entry_finder:
#             remove_task(task)
#         count = next(counter)
#         entry = [priority, count, task]
#         entry_finder[task] = entry
#         heappush(pq, entry)
#
#     def remove_task(task):
#         'Mark an existing task as REMOVED.  Raise KeyError if not found.'
#         entry = entry_finder.pop(task)
#         entry[-1] = REMOVED
#
#     def pop_task():
#         'Remove and return the lowest priority task. Raise KeyError if empty.'
#         while pq:
#             priority, count, task = heappop(pq)
#             if task is not REMOVED:
#                 del entry_finder[task]
#                 return task
#         raise KeyError('pop from an empty priority queue')
#
#     distance = {}
#     task = (state.x, state.y, state.direction)
#     distance[task] = 0
#     visited = set()
#     add_task(task, distance[task])
#     while pq:
#         task = pop_task()
#         visited.add(task)
#         x, y, direction = task
#         #
#         # temp_state = copy.deepcopy(state)
#         # virtual_explore(temp_state, x, y, direction)
#         # if temp_state.num_explored != state.num_explored:
#         #     return distance[task]
#
#         for action in Actions:
#             next_x, next_y, next_direction = state.robot.next_state(action, x, y, direction)
#             next_task = (next_x, next_y, next_direction)
#
#             # check is allowed
#             if not state.grid.is_allowed(next_x, next_y):
#                 continue
#
#             # find the shortest distance to the first unexplored cell
#             if state.explored_grid[next_x][next_y].is_same(CellState.UNKNOWN):
#                 return distance[task]+dist[action.name]
#
#             if state.grid[next_x][next_y].is_same(CellState.OBSTACLE):
#                 continue
#
#             # if state.grid.is_virtual_wall(next_x, next_y):
#             #     continue
#             distance[next_task] = distance[task]+dist[action.name]
#             if next_task not in visited:
#                 add_task(next_task, distance[next_task])

def dijkstra(state):
    # shortest distance to sense unexplored area
    if state.num_explored == 300:
        return 1.0
    pq = []  # list of entries arranged in a heap
    entry_finder = {}  # mapping of tasks to entries
    REMOVED = '<removed-task>'  # placeholder for a removed task
    counter = itertools.count()  # unique sequence count

    def add_task(task, priority=0):
        'Add a new task or update the priority of an existing task'
        if task in entry_finder:
            remove_task(task)
        count = next(counter)
        entry = [priority, count, task]
        entry_finder[task] = entry
        heappush(pq, entry)

    def remove_task(task):
        'Mark an existing task as REMOVED.  Raise KeyError if not found.'
        entry = entry_finder.pop(task)
        entry[-1] = REMOVED

    def pop_task():
        'Remove and return the lowest priority task. Raise KeyError if empty.'
        while pq:
            priority, count, task = heappop(pq)
            if task is not REMOVED:
                del entry_finder[task]
                return task
        raise KeyError('pop from an empty priority queue')

    distance = {}
    x, y, direction = state.x, state.y, state.direction
    task = (x, y, direction)
    distance[task] = 1.0
    visited = set()
    add_task(task, distance[task])
    # print("initial append to pq:", task, distance[task])
    while pq:
        task = pop_task()
        visited.add(task)
        x, y, direction = task

        if virtual_explore(state, x, y, direction):
            # print(x, y, direction, distance[task])
            return distance[task]

        for _action in Actions:
            _x, _y, _direction = state.robot.next_state(_action, x, y, direction)
            _task = (_x, _y, _direction)
            if (_x, _y, _direction) in visited:
                continue

            # check is allowed
            if not __isAllowed(state, _x, _y):
                continue

            if state.explored_grid.is_virtual_wall(_x, _y):
                visited.add((_x, _y, _direction))
                continue

            if state.explored_grid[_x][_y].is_same(CellState.OBSTACLE):
                visited.add((_x, _y, _direction))
                continue

            if _task not in visited:
                distance[_task] = distance[task] + dist[_action.name]
                # print("append to pq:", _task, distance[_task])
                add_task(_task, distance[_task])

    raise("There exist cells that are unable to reach")

def total_number_newly_explore_given_steps(state, action, num_step):
    pass

def discontinuous_unexplored_cells(state):
    pass


#compiled smoke simulation code

import numpy as np
import matplotlib.pyplot as plt

# Creates initial density and velocity arrays

a0 = np.zeros((20,20))    #create iniital density array
a = np.zeros((20,20))        #create next density array

for i in range (8,12):
    for j in range (8,12):
        a0[i,j]=1

N = a0.shape[0]-2   #sets N as 2 less than the number of grid cells per plot side

dt = .04   #defining dt

visc =  .1   #defining viscosity constant

#h0 = np.zeros((100,100)) #creates initial horizontal and vertical velocity array
#v0 = np.zeros((100,100))
#
#for i in range (45,55):
#    for j in range (45,55):
#        v0[i,j] = 1
#        h0[i,j] = 1
#
#v = np.zeros((100,100))
#h = np.zeros((100,100))

# Smaller velocity array for visualization

h0 = np.zeros((20,20)) #creates initial horizontal and vertical velocity array
v0 = np.zeros((20,20))

for i in range (8,12):
    for j in range (8,12):
        v0[i,j] = 1
        h0[i,j] = 1

v = np.zeros((20,20))
h = np.zeros((20,20))

#N = 18

#visualizes initial velocity array

#plt.quiver(v0, h0, units = 'x', scale = .5)
#plt.show()

#N = 18   #sets N as 2 less than the number of grid cells per plot side

# using "loc" to indicate the local variable version of N

def draw_array(a1):   #flips i and j in the plot to correspond with desired conventions
    plt.imshow(np.transpose(a1), origin = "lower", cmap="spectral", interpolation = "none")
    plt.colorbar()
    plt.show(block=False)
    plt.draw()

def draw_vector_field(h, v, scale):    #h and v are the arrays containing horizontal and vertical components of the vector field
    plt.quiver(h.transpose(),v.transpose(), units = "x", scale = scale )
    plt.show()

def set_bnd (N_loc, b, array):
    for i in range (1,N_loc+1):
        if b==1:
            array[0,i]= -array[1,i]
            array[N_loc+1, i] = -array[N_loc, i]
        else:
            array[0,i] = array[1,i]
            array[N_loc+1 ,i] = array[N_loc, i]

        if b==2:
            array[i,0] = -array[i,1]
            array[i,N_loc + 1] = -array[i, N_loc]
        else:
            array[i,0] = array[i,1]
            array[i, N_loc+1] = array[i, N_loc]

    array[0,0] = 0.5*(array[1,0]+ array[0,1])
    array[0, N_loc + 1] = 0.5*(array[1,N_loc + 1] + array[0, N_loc])
    array[N_loc + 1, 0] = 0.5*(array[N_loc,0] + array[N_loc + 1,1])
    array[N_loc + 1, N_loc + 1] = 0.5*(array[N_loc, N_loc + 1] + array[N_loc + 1, N_loc])

def diffuse(N_loc, dens_array, dens_array0, diff, dt, b):
    c = dt*diff*N_loc*N_loc
    k=0
    while (k<20):
        for i in range (1,N_loc+1):
            for j in range (1,N_loc+1):
                dens_array[i,j]=(dens_array0[i,j]+c*(dens_array[i-1,j] + dens_array[i+1,j] + dens_array[i,j-1] + dens_array[i, j+1]))/(1+4*c)
        k = k + 1

    set_bnd(N_loc,b,dens_array)

def advect(N_loc, b, dens_array, dens_array0, h_vel, v_vel, dt):
    dt0 = dt*N_loc
    for i in range (1,N_loc+1):
        for j in range (1, N_loc+1):
            x = i - dt0*v_vel[i,j]
            y = j - dt0*h_vel[i,j]

            if (x<0.5):
                x=0.5

            if (x > N_loc + 0.5):
                x = N_loc + 0.5

            i0 = int(x)
            i1 = i0 + 1

            if (y<0.5):
                y=0.5
            if (y > N_loc + 0.5):
                y = N_loc + 0.5

            j0 = int(y)
            j1 = j0 +1

            s1 = x-i0
            s0 = 1-s1
            t1 = y-j0
            t0 = 1-t1

            dens_array[i,j] = s0*(t0*dens_array0[i0,j0] + t1*dens_array0[i0,j1]) + s1*(t0*dens_array0[i1,j0] + t1*dens_array0[i1,j1])

    set_bnd(N_loc, b, dens_array)

def project(N_loc, h_vel, v_vel, p, div):
    h = 1.0/N_loc
    k=0
    for i in range (1,N_loc+1):
        for j in range (1,N_loc+1):
            div[i,j] = -0.5*h*(h_vel[i+1,j] - h_vel[i-1,j] + v_vel[i,j+1] - v_vel[i,j-1])
            p[i,j] = 0
    set_bnd(N_loc, 0, div)
    set_bnd(N_loc, 0, p)

    draw_array(div)

    while k<20:
        for i in range (1,N_loc+1):
            for j in range (1,N_loc+1):
                p[i,j] = (div[i,j]+p[i-1,j] + p[i+1,j] + p[i,j-1] + p[i,j+1])/4
        set_bnd(N_loc, 0, p)
        k = k+1

    draw_array(p)

    for i in range (1, N_loc+1):
        for j in range (1, N_loc+1):
            h_vel[i,j] -= 0.5*(p[i+1,j] - p[i-1,j])/h
            v_vel[i,j] -= 0.5*(p[i,j+1] - p[i,j-1])/h
    set_bnd(N_loc, 1, h_vel)
    set_bnd(N_loc, 2, v_vel)

def vel_step(N_loc, h_vel, v_vel, h_vel0, v_vel0, visc, dt):

    diffuse(N_loc, h_vel, h_vel0, visc, dt, 1)
    draw_vector_field(h_vel,v_vel,0.5)

    diffuse(N_loc, v_vel, v_vel0, visc, dt, 2)
    draw_vector_field(h_vel,v_vel,0.5)

    project(N_loc, h_vel, v_vel, h_vel0, v_vel0)
    draw_vector_field(h_vel,v_vel,0.5)

    h_vel0, h_vel = h_vel, h_vel0
    v_vel0, v_vel = v_vel, v_vel0

    advect (N_loc, 1, h_vel, h_vel0, h_vel0, v_vel0, dt)
    draw_vector_field(h_vel,v_vel,0.5)

    advect (N_loc, 2, v_vel, v_vel0, h_vel0, v_vel0, dt)
    draw_vector_field(h_vel,v_vel,0.5)

    project (N_loc, h_vel, v_vel, h_vel0, v_vel0)
    draw_vector_field(h_vel,v_vel,0.5)

#Smoke simulation loop

#while True:
#    vel_step(N, h, v, h0, v0, visc, dt)
#    diffuse (N, a, a0, visc, dt, 0)
#    a0, a = a, a0
#    advect(N, 0, a, a0, h0, v0, dt) #Stam's code has h and v rather than h0 and v0 passed in here, although for whatever reason this seems to make the advection more effective. Why?
#    a0, a = a, a0
#    draw_array(a0)
#    draw_vector_field(h0,v0,0.5)

#Visualizing velocity fields at each stage through "vel_step" function

#vel_step (N, h, v, h0, v0, visc, dt)
#draw_vector_field(h0,v0,0.5)
#
#project(N, h0, v0, h, v)
#draw_vector_field(h0,v0,0.5)

while True:
    diffuse(N, a, a0, visc, dt, 0)
    a, a0 = a0, a
    draw_array(a0)


#! /usr/bin/env python3.8
# encoding: utf-8
import open3d as o3d
import copy
import numpy as np
import math
import rospy
from geometry_msgs.msg import PoseStamped
from pyquaternion import Quaternion
from sensor_msgs.msg import PointCloud2, PointField
from sensor_msgs import point_cloud2
from std_msgs.msg import Header

## 函数区
# 考虑x/y方向的路径
def XdirectionZigPath(xmin,xmax,ymin,ymax,Nx):
    paths = []
    dx = float(xmax-xmin)/(Nx-1)  # the y step-over
    flag=1      #奇偶分别
    path=[]
    for n in range(0,Nx):
        x = xmin+n*dx              # current y-coordinate
        # if (n==Nx-1):
        #     assert( x==xmax)
        # elif (n==0):
        #     assert( x==xmin)
        if flag==1:
            p1 = [x,ymin,0]   # start-point of line
            p2 = [x,ymax,0]   # end-point of line
            # print(flag)
        if flag==-2:
            p1 = [x,ymax,0]   # start-point of line
            p2 = [x,ymin,0]   # end-point of line
            # print(flag)
        path.append(p1)       # add the line to the path
        path.append(p2)
        flag=~flag
        # paths.append(path)
    return path

# 得到步进x/y方向的路径
def feedPath(path,step,step_num):
    flag=1      #奇偶分别
    fpath=[]
    n=len(path)
    for i in range(n//2):
        for j in range(step_num):
            if flag==1:
                p=[path[2*i][0],path[2*i][1]+j*step,path[2*i][2]]
            if flag==-2:
                p=[path[2*i][0],path[2*i][1]-j*step,path[2*i][2]]
            fpath.append(p)
        flag=~flag
    return fpath

# 依据点云坐标得到z方向的坐标
def ZdirectionPath(fpath,points,normals,scan_height,rapid_height):
    zpath=[]
    npath=[]
    n=len(fpath)
    # 初始点
    zpath.append([fpath[0][0],fpath[0][1],rapid_height])
    npath.append([0,0,-1])
    # 中间点
    for i in range(n):
        temp=[]
        for m in range(len(points)):
            temp.append(math.sqrt((fpath[i][0]-points[m][0])**2+(fpath[i][1]-points[m][1])**2))
        min_value=np.min(temp)
        min_index=np.argmin(temp)
        # print(min_value)
        threshold=0.004     #阈值可修改
        if min_value<threshold:
            scan_z=points[min_index][2]+scan_height
            zpath.append([fpath[i][0],fpath[i][1],scan_z])
            npath.append([normals[min_index][0],normals[min_index][1],normals[min_index][2]])
    # 结束点
    zpath.append([fpath[n-1][0],fpath[n-1][1],rapid_height])
    npath.append([0,0,-1])
    # 修改初始点和结束点

    return zpath,npath

# 主函数
if __name__ == "__main__":
    mesh_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.1, origin=[0, 0, 0])
    data = o3d.io.read_point_cloud("./src/data/point_cloud/pointcloud_1.pcd")
    # o3d.visualization.draw_geometries([data,mesh_frame])
    # 红色：x
    # 绿色：y
    # 蓝色：z

    # 使用欧拉角创建旋转矩阵
    pcd = copy.deepcopy(data).translate((0, 0, -0.24))
    # o3d.visualization.draw_geometries([pcd,mesh_frame])

    # 旋转网格
    R = mesh_frame.get_rotation_matrix_from_xyz((np.pi, 0, 0))
    pcd.rotate(R, center=(0, 0, 0))
    R = mesh_frame.get_rotation_matrix_from_xyz((0, 0, np.pi/12))
    pcd.rotate(R, center=(0, 0, 0))
    # o3d.visualization.draw_geometries([pcd,mesh_frame])

    # 交互选区
    vis = o3d.visualization.VisualizerWithVertexSelection()
    vis.create_window(window_name='select region holding shift', visible=True)
    vis.add_geometry(pcd)
    vis.run()
    point = vis.get_picked_points()
    vis.destroy_window()
    # print(point[0].index, np.asarray(point[0].coord))
    # 原文链接：https://blog.csdn.net/qq_45912037/article/details/127096161

    point_temp=[]
    for i in range(len(point)):
        point_temp.append(point[i].coord)

    outlier_cloud = o3d.geometry.PointCloud()# 传入3d点云
    outlier_cloud.points = o3d.utility.Vector3dVector(point_temp)  # point_points 二维 numpy 矩阵,将其转换为 open3d 点云格式

    o3d.visualization.draw_geometries([outlier_cloud,mesh_frame])

    # 计算法向量
    outlier_cloud.estimate_normals(
        search_param=o3d.geometry.KDTreeSearchParamKNN(knn=200)                        # 计算近邻的20个点
    )
    o3d.geometry.PointCloud.orient_normals_to_align_with_direction(outlier_cloud, orientation_reference=np.array([0.0, 0.0, -1.0]))  #设定法向量在z轴方向上，全部z轴正方向一致
    normals = np.array(outlier_cloud.normals)    # 法向量结果与点云维度一致(N, 3)
    points = np.array(outlier_cloud.points)
    # print(points)

    # 法向量可视化
    o3d.visualization.draw_geometries([outlier_cloud,mesh_frame],
                                         window_name="Open3d",
                                         point_show_normal=True,
                                         width=800,   # 窗口宽度
                                         height=600)  # 窗口高度

    # 获取工件x/y方向的最大值和最小值
    xmin=np.min(points[:,0])
    xmax=np.max(points[:,0])
    ymin=np.min(points[:,1])
    ymax=np.max(points[:,1])
    # 确定x方向分Nx条线
    Nx=20  # number of lines in the x-direction
    path = XdirectionZigPath(xmin,xmax,ymin,ymax,Nx)
    # print(path)

    # 设置每条线走几步
    step_num=20
    step=(ymax-ymin)/(step_num-1)
    fpath=feedPath(path,step,step_num)

    scan_height=0.01
    rapid_height=0.2
    zpath,npath=ZdirectionPath(fpath,points,normals,scan_height,rapid_height)
    # print(zpath)

    # 将路径画在点云上,可视化
    #绘制顶点
    lines=[]
    for i in range(len(zpath)-1):
        l=[i,i+1]
        lines.append(l) #连接的顺序
    color = [[0, 0, 0.8] for i in range(len(lines))]
    #添加顶点，点云
    points_pcd = o3d.geometry.PointCloud()# 传入3d点云
    points_pcd.points = o3d.utility.Vector3dVector(zpath)  # point_points 二维 numpy 矩阵,将其转换为 open3d 点云格式
    points_pcd.paint_uniform_color([0, 0.8, 0]) #点云颜色
    points_pcd.normals= o3d.utility.Vector3dVector(npath)
    #绘制线条
    lines_pcd = o3d.geometry.LineSet()
    lines_pcd.lines = o3d.utility.Vector2iVector(lines)
    lines_pcd.colors = o3d.utility.Vector3dVector(color) #线条颜色
    lines_pcd.points = o3d.utility.Vector3dVector(zpath)
    # 可视化
    o3d.visualization.draw_geometries([points_pcd,lines_pcd,outlier_cloud,mesh_frame])
    o3d.visualization.draw_geometries([points_pcd,lines_pcd,mesh_frame],point_show_normal=True)
'''
    # 发布话题
    rospy.init_node("pathplan_select")
    pub = rospy.Publisher("pathplanning_select",PoseStamped,queue_size=10)
    count=0
    rate=rospy.Rate(1)
    ps = PoseStamped()
    while not rospy.is_shutdown():
        # x/y/z坐标
        ps.pose.position.x=zpath[count][0]
        ps.pose.position.y=zpath[count][1]
        ps.pose.position.z=zpath[count][2]

        # 构建旋转矩阵
        rotate_matrix=[[0,0,0],[0,0,0],[0,0,0]]
        Z = np.array([npath[i][0], npath[i][1], npath[i][2]])
        X = np.array([Z[1], -Z[0], 0])
        Z = Z/np.linalg.norm(Z)
        X = X/np.linalg.norm(X)
        rotate_matrix[0][2]=Z[0]
        rotate_matrix[1][2]=Z[1]
        rotate_matrix[2][2]=Z[2]
        rotate_matrix[0][0]=X[0]
        rotate_matrix[1][0]=X[1]
        rotate_matrix[2][0]=X[2]
        # 计算叉乘
        Y = np.cross(Z,X)
        Y = Y/np.linalg.norm(Y)
        rotate_matrix[0][1]=Y[0]
        rotate_matrix[1][1]=Y[1]
        rotate_matrix[2][1]=Y[2]
        rotateMatrix = np.array(rotate_matrix)
        print(rotateMatrix)
        q = Quaternion(matrix=rotateMatrix)
        ps.pose.orientation.x=q.x
        ps.pose.orientation.y=q.y
        ps.pose.orientation.z=q.z
        ps.pose.orientation.w=q.w
        # 发布话题
        pub.publish(ps)
        rospy.loginfo("%s",str(ps))

        count+=1
        if count>=len(zpath):
            rospy.loginfo("len%d",len(zpath))
            break
'''


from flask import Flask, request, jsonify
from flask_cors import CORS
from database_manager import DatabaseManager
from course_tracker import CourseTracker
from sentiment_analyzer import SentimentAnalyzer
import collections

app = Flask(__name__)
CORS(app)

@app.route("/word_cloud", methods=['GET'])
def word_cloud():
    query = request.args.get("query")
    if query is None:
        return jsonify({"error": "missing query"}), 400

    db = DatabaseManager()
    comments = db.comments_containing(query)
    words = [word.lower() for c in comments for word in c.content.split()]
    counts = collections.Counter(words).most_common(25)
    return jsonify(dict(counts))

@app.route("/courses_by_popularity", methods=['GET'])
def courses_by_popularity():
    course_tracker = CourseTracker()
    db = DatabaseManager()
    analyzer = SentimentAnalyzer()
    sentiments = []
    for course in course_tracker.get_all_courses():
        course_comments = db.comments_containing(course.name)
        if len(course_comments) == 0:
            continue
        course_sentiments = [
            analyzer.analyze_sentiment(c.content) for c in course_comments
        ]
        avg_sentiment = sum(course_sentiments) / len(course_sentiments)
        sentiments.append({
            "course": course.name,
            "avg_sentiment": avg_sentiment
        })

    return jsonify(
        sorted(sentiments, key=lambda x: x["avg_sentiment"], reverse=True))

@app.route("/most_upvoted", methods=['GET'])
def most_upvoted():
    query = request.args.get("query", )
    n = request.args.get("n", type=int)
    if query is None:
        return jsonify({"error": "missing query"}), 400
    if n is None:
        return jsonify({"error": "missing n"}), 400

    db = DatabaseManager()
    comments = db.most_upvoted_comments_containing(query, n)
    comments.sort(key=lambda x: x.votes, reverse=True)
    return jsonify([c.to_dict() for c in comments])


import pymunk
import pymunk.pygame_util
import pygame
import sys
from pygame.locals import *
from recursos import colores
pygame.init()
space = pymunk.Space()
space.gravity = 0, -900

class circulo:
    def __init__(self, masa, momentum, posicion, elasticidad,radio):
        self.masa=masa
        self.momentum=momentum
        self.elasticidad=elasticidad
        self.body = pymunk.Body()
        self.radio = radio
        self.posicion= posicion
        self.body = pymunk.Body(mass=self.masa, moment=self.momentum)
        self.body.position = self.posicion

        self.circle = pymunk.Circle(self.body, radius=self.radio)
        self.circle.elasticity = self.elasticidad
        space.add(self.body,self.circle)
    def mover(self, keys):
        if keys[K_RIGHT]:
            self.body.position= self.body.position[0]

    def mover(self, keys):
        if keys[K_RIGHT]:
            self.posicion=self.posicon[1]+1

class App:
    size = 800, 540
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode(self.size)
        self.draw_options = pymunk.pygame_util.DrawOptions(self.screen)
        self.running = True

    def run(self):
        circulo(1, 10, (50,200), 0.95,30)
        img=pygame.image.load("img/assets/Tiles/grass.png")
        img=pygame.transform.smoothscale(img, (40,40))
        reloj=pygame.time.Clock()

        while self.running:
            keys = pygame.key.get_pressed()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                    pygame.image.save(self.screen, 'intro.png')
            circulo.mover(keys)
            self.screen.fill(colores.Lime)
            space.debug_draw(self.draw_options)
            j=0
            for l in range(100):
                self.screen.blit(img,(0+j,500))
                j=j+30
            pygame.display.update()
            space.step(0.01)
            reloj.tick(60)
        pygame.quit()


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

# Universal Buzzer to midi
# Doc : http://github.com/pigetArduino/ubuzzer
# Author : Rémi Sarrailh (madnerd.org)
# Licence : MIT

# Arduino communication is completely managed by arduino module
# If connection is lost it will try to reconnect

import rtmidi2
from tkinter import *
import time
from threading import Thread
from functools import partial
import os
from lib import USB

# Change device_name to detect another device
# Device name CH340 is arduino nano clone
# Device type is sent to the arduino and it should answer return_string
# Baudrate : Should be 9600 or 115200
device_name = "CH340"
device_type = "UBuzzer"
device_return_string = "OK"
device_baudrate = 115200

# Bootstrap color for ui
bg_grey = "#f3f3f3"

######################
# Universal Buzzer   #
######################

global lastnote,last_time
lastnote = 0
last_time = 0

midi_to_hz = {
11:31,
12:33,
13:35,
14:37,
15:39,
16:41,
17:44,
18:46,
19:49,
20:52,
21:55,
22:58,
23:62,
24:65,
25:69,
26:73,
27:78,
28:82,
29:87,
30:93,
31:98,
32:104,
33:110,
34:117,
35:123,
36:131,
37:139,
38:147,
39:156,
40:165,
41:175,
42:185,
43:196,
44:208,
45:220,
46:233,
47:247,
48:262,
49:277,
50:294,
51:311,
52:330,
53:349,
54:370,
55:392,
56:415,
57:440,
58:466,
59:494,
60:523,
61:554,
62:587,
63:622,
64:659,
65:698,
66:740,
67:784,
68:831,
69:880,
70:932,
71:988,
72:1047,
73:1109,
74:1175,
75:1245,
76:1319,
77:1397,
78:1480,
79:1568,
80:1661,
81:1760,
82:1865,
83:1976,
84:2093,
85:2217,
86:2349,
87:2489,
88:2637,
89:2794,
90:2960,
91:3136,
92:3322,
93:3520,
94:3729,
95:3951,
96:4186,
97:4435,
98:4699,
98:4978
}

#####################
# GUI Functions     #
#####################
# We use a callback when we quit the application so
# we can correctly close the arduino connection
def quit_callback():
	try:
		usb.close()
	except:
		print("Arduino was not gracefully closed")
	root.destroy()

# This function generate buttons and commands with arguments
# We need to use partial to programatically create the commands

# GUI

# Create interface
root = Tk()
root.title(device_type) #Title
root.geometry("210x50")
root.configure(background=bg_grey) #Background color
root.iconbitmap('ubuzzer.ico') #Icon

# Callback when application is closed
root.protocol("WM_DELETE_WINDOW", quit_callback)

#################
# Buttons Frame #
#################
frame_commands = Frame(root)
frame_commands.grid(row=0)

def midi_callback(message, time_stamp):
    global lastnote,last_time
    note = message[1]
    velocity = message[2]

    if velocity != 0:
        print("ON:  "+str(note) + " " + str(time_stamp))
        midi.config(text=str(note))
        lastnote = note #Send tone
        last_time = time_stamp
        usb.write(str(midi_to_hz[note]))
    if velocity == 0:
        if lastnote == note:
            usb.write("OFF")
            print("OFF: "+str(note) + " " + str(time_stamp))
        else:
            print("DIS OFF: "+str(note) + " " + str(time_stamp) + "  " + str(last_time))

def midi_out_callback(message,time_stamp):
    print(message)

def check_midi():
    midi_in = rtmidi2.MidiInMulti()
    curr_ports = []
    prev_ports = []
    first_loop = True

    while True:
        curr_ports = rtmidi2.get_in_ports()
        if(len(prev_ports) != len(curr_ports)):
            midi_in.close_ports()
            prev_ports = []
            for port in curr_ports:
                if port not in prev_ports and 'Midi Through' not in port and (len(prev_ports) != len(curr_ports)):
                    midi_in.open_ports(port)
                    midi_in.callback = midi_callback
                    if first_loop:
                        print('Opened MIDI port: ' + port)
                    else:
                        print('Reopening MIDI port: ' + port)
        prev_ports = curr_ports
        first_loop = False
        time.sleep(0.2)

MidiThread = Thread(target=check_midi)
MidiThread.daemon = True
MidiThread.start()

#################
# Status Frame  #
#################

frame_status = Frame(root)
frame_status.grid(row=2)
status = Label(frame_status,fg="red",text="Searching...")
status.grid()
midi = Label(frame_status,fg="blue",text="Midi")
midi.grid()

# Search arduino as soon as the gui is created
# We use a thread or the gui will be blocked by the function
# We passed the status label object, you can remove this if you don't want to
usb = USB.Device(device_name,device_type,device_return_string,device_baudrate,status)

# Start application (if something bad happens close arduino connection)
try:
	root.mainloop()
except:
	print("Application was forced to stop")
	try:
		#If something go wrong we try to close the serial connection correctly
		usb.close()
	except:
		print("Arduino Not gracefully closed")


#!/usr/bin/env python3

import argparse
import json
import sys
import requests
from es2json import esgenerator, isint, litter, eprint

lookup_table_wdProperty = {"http://viaf.org": {"property": "P214",
                                               "delim": "/"},
                           "https://d-nb.info/gnd": {"property": "P227",
                                                     "delim": "/"},
                           "http://isni.org": {"property": "P213",
                                               "delim": "/"},
                           "http://id.loc.gov": {"property": "P244",
                                                 "delim": "/"},
                           "https://deutsche-digitale-bibliothek.de": {"property": "P4948",
                                                                       "delim": "/"},
                           "http://catalogue.bnf.fr/ark": {"property": "P268",
                                                           "delim": "/cb"},
                           "http://geonames.org": {"property": "P1566",
                                                   "delim": "/"},
                           "http://filmportal.de/person": {"property": "P2639",
                                                           "delim": "/"},
                           "http://orcid.org": {"property": "P496",
                                                "delim": "/"},
                           "http://swb.bsz-bw.de/DB=2.1/PPNSET?PPN=": {"property": "P1044",
                                                                       "delim": "="}
                           }

def get_wdid(_ids, rec):
    """
    gets an list of sameAs Links, e.g. ['https://d-nb.info/gnd/118827545', 'http://swb.bsz-bw.de/DB=2.1/PPNSET?PPN=035143010', 'http://catalogue.bnf.fr/ark:/12148/cb119027159', 'http://id.loc.gov/rwo/agents/n50002729', 'http://isni.org/isni/0000000120960218', 'http://viaf.org/viaf/44298691']
    """
    if not isinstance(_ids, list):
        return None
    changed = False
    url = "https://query.wikidata.org/bigdata/namespace/wdq/sparql"
    # Define header according to wikidata's User-Agent policy
    # see: https://meta.wikimedia.org/wiki/User-Agent_policy
    headers = {
            'User-Agent': 'efre-lod-enrich-wikidata-bot/0.1 '
                          '(https://github.com/slub/esmarc) '
                          'python-requests/2.22'
            }

    or_mapping = []
    for _id in _ids:
        for key, value in lookup_table_wdProperty.items():
            if _id.startswith(key):
                or_mapping.append("?item wdt:{Property} \"{value}\"".format(
                    Property=value["property"], value=_id.split(value["delim"])[-1]))
                break

    if or_mapping:
        # BUILD an SPARQL OR Query with an UNION Operator.
        # Still builds an normal query without UNION when or_mapping List only contains one element
        query = '''SELECT DISTINCT ?item \nWHERE {{\n\t{{ {UNION} }}\n}}'''.format(
            UNION="} UNION\n\t\t {".join(or_mapping))
        data = requests.get(url, headers=headers, params={'query': query, 'format': 'json'})
        if data.ok and len(data.json().get("results").get("bindings")) > 0:
            for item in data.json().get("results").get("bindings"):
                rec["sameAs"] = litter(
                    rec["sameAs"], {"@id": item.get("item").get("value"),
                                    "publisher": {
                        "@id": "https://www.wikidata.org/wiki/Q2013",
                        "abbr": "WIKIDATA",
                        "preferredName": "Wikidata"},
                        "isBasedOn": {
                            "@type": "Dataset",
                            "@id": item.get("item").get("value")}})
                changed = True
        elif not data.ok:
            eprint("wikidata: Connection Error {status}: \'{message}\'"
                   .format(status=data.status_code, message=data.content)
                   )
    if changed:
        return rec

def run():
    parser = argparse.ArgumentParser(description='enrich ES by WD!')
    parser.add_argument('-host', type=str, default="127.0.0.1",
                        help='hostname or IP-Address of the ElasticSearch-node to use, default is localhost.')
    parser.add_argument('-port', type=int, default=9200,
                        help='Port of the ElasticSearch-node to use, default is 9200.')
    parser.add_argument('-index', type=str,
                        help='ElasticSearch Search Index to use')
    parser.add_argument('-type', type=str,
                        help='ElasticSearch Search Index Type to use')
    parser.add_argument(
        "-id", type=str, help="retrieve single document (optional)")
    parser.add_argument('-stdin', action="store_true",
                        help="get data from stdin")
    parser.add_argument('-pipeline', action="store_true",
                        help="output every record (even if not enriched) to put this script into a pipeline")
    # no, i don't steal the syntax from esbulk...
    parser.add_argument(
        '-server', type=str, help="use http://host:port/index/type/id?pretty. overwrites host/port/index/id/pretty")
    args = parser.parse_args()
    if args.server:
        slashsplit = args.server.split("/")
        args.host = slashsplit[2].rsplit(":")[0]
        if isint(args.server.split(":")[2].rsplit("/")[0]):
            args.port = args.server.split(":")[2].split("/")[0]
        args.index = args.server.split("/")[3]
        if len(slashsplit) > 4:
            args.type = slashsplit[4]
        if len(slashsplit) > 5:
            if "?pretty" in args.server:
                args.pretty = True
                args.id = slashsplit[5].rsplit("?")[0]
            else:
                args.id = slashsplit[5]
    if args.stdin:
        for line in sys.stdin:
            rec = json.loads(line)
            record = None
            if (rec and isinstance(rec.get("sameAs"), list)
                    and "wikidata.org" not in str(rec["sameAs"])):
                record = get_wdid([x["@id"] for x in rec["sameAs"]], rec)
                if record:
                    rec = record
            if (record or args.pipeline) and rec:
                print(json.dumps(rec, indent=None))
    else:
        body = {"query": {"bool": {"filter": {"bool": {"should": [], "must_not": [
                   {"match": {"sameAs.publisher.abbr.keyword": "WIKIDATA"}}
               ]}}}}}
        for key in lookup_table_wdProperty:
            body["query"]["bool"]["filter"]["bool"]["should"].append(
                {"prefix": {"sameAs.@id.keyword": key}})
        for rec in esgenerator(host=args.host, port=args.port, index=args.index, type=args.type, id=args.id, headless=True, body=body):
            record = None
            if rec.get("sameAs") and isinstance(rec.get("sameAs"), list):
                record = get_wdid([x["@id"] for x in rec["sameAs"]], rec)
                if record:
                    rec = record
            if record or args.pipeline:
                print(json.dumps(rec, indent=None))

if __name__ == "__main__":
    run()


##Packages######################################
import numpy as np
import string
import pandas  as  pd
import datetime
import pymongo
import json
import requests
from dateutil import parser
import pyelasticsearch
from pyelasticsearch import ElasticSearch
from elasticsearch import Elasticsearch
###################################################

es = Elasticsearch("http://127.0.0.1:9300")    #### Initializing  ElasticSearch instance  with localhost  at port  9300

##############################################################################

############################# Mapping  of  data  to be inserted into elastic search############
######  There  will  be 3  sensors in our  database(index)  "sensor" ,  sensor1, sensor2, sensor3  as  type(tables)
#####   Each sensor  have  3  pairs  of values  - "sensor_value" , "created"(date_format) , "sensor_descr" (description about the sensor)
####    Below  we  defined  the  datatypes  of the above variables  using mapping .
'''
PUT provider2
{
    "mappings": {
        "sensor1": {
            "properties": {

                "sensor_value": {
                    "type": "long"
                },

                "created": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss"
                },

                "sensor_descr": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

'''

##########################################################################
###############Define  Data to  be inserted  into  3 sensors

def provider_value_insert(provider_name,sensor_1,sensor_2,sensor_3):
    from datetime import datetime, timedelta
    import datetime

    ##### Took 3 dates   , present  ,  previous  , and  day  before  previous  for all  the  three  sensors
    #### removed  microsecound

    todays_date= datetime.datetime.now().replace(microsecond=0)
    yesterdays_date=todays_date.replace(microsecond=0)- timedelta(days=1)
    day_before_yesterday_date=todays_date.replace(microsecond=0)- timedelta(days=2)

    sensor1=pd.DataFrame({"sensor_value":[100,101,102],"created":[todays_date,yesterdays_date,day_before_yesterday_date],"sensor_descr":["first_freq","secnd_freq","third_freq"]})
    sensor2=pd.DataFrame({"sensor_value":[200,201,202],"created":[todays_date,yesterdays_date,day_before_yesterday_date],"sensor_descr":["forth_freq","fifth_freq","sixth_freq"]})
    sensor3=pd.DataFrame({"sensor_value":[300,301,302],"created":[todays_date,yesterdays_date,day_before_yesterday_date],"sensor_descr":["seventh_freq","eight_freq","nine_freq"]})

    ###   Convert all  dataframe   to json  format
    SENSOR1_JSON = sensor1.to_dict(orient='records')
    SENSOR2_JSON = sensor2.to_dict(orient='records')
    SENSOR3_JSON = sensor3.to_dict(orient='records')
    ########################################UPDATE SENSOR1 SENSOR2 SENSOR3 TABLES  ###############################

    def myconverter(o):
        if isinstance(o, datetime.datetime):
            return o.__str__()

    #####################################SENSOR1  UPDATE
    extended_dat = []
    for i in range(sensor1.__len__()):  ###  converting  dict  to  strings
        extended_dat.append(json.dumps(SENSOR1_JSON[i], default=myconverter))

    for item in range(SENSOR1_JSON.__len__()):  ####  dumping  all  data  into  elastic search  .
        req = requests.post('http://localhost:9200/'+provider_name+'/'+sensor_1+'/', data=extended_dat[item])
        print(req.text)

    #####################################SENSOR2  UPDATE
    extended_dat = []
    for i in range(sensor1.__len__()):  ###  converting  dict  to  strings
        extended_dat.append(json.dumps(SENSOR2_JSON[i], default=myconverter))

    for item in range(SENSOR1_JSON.__len__()):  ####  dumping  all  data  into  elastic search  .
        req = requests.post('http://localhost:9200/'+provider_name+'/'+sensor_2+'/', data=extended_dat[item])
        print(req.text)

    #####################################SENSOR3  UPDATE
    extended_dat = []
    for i in range(sensor3.__len__()):  ###  converting  dict  to  strings
        extended_dat.append(json.dumps(SENSOR3_JSON[i], default=myconverter))

    for item in range(SENSOR3_JSON.__len__()):  ####  dumping  all  data  into  elastic search  .
        req = requests.post('http://localhost:9200/'+provider_name+'/'+sensor_3+'/', data=extended_dat[item])
        print(req.text)

######################################### DATA UPDATE  FINISHED ########################

provider_value_insert("provider1","sen1","sen2","sen3")  #### Provider 1

provider_value_insert("provider2","sen4","sen5","sen6")  ###  Provider 2

provider_value_insert("provider3","sen7","sen8","sen9")  ###  Provider 3


import pygame
import sys

# Initialize Pygame
pygame.init()

# Set up some constants
WIDTH, HEIGHT = 800, 600
BACKGROUND_SPEED = 2

# Create the screen
screen = pygame.display.set_mode((WIDTH, HEIGHT))

# Load the background image (add your image file path)
background = pygame.image.load("./img/dark-yellow2-road.png")

# This is to make sure the image fits in the screen. You can skip this if your image size matches the screen size
background = pygame.transform.scale(background, (WIDTH, HEIGHT))

# Initial position of the background
y = 0

# Game loop
running = True
while running:
    # Event loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # Move the background
    y += BACKGROUND_SPEED
    if y >= HEIGHT:
        y = 0

    # Draw the background twice to create the continuous scrolling effect
    screen.blit(background, (0, y))
    screen.blit(background, (0, y - HEIGHT))

    # Update the display
    pygame.display.flip()

# Quit Pygame
pygame.quit()
sys.exit()