import hax
import json
from hax.minitrees import TreeMaker
from pax import utils
from pax.configuration import load_configuration
from hax.treemakers.common import get_largest_indices
import numpy as np
from hax.corrections_handler import CorrectionsHandler

class Corrections(TreeMaker):
    """Applies high level corrections which are used in standard analyses.

    Provides:
    - Corrected S1 contains xyz-correction:
      - cs1: The corrected area of the main interaction's S1 using w/  correction of electric field effects
      - cs1_no_field_corr_nn_tf: The corrected S1 using w/o correction of electric field effects,
            using position from nn_tf
      - cs1_no_field_corr_nn: The corrected S1 using w/o correction of electric field effects,
            using position from nn
      - cs1_no_field_corr_tpf: The corrected S1 using w/o correction of electric field effects,
            using position from tpf
      - cs1_nn_tf: The corrected S1 using w/ correction of electric field effects,
            using position from nn_tf
      - cs1_nn: The corrected S1 using w/ correction of electric field effects,
            using position from nn
      - cs1_tpf: The corrected S1 using w/ correction of electric field effects,
            using position from tpf

    - Corrected S2 contains xy-correction and electron lifetime based on Kr83m trend:
      - cs2: The corrected area in pe of the main interaction's S2
      - cs2_top: The corrected area in pe of the main interaction's S2 from the top array.
      - cs2_bottom: The corrected area in pe of the main interaction's S2 from the bottom array.
      - cs2_nn_tf: The corrected area in pe of the main interaction's S2,
        using position from nn_tf
      - cs2_top_nn_tf: The corrected area in pe of the main interaction's S2 from the top array,
        using position from nn_tf
      - cs2_bottom_nn_tf: The corrected area in pe of the main interaction's S2 from the bottom array,
        using position from nn_tf
      - cs2_nn: The corrected area in pe of the main interaction's S2,
        using position from nn
      - cs2_top_nn: The corrected area in pe of the main interaction's S2 from the top array,
        using position from nn
      - cs2_bottom_nn: The corrected area in pe of the main interaction's S2 from the bottom array,
        using position from nn
      - cs2_tpf: The corrected area in pe of the main interaction's S2,
        using position from nn_tpf
      - cs2_top_tpf: The corrected area in pe of the main interaction's S2 from the top array,
        using position from nn_tpf
      - cs2_bottom_tpf: The corrected area in pe of the main interaction's S2 from the bottom array,
        using position from nn_tpf

    - Observed positions, not corrected with FDC maps, for both NN and TPF:
      - r_observed_tpf: the observed interaction r coordinate (using TPF).
      - x_observed_tpf: the observed interaction x coordinate (using TPF).
      - y_observed_tpf: the observed interaction y coordinate (using TPF).
      - r_observed_nn: the observed interaction r coordinate (using NN).
      - x_observed_nn: the observed interaction x coordinate (using NN).
      - y_observed_nn: the observed interaction y coordinate (using NN).
      - r_observed_nn_tf: the observed interaction r coordinate (using NN_TF).
      - x_observed_nn_tf: the observed interaction x coordinate (using NN_TF).
      - y_observed_nn_tf: the observed interaction y coordinate (using NN_TF).
      - z_observed: the observed interaction z coordinate (before the r, z correction).

    - Data-driven 3D position correction (applied to both NN and TPF observed positions):
      - r_3d_nn: the corrected interaction r coordinate (using NN).
      - x_3d_nn: the corrected interaction x coordinate (using NN).
      - y_3d_nn: the corrected interaction y coordinate (using NN).
      - z_3d_nn: the corrected interaction z coordinate (using NN).
      - r_3d_tpf: the corrected interaction r coordinate (using TPF).
      - x_3d_tpf: the corrected interaction x coordinate (using TPF).
      - y_3d_tpf: the corrected interaction y coordinate (using TPF).
      - z_3d_tpf: the corrected interaction z coordinate (using TPF).
      - r_3d_nn_tf: the corrected interaction r coordinate (using NN_TF).
      - x_3d_nn_tf: the corrected interaction x coordinate (using NN_TF).
      - y_3d_nn_tf: the corrected interaction y coordinate (using NN_TF).
      - z_3d_nn_tf: the corrected interaction z coordinate (using NN_TF).

    - Correction values for 'un-doing' single corrections:
      - s2_lifetime_correction
      - s2_xy_correction_tot_nn_tf
      - s2_xy_correction_top_nn_tf
      - s2_xy_correction_bottom_nn_tf
      - s2_xy_correction_tot_nn
      - s2_xy_correction_top_nn
      - s2_xy_correction_bottom_nn
      - s2_xy_correction_tot_tpf
      - s2_xy_correction_top_tpf
      - s2_xy_correction_bottom_tpf
      - r_correction_3d_nn_tf
      - r_correction_3d_nn
      - r_correction_3d_tpf
      - z_correction_3d_nn_tf
      - z_correction_3d_nn
      - z_correction_3d_tpf

    Notes:
    - The cs2, cs2_top and cs2_bottom variables are corrected
    for electron lifetime and x, y dependence.

    """
    __version__ = '2.5'
    extra_branches = ['peaks.area_per_channel[260]',
                      'peaks.n_saturated_per_channel[260]',
                      'peaks.s2_saturation_correction',
                      'interactions.s2_lifetime_correction',
                      'peaks.area_fraction_top',
                      'peaks.area',
                      'peaks.reconstructed_positions*',
                      'interactions.x',
                      'interactions.y',
                      'interactions.z',
                      'interactions.r_correction',
                      'interactions.z_correction',
                      'interactions.drift_time',
                      'start_time']

    def __init__(self):
        hax.minitrees.TreeMaker.__init__(self)
        self.extra_metadata = hax.config['corrections_definitions']
        self.corrections_handler = CorrectionsHandler()
        self.tfnn_posrec = tfnn_position_reconstruction()

    def extract_data(self, event):
        result = dict()

        # If there are no interactions cannot do anything
        if not len(event.interactions):
            return result

        # Workaround for blinding cut. S2 area and largest_other_s2 needed.
        interaction = event.interactions[0]
        s2 = event.peaks[interaction.s2]
        s1 = event.peaks[interaction.s1]
        largest_other_indices = get_largest_indices(
            event.peaks, exclude_indices=(interaction.s1, interaction.s2))
        largest_area_of_type = {ptype: event.peaks[i].area
                                for ptype, i in largest_other_indices.items()}
        result['largest_other_s2'] = largest_area_of_type.get('s2', 0)
        result['s2'] = s2.area

        # Need the observed ('uncorrected') position.
        # pax Interaction positions are corrected so lookup the
        # uncorrected positions in the ReconstructedPosition objects
        for rp in s2.reconstructed_positions:
            if rp.algorithm == 'PosRecNeuralNet':
                result['x_observed_nn'] = rp.x
                result['y_observed_nn'] = rp.y
                result['r_observed_nn'] = np.sqrt(rp.x ** 2 + rp.y ** 2)
            if rp.algorithm == 'PosRecTopPatternFit':
                result['x_observed_tpf'] = rp.x
                result['y_observed_tpf'] = rp.y
                result['r_observed_tpf'] = np.sqrt(rp.x ** 2 + rp.y ** 2)

        z_observed = interaction.z - interaction.z_correction
        result['z_observed'] = z_observed

        # Position reconstruction based on NN from TensorFlow
        # First Check for MC data, and avoid Tensor Flow if MC.
        if not self.mc_data:  # Temporary for OSG production
            # Calculate TF_NN reconstructed position
            predicted_xy_tensorflow = self.tfnn_posrec(list(s2.area_per_channel), self.run_number)

            result['x_observed_nn_tf'] = predicted_xy_tensorflow[0, 0] / 10.
            result['y_observed_nn_tf'] = predicted_xy_tensorflow[0, 1] / 10.
            result['r_observed_nn_tf'] =\
                np.sqrt(result['x_observed_nn_tf']**2 + result['y_observed_nn_tf']**2)

            # 3D FDC NN_TF
            algo = 'nn_tf'
            cvals = [result['x_observed_' + algo], result['y_observed_' + algo], z_observed]
            result['r_correction_3d_' + algo] = self.corrections_handler.get_correction_from_map(
                "fdc_3d_tfnn", self.run_number, cvals)

            result['r_3d_' + algo] = (result['r_observed_' + algo] +
                                      result['r_correction_3d_' + algo])
            result['x_3d_' + algo] = (result['x_observed_' + algo] *
                                      (result['r_3d_' + algo] / result['r_observed_' + algo]))
            result['y_3d_' + algo] = (result['y_observed_' + algo] *
                                      (result['r_3d_' + algo] / result['r_observed_' + algo]))

            if abs(z_observed) > abs(result['r_correction_3d_' + algo]):
                result['z_3d_' + algo] = -np.sqrt(z_observed ** 2 -
                                                  result['r_correction_3d_' + algo] ** 2)
            else:
                result['z_3d_' + algo] = z_observed

            result['z_correction_3d_' + algo] = result['z_3d_' + algo] - z_observed

        # Apply the 3D data driven NN_FDC, for NN positions and TPF positions
        for algo in ['nn', 'tpf']:
            cvals = [result['x_observed_' + algo], result['y_observed_' + algo], z_observed]
            result['r_correction_3d_' + algo] = self.corrections_handler.get_correction_from_map(
                "fdc_3d", self.run_number, cvals)

            result['r_3d_' + algo] = result['r_observed_' + algo] + result['r_correction_3d_' + algo]
            result['x_3d_' + algo] =\
                result['x_observed_' + algo] * (result['r_3d_' + algo] / result['r_observed_' + algo])
            result['y_3d_' + algo] =\
                result['y_observed_' + algo] * (result['r_3d_' + algo] / result['r_observed_' + algo])

            if abs(z_observed) > abs(result['r_correction_3d_' + algo]):
                result['z_3d_' + algo] = -np.sqrt(z_observed ** 2 -
                                                  result['r_correction_3d_' + algo] ** 2)
            else:
                result['z_3d_' + algo] = z_observed

            result['z_correction_3d_' + algo] = result['z_3d_' + algo] - z_observed

        # electron lifetime correction
        result['s2_lifetime_correction'] = (
            self.corrections_handler.get_electron_lifetime_correction(
                self.run_number, self.run_start, interaction.drift_time, self.mc_data))

        for algo in ['nn_tf', 'nn', 'tpf']:
            # Correct S2
            result['r_observed_' + algo] = \
                np.sqrt(result['x_observed_' + algo] ** 2 + result['y_observed_' + algo] ** 2)

            cvals = [result['x_observed_' + algo], result['y_observed_' + algo]]
            result['s2_xy_correction_tot_' + algo] = \
                (1.0 / self.corrections_handler.get_correction_from_map("s2_xy_map", self.run_number, cvals))
            result['s2_xy_correction_top_' + algo] = (1.0 /
                                                      self.corrections_handler.get_correction_from_map(
                                                          "s2_xy_map", self.run_number, cvals, map_name='map_top'))
            result['s2_xy_correction_bottom_' + algo] = (1.0 /
                                                         self.corrections_handler.get_correction_from_map(
                                                             "s2_xy_map", self.run_number,
                                                             cvals, map_name='map_bottom'))

            # Combine all the s2 corrections
            result['cs2_' + algo] = \
                s2.area * result['s2_lifetime_correction'] * result['s2_xy_correction_tot_' + algo]
            result['cs2_top_' + algo] = \
                s2.area * s2.area_fraction_top * \
                result['s2_lifetime_correction'] * result['s2_xy_correction_top_' + algo]
            result['cs2_bottom_' + algo] = \
                s2.area * (1.0 - s2.area_fraction_top) * \
                result['s2_lifetime_correction'] * result['s2_xy_correction_bottom_' + algo]

            # Correct S1
            cvals = [result['x_3d_' + algo], result['y_3d_' + algo], result['z_3d_' + algo]]
            result['s1_xyz_correction_fdc_3d_' + algo] = \
                (1 / self.corrections_handler.get_correction_from_map(
                    "s1_lce_map_nn_fdc_3d", self.run_number, cvals))
            result['cs1_no_field_corr_' + algo] = s1.area * result['s1_xyz_correction_fdc_3d_' + algo]

            # Apply corrected LCE (light collection efficiency correction to s1, including field effects)
            result['s1_xyz_true_correction_fdc_3d' + algo] = \
                (1 / self.corrections_handler.get_correction_from_map(
                    "s1_corrected_lce_map_nn_fdc_3d", self.run_number, cvals))
            result['cs1_' + algo] = s1.area * result['s1_xyz_true_correction_fdc_3d' + algo]

        # default cS1 and cS2 values
        default_algo = 'nn_tf'
        result['cs1'] = result['cs1_' + default_algo]
        result['cs2'] = result['cs2_' + default_algo]
        result['cs2_top'] = result['cs2_top_' + default_algo]
        result['cs2_bottom'] = result['cs2_bottom_' + default_algo]

        return result

class tfnn_position_reconstruction(object):
    """
    Class for loading and calculate tfnn position given area per channel
    """
    def __init__(self):
        self.corrections_handler = CorrectionsHandler()
        # We need to pull some stuff from the pax config
        self.pax_config = load_configuration("XENON1T")
        self.tpc_channels = self.pax_config['DEFAULT']['channels_in_detector']['tpc']
        self.top_channels = self.pax_config['DEFAULT']['channels_top']

        self.run_number = -1

    def __call__(self, per_channel_area, run_number):
        # per_channel_area as a list of channel area
        # OR as an array of shape (#peaks, #channels w/o bad pmt removal)
        # If we haven't loaded weights or it's another run reload nn
        if (('tfnn_weights' not in self.__dict__.keys()) or
                ('tfnn_model' not in self.__dict__.keys()) or
                (run_number != self.run_number)):
            self.load_nn(run_number)

        if isinstance(per_channel_area, list):
            per_channel_area = np.array([per_channel_area])

        # Take channel clean (top but not bad)
        per_channel_area = np.take(per_channel_area, self.clean_channels, axis=-1)
        # Divide by the sum area of each peak, preform transform due to np division law
        # Final transform due to nn predict input requires (none, #channels)
        per_channel_area = (per_channel_area.T / np.sum(per_channel_area, axis=-1)).T

        return self.loaded_nn.predict(per_channel_area)

    def load_nn(self, run_number):
        from keras.models import model_from_json

        self.tfnn_weights = self.corrections_handler.get_misc_correction(
            "tfnn_weights", run_number)
        self.tfnn_model = self.corrections_handler.get_misc_correction(
            "tfnn_model", run_number)
        self.run_number = run_number

        # Get tfnn bat pmt list from JSON file
        with open(utils.data_file_name(self.tfnn_model), 'r') as json_file_nn:
            loaded_model_json_dict = json.load(json_file_nn)
            self.list_bad_pmts = loaded_model_json_dict['badPMTList']

        self.clean_channels = list(set(self.top_channels).difference(self.list_bad_pmts))

        # Get tfnn model from JSON file
        with open(utils.data_file_name(self.tfnn_model), 'r') as json_file_nn:
            loaded_model_json = json_file_nn.read()
            self.loaded_nn = model_from_json(loaded_model_json)

        weights_file = utils.data_file_name(self.tfnn_weights)
        self.loaded_nn.load_weights(weights_file)


# import the time module
import time
from tkinter import *
from tkinter import messagebox
import pygame

# ---------------------------- CONSTANTS ------------------------------- #
PINK = "#e2979c"
RED = "#e7305b"
GREEN = "#9bdeac"
YELLOW = "#f7f5dd"
FONT_NAME = "Courier"
pygame.mixer.init()  # initialise the pygame

rest_timer = None

def time():
    timer = int(app_entry.get())

    timer = timer * 60
    countdown(timer)

def countdown(count):
    global rest_timer
    mins, secs = divmod(count, 60)
    canvas.itemconfig(timer_text, text='{:02d}:{:02d}'.format(mins, secs))
    if count > 0:
        print(count)
        rest_timer = window.after(1000, countdown, count - 1)
    else:
        pygame.mixer.music.load("sound.mp3")
        pygame.mixer.music.play(loops=2)

def rest_timer():
    window.after_cancel(rest_timer)
    canvas.itemconfig(timer_text, text="00:00")

window = Tk()
window.title("Timer")
window.config(padx=100, pady=50, bg=YELLOW)
canvas = Canvas(width=200, height=224, bg=YELLOW, highlightthickness=0)
tomato_img = PhotoImage(file="tomato - Copy.png")
timer_text = canvas.create_text(100, 128, text="00:00", fill="black", font=(FONT_NAME, 35, "bold"))
# app_entry = Entry(width=60)

app_entry = Spinbox(from_=1,
                    to=60, )
app_entry.focus()
app_entry.place(x=100, y=60)
start_button = Button(text="start", font=(FONT_NAME, 15, "bold"), command=time)
start_button.grid(column=1, row=4)
rest_button = Button(text="Rest", font=(FONT_NAME, 15, "bold"), command=rest_timer)
rest_button.grid(column=3, row=4)
canvas.grid(column=2, row=2)
apps_label = Label(text="Choose How many minutes to Shutdown", fg=GREEN, bg="white", font=("Ariel", 15, "italic"))
apps_label.place(x=0, y=20)

window.mainloop()


'''
note:
1, Query in the databse if we stored this user before
2.a, If not, we grab tweets from last 7 days as usual,
2.b, If so, we query the date of the last tweets we store.
    - if it is still within 7 days, we used it as the since_id
    - if it is beyond 7 days range, we go back to 2.a

side note:
1, Consider letting the server to grab Trump's tweets every 10 minutes
2, Front-end would by default set to Trump's tweets

'''

'''
Serious corner case: name changed and the database would meddle two different accounts together:
so => double check by ID
'''

import traceback
from db import db
from flask_restful import Resource, reqparse
from datetime import datetime, timedelta
from pytz import timezone

from models.user import UserModel
from models.target_search import SearchModel
from models.tweets import TweetModel

from resources.tweetify import Tweetify

class Target_Search(Resource):

    @classmethod
    def get(self, screen_name):
        # TODO check if user already in database and change endtime accordling
        time_now = datetime.now(tz = timezone("US/Eastern"))
        user = UserModel.find_by_screen_name(screen_name)
        try:
            within_a_week = timezone('US/Eastern').localize(user.lastCheckedTime).date() >= time_now.date() - timedelta(days = 6)
        except:
            within_a_week = False

        if user and within_a_week:
            end_date = user.lastCheckedTime
            since_id = user.lastTweetId
        else:
            end_date = time_now - (timedelta(days = 6))
            since_id = "-1"

        tweet_user = Tweetify(screen_name, end_date, since_id, time_now)

        data = {
            "userId" :tweet_user.user_id,
            "screenName" : screen_name,
            "timestamp" : time_now,
        }

        result = tweet_user.result;

        # Not user by this screen_name
        if result["error"]:
            data["isSuccess"] = False
            data["statusCount"] = 0
            search = SearchModel(**data)
            search.save_to_db()
            return {"search_info":search.json(),"error":result["error"]}, 404

        # Save to user db
        user_data = result["user"][0]

        if user:
            user.name = user_data["name"]
            user.insensitive_name = user_data["insensitiveName"]
            user.description = user_data["description"]
            user.followers = user_data["followers"]
            user.friends = user_data["friends"]
            user.statusCount = user_data["statusCount"]
            user.favCount = user_data["favCount"]
            user.location = user_data["location"]
            user.isVerified = user_data["isVerified"]
            user.avatarUrl = user_data["avatarUrl"]
            user.bannerUrl = user_data["bannerUrl"]
            user.lastTweetId = user_data["lastTweetId"]
            user.lastCheckedTime = user_data["lastCheckedTime"]
            user.webUrl = user_data["webUrl"]
            user.tweets_onfile += len(result["tweets"])
            user.save_to_db()

        else:
            new_user = UserModel(tweets_onfile = len(result["tweets"]), **user_data)
            new_user.save_to_db()

        # TODO Save to tweets db
        tweets = result["tweets"]

        for t in tweets:
            tweet_data = {
                "id" : t.id_str,
                "created_at" : t.created_at,
                "user_id" : tweet_user.user_id,
                "user_screen_name" : t.author.screen_name,
                "full_text" : t.full_text,
                "is_quote_status" : t.is_quote_status,
                "rt_count" : t.retweet_count,
                "fv_count" : t.favorite_count,
            }
            try:
                tweet_data["retweeted_statsus_id"] = t.retweeted_status.id
                tweet_data["is_retweeted"] = True
                tweet_data["fv_count"] = t.retweeted_status.favorite_count
            except:
                tweet_data["is_retweeted"] = False;
                tweet_data["retweeted_statsus_id"] = None

            new_tweet = TweetModel(**tweet_data)
            new_tweet.save_to_db()

        # Save to DB & return flag to front-end
        data["isSuccess"] = True
        data["statusCount"] = len(tweets)
        search = SearchModel(**data)
        search.save_to_db()

        return {"search_info":search.json()},  200

class Update_Search(Resource):
    parser = reqparse.RequestParser()
    parser.add_argument('user_id', type=str, required=True, help="User id needed")
    parser.add_argument('since_id', type=str, required=True, help="Since id needed")

    @classmethod
    def post(self):
        data = self.parser.parse_args()
        if not data['user_id']:
                return {'message' : 'User ID cannot be blank.'}, 400

        if not data['since_id']:
                return {'message' : 'Since ID cannot be blank.'}, 400

        id = int(data['user_id'])
        since_id = int(data['since_id']) - 1
        time_now = datetime.now(tz = timezone("US/Eastern"))
        user = UserModel.find_by_user_id(id)

        within_five = not user.lastUpdatedTime or timezone('US/Eastern').localize(user.lastUpdatedTime) >= time_now - timedelta(minutes = 1)

        if within_five:
            return {'message' : 'Already updated in the last five minutes'}, 200
        else:
            user.lastUpdatedTime = time_now
            user.save_to_db()

        new_tweets = Tweetify.update_list(id, since_id)
        pre_tweets = TweetModel.find_tweets_before(id, since_id)

        try:
            #print('length is {}'.format(len(new_tweets)))
            for t in pre_tweets:

                if not new_tweets:
                    break

                t_id = t.id
                '''
                setattr(t, "rt_count", new_tweets[t_id]['rt'])
                setattr(t, "fv_count", new_tweets[t_id]['fav'])
                '''
                #print('before, {} rt is {}, fv is {}'.format(t.id, t.rt_count, t.fv_count))
                t.rt_count = new_tweets[t_id]['rt']
                t.fv_count = new_tweets[t_id]['fav']
                #print('after, {} rt is {}, fv is {}'.format(t.id, t.rt_count, t.fv_count))
                t.save_to_db()

            message = "updated {} tweets.".format(pre_tweets.count());
            return {'message': message}, 200
        except:
            traceback.print_exc()
            return {'message': 'update failed'}, 500


import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from math import sqrt
from random import randint
import pygame
from pygame.locals import QUIT, KEYUP, KEYDOWN, K_LEFT, K_RIGHT, K_DOWN, K_SPACE, K_UP, K_z, K_RETURN
from util.getloc import *
from util.getloc2 import getloc2
from Pang import *
from screen.screen3 import *
from screen.playerOne_over import *
from screen.screen4 import *
from screen.screen_key import *

BLOCK_DATA = (
    (
        (0, 0, 8,
         8, 8, 8,
         0, 0, 0),
        (0, 8, 0,
         0, 8, 0,
         0, 8, 8),
        (0, 0, 0,
         8, 8, 8,
         8, 0, 0),
        (8, 8, 0,
         0, 8, 0,
         0, 8, 0),
    ), (
        (9, 0, 0,
         9, 9, 9,
         0, 0, 0),
        (0, 9, 9,
         0, 9, 0,
         0, 9, 0),
        (0, 0, 0,
         9, 9, 9,
         0, 0, 9),
        (0, 9, 0,
         0, 9, 0,
         9, 9, 0)
    ), (
        (0, 3, 0,
         3, 3, 3,
         0, 0, 0),
        (0, 3, 0,
         0, 3, 3,
         0, 3, 0),
        (0, 0, 0,
         3, 3, 3,
         0, 3, 0),
        (0, 3, 0,
         3, 3, 0,
         0, 3, 0)
    ), (
        (4, 4, 0,
         0, 4, 4,
         0, 0, 0),
        (0, 0, 4,
         0, 4, 4,
         0, 4, 0),
        (0, 0, 0,
         4, 4, 0,
         0, 4, 4),
        (0, 4, 0,
         4, 4, 0,
         4, 0, 0)
    ), (
        (0, 5, 5,
         5, 5, 0,
         0, 0, 0),
        (0, 5, 0,
         0, 5, 5,
         0, 0, 5),
        (0, 0, 0,
         0, 5, 5,
         5, 5, 0),
        (5, 0, 0,
         5, 5, 0,
         0, 5, 0)
    ), (
        (6, 6, 6, 6),
        (6, 6, 6, 6),
        (6, 6, 6, 6),
        (6, 6, 6, 6)
    ), (
        (0, 7, 0, 0,
         0, 7, 0, 0,
         0, 7, 0, 0,
         0, 7, 0, 0),
        (0, 0, 0, 0,
         7, 7, 7, 7,
         0, 0, 0, 0,
         0, 0, 0, 0),
        (0, 0, 7, 0,
         0, 0, 7, 0,
         0, 0, 7, 0,
         0, 0, 7, 0),
        (0, 0, 0, 0,
         0, 0, 0, 0,
         7, 7, 7, 7,
         0, 0, 0, 0)
    )
)

class Block:
    """ 블록 객체 """

    def __init__(self, count):
        self.turn = 0  # 시간표 모양을 보여주기 위해서 초기 turn 값은 0으로 고정
        #self.turn = randint(0, 3)
        self.type = BLOCK_DATA[randint(0, len(BLOCK_DATA)-1)]
        #self.type = BLOCK_DATA[1]
        self.data = self.type[self.turn]
        self.size = int(sqrt(len(self.data)))
        self.xpos = 2
        self.ypos = 1 - self.size + 4  # 필드에서 벗어나지 않도록 시작 위치를 아래로 내림
        self.fire = count + INTERVAL

    def update(self, count):
        """ 블록 상태 갱신 (소거한 단의 수를 반환한다) """
        # 아래로 총돌?
        erased = 0
        if is_overlapped(self.xpos, self.ypos + 1, self.turn):
            for y_offset in range(BLOCK.size):
                for x_offset in range(BLOCK.size):
                    if 0 <= self.xpos+x_offset < WIDTH and 0 <= self.ypos+y_offset < HEIGHT:
                        val = BLOCK.data[y_offset*BLOCK.size + x_offset]
                        if val != 0:
                            FIELD[self.ypos+y_offset][self.xpos+x_offset] = val
            erased = erase_line()
            go_next_block(count)

        if self.fire < count:
            self.fire = count + INTERVAL
            self.ypos += 1
        return erased

    def draw(self):
        """ 블록을 그린다 """
        for index in range(len(self.data)):
            xpos = index % self.size
            ypos = index // self.size
            val = self.data[index]
            if 0 <= ypos + self.ypos < HEIGHT and 0 <= xpos + self.xpos < WIDTH and val != 0:
                x_pos = BLOCK_SIZE + (xpos + self.xpos) * BLOCK_SIZE
                y_pos = BLOCK_SIZE + (ypos + self.ypos) * BLOCK_SIZE
                pygame.draw.rect(SURFACE, COLORS[val],
                                 (x_pos, y_pos, BLOCK_SIZE-1, BLOCK_SIZE-1))

def erase_line():
    """ 행이 모두 찬 단을 지운다 """
    erased = 0
    ypos = HEIGHT-2
    while ypos >= 0:
        if all(FIELD[ypos]):
            erased += 1
            del FIELD[ypos]
            FIELD.insert(0, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
        else:
            ypos -= 1
    return erased

def is_game_over():
    """ 게임 오버인지 아닌지 """
    game_over = False
    for i in range(0, 3):
        filled = 0
        for cell in FIELD[i]:
            if cell != 0:
                filled += 1
        if filled > 2:  # 2 = 좌우의 벽
            game_over = True

    return game_over

def go_next_block(count):
    """ 다음 블록으로 전환한다 """
    global BLOCK, NEXT_BLOCK
    BLOCK = NEXT_BLOCK if NEXT_BLOCK != None else Block(count)
    NEXT_BLOCK = Block(count)

def is_overlapped(xpos, ypos, turn):
    """ 블록이 벽이나 땅의 블록과 충돌하는지 아닌지 """
    data = BLOCK.type[turn]
    for y_offset in range(BLOCK.size):
        for x_offset in range(BLOCK.size):
            if 0 <= xpos+x_offset < WIDTH and 0 <= ypos+y_offset < HEIGHT:
                if data[y_offset*BLOCK.size + x_offset] != 0 and FIELD[ypos+y_offset][xpos+x_offset] != 0:
                    return True
    return False

# 전역 변수

WIDTH = 12
HEIGHT = 32
INTERVAL = 160
FIELD = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]
COLORS = ((0, 0, 0), (128, 128, 128), (205, 116, 102), (204, 168, 92), (76, 62, 34),
          (255, 165, 0), (0, 0, 255), (0, 255, 255), (0, 255, 0), (255, 0, 255),
          (69, 36, 59), (231, 255, 0), (2, 208, 178), (57, 16, 81), (6, 38, 22),
          (161, 217, 126), (254, 198, 103), (255,
                                             113, 103), (162, 151, 1), (200, 120, 183),
          (164, 75, 0), (189, 217, 158), (254, 190,
                                          240), (102, 173, 255), (249, 246, 113),
          (255, 174, 207), (5, 26, 100), (0, 111,
                                          53), (171, 228, 213), (124, 154, 126),
          (167, 202, 109), (137, 116, 193), (106, 142,
                                             202), (110, 180, 166), (255, 178, 126),
          (255, 0, 0))
BLOCK = None
BLOCK_SIZE = 20
NEXT_BLOCK = None
cur_lecture = []
game_over_count = 0

def tetris_game(cur_lecture, porc: int, info=None):
    # porc = 개인인지 경쟁인디 모드 알려주는 변수
    SURFACE = pygame.display.set_mode([600, 800])
    pygame.init()
    pygame.key.set_repeat(120, 120)
    SURFACE = pygame.display.set_mode([600, 800])
    FPSCLOCK = pygame.time.Clock()
    k_font = pygame.font.SysFont('malgungothic', 20)
    """ 메인 루틴 """
    global INTERVAL
    count = 0
    score = 0
    game_over = False
    smallfont = pygame.font.SysFont(None, 36)
    largefont = pygame.font.SysFont(None, 72)
    message_over = largefont.render("GAME OVER!!",
                                    True, (0, 255, 225))
    message_rect = message_over.get_rect()
    message_rect.center = (300, 300)

    bgm = pygame.mixer.Sound(adress + "배경음악.wav")
    #effect_sount = pygame.mixer.Sound("효과음.wav")

    go_next_block(INTERVAL)

    for ypos in range(HEIGHT):
        for xpos in range(WIDTH):
            FIELD[ypos][xpos] = 1 if xpos == 0 or xpos == WIDTH - 1 else 0
    for index in range(WIDTH):
        FIELD[HEIGHT-1][index] = 1

    while True:
        bgm.play(-1)  # 배경음악
        key = None
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                key = event.key

        game_over = is_game_over()
        if not game_over:
            count += 5
            if count % 1000 == 0:
                INTERVAL = max(1, INTERVAL - 2)
            erased = BLOCK.update(count)

            if erased > 0:
                score += (2 ** erased) * 100

            # 키 이벤트 처리
            next_x, next_y, next_t = BLOCK.xpos, BLOCK.ypos, BLOCK.turn
            if key == K_UP:
                next_t = (next_t + 1) % 4
            elif key == K_z:
                next_t = (next_t - 1) % 4
            elif key == K_RIGHT:
                next_x += 1
            elif key == K_LEFT:
                next_x -= 1
            elif key == K_DOWN:
                next_y += 1

            if not is_overlapped(next_x, next_y, next_t):
                BLOCK.xpos = next_x
                BLOCK.ypos = next_y
                BLOCK.turn = next_t
                BLOCK.data = BLOCK.type[BLOCK.turn]

        # 전체&낙하 중인 블록 그리기
        SURFACE.fill((0, 0, 0))
        for ypos in range(HEIGHT):
            for xpos in range(WIDTH):
                val = FIELD[ypos][xpos]
                pygame.draw.rect(SURFACE, COLORS[val],
                                 (xpos*BLOCK_SIZE + BLOCK_SIZE, ypos*BLOCK_SIZE + BLOCK_SIZE, BLOCK_SIZE-1, BLOCK_SIZE-1))
        BLOCK.draw()

        temp = 0
        # 다음 블록 그리기
        for ypos in range(NEXT_BLOCK.size):
            for xpos in range(NEXT_BLOCK.size):
                val = NEXT_BLOCK.data[xpos + ypos*NEXT_BLOCK.size]
                temp = max(temp, val)
                pygame.draw.rect(SURFACE, COLORS[val], (
                    xpos*BLOCK_SIZE + 460, ypos*BLOCK_SIZE + BLOCK_SIZE*4, BLOCK_SIZE-1, BLOCK_SIZE-1))

        # 점수 나타내기
        score_str = str(score).zfill(6)

        score_image = smallfont.render(score_str, True, (0, 255, 0))
        SURFACE.blit(score_image, (500, 30))

        lec_name_str = str("강의명 : " + cur_lecture[temp - 3].name)
        lec_name_image = k_font.render(lec_name_str, True, (0, 255, 0))

        lec_professor_str = str(
            "교수명 : " + cur_lecture[temp - 3].professor + " 교수님")
        lec_professor_image = k_font.render(
            lec_professor_str, True, (0, 255, 0))

        SURFACE.blit(lec_name_image, (325, 300))
        SURFACE.blit(lec_professor_image, (325, 360))

        if game_over:
            global game_over_count
            if game_over_count < 2:
                game_over_count += 1
            SURFACE.blit(message_over, message_rect)
            bgm.stop()
            if game_over_count == 2:
                # 개인 모드 일 때는 점수만 보여주기
                if (porc == 0):
                    if key == K_RETURN:
                        # playerOne_over에서 가져오기
                        pygame.display.set_mode([1250, 700])
                        pygame.init()
                        gameOver_screen(score)

            if game_over_count == 2:
                # 경쟁 모드 일 때는 랭킹창
                if (porc == 1):
                    if key == K_RETURN:
                        pygame.display.set_mode([1250, 700])
                        pygame.init()
                        nick_screen(score, info)

        pygame.display.update()

        # 게임 속도 조절 및 중복 입력 방지
        FPSCLOCK.tick(60)

def game_personal(cur_lecture):
    # 개인모드
    global BLOCK_DATA
    # get_block_personal(id, pw, table_id) 이 부분에 UI에서 받아온 값을 넣어야함. table_id = 0~3
    cur_lecture, _BLOCK_DATA = get_blocks_personal(cur_lecture)
    BLOCK_DATA = _BLOCK_DATA

    BLOCK_DATA.append((
        (0, 0, 0,
         2, 2, 0,
         0, 0, 0),
        (0, 2, 0,
         0, 2, 0,
         0, 0, 0),
        (0, 0, 0,
         0, 2, 2,
         0, 0, 0),
        (0, 0, 0,
         0, 2, 0,
         0, 2, 0),
    ))
    bonus = Lecture("BONUS", "BONUS")
    cur_lecture.append(bonus)

    BLOCK_DATA.append((
        (0, 0, 0,
         0, 2, 0,
         0, 0, 0),
        (0, 0, 0,
         0, 2, 0,
         0, 0, 0),
        (0, 0, 0,
         0, 2, 0,
         0, 0, 0),
        (0, 0, 0,
         0, 2, 0,
         0, 0, 0),
    ))
    bonus = Lecture("BONUS", "BONUS")
    cur_lecture.append(bonus)

    # 보너스 조각 넣는건 cur_lecture 때문에 어려움
    tetris_game(cur_lecture, 0)

def game_competition(info=1):
    # 경쟁모드
    # get_blocks_competition(id) 에서 id에 UI에서 받아온 값을 넣어야함. 1~4임
    global BLOCK_DATA
    cur_lecture, _BLOCK_DATA = get_blocks_competition(info)
    print(_BLOCK_DATA)
    BLOCK_DATA = _BLOCK_DATA
    for i in range(0, 3):
        BLOCK_DATA.append((
            (0, 0, 0,
             2, 2, 0,
             0, 0, 0),
            (0, 2, 0,
             0, 2, 0,
             0, 0, 0),
            (0, 0, 0,
             0, 2, 2,
             0, 0, 0),
            (0, 0, 0,
             0, 2, 0,
             0, 2, 0),
        ))
        bonus = Lecture("BONUS", "BONUS")
        cur_lecture.append(bonus)

    for i in range(0, 3):
        BLOCK_DATA.append((
            (0, 0, 0,
             0, 2, 0,
             0, 0, 0),
            (0, 0, 0,
             0, 2, 0,
             0, 0, 0),
            (0, 0, 0,
             0, 2, 0,
             0, 0, 0),
            (0, 0, 0,
             0, 2, 0,
             0, 0, 0),
        ))
        bonus = Lecture("BONUS", "BONUS")
        cur_lecture.append(bonus)

    tetris_game(cur_lecture, 1, info)

if __name__ == '__main__':
    # 강의 정보 불러오기
    tetris_game(get_blocks_competition(1)[0], 1)
    print()


import numpy as np
from scipy import signal
import eventlet
from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins='http://localhost:5173')

print('Server listening on port 5001...')

def preprocess_audio(audio_data):
    # Apply a moving average filter to reduce noise
    window_size = 7
    filtered_data = signal.convolve(audio_data, np.ones(window_size) / window_size, mode='same')

    return filtered_data

def estimate_pitch(audio_data, sample_rate):
    preprocessed_data = preprocess_audio(audio_data)

    # Normalize the preprocessed audio data
    preprocessed_data = preprocessed_data / np.max(np.abs(preprocessed_data))

    # Compute the autocorrelation of the audio signal
    autocorr = np.correlate(preprocessed_data, preprocessed_data, mode='full')

    # Keep only the positive part of the autocorrelation
    autocorr = autocorr[len(autocorr)//2:]

    # Find the first peak in the autocorrelation (excluding the first sample)
    peak_index = signal.argrelmax(autocorr, order=1)[0][0]

    # Convert the peak index to a frequency (in Hz)
    frequency = sample_rate / peak_index

    return frequency

threshold_db = -30  # Adjust the threshold level as per your requirements

def calculate_db(audio_data):
    rms = np.sqrt(np.mean(np.square(audio_data)))
    db = 20 * np.log10(rms)
    return db

consecutive_hits_threshold = 2  # Adjust the threshold for consecutive hits as per your requirements
consecutive_misses_threshold = 10  # Adjust the threshold for consecutive misses as per your requirements

consecutive_hits = 0
consecutive_misses = 0

@socketio.on('connect')
def connect():
    print('Client connected.')

@socketio.on('audioData')
def audio_data(data):
    global consecutive_hits, consecutive_misses
    audio_data = np.frombuffer(data['data'], dtype=np.float32)
    sample_rate = 44100

    frequency = estimate_pitch(audio_data, sample_rate)

    if 875 <= frequency <= 1000 and calculate_db(audio_data) >= threshold_db:
        consecutive_hits += 1

        if consecutive_hits >= consecutive_hits_threshold and consecutive_misses >= consecutive_misses_threshold:
            consecutive_hits = 0
            consecutive_misses = 0
            socketio.emit('message', 'HIT')
        # else:
        #     socketio.emit('message', 'miss')
    else:
        consecutive_hits = 0
        consecutive_misses += 1
        # socketio.emit('message', 'miss')

    # use miss messages to fine tune audio analysis.

@socketio.on('disconnect')
def disconnect():
    global consecutive_hits, consecutive_misses
    print('Client disconnected.')

if __name__ == '__main__':
    eventlet.wsgi.server(eventlet.listen(('0.0.0.0', 5001)), app)


import pandas as pd
import psycopg2
import streamlit as st
from PIL import Image
from nutrients import search_nutrients
from ingredients import search_ingredients
from zori_method import search_cook
from basket import basket
from name import search_name
from information import information

### 조, 조원 이름 추가

if 'choice_name' not in st.session_state:
    st.session_state['choice_name'] = []

if 'choice_kcal' not in st.session_state:
    st.session_state['choice_kcal'] = []

st.set_page_config(layout='wide', page_title = "FOODPIA",page_icon = ":shark:")
st.markdown('
FOODPIA
',unsafe_allow_html = True)
st.markdown('
Food Recommendation System
', unsafe_allow_html=True)
st.markdown('
Jiheon Seok
',unsafe_allow_html = True)
st.markdown('
Sojeong Yeon
',unsafe_allow_html = True)
st.markdown('
Yein Hwang
',unsafe_allow_html = True)
st.markdown('
Sungeun Byun
',unsafe_allow_html = True)
st.markdown('
Yoonseok Lee
',unsafe_allow_html = True)

search_option = st.selectbox(
        "Select how do you search or what you want",
        ('Search', 'Name', 'Nutrients', 'Cook', 'Ingredients','Basket', 'Add_Information')
    )

if search_option=='Nutrients':
    search_nutrients()

elif search_option=='Name':
    search_name()

elif search_option=='Cook':
    search_cook()

elif search_option=='Ingredients':
    search_ingredients()

elif search_option=='Basket':
    basket()

elif search_option=='Add_Information':
    information()

image = Image.open('food.jpg')
st.image(image)


import pandas as pd
from IPython.display import display
pd.set_option("display.max_row", None)
df = pd.read_csv(
    "/home/hanzala/Development/Python_the_ultimate_course_2023/22. Pandas and Tabular Data Processing/datafarm_basics.csv")

# to display the correct results we use display on datraframes not print because it give us the
# crroupt dataframe.....
# print(df)
print("\n================================")
display(df)

print("\n================================")

print("Results after Date Filtering:")

print("================================")

df['Date'] = pd.to_datetime(df['Date'])
date_1 = pd.to_datetime('1/1/2020')
date_2 = pd.to_datetime('30/12/2020')

filterDate = df[df.Date.between(date_1, date_2)]

display(filterDate)

22. Pandas and Tabular Data Processing/10_DateFilterFinal.py


import os
import sys
import random
import w2lib
from copy import deepcopy
PROG_NAME = os.path.splitext(sys.argv[0])[0]
DATASET_DIR = os.path.join(os.getcwd(), "datasets/{}".format(PROG_NAME))

def eulerPath(adjacency_dict) :
    if len(adjacency_dict) == 0 : return

    adj_dict_values = [v for val in list(adjacency_dict.values()) for v in val]
    adj_dict_keys = list(adjacency_dict.keys())
    end_node = ""
    start_node = ""

    # Search for start and end node for the path (unbalanced node)
    for k, v in adjacency_dict.items() :
        outdegree = len(v)
        indegree = adj_dict_values.count(k)

        # If odd degree, it's either start or end node
        if (indegree + outdegree) % 2 != 0 :
            if outdegree < indegree :
                # end node
                end_node = k
            else :
                start_node = k

    if end_node == "" :
        for node in list(set(adj_dict_values)) :
            if node not in adj_dict_keys :
                end_node = node
                break

    # Create edge from end_node -> start_node which will create
    # euler_cycle, which then we can just run euler_cycle to find
    # the euler_path.
    if end_node in adjacency_dict.keys() :
        adjacency_dict[end_node].append(start_node)
    else :
        adjacency_dict[end_node] = [start_node]

    # Create dictionary to track down edges
    edge_tracker = {}
    nodes = list(adjacency_dict.keys())
    for node in nodes :
        edge_tracker[node] = len(adjacency_dict[node])

    curr_path = []
    path = []

    curr_node = start_node
    curr_path.append(curr_node)

    while len(curr_path) :
        if edge_tracker[curr_node] :
            # If there's still outgoing edge
            curr_path.append(curr_node)

            # Choose next node
            next_node = random.choice(adjacency_dict[curr_node])

            # Remove visited edge
            edge_tracker[curr_node] -= 1
            adjacency_dict[curr_node].remove(next_node)

            curr_node = next_node

        else :
            path.append(curr_node)

            # back tracking
            curr_node = curr_path[-1]
            curr_path.pop()

    end_node_idx = path.index(end_node)

    # Need to reorganize the path
    path = path[end_node_idx:] + path[1:end_node_idx]

    return path[::-1]

def main() :
    util = w2lib.Week2Library()
    description = '''\
        Given adjacency list, it will reconstruct and output the Eulerian path.

        Input File format :
        ---------------------------------------
        0 -> 2
        1 -> 3
        2 -> 1
        3 -> 0,4
        6 -> 3,7
        7 -> 8
        8 -> 9
        9 -> 6

        Expected output :
        ---------------------------------------
        6->7->8->9->6->3->0->2->1->3->4
        '''
    args = util.create_parser(__file__, description)

    dataset_path = "{}/real_dataset.txt".format(DATASET_DIR)

    # Default to the dataset folder, if not provided
    if not args.file : args.file = dataset_path

    adjacency_dict = {}

    # Read from dataset file
    with open(args.file, 'r') as f :
        rows = f.readlines()

    for row in rows :
        row = row.replace(" ", "").strip().split("->")
        adjacency_dict[row[0]] = [r for r in row[1].split(",")]

    path = eulerPath(adjacency_dict)
    print("->".join(path))

if __name__ == "__main__":
    main()


from heapq import *
from collections import defaultdict

"""
    1st: sort + hashtable
    - put every number counter
    - sort the array
    - for each unused number, try to see if we can form a sequence(in length of K)

    Time    O(NlogN + NK)
    Space   O(N)
    612 ms, faster than 12.45%
"""

class Solution(object):
    def isPossibleDivide(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        nums.sort()
        counter = Counter(nums)
        for i in range(len(nums)):
            x = nums[i]
            if x not in counter:
                continue
            seq = [x]
            cur = x
            counter[cur] -= 1
            if counter[cur] == 0:
                del counter[cur]
            while cur+1 in counter and len(seq) < k:
                cur += 1
                seq.append(cur)
                counter[cur] -= 1
                if counter[cur] == 0:
                    del counter[cur]
            if len(seq) != k:
                return False
        return True

"""
    2nd: min heap
    - exactly the same as lc846
    - sort the array
    - keep adding a current item into a list from the heap if list[0] + 1 == current
    - if a list is of length k, put that into a cache
    - the overall items in the cache should be N

    corner case: nums = [1,2,3], k = 1

    Time    O(NlogN + NlogK)
    Space   O(N)
    496 ms, faster than 21.89%
"""

class Solution:
    def isPossibleDivide(self, nums: List[int], k: int) -> bool:
        nums.sort()
        minheap = []
        res = []
        for x in nums:
            if len(minheap) > 0 and minheap[0][0] + 1 == x and len(minheap[0][1]) < k:
                head, arr = heappop(minheap)
                arr.append(x)
                if len(arr) == k:
                    res.append(arr)
                else:
                    heappush(minheap, (x, arr))
            else:
                if k == 1:
                    res.append([x])
                else:
                    heappush(minheap, (x, [x]))
        return len(minheap) == 0


"""

Peptide

All API information related to Peptide samples

"""

# Flask
from flask import Blueprint, redirect, request

# Flask WTF
from wtforms import IntegerField, StringField

# Local Imports
from .. import (
    SampleForm,
    all_samples_page,
    build_sample_copy_form,
    build_sample_edit_form,
    build_sample_form,
    build_sample_form_in_pos,
    delete_sample,
    sample_create
)
from ...model.sample import Peptide

PEPTIDE = Blueprint(
    'peptide',
    __name__,
    template_folder='templates'
)

PEPTIDE_CUSTOM_VARIABLES = [
    'cell_type',
    'vial_source',
    'batch_number',
    'lot_number'
]

class PeptideForm(SampleForm):
    '''Form for handling Peptide data'''

    cell_type = StringField('Cell Type')
    vial_source = StringField('Vial Source')
    batch_number = StringField('Batch Number')
    lot_number = StringField('Lot Number')

@PEPTIDE.route('/', methods=['POST'])
def create():
    """Insert a single dataset into the SQLite database"""

    return sample_create(request, Peptide, PEPTIDE_CUSTOM_VARIABLES)

@PEPTIDE.route('/', methods=['GET'])
def read_all():
    """Placeholder for retrieving Peptide data from the SQLite database"""

    return all_samples_page('peptide', Peptide, PeptideForm)

@PEPTIDE.route('/create/', methods=['GET'])
def create_peptide():
    """Provide the HTML form for peptide creation"""

    sample_title = 'Add Peptide'
    return build_sample_form(sample_title, 'peptide', PeptideForm)

@PEPTIDE.route('/create/<box_id>/<pos>', methods=['GET'])
def create_peptide_in_pos(box_id, pos):
    """Provide the HTML form for peptide creation"""
    sample_title = 'Add Peptide'

    return build_sample_form_in_pos(sample_title, 'peptide', PeptideForm, box_id, pos)

@PEPTIDE.route('/edit/<peptide_id>', methods=['GET'])
def edit_peptide_form(peptide_id):
    """Provide the HTML form for Peptide creation"""

    sample_title = 'Edit Peptide'
    return build_sample_edit_form(
        sample_title,
        peptide_id,
        'peptide',
        PeptideForm,
        Peptide,
        PEPTIDE_CUSTOM_VARIABLES
    )

@PEPTIDE.route('/copy/<peptide_id>', methods=['GET'])
def copy_peptide_form(peptide_id):
    """Provide the HTML form for Peptide copy"""

    sample_title = 'Copy Sample: Peptide'
    return build_sample_copy_form(
        sample_title,
        peptide_id,
        'peptide',
        PeptideForm,
        Peptide,
        PEPTIDE_CUSTOM_VARIABLES
    )

@PEPTIDE.route('/delete/<peptide_id>', methods=['GET'])
def delete_peptide_form(peptide_id):
    """Delete a Peptide item using ID"""

    delete_sample(Peptide, peptide_id)

    return redirect(request.referrer)


# -*- coding: utf-8 -*-
"""
Created on Wed May 25 14:54:47 2016
@author: Kostya S, nms code from: http://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/ and
    https://github.com/layumi/2015_Face_Detection/blob/master/nms.m
"""

import scipy as sp
import itertools
import os
from fnmatch import fnmatch

class Util():
    k_max = 48

    sn = (0.83, 0.91, 1.0, 1.10, 1.21)
    xn = (-0.17, 0.0, 0.17)
    yn = (-0.17, 0.0, 0.17)
    prod = sp.array([e for e in itertools.product(sn,xn,yn)])

    @staticmethod
    def load_from_npz(data_name):
        with sp.load(data_name) as f:
            values = [f['arr_%d' % i] for i in range(len(f.files))][0]
            return values

    @staticmethod
    def get_files(rootdir = '',fexpr = ''):
        paths = []
        for path, subdirs, files in os.walk(rootdir):
            for indx,fname in enumerate(files):
                if fexpr == None or fexpr == '' or fnmatch(fname, fexpr):
                    paths.append(os.path.join(path, fname))
        return paths

    @staticmethod
    def get_splited_files(paths,batch_size = 2):
        splited_files = paths
        N = max(1,batch_size)
        for item in [splited_files[i:i + N] for i in range(0, len(splited_files), N)]:
            labels = [0 if e.find('neg') > 0 else 1 for e in item]
            yield item,labels

    @staticmethod
    def calib (i,j,h,w,n):
        prod = Util.prod
        new_i = round(i-(prod[n][1]*w/prod[n][0]))
        new_j = round(j-(prod[n][2]*h/prod[n][0]))
        new_h = round(h/prod[n][0])
        new_w = round(w/prod[n][0])
        return (new_i,new_j,new_h,new_w)

    @staticmethod
    def calib_apply(i,j,h,w,sn,xn,yn):

        new_i = round(i-(xn*w/sn))
        new_j = round(j-(yn*h/sn))
        new_h = round(h/sn)
        new_w = round(w/sn)
        return (new_i,new_j,new_h,new_w)

    @staticmethod
    def inv_calib (i,j,h,w,n):
        prod = Util.prod
        new_i = round(i-(-prod[n][1]*w/(prod[n][0]**-1)))
        new_j = round(j-(-prod[n][2]*h/(prod[n][0]**-1)))
        new_h = round(h/prod[n][0]**-1)
        new_w = round(w/prod[n][0]**-1)
        return (new_i,new_j,new_h,new_w)

    @staticmethod
    def nms(dets,proba, T):

        dets = dets.astype("float")
        if len(dets) == 0:
            return []

        x1 = dets[:, 0]
        y1 = dets[:, 1]
        x2 = dets[:, 2]
        y2 = dets[:, 3]
        scores = proba

        areas = (x2 - x1 + 1) * (y2 - y1 + 1)
        order = scores.argsort()[::-1]

        keep = []
        while order.size > 0:
            i = order[0]
            keep.append(i)
            xx1 = sp.maximum(x1[i], x1[order[1:]])
            yy1 = sp.maximum(y1[i], y1[order[1:]])
            xx2 = sp.minimum(x2[i], x2[order[1:]])
            yy2 = sp.minimum(y2[i], y2[order[1:]])

            w = sp.maximum(0.0, xx2 - xx1 + 1)
            h = sp.maximum(0.0, yy2 - yy1 + 1)
            inter = w * h
            ovr = inter / (areas[i] + areas[order[1:]] - inter)
            inds = sp.where(ovr <= T)[0]
            order = order[inds + 1]

        return keep

    @staticmethod
    def minmax(arr):
        minv = arr[0]
        maxv = arr[0]
        for val in arr:
            if val > maxv:
                maxv = val
            elif val < minv:
                minv = val
        return int(sp.floor(minv)), int(sp.ceil(maxv))

    @staticmethod
    def ellipse2bbox(a, b, angle, cx, cy):
        a, b = max(a, b), min(a, b)
        ca = sp.cos(angle)
        sa = sp.sin(angle)
        if sa == 0.0:
            cta = 2.0 / sp.pi
        else:
            cta = ca / sa

        if ca == 0.0:
            ta = sp.pi / 2.0
        else:
            ta = sa / ca

        x = lambda t: cx + a * sp.cos(t) * ca - b * sp.sin(t) * sa

        y = lambda t: cy + b * sp.sin(t) * ca + a * sp.cos(t) * sa

        # x = cx + a * cos(t) * cos(angle) - b * sin(t) * sin(angle)
        # tan(t) = -b * tan(angle) / a
        tx1 = sp.arctan(-b * ta / a)
        tx2 = tx1 - sp.pi
        x1, y1 = x(tx1), y(tx1)
        x2, y2 = x(tx2), y(tx2)

        # y = cy + b * sin(t) * cos(angle) + a * cos(t) * sin(angle)
        # tan(t) = b * cot(angle) / a
        ty1 = sp.arctan(b * cta / a)
        ty2 = ty1 - sp.pi
        x3, y3 = x(ty1), y(ty1)
        x4, y4 = x(ty2), y(ty2)

        minx, maxx = Util.minmax([x1, x2, x3, x4])
        miny, maxy = Util.minmax([y1, y2, y3, y4])
        return sp.floor(minx), sp.floor(miny), sp.ceil(maxx), sp.ceil(maxy)

    @staticmethod
    def kfold(X,y, k_fold = 2):
        for k in range(k_fold):
            t_indx = [i for i, e in enumerate(X) if i % k_fold != k]
            v_indx = [i for i, e in enumerate(X) if i % k_fold == k]
            yield t_indx,v_indx


import random
import os
import hangman_art

def hangman():
    with open("./data/data.txt", "r", encoding="utf-8") as f:
        word_list = [i for i in f]
    chosen_word = random.choice(word_list)
    word_length = len(chosen_word) - 1
    end_of_game = False
    lives = 6

    display = []
    for _ in range(word_length):
        display += "_"

    while not end_of_game:
        guess = input("Guess a letter: ").lower()
        for position in range(word_length):
            letter = chosen_word[position]

            if letter == guess:
                os.system("cls")
                print(hangman_art.logo)
                display[position] = letter

        if guess not in chosen_word:
            os.system("cls")
            print(hangman_art.logo)
            lives -= 1
            if lives == 0:
                end_of_game = True
                print(f"\nYou lose, the word was {chosen_word}.")

        print(f"{' '.join(display)}")

        if "_" not in display:
            end_of_game = True
            os.system("cls")
            print(hangman_art.logo)
            print(f"\nYou won, the word was {chosen_word}.")
        print(hangman_art.stages[lives])

def run():
    os.system("cls")
    print(hangman_art.logo)
    hangman()

if __name__ == "__main__":
    run()


from abc import ABC, abstractmethod

import numpy as np

from motndp.city import City

class Constraints(ABC):
    """Limits the space of the agent's next action, based on different spatial/directional constraints.."""

    def __init__(self):
        super(Constraints, self).__init__()

    @abstractmethod
    def mask_actions(self, current_location, possible_next_locations, visited_locations):
        """Applies different routing constraints and returns a binary mask of allowed actions, of size (n_actions,).
        The selection is based on the previous & current locations (direction).

        Args:
            current_location (numpy.ndarray): current location of the agent, of size (2,).
            possible_next_locations (numpy.ndarray): possible next locations of the agent, of size (n_actions, 2).
            visited_locations (numpy.ndarray): previously visited locations of the agent, of size (n_visited, 2).

        Returns:
        numpy.ndarray: mask of size (n_actions,) with 1s for allowed actions and 0s for disallowed actions.
        """
        pass

class BasicConstraints(Constraints):
    """Do not move outside of the grid, do not go to previously visited locations."""

    def __init__(self, city: City):
        super(BasicConstraints, self).__init__()

        self.city = city

    def mask_actions(self, current_location, possible_next_locations, visited_locations):
        action_mask = np.all(possible_next_locations >= 0, axis=1) &  \
                            (possible_next_locations[:, 0] < self.city.grid_x_size) & \
                            (possible_next_locations[:, 1] < self.city.grid_y_size) & \
                            ~(possible_next_locations[:, None] == visited_locations).all(2).any(1) # mask out visited cells -> https://stackoverflow.com/questions/54828039/how-to-match-pairs-of-values-contained-in-two-numpy-arrays
                            # np.all(~np.isin(possible_next_locations, visited_locations), axis=1)

        return action_mask.astype(np.int8)

class MetroConstraints(Constraints):
    """Do not move outside of the grid, do not go to previously visited locations.
    Also, move in a way that resembles a metro network (mostly straight line), without meandering and circular routes.
    More information on these constraints on Wei et al. 2020 paper: City Metro Network Expansion with Reinforcement Learning: https://www.kdd.org/kdd2020/accepted-papers/view/city-metro-network-expansion-with-reinforcement-learning
    """

    dir_up = (-1, 0)
    dir_down = (1, 0)
    dir_left = (0, -1)
    dir_right = (0, 1)
    dir_upleft = (-1, -1)
    dir_upright = (-1, 1)
    dir_downleft = (1, -1)
    dir_downright = (1, 1)

    def __init__(self, city: City):
        super(MetroConstraints, self).__init__()

        self.city = city

    def mask_actions(self, current_location, possible_next_locations, visited_locations):
        # Dont allow actions that go outside of the grid or to previously visited locations
        action_mask = np.all(possible_next_locations >= 0, axis=1) &  \
                            (possible_next_locations[:, 0] < self.city.grid_x_size) & \
                            (possible_next_locations[:, 1] < self.city.grid_y_size) & \
                            ~(possible_next_locations[:, None] == visited_locations).all(2).any(1) # mask out visited cells -> https://stackoverflow.com/questions/54828039/how-to-match-pairs-of-values-contained-in-two-numpy-arrays
                            # np.all(~np.isin(possible_next_locations, visited_locations), axis=1)
        action_mask = action_mask.astype(np.int8)

        if len(visited_locations) < 2:
            return action_mask

        # get the direction of the agent (based on the last two visited locations)
        direction = current_location - visited_locations[-2]
        direction[direction > 0] = 1
        direction[direction < 0] = -1

        if len(visited_locations) > 2:
            # We want to detect indirect diagonal movement, e.g. up then left, or left then up and so on.
            # To do this, we check the direction of the last two steps.
            two_step_dir = current_location - visited_locations[-3]
            two_step_dir[two_step_dir > 0] = 1
            two_step_dir[two_step_dir < 0] = -1

            if np.array_equal(two_step_dir, self.dir_upleft):
                direction = self.dir_upleft
            elif np.array_equal(two_step_dir, self.dir_upright):
                direction = self.dir_upright
            elif np.array_equal(two_step_dir, self.dir_downleft):
                direction = self.dir_downleft
            elif np.array_equal(two_step_dir, self.dir_downright):
                direction = self.dir_downright

        # mask out actions that are not in the direction of the agent, to prevent meandering and circular routes
        # up-left movement
        if (np.array_equal(direction, self.dir_upleft)):
            action_mask[[1, 2, 3, 4, 5]] = 0
        # up-right movement
        elif (np.array_equal(direction, self.dir_upright)):
            action_mask[[3, 4, 5, 6, 7]] = 0
        # down-left movement
        elif (np.array_equal(direction, self.dir_downleft)):
            action_mask[[0, 1, 2, 3, 7]] = 0
        # down-right movement
        elif (np.array_equal(direction, self.dir_downright)):
            action_mask[[0, 1, 5, 6, 7]] = 0
        # upwards movement
        elif np.array_equal(direction, self.dir_up):
            action_mask[[3, 4, 5]] = 0
        # downwards movement
        elif np.array_equal(direction, self.dir_down):
            action_mask[[0, 1, 7]] = 0
        # left movement
        elif np.array_equal(direction, self.dir_left):
            action_mask[[1, 2, 3]] = 0
        # right movement
        elif np.array_equal(direction, self.dir_right):
            action_mask[[5, 6, 7]] = 0

        return action_mask


#!/usr/bin/python
import roslib
roslib.load_manifest("moby")
import rospy, math
from moby.msg import GPS
from geometry_msgs.msg import Vector3, Point
from visualization_msgs.msg import Marker
from sensor_msgs.msg import FluidPressure
from std_msgs.msg import Header, ColorRGBA

lat = 0.0
lon = 0.0
fix = False
pressure_offset = -1
relative_alt = 0

def update_gps(data):
    global lat
    global lon
    global fix
    lat = data.lat
    lon = data.long
    fix = data.fix

def update_pressure(data):
    global pressure_offset
    global relative_alt
    raw_pressure = data.fluid_pressure
    if pressure_offset == -1:
        rospy.loginfo("Setting pressure offset: " + str(raw_pressure) + " Pa")
        pressure_offset = raw_pressure

    relative_alt = pressure_offset - raw_pressure

def visualizer():
    rospy.Subscriber("baro/pressure", FluidPressure, update_pressure)
    rospy.Subscriber("gps", GPS, update_gps)
    rate = rospy.Rate(1)
    trace_pub = rospy.Publisher("viz/gps_trace", Marker)
    primary_geofence_pub = rospy.Publisher("viz/primary_geofence", Marker)
    secondary_geofence_pub = rospy.Publisher("viz/secondary_geofence", Marker)
    trace_points = []
    # initialize parameters
    secondary_geofence_width = rospy.get_param("secondary_geofence/width", 0.00002)
    min_lon = 0
    max_lon = 0
    min_lat = 0
    max_lat = 0
    try:
        min_lon = rospy.get_param("geofence/lon/min")
        max_lon = rospy.get_param("geofence/lon/max")
        min_lat = rospy.get_param("geofence/lat/max")
        max_lat = rospy.get_param("geofence/lat/min")
    except KeyError:
        rospy.logfatal("Geofence was not configured on the parameter server! Shutting down")
        sys.exit(1)

    # get parameters with defaults that require the aforementioned non-default parameters
    secondary_min_lat = rospy.get_param("secondary_geofence/lat/min", min_lat + secondary_geofence_width)
    secondary_max_lat = rospy.get_param("secondary_geofence/lat/max", max_lat - secondary_geofence_width)
    secondary_min_lon = rospy.get_param("secondary_geofence/lon/min", min_lon - secondary_geofence_width)
    secondary_max_lon = rospy.get_param("secondary_geofence/lon/max", max_lon + secondary_geofence_width)

    while not rospy.is_shutdown():
        if fix and pressure_offset != -1:
            gps_divisor = rospy.get_param("~gps_divisor", 0.00001)
            try:
                primary_geofence_pts = (
                    Point(0, 0, 0),
                    Point(0, (max_lat - min_lat) / gps_divisor, 0),
                    Point((max_lon - min_lon) / gps_divisor, (max_lat - min_lat) / gps_divisor, 0),
                    Point((max_lon - min_lon) / gps_divisor, 0, 0),
                    Point(0, 0, 0)
                )
                secondary_geofence_pts = (
                    Point((secondary_min_lon - min_lon) / gps_divisor, (secondary_min_lat - min_lat) / gps_divisor, 0),
                    Point((secondary_min_lon - min_lon) / gps_divisor, (secondary_max_lat - min_lat) / gps_divisor, 0),
                    Point((secondary_max_lon - min_lon) / gps_divisor, (secondary_max_lat - min_lat) / gps_divisor, 0),
                    Point((secondary_max_lon - min_lon) / gps_divisor, (secondary_min_lat - min_lat) / gps_divisor, 0),
                    Point((secondary_min_lon - min_lon) / gps_divisor, (secondary_min_lat - min_lat) / gps_divisor, 0)
                )
                trace_points.append(Point((lon - min_lon) / gps_divisor, (lat - min_lat) / gps_divisor, relative_alt / rospy.get_param("~baro_divisor", 10)))
                trace_color = rospy.get_param("~trace_color", {"r": 0, "g": 1, "b": 0, "a": 1})
                viz_trace_color = ColorRGBA(trace_color['r'], trace_color['g'], trace_color['b'], trace_color['a'])

                primary_geofence_color = rospy.get_param("~primary_geofence_color", {"r": 1, "g": 1, "b": 0, "a": 1})
                viz_primary_geofence_color = ColorRGBA(primary_geofence_color['r'], primary_geofence_color['g'], primary_geofence_color['b'], primary_geofence_color['a'])
                secondary_geofence_color = rospy.get_param("~secondary_geofence_color", {"r": 1, "g": 0, "b": 0, "a": 1})
                viz_secondary_geofence_color = ColorRGBA(secondary_geofence_color['r'], secondary_geofence_color['g'], secondary_geofence_color['b'], secondary_geofence_color['a'])

                scale = rospy.get_param("~scale", 0.25)
                scale_vec = Vector3(scale, 0, 0)

                trace_ns = rospy.get_param("~trace_ns", "moby_trace")
                primary_geofence_ns = rospy.get_param("~primary_geofence_ns", "moby_primary_geofence")
                secondary_geofence_ns = rospy.get_param("~secondary_geofence_ns", "moby_secondary_geofence")

                header = Header()
                header.stamp = rospy.Time.now()
                header.frame_id = "map"
                trace_msg = Marker(header=header, ns=trace_ns, id=0, type=4, action=0, scale=scale_vec, color=viz_trace_color, lifetime=rospy.Duration(), frame_locked=False, points=trace_points)
                trace_msg.pose.orientation.w = 1.0
                trace_pub.publish(trace_msg)

                primary_geofence_msg = Marker(header=header, ns=primary_geofence_ns, id=0, type=4, action=0, scale=scale_vec, color=viz_primary_geofence_color, lifetime=rospy.Duration(), frame_locked=False, points=primary_geofence_pts)
                primary_geofence_pub.publish(primary_geofence_msg)
                secondary_geofence_msg = Marker(header=header, ns=secondary_geofence_ns, id=0, type=4, action=0, scale=scale_vec, color=viz_secondary_geofence_color, lifetime=rospy.Duration(), frame_locked=False, points=secondary_geofence_pts)
                secondary_geofence_pub.publish(secondary_geofence_msg)
            except KeyError:
                rospy.logerr("Visualization is enabled but zero point(s) are not set!")

        rate.sleep()

if __name__ == "__main__":
    rospy.init_node('visualizer')
    try:
        visualizer()
    except rospy.ROSInterruptException:
        pass


#### LOGIN AND REGISTRATION URLS ####
from django.conf.urls import url
from . import views

app_name = 'secrets'
urlpatterns = [
    url(r'^$', views.index, name ='index'),
    url(r'^post_secret$', views.post_secret, name ='post_secret'),
    url(r'^delete_secret/(?P<id>\d+)$', views.delete_secret, name ='delete_secret'),
    url(r'^like_secret/(?P<id>\d+)$', views.like_secret, name ='like_secret'),

]


# -*- coding: utf-8 -*-
"""
Created on Mon Jun  4 20:58:47 2018

@author: evan9
"""

import socket

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80 ))
cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)    #Receive up to 512 characters
    if len(data) < 1:
        break
    print(data.decode(),end='')
mysock.close()

##Approach2
#import urllib.request, urllib.parse, urllib.error
#
#url = 'http://data.pr4e.org/romeo.txt'
##url = 'http://www.dr-chuck.com/page1.htm'
#
#fhand = urllib.request.urlopen(url)
#for line in fhand:
#    print(line.decode().strip())


#! /usr/bin/env python
# encoding: utf-8

import os
import shutil
import platform
from waflib import Build, Errors, Logs

APPNAME = "srt"
VERSION = "1.1.0"

def build(bld):
    bld.post_mode = Build.POST_LAZY

    # Find the source directory for the external library
    src_dir = bld.dependency_node("srt-source")

    # Declare the temporary build directory for the external library
    # it is best to keep it under the project build directory
    build_dir = bld.bldnode.make_node("cmake_build")

    # Declare the install directory for the external library
    install_dir = build_dir.make_node("install")

    # Declare the include directory for the external library
    include_dir = install_dir.make_node("include")

    # Declare the lib directory for the external library
    lib_dir = install_dir.make_node("lib")

    # build the external library through an external process
    bld(
        rule=CMakeBuildTask,
        target=build_dir.make_node("flag.lock"),
        install_dir=install_dir,
        source=src_dir,
    )

    # once it is done create a second build group
    bld.add_group()

    if platform.system() == "Windows":
        lib_name = "srt_static"
    else:
        lib_name = "srt"

    bld.read_stlib(lib_name, paths=[lib_dir], export_includes=[include_dir])

    if bld.is_toplevel():
        bld.program(
            features="cxx test",
            source=bld.path.ant_glob("test/**/*.cpp"),
            target="srt_test",
            use=[lib_name, "gtest", "platform_includes"],
        )

def CMakeBuildTask(task):
    CMAKE_BUILD_TYPE = "Release"
    SRT_ENABLE_DEBUG = "OFF"
    if task.env['stored_options']['cxx_debug']:
        CMAKE_BUILD_TYPE = "Debug"
        SRT_ENABLE_DEBUG = "ON"

    # This is the directory where the external library will be installed the
    # task.outputs[0] is the flag file that will be created once the external
    # library is installed
    output_dir = task.outputs[0].parent

    # This is the directory where the external library source code is located
    source_dir = task.inputs[0]

    # The install dir is passed as a parameter to the task
    install_dir = task.generator.install_dir

    # remove the output directory if it exists
    shutil.rmtree(output_dir.abspath())

    # create the output directory
    os.makedirs(output_dir.abspath())

    flags = []
    # Our waf mkspec hardcodes the windows runtime to be mutlithreaded static i.e. /MT
    # so we need to pass this to cmake as well so that it can link properly
    # See https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html
    if platform.system() == "Windows":
        flags.append("-DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW")
        if CMAKE_BUILD_TYPE == "Debug":
                flags.append("-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug")
        elif CMAKE_BUILD_TYPE == "Release":
            flags.append("-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded")
        # For 32 bit builds we need to pass -A Win32 for cross compiling with mkspec
        if task.env['DEST_CPU'] == 'x86':
            flags.append("-A Win32")

    # SRT cmake flags
    flags += [
        "-DENABLE_SHARED=OFF",
        "-DENABLE_STATIC=ON",
        "-DENABLE_APPS=OFF",
        "-DENABLE_ENCRYPTION=OFF",
        "-DENABLE_BONDING=ON",
        f"-DENABLE_DEBUG={SRT_ENABLE_DEBUG}",
        f"-DCMAKE_BUILD_TYPE={CMAKE_BUILD_TYPE}",
    ]
    flags = " ".join(flags)

    # Run all commands in the output directory
    cwd = output_dir.abspath()

    try:
        task.generator.bld.cmd_and_log(
            f"cmake {flags} -S {source_dir}", cwd=cwd, quiet=0, output=0
        )
        task.generator.bld.cmd_and_log(
            f"cmake --build . --parallel --config {CMAKE_BUILD_TYPE}",
            cwd=cwd,
            quiet=0,
            output=0,
        )

        task.generator.bld.cmd_and_log(
            f"cmake --install . --prefix {install_dir} --config {CMAKE_BUILD_TYPE}",
            cwd=cwd,
            quiet=0,
            output=0,
        )

    except Errors.WafError as e:
        Logs.error(e.stderr)
        return -1

    Logs.info(f"Installed srt lib to {output_dir}")

    # write a lock file so that a rebuild occurs if files are removed manually
    task.outputs[0].write("ok")


from . import utils

def convert_lux(x, a, b, c, d, e):
    return a * x + b * x**2 + c * x**3 + d * x**4 + e

#@service
#def check_lux_conversion(light_id=None, input_type=None, value=None):
#    """yaml
#    name: Check the conversion between light pct and lux level
#    description: |
#        This tests the polynomial function values calculated by pyscript.calculate_lux_polynomials
#    fields:
#        light_id:
#            description: The entity_id of the light to test
#            example: light.office
#            required: true
#            selector:
#                entity:
#                    domain: light
#        input_type:
#            description: Convert from lux or light brightness?
#            example: lux
#            required: true
#            selector:
#                select:
#                    options:
#                    - lux
#                    - brightness
#        value:
#            description: The number to convert
#            example: 30
#            required: true
#            selector:
#                number:
#                   start: 0
#                   end: 254
#    """
#    attrs = state.getattr(light_id)
#    poly = [ float(n) for n in attrs[f"{input_type}_poly"] ]
#    out = round(convert_lux(value, *poly), 0)
#    output_type = 'lux' if input_type == 'brightness' else 'brightness'
#    persistent_notification.create(message=f"{output_type} is {out} at {input_type} {value}")

#@service
#def setup_ambilight_entity(name: str, light_id: str, sensor_id: str, target_lux_id: str, motion_sensor_id: str):
#    """yaml
#    name: Set up Ambient Lighting
#    description: |
#        This will set up an Ambient Lighting entity.
#        It will gather the lux levels at 5% increments of brightness.
#        It is recommended that you block out all other light sources while running this.
#    fields:
#        name:
#            name: Name
#            description: Name of the Ambilight entity
#            example: Office Ambilight
#            required: true
#            selector:
#                text:
#        light_id:
#            name: Light entity
#            description: The entity_id of the light to test
#            example: light.office
#            required: true
#            selector:
#                entity:
#                    domain: light
#        lux_sensor_id:
#            name: Lux sensor entity
#            description: The entity_id of the lux sensor to use
#            example: sensor.office_lux
#            required: true
#            selector:
#                entity:
#                    domain: sensor
#                    device_class: illuminance
#        target_lux_id:
#            name: Lux target entity
#            description: Input Number entity which defines the target lux
#            example: input_number.office_lux_min
#            required: true
#            selector:
#                entity:
#                    domain: input_number
#        motion_sensor_id:
#            name: Motion sensor entity
#            description: The entity_id of the motion sensor to tie to the ambilight
#            example: binary_sensor.office_motion
#            required: true
#            selector:
#                entity:
#                    domain: binary_sensor
#                    device_class: motion
#    """
#    log.info("setup_ambilight_entity")
#    entity_id = f"pyscript.{name.lower().replace(' ', '_')}"
#    if entity_id in state.names('pyscript'):
#        persistent_notification.create(message=f"The entity {entity_id} is already set up")
#        return
#
#    try:
#        lux, brightness, minimum, maximum = update_ambilight_polynomials(entity_id, light_id, sensor_id)
#        values = {
#            'light_id': light_id,
#            'lux_sensor_id': sensor_id,
#            'target_lux_id': target_lux_id,
#            'motion_sensor_id': motion_sensor_id,
#            'friendly_name': name,
#            'lux_minimum': minimum,
#            'lux_maximum': maximum,
#            'polynomial_lux': lux,
#            'polynomial_brightness': brightness
#        }
#        state.persist(entity_id, 'off', values)
#        persistent_notification.create(message=f"{name} set up successfully")
#    except Exception as e:
#        persistent_notification.create(message=f"Unable to set up {name}")
#        log.error(e)

@service
def update_ambilight_polynomials(entity_id: str):
    """yaml
    name: Update Ambilight polynomials
    description: This re-runs the set-up stage and calculations for the lux polynomial functions
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
    """
    log.debug("update_ambilight_polynomials")
    ambilight = state.get(entity_id)
    try:
        levels = utils.gather_lux_levels(ambilight.light_id, ambilight.lux_sensor_id)
        log.debug(f"Lux levels gathered for {entity_id}")
    except Exception as e:
        persistent_notification.create(message=f"Unable to gather lux levels for {entity_id}")
        raise(e)

    try:
        levels[0], levels[1] = utils.get_polynomials(levels[0], levels[1])
        log.debug(f"Got polynomials for {entity_id}")
    except Exception as e:
        persistent_notification.create(message=f"Unable to query polynomials for {entity_id}")
        raise(e)

    try:
        state.setattr(f"{entity_id}.lux_minimum", levels[2])
        state.setattr(f"{entity_id}.lux_maximum", levels[3])
        state.setattr(f"{entity_id}.polynomial_lux", levels[0])
        state.setattr(f"{entity_id}.polynomial_brightness", levels[1])
        persistent_notification.create(message=f"Lux levels updated for {entity_id}")
    except:
        persistent_notification.create(message=f"Unable to save attributes for {entity_id}")

@service
def set_ambilight_attribute(entity_id: str, attribute: str, value: str):
    """yaml
    name: Set an Ambilight attribute
    description: Set an attribute for an ambilight
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
        attribute:
            name: Attribute
            example: attribute
            required: true
            selector:
                text:
        value:
            name: Value
            example: value
            required: true
            selector:
                text:
    """
    state.setattr(f"{entity_id}.{attribute}", value)

#@service
#def delete_ambilight_attribute(entity_id: str, attribute: str, value: str):
#    """yaml
#    name: Delete an Ambilight attribute
#    description: Delete an attribute from an ambilight entity
#    fields:
#        entity_id:
#            name: Entity
#            example: pyscript.office_ambilight
#            required: true
#            selector:
#                entity:
#                    domain: pyscript
#        attribute:
#            name: Attribute
#            example: attribute
#            required: true
#            selector:
#                text:
#    """
#    state.delete(f"{entity_id}.{attribute}")

@service
def delete_ambilight_entity(entity_id: str):
    """yaml
    name: Delete Ambient Lighting entity
    description: Delete an Ambient Lighting entity.
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
    """
    state.delete(entity_id)

@service
def enable_ambilight(entity_id: str):
    """yaml
    name: Enable an Ambient Lighting entity
    description: Enable an Ambient Lighting entity.
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
    """
    state.set(entity_id, 'on')

@service
def disable_ambilight(entity_id: str):
    """yaml
    name: Disable an Ambient Lighting entity
    description: Disable an Ambient Lighting entity.
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
    """
    state.set(entity_id, 'off')

@service
def toggle_ambilight(entity_id: str):
    """yaml
    name: Toggle an Ambient Lighting entity
    description: Toggle an Ambient Lighting entity.
    fields:
        entity_id:
            name: Entity
            example: pyscript.office_ambilight
            required: true
            selector:
                entity:
                    domain: pyscript
    """
    to_state = 'on' if state.get(entity_id) == 'off' else 'off'
    state.set(entity_id, to_state)


import pytest

from classes.operations import Operations

def test_operations_repr():
    operations = Operations([{'id': 1, 'date': '2022-01-01T12:00:00', 'description': 'Operation 1'}])
    expected_repr = [{'id': 1, 'date': '2022-01-01T12:00:00', 'description': 'Operation 1'}]
    assert operations.__repr__() == f"Operations({expected_repr})"

def test_operations_set_last_operations():
    all_operations = [
        {'id': 1, 'date': '2022-01-01T12:00:00', 'description': 'Operation 1'},
        {'id': 2, 'date': '2022-01-02T12:00:00', 'description': 'Operation 2'},
        {'id': 3, 'description': 'Operation 3'}
    ]
    operations = Operations(all_operations)
    assert len(operations._Operations__last_operations) == 2
    assert operations._Operations__last_operations[0]['id'] == 2
    assert operations._Operations__last_operations[1]['id'] == 1

def test_date_reversed():
    assert Operations._Operations__date_reversed('2022-01-01T12:00:00') == "01.01.2022"

@pytest.fixture
def operations_instance():
    all_operations = [
        {
            'id': 1,
            'date': '2017-01-01T12:00:00',
            'description': 'Operation 2',
            'from': 'Account A',
            'to': 'Account B',
            'operationAmount': {'amount': 100, 'currency': {'name': 'USD'}},
            'state': 'EXECUTED'

        },
        {
            'id': 2,
            'date': '2018-01-01T12:00:00',
            'description': 'Operation 2',
            'from': 'Account A',
            'to': 'Account B',
            'operationAmount': {'amount': 100, 'currency': {'name': 'USD'}},
            'state': 'EXECUTED'
        },
        {
            'id': 3,
            'date': '2015-01-01T12:00:00',
            'description': 'Operation 3',
            'from': 'Account A',
            'to': 'Account B',
            'operationAmount': {'amount': 100, 'currency': {'name': 'USD'}},
            'state': 'EXECUTED'
        },
        {
            'id': 4,
            'date': '2020-01-01T12:00:00',
            'description': 'Operation 4',
            'from': 'Account A',
            'to': 'Account B',
            'operationAmount': {'amount': 100, 'currency': {'name': 'USD'}},
            'state': 'EXECUTED'
        },
        {},
        {
            'id': 5,
            'date': '2021-01-01T12:00:00',
            'description': 'Operation 5',
            'operationAmount': {'amount': 100, 'currency': {'name': 'RUB'}},
            'state': 'EXECUTED'
        },
        {
            'id': 6,
            'date': '2022-01-01T12:00:00',
            'description': 'Operation 6',
            'from': 'Account A',
            'to': 'Account B',
            'operationAmount': {'amount': 100, 'currency': {'name': 'USD'}},
            'state': 'EXECUTED'
        }

    ]
    return Operations(all_operations)

def test_operations_output_last_operations(operations_instance, capsys):
    operations_instance.output_last_operations()
    captured = capsys.readouterr()
    assert 'Операция: 2' in captured.out
    assert '01.01.2022 Operation 6' in captured.out
    assert 'Операция: 3' not in captured.out


'''
Simulate PSF using marx
    parameters:
        evt_file - associated event file (string)
        psf_file - associated psf fits file (string)
        outname - name of .psf file to be created (string)
    outputs:
        Creates a .psf for event
'''

import os
from ciao_contrib.runtool import *

def simulatePSF(evt_file,psf_file,outname):
    #Get source RA and dec from PSF
    temp_a = os.popen('dmlist '+psf_file+' header | grep SRC_RA').readlines()
    ra = temp_a[0].split("[deg]")[0].split("SRC_RA")[1].strip()
    temp_b = os.popen('dmlist '+psf_file+' header | grep SRC_DEC').readlines()
    dec = temp_b[0].split("[deg]")[0].split("SRC_DEC")[1].strip()
    #Simulate PSF
    simulate_psf.punlearn()
    simulate_psf.infile = evt_file+'.fits'
    simulate_psf.outroot = outname
    simulate_psf.ra = ra
    simulate_psf.dec = dec
    simulate_psf.simulator = 'file'
    simulate_psf.rayfile = psf_file
    simulate_psf.projector = 'marx'
    simulate_psf()
    return None
#-------------------------------------------------#
#-------------------------------------------------#


import torch
import torch.nn as nn
from math import pi as pi_constant
from typing import Tuple

Tensor = torch.cuda.DoubleTensor
torch.set_default_tensor_type(Tensor)

class SAC:
    def __init__(self, config):
    	# soft actor critic for continuous action space

        torch.manual_seed(config['seed'])

        self.lr = config['lr']  # learning rate
        self.smooth = config['smooth']  # smoothing coefficient for target net
        self.discount = config['discount']  # discount factor
        self.alpha = config['alpha']  # temperature parameter in SAC
        self.batch_size = config['batch_size']  # mini batch size

        self.dims_hidden_neurons = config['dims_hidden_neurons']
        self.dim_obs = config['dim_obs']
        self.dim_action = config['dim_action']

        self.actor = ActorNet(dim_obs=self.dim_obs,
                              dim_action=self.dim_action,
                              dims_hidden_neurons=self.dims_hidden_neurons)
        self.Q1 = QCriticNet(dim_obs=self.dim_obs,
                             dim_action=self.dim_action,
                             dims_hidden_neurons=self.dims_hidden_neurons)
        self.Q2 = QCriticNet(dim_obs=self.dim_obs,
                             dim_action=self.dim_action,
                             dims_hidden_neurons=self.dims_hidden_neurons)
        self.Q1_tar = QCriticNet(dim_obs=self.dim_obs,
                                 dim_action=self.dim_action,
                                 dims_hidden_neurons=self.dims_hidden_neurons)
        self.Q2_tar = QCriticNet(dim_obs=self.dim_obs,
                                 dim_action=self.dim_action,
                                 dims_hidden_neurons=self.dims_hidden_neurons)

        self.actor.cuda()
        self.Q1.cuda()
        self.Q2.cuda()
        self.Q1_tar.cuda()
        self.Q2_tar.cuda()

        self.optimizer_actor = torch.optim.Adam(self.actor.parameters(), lr=self.lr)
        self.optimizer_Q1 = torch.optim.Adam(self.Q1.parameters(), lr=self.lr)
        self.optimizer_Q2 = torch.optim.Adam(self.Q2.parameters(), lr=self.lr)

    def update(self, buffer):
        # sample from replay memory
        t = buffer.sample(self.batch_size)

        # update critic
        with torch.no_grad():
            next_action_sample, next_logProb_sample, next_mu_sample = self.actor(t.next_obs)
            Qp = torch.min(self.Q1_tar(t.next_obs, next_action_sample),
                           self.Q2_tar(t.next_obs, next_action_sample))
            Q_target = t.reward + self.discount * (~t.done) * (Qp - self.alpha * next_logProb_sample)

        loss_Q1 = torch.mean((self.Q1(t.obs, t.action) - Q_target) ** 2)
        loss_Q2 = torch.mean((self.Q2(t.obs, t.action) - Q_target) ** 2)

        self.optimizer_Q1.zero_grad()
        loss_Q1.backward()
        self.optimizer_Q1.step()

        self.optimizer_Q2.zero_grad()
        loss_Q2.backward()
        self.optimizer_Q2.step()

        # update actor
        action_sample, logProb_sample, mu_sample = self.actor(t.obs)
        Q = torch.min(self.Q1(t.obs, action_sample),
                      self.Q2(t.obs, action_sample))
        objective_actor = torch.mean(Q - self.alpha * logProb_sample)
        loss_actor = -objective_actor

        self.optimizer_actor.zero_grad()
        loss_actor.backward()
        self.optimizer_actor.step()

        with torch.no_grad():
            for p, p_tar in zip(self.Q1.parameters(), self.Q1_tar.parameters()):
                p_tar.data.copy_(p_tar * self.smooth + p * (1-self.smooth))
            for p, p_tar in zip(self.Q2.parameters(), self.Q2_tar.parameters()):
                p_tar.data.copy_(p_tar * self.smooth + p * (1-self.smooth))

    def act_probabilistic(self, obs: torch.Tensor):
        self.actor.eval()
        a, logProb, mu = self.actor(obs)
        self.actor.train()
        return a

    def act_deterministic(self, obs: torch.Tensor):
        self.actor.eval()
        a, logProb, mu = self.actor(obs)
        self.actor.train()
        return mu

class ActorNet(nn.Module):
    def __init__(self,
                 dim_obs: int,
                 dim_action: int,
                 dims_hidden_neurons: Tuple[int] = (64, 64)):
        super(ActorNet, self).__init__()
        self.n_layers = len(dims_hidden_neurons)
        self.dim_action = dim_action

        self.ln2pi = torch.log(Tensor([2*pi_constant]))

        n_neurons = (dim_obs,) + dims_hidden_neurons + (dim_action,)
        for i, (dim_in, dim_out) in enumerate(zip(n_neurons[:-2], n_neurons[1:-1])):
            layer = nn.Linear(dim_in, dim_out).double()
            # nn.Linear: input: (batch_size, n_feature)
            #            output: (batch_size, n_output)
            torch.nn.init.xavier_uniform_(layer.weight)
            torch.nn.init.zeros_(layer.bias)
            exec('self.layer{} = layer'.format(i + 1))

        self.output_mu = nn.Linear(n_neurons[-2], n_neurons[-1]).double()
        torch.nn.init.xavier_uniform_(self.output_mu.weight)
        torch.nn.init.zeros_(self.output_mu.bias)

        self.output_logsig = nn.Linear(n_neurons[-2], n_neurons[-1]).double()
        torch.nn.init.xavier_uniform_(self.output_logsig.weight)
        torch.nn.init.zeros_(self.output_logsig.bias)

    def forward(self, obs: torch.Tensor):
        x = obs
        for i in range(self.n_layers):
            x = eval('torch.tanh(self.layer{}(x))'.format(i + 1))
        mu = self.output_mu(x)
        sig = torch.exp(self.output_logsig(x))

        # for the log probability under tanh-squashed Gaussian, see Appendix C of the SAC paper
        u = mu + sig * torch.normal(torch.zeros(size=mu.shape), 1)
        a = torch.tanh(u)
        logProbu = -1/2 * (torch.sum(torch.log(sig**2), dim=1, keepdim=True) +
                           torch.sum((u-mu)**2/sig**2, dim=1, keepdim=True) +
                           a.shape[1]*self.ln2pi)
        logProba = logProbu - torch.sum(torch.log(1 - a ** 2 + 0.000001), dim=1, keepdim=True)
        return a, logProba, torch.tanh(mu)

class QCriticNet(nn.Module):
    def __init__(self,
                 dim_obs: int,
                 dim_action: int,
                 dims_hidden_neurons: Tuple[int] = (64, 64)):
        super(QCriticNet, self).__init__()
        self.n_layers = len(dims_hidden_neurons)
        self.dim_action = dim_action

        n_neurons = (dim_obs + dim_action,) + dims_hidden_neurons + (1,)
        for i, (dim_in, dim_out) in enumerate(zip(n_neurons[:-2], n_neurons[1:-1])):
            layer = nn.Linear(dim_in, dim_out).double()
            # nn.Linear: input: (batch_size, n_feature)
            #            output: (batch_size, n_output)
            torch.nn.init.xavier_uniform_(layer.weight)
            torch.nn.init.zeros_(layer.bias)
            exec('self.layer{} = layer'.format(i + 1))

        self.output = nn.Linear(n_neurons[-2], n_neurons[-1]).double()
        torch.nn.init.xavier_uniform_(self.output.weight)
        torch.nn.init.zeros_(self.output.bias)

    def forward(self, obs: torch.Tensor, action: torch.Tensor):
        x = torch.cat((obs, action), dim=1)
        for i in range(self.n_layers):
            x = eval('torch.tanh(self.layer{}(x))'.format(i + 1))
        return self.output(x)


def change(n):
    la=[]
    while True:
        n,rem=divmod(n,2)
        la.append(str(rem))
        if n==0:
            return ''.join(la[::-1])

num=int(input("请输入一个十进制的整数："))
print(change(num))


import requests as r
RAPID_API = "https://rapid-cloud.co/ajax/embed-6/getSources?id="

def get(id):
    data =  r.get(RAPID_API + id).json()

    sources = data["sources"]
    sources_backup = data["sourcesBackup"]
    sub = [i['file'] for i in data['tracks'] if i.get('label') == 'English'][0]

    print(sources, sources_backup, sub)

print(get("7ppphq8wiFCk"))