import pyart
import numpy as np
from scipy.ndimage import median_filter

#speed of light constant
c = 3e8

def dual_nyquist(radar):
    """
    This function evaluates de staggered PRT Nyquist velocity as in Zrnic and Mahapatra (1985)

    Parameters
    __________

    radar: Radar
        Radar object used

    Returns
    __________

    Radar object with correct Nyquist velocity.
    """

    #get radar wavelenghth
    lamb = c/radar.instrument_parameters['frequency']['data']

    #evaluate the extended Nyquist interval and add it to the radar object
    prt_ratio = radar.instrument_parameters['prt_ratio']['data'][0]
    nyquist = lamb/(4*radar.instrument_parameters['prt']['data'][0]*((1/prt_ratio)-1))
    radar.instrument_parameters['nyquist_velocity']['data'] = np.resize(nyquist, radar.nrays)

def staggered_to_dual(radar):
    """
    This function modifies some of the instrument parameters to make it look like the radar is operating in dual-PRF mode

    Parameters
    __________

    radar: Radar
        Radar object used

    Returns
    __________

    Radar object with correct dummy dual-PRF instrument parameters.
    """

    #evaluate the correct Nyquist velocity and add it to the radar object
    dual_nyquist(radar)

    #check for sweeps that use the staggered PRT method and change them to dual-PRF mode
    for n, prt_mode in enumerate(radar.instrument_parameters['prt_mode']['data']):
        if prt_mode =='staggered':
            radar.instrument_parameters['prt_mode']['data'][n] = b'dual'
        if prt_mode =='fixed':
            radar.instrument_parameters['prt_mode']['data'][n] = b'fixed'
    radar.instrument_parameters['prt_mode']['data'] = radar.instrument_parameters['prt_mode']['data'].astype('|S5')

    #invert the PRT ratio to look like the PRF ratio
    radar.instrument_parameters['prt_ratio']['data'] = 1 / radar.instrument_parameters['prt_ratio']['data']

    #add a PRF flag dictionary
    radar.instrument_parameters['prf_flag'] = {'units': 'unitless',
                                           'comments': 'PRF used to collect ray. 0 for high PRF, 1 for low PRF.',
                                           'meta_group': 'instrument_parameters',
                                           'long_name': 'PRF flag',
                                           'data':np.resize(([0, 1]), radar.nrays)}

def smooth_vel(radar, vel_name = 'vcor_cmean'):
    """
    This function applies a 3x3 median filter moving window in order to correct remaining speckles of adequately corrected velocity at the expense of smoothing some extremes.

    Parameters
    __________

    radar: Radar
        Radar object used

    vel_name: str
        velocity field name to be corrected

    Returns
    __________

    adds the smoothed velocity field to the radar object.
    """

    #smooth the velocity field
    vel_smooth = median_filter(radar.fields[vel_name]['data'], 3)

    #mask undesirable gates
    smooth_data_ma = np.ma.masked_where(np.ma.getmask(radar.fields[vel_name]['data']), vel_smooth)
    smooth_data_ma = np.ma.masked_equal(smooth_data_ma, smooth_data_ma.min())

    #add field to radar object
    radar.add_field_like('vcor_cmean', 'vcor_cmean_smooth',
                         smooth_data_ma, replace_existing = True)


import mock
from unittest import TestCase
from multiprocessing import Event

from skyengine.concurrent import synchronized, blocking_poll
from skyengine.exceptions import FlightAbortedException

class TestConcurrent(TestCase):

    def test_synchronized(self):
        lock = mock.Mock()

        @synchronized(lock)
        def plusone(x):
            return x + 1
        self.assertEquals(plusone(1), 2)
        lock.acquire.assert_called_once()
        lock.release.assert_called_once()

        self.assertEquals(plusone(2), 3)
        self.assertEquals(lock.acquire.call_count, 2)
        self.assertEquals(lock.release.call_count, 2)

    @mock.patch("skyengine.concurrent.time")
    def test_blocking_poll_timeout(self, mock_time):
        # Make a blocking poll that times out
        mock_predicate = mock.Mock()
        mock_predicate.side_effect = lambda: False
        mock_time.time.side_effect = [0, 0.3, 2.0]
        self.assertFalse(blocking_poll(mock_predicate, 0.25, timeout_sec=1.0))
        # Was the predicate actually used?
        self.assertEqual(mock_predicate.call_count, 2)
        # Did we delay like we were supposed to?
        mock_time.sleep.assert_called_once_with(0.25)
        # Did we timeout?
        self.assertEqual(mock_time.time.call_count, 3)

    @mock.patch("skyengine.concurrent.time")
    def test_blocking_poll_success(self, mock_time):
        # Make a blocking poll that succeeds.
        mock_predicate = mock.Mock()
        mock_predicate.side_effect = lambda: True
        mock_time.time.side_effect = [0, 0.3]
        # Should report success
        self.assertTrue(blocking_poll(mock_predicate, 0.25, timeout_sec=0.1))
        # Should get an initial time
        mock_time.time.assert_called_once()
        # Should actually use the predicate
        mock_predicate.assert_called_once()
        # Should skip a useless "sleep"
        mock_time.sleep.assert_not_called()

    @mock.patch("skyengine.concurrent.time")
    def test_blocking_poll_aborts(self, mock_time):
        mock_predicate = mock.Mock()
        mock_predicate.side_effect = lambda: True
        mock_time.side_effect = lambda: 0.0

        abort_event = Event()
        abort_event.set()
        with self.assertRaises(FlightAbortedException):
            blocking_poll(mock_predicate, 0.25, abort_event=abort_event)

        # Shouldn't even have run the command in question if the abort event
        # was triggered!
        mock_predicate.assert_not_called()


import RPi.GPIO as GPIO
import time
import datetime
import pygame.mixer
from pygame.mixer import Sound
from yeelight import Bulb

### Button Definitions ###

# For Distance Sensor
GPIO_TRIGGER = 18
GPIO_ECHO = 24

# For Time Change / Alarm Toggle Buttons
GPIO_HOUR = 27
GPIO_MINUTE = 22
GPIO_HOLD_FOR_TIME = 23
GPIO_TOGGLE_ALARM = 10

### Init ###
# Alarm Sound Init
pygame.mixer.init()
sound = pygame.mixer.Sound("./Alarm.wav")

# LED Light Init
bulb = Bulb("192.168.43.2")
bulb = Bulb("192.168.43.2",auto_on = True, effect = "smooth", duration = 600000) # turns on in a duration of 10 minutes when light_on() is called

# Lets us use pin numberings from board
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

# Setup the buttons we want to use
GPIO.setup(GPIO_HOUR, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(GPIO_MINUTE, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(GPIO_HOLD_FOR_TIME, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(GPIO_TOGGLE_ALARM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# Setup for distance sensor GPIO
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

# Read alarm_time.txt
filer = open("./capstone-app/src/assets/alarm_time.txt","r")
alarm_time = filer.read(10)
filer.close()

# Get time
sys_time = datetime.datetime.now().strftime('%H:%M')

# Init alarm being enabled
# Later could make this based from config
alarm_enabled = True

### Init Distance Sensor and Buttons ###

# Button function for toggling the alarm
def toggle_alarm(channel):
  global alarm_enabled
  if (alarm_enabled):
    print("Disabling Alarm")
  else:
    print("Enabling Alarm")
  alarm_enabled = not alarm_enabled

# Button function for changing time
# This is writing back to the file going up to
# 24 hours instead of 12 to keep track of AM/PM
# Also the function to get time from Python works better like this
def change_alarm_time(channel):
  # Get the alarm time in the function
  global alarm_time

  # Read string val into local numbers to make manipulation easier
  tempHr = ""
  tempMin = ""
  readHr = True
  for char in alarm_time:
    if (char == ':'):
      readHr = False
    elif (readHr):
      tempHr += char
    elif (not readHr):
      tempMin += char

  hour = int(tempHr)
  minute = int(tempMin)

  # While the button that called this function is being held
  while(GPIO.input(channel)):

    # If the button to increment alarm time by hour is pressed
    if (GPIO.input(GPIO_HOUR)):

      print("Incrementing Alarm Time by 1 hour.")

      # Do some string manipulation and change the alarm_time global var
      hour += 1
      if (hour == 24):
        hour = 0

    # If the button to increment alarm time by minute is pressed
    elif (GPIO.input(GPIO_MINUTE)):
      print("Incrementing Alarm Time by 1 minute.")

      # Increment minute
      minute += 1
      if (minute == 60):
        minute = 0

    # Convert local alarm time back to global
    tempTime = str(hour) + ":"

    # Have to consider having a time like 8:1 when we want 8:01
    if (minute < 10):
      tempTime += "0" + str(minute)
    else:
      tempTime += str(minute)

    alarm_time = tempTime

    # Write alarm time to file
    filew = open("./capstone-app/src/assets/alarm_time.txt","w")
    filew.write(alarm_time)
    filew.close()
    time.sleep(0.5)

  return

### Always be scanning for button presses ##

# This scans for if we should change the alarm time
GPIO.add_event_detect(GPIO_HOLD_FOR_TIME,GPIO.RISING,callback=change_alarm_time)

# This scans for if we should enable or disable the alarm
# The alarm is enabled by default (potentially add param for this later?)
GPIO.add_event_detect(GPIO_TOGGLE_ALARM,GPIO.RISING,callback=toggle_alarm)

### Distance Sensor Code ###

def distance():
  # set Trigger to HIGH
  GPIO.output(GPIO_TRIGGER, True)

  # set Trigger after 0.01ms to LOW
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)

  StartTime = time.time()
  StopTime = time.time()

  # save StartTime
  while GPIO.input(GPIO_ECHO) == 0:
    StartTime = time.time()

  # save time of arrival
  while GPIO.input(GPIO_ECHO) == 1:
    StopTime = time.time()

  # time difference between start and arrival
  TimeElapsed = StopTime - StartTime
  # multiply with the sonic speed (34300 cm/s)
  # and divide by 2, because there and back
  distance = (TimeElapsed * 34300) / 2

  return distance

def alarm_on(sound):
  print("Turning alarm on")

  # Make it do a procedural increase in volume eventually
  # To do this we can use sound.set_volume(x) 0 <= x <= 1
  sound.set_volume(0.1)
  sound.play()

def alarm_off(sound):
  print("Turning alarm off")
  sound.stop()

def light_on(bulb):
  print("Turning light on")
  bulb.set_color_temp(4000) #sets the color temperature to match the sun
  bulb.turn_on()  #turns light on gradually within 10 minutes

def light_off(bulb):
  print("Turning light off")
  bulb.turn_off()

def turn_on_light_time(alarm):
  tempHr = ""
  tempMin = ""
  readHr = True
  for char in alarm:
    if (char == ':'):
      readHr = False
    elif (readHr):
      tempHr += char
    elif (not readHr):
      tempMin += char

  hour = int(tempHr)
  minute = int(tempMin)

  if (minute >= 10):
    minute -= 10
  else:
    if (hour == 0):
      hour = 24
    else:
      hour -= 1
    minute = 60 - (10 - minute)

  tempTime = str(hour) + ":"

  # Have to consider having a time like 8:1 when we want 8:01
  if (minute < 10):
    tempTime += "0" + str(minute)
  else:
    tempTime += str(minute)
  return tempTime

### When X time until alarm, start alarm processes ###
# If the alarm is disabled in this time we want this process to stop
# Need to test putting a sleep function in this, don't know if it will
# keep button functions from working...
is_light_on = False
while(True):
  # Going to overflow the I/O with this if the sleep doesnt work
  print("Running")
  if (alarm_enabled):
    #Update the sys time constantly
    sys_time = datetime.datetime.now().strftime('%H:%M')
    light_time = turn_on_light_time(alarm_time)
    # So with the light and alarm functions.. I'm not sure if
    # they will work on 1 thread of execution so we might have to
    # unfortunately multithread this :(
    print("Alarm Time: " + alarm_time)
    print("Light Time: " + light_time)
    print("Sys Time: " + sys_time)
    # As long as these if statements execute more than once per minute we are fine
    if ((light_time == sys_time) and (not is_light_on)):
      is_light_on = True
      light_on(bulb)

    if (alarm_time == sys_time):
      alarm_on(sound)  #function that turns the alarm on
      # Add function to constantly check sensor distance
      delta = 5 # Need to figure this out more
      basket_made = False
      while (not basket_made):
        time.sleep(0.1)
        if (distance() < delta):
          basket_made = True
      # Add if distance is within threshold
      alarm_off(sound) #function that turns alarm off
      light_off(bulb) #function that turns light off
      is_light_on = False

  # Going to try and buffer everything with this sleep
  # might prevent buttons from working during the sleep but not sure
  time.sleep(0.5)


# This class takes in a Maze, as a list of MazeNode objects (each knowing if they are the start/ end of the maze,
# and which of their sides have walls or walkable space), and returns a solution to the maze using a path-finding
# algorithm (depth-first-search, breadth-first-search, A*, etc.).

from collections import deque  # needed for creating a queue for breadth first search
import queue  # needed for creating a priority queue for a star
import sys

class MazeSolver:
    # defines constructor for MazeGenerator class
    def __init__(self, mazeObject):
        self.mazeNodes = mazeObject.getMazeArray()
        self.mazeRows = mazeObject.getTotalRows()
        self.mazeCols = mazeObject.getTotalCols()
        self.startIndex = mazeObject.getStartNodeIndex()
        self.endIndex = mazeObject.getEndNodeIndex()

        # reset the recursion limit for large mazes to prevent crashing
        if self.mazeRows * self.mazeCols > sys.getrecursionlimit():
            sys.setrecursionlimit(self.mazeRows * self.mazeCols + 5)

        self.nodesExplored = 0
        self.solutionPath = []

    # defines representation for Python Interpreter
    def __repr__(self):
        return self

    # defines method for solving with a recursive depth-first search algorithm
    def solveWithDFS(self):
        # set up visitedNodes stack and push start node's index
        stack = []
        stack.append(self.startIndex)

        # now that setup is complete do the recursive depth-first search
        self.depthFirstSearch(stack)
        return self.solutionPath

    # defines method for getting the solution path with DFS
    def depthFirstSearch(self, stack):
        self.nodesExplored = self.nodesExplored + 1

        # get the last added node index from the stack
        nodeIndex = stack.pop()
        node = self.mazeNodes[nodeIndex]

        # get the neighbor node indexes of neighbors that can be walked to from current node
        neighborNodeIndexes = self.getLegalNeighborNodeIndexes(node)

        # add the current node index to the stack of visited node's indexes
        stack.append(nodeIndex)

        if neighborNodeIndexes:
            # for each neighbor node
            for x in range(len(neighborNodeIndexes)):
                neighborNodeIndex = neighborNodeIndexes[x]
                neighborNode = self.mazeNodes[neighborNodeIndex]

                if neighborNode.isMazeEnd():
                    # set parent index for getting the solution path
                    neighborNode.setParentIndex(node.getIndexInMazeArray())
                    return self.getSolutionPath(neighborNode)
                if neighborNodeIndex not in stack:
                    # set parent index for getting the solution path later
                    neighborNode.setParentIndex(node.getIndexInMazeArray())

                    # add the unvisited node index to the stack to be carried to the next dfs iteration
                    stack.append(neighborNodeIndex)

                    # do dfs for last neighborNodeIndex pushed to the stack
                    self.depthFirstSearch(stack)

    # defines method for solving with a recursive breadth-first search algorithm
    def solveWithBFS(self):
        # set up checkedNodes list and uncheckedNodesQ queue and then enqueue start node's index
        checkedNodes = []
        uncheckedNodesQ = deque()
        uncheckedNodesQ.append(self.startIndex)

        # now that setup is complete do the recursive depth-first search
        self.breadthFirstSearch(checkedNodes, uncheckedNodesQ)
        return self.solutionPath

    # defines method for getting the solution path with BFS
    def breadthFirstSearch(self, checkedNodes, uncheckedNodesQ):
        self.nodesExplored = self.nodesExplored + 1

        # get the first added node index from the queue
        nodeIndex = uncheckedNodesQ.popleft()
        node = self.mazeNodes[nodeIndex]

        # get the neighbor node indexes of neighbors that can be walked to from current node
        neighborNodeIndexes = self.getLegalNeighborNodeIndexes(node)

        # add the current node index to the queue of checked node's indexes
        checkedNodes.append(nodeIndex)

        if neighborNodeIndexes:
            # for each neighbor node
            for x in range(len(neighborNodeIndexes)):
                neighborNodeIndex = neighborNodeIndexes[x]
                neighborNode = self.mazeNodes[neighborNodeIndex]

                if neighborNode.isMazeEnd():
                    # set parent index for getting the solution path
                    neighborNode.setParentIndex(nodeIndex)
                    return self.getSolutionPath(neighborNode)
                if neighborNodeIndex not in checkedNodes:
                    # set parent index for getting the solution path
                    neighborNode.setParentIndex(nodeIndex)

                    # add the unchecked node index to the queue to be carried to the next bfs iteration
                    uncheckedNodesQ.append(neighborNodeIndex)

        # do bfs for first neighborNodeIndex in the queue
        self.breadthFirstSearch(checkedNodes, uncheckedNodesQ)

    # defines method for solving with a recursive A* Algorithm
    def solveWithAStar(self):
        # set up openNodePQ priority queue and checkedNodes list
        openNodePQ = queue.PriorityQueue(0)
        checkedNodes = []

        # set the values for the starting node and put it in the priority queue
        self.mazeNodes[self.startIndex].setFValue(0)
        self.mazeNodes[self.startIndex].setGValue(0)
        self.mazeNodes[self.startIndex].setHValue(0)
        openNodePQ.put([0, self.startIndex])

        # now that setup is complete do the recursive A* search
        self.aStarSearch(openNodePQ, checkedNodes)

        return self.solutionPath

    # defines method for getting the solution path with a recursive A* Algorithm
    def aStarSearch(self, openNodesPQ, checkedNodes):
        self.nodesExplored = self.nodesExplored + 1

        # get the node index with lowest f value from the openNodesPQ
        nodeIndex = openNodesPQ.get()[1]
        currentNode = self.mazeNodes[nodeIndex]

        # get the neighbor node indexes of neighbors that can be walked to from current node
        neighborNodeIndexes = self.getLegalNeighborNodeIndexes(currentNode)

        if neighborNodeIndexes:
            # for each neighbor node
            for x in range(len(neighborNodeIndexes)):
                neighborNodeIndex = neighborNodeIndexes[x]
                neighborNode = self.mazeNodes[neighborNodeIndex]

                if neighborNode.isMazeEnd():
                    # set parent index for getting the solution path
                    neighborNode.setParentIndex(currentNode.getIndexInMazeArray())
                    return self.getSolutionPath(neighborNode)
                if neighborNodeIndex not in checkedNodes and self.is_not_in_queue(neighborNodeIndex, openNodesPQ):
                    # set parent index for getting the solution path
                    neighborNode.setParentIndex(currentNode.getIndexInMazeArray())

                    # set the neighbor node's fValue, gValue, and hValue
                    gValue = self.calculateGValue(currentNode, neighborNode)
                    hValue = self.calculateHValue(currentNode)
                    fValue = gValue + hValue
                    neighborNode.setGValue(gValue)
                    neighborNode.setHValue(hValue)
                    neighborNode.setFValue(fValue)

                    # when finished add it to the priority queue then go to next neighbor
                    openNodesPQ.put([fValue, neighborNodeIndex])
                if neighborNodeIndex not in checkedNodes and self.is_in_queue(neighborNodeIndex, openNodesPQ):
                    # check to see if this new path to the neighborNode is better than previous path
                    newGValue = self.calculateGValue(currentNode, neighborNode)
                    if newGValue < neighborNode.getGValue():
                        # set parent index for getting the solution path
                        neighborNode.setParentIndex(currentNode.getIndexInMazeArray())

                        # set the neighbor node's fValue, gValue, and hValue
                        newFValue = newGValue + neighborNode.getHValue()
                        neighborNode.setGValue(newGValue)
                        neighborNode.setFValue(newFValue)

                        # when finished add it to the priority queue then go to next neighbor
                        openNodesPQ.put([newFValue, neighborNodeIndex])
                # add current node to checkedNodes after exploring all neighbors
            checkedNodes.append(currentNode.getIndexInMazeArray())
            # do a* for the next lowest fValue node in openNodesPQ
            self.aStarSearch(openNodesPQ, checkedNodes)

    # define method getting the indexs of legal, walkable neighbor nodes
    def getLegalNeighborNodeIndexes(self, currentNode):
        walkableNeighbors = []

        # if node's neighbor is legal, exists and isn't the previous visited node, then add it to neighborNodesIndexes
        if (currentNode.hasLeftNeighbor()) and (currentNode.getLeftWalkable()):
            walkableNeighbors.append(currentNode.getLeftNeighborIndex(self.mazeCols))

        if (currentNode.hasRightNeighbor(self.mazeCols)) and (currentNode.getRightWalkable()):
            walkableNeighbors.append(currentNode.getRightNeighborIndex(self.mazeCols))

        if (currentNode.hasTopNeighbor()) and (currentNode.getTopWalkable()):
            walkableNeighbors.append(currentNode.getTopNeighborIndex(self.mazeCols))

        if (currentNode.hasBottomNeighbor(self.mazeRows)) and (currentNode.getBottomWalkable()):
            walkableNeighbors.append(currentNode.getBottomNeighborIndex(self.mazeRows, self.mazeCols))
        return walkableNeighbors

    # defines method for getting the cost it takes to get from current node to a given node
    def calculateGValue(self, node, givenNode):
        gValueOfThisNode = node.getGValue()
        if givenNode.isAboveOf(node):
            # moving upwards takes you farther from the bottom row where the goalNode (so higher cost)
            return gValueOfThisNode + 25
        elif givenNode.isLeftOf(node) or givenNode.isRightOf(node):
            # moving left or right keeps you at the same level (so moderate cost)
            return gValueOfThisNode + 15
        elif givenNode.isBelowOf(node):
            # moving down gets you closer to the bottom row where the goalNode is (so lower cost)
            return gValueOfThisNode + 5
        else:
            # only return -1 if something goes horribly wrong
            return -1

    # defines method for getting the heuristic value of a node
    def calculateHValue(self, node):
        # given two points P(p1,p2) and Q(q1,q2), the taxicab distance D between P and Q is
        # given by the equation D = |p1-q1| + |p2-q2|
        goalNode = self.mazeNodes[self.endIndex]
        return abs(node.getRowPosition() - goalNode.getRowPosition()) + abs(
            node.getColPosition() - goalNode.getColPosition())

    # defines method for getting the total number of nodes explored while solving
    def getNodesExplored(self):
        return self.nodesExplored

    # defines method for getting the solution path after the maze has been solved
    def getSolutionPath(self, node):
        # add node path from end to start
        string = "(" + str(node.getRowPosition()) + "," + str(node.getColPosition()) + ")"
        self.solutionPath.append(string)

        # if node's parent index = -1 then you've reached the start node
        if node.getParentIndex() == -1:
            # reverse the list so that it prints the path from start node to end node
            self.solutionPath.reverse()
            return self.solutionPath
        else:
            self.getSolutionPath(self.mazeNodes[node.getParentIndex()])

    # defines method for knowing if x is in a q
    # http://stackoverflow.com/questions/22737111/check-if-something-is-already-in-priority-queue-python
    def is_in_queue(self, x, q):
        with q.mutex:
            return x in q.queue

    # defines method for knowing if x is not in a q
    # http://stackoverflow.com/questions/22737111/check-if-something-is-already-in-priority-queue-python
    def is_not_in_queue(self, x, q):
        with q.mutex:
            return not (x in q.queue)


import image
from image import *
import pygame
from pygame.locals import *
from sys import exit
import userpage
import player
class Inputpage:
    def __init__(self):
        pygame.init()
        screen=pygame.display.set_mode((1440,900),0,32)
        background = pygame.image.load(inputpage).convert()
        screen.blit(background, (0,0))
        name = ""
        font = pygame.font.Font(None, 150)
        while True:
            for evt in pygame.event.get():
                if evt.type == KEYDOWN:
                    screen=pygame.display.set_mode((1440,900),0,32)
                    background = pygame.image.load(inputpage).convert()
                    screen.blit(background, (0,0))
                    if evt.unicode.isalpha():
                        name += evt.unicode
                    elif evt.key == K_BACKSPACE:
                        name = name[:-1]
                    elif evt.key == K_RETURN:

                        player.setInitial(name)
                        userpage.Userpage()
                        #userpage.initial()
                elif evt.type == pygame.QUIT:
                        pygame.quit()
                        exit()
            block = font.render(name, True, (0, 0, 0))
            rect = block.get_rect()
            rect.center = screen.get_rect().center
            screen.blit(block, rect)
            pygame.display.update()

if __name__ == '__main__':
    start = Inputpage()


import csv
import json
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import os
import sys

# First we check if the code is executed from Python or from the .exe, because the way to get the
# path from where the code is executed is different in both cases.
if getattr(sys, 'frozen', False):
    # Runs from the .exe
    application_path = os.path.dirname(sys.executable)
else:
    # Runs from Python
    application_path = os.path.dirname(os.path.abspath(__file__))

# Once we have the path, we read the configuration file and obtain the parameters
with open(os.path.join(application_path, "config.json")) as jsonFile:
    jsonObject = json.load(jsonFile)
    jsonFile.close()

# Parameter reading
url = jsonObject['url']
csv_file = os.path.join(application_path, jsonObject['csv_filename'])
csv_encoding = jsonObject['csv_encoding']
selenium_webdriver_useragent = jsonObject['selenium_webdriver_useragent']
header = jsonObject['header']

iframe_xpath = jsonObject['iframe_xpath']

output_SuitNo_xpath = jsonObject['output_SuitNo_xpath']
output_ParcelNo_xpath = jsonObject['output_ParcelNo_xpath']
output_Owner_xpath = jsonObject['output_Owner_xpath']
CoOwner_xpath = jsonObject['CoOwner_xpath']
LegalDesc_xpath = jsonObject['LegalDesc_xpath']
PropertyAddress_xpath = jsonObject['PropertyAddress_xpath']
PropertyCity_xpath = jsonObject['PropertyCity_xpath']
PropertyState_xpath = jsonObject['PropertyState_xpath']
DateSold_xpath = jsonObject['DateSold_xpath']
PurchasePrice_xpath = jsonObject['PurchasePrice_xpath']
Judgment_xpath = jsonObject['Judgment_xpath']
Excess_xpath = jsonObject['Excess_xpath']
Purchaser_xpath = jsonObject['Purchaser_xpath']
PurchaserAddress_xpath = jsonObject['PurchaserAddress_xpath']
PurchaserCity_xpath = jsonObject['PurchaserCity_xpath']
PurchaserState_xpath = jsonObject['PurchaserState_xpath']
PurchaserZip_xpath = jsonObject['PurchaserZip_xpath']
HearingDate_xpath = jsonObject['HearingDate_xpath']
HearingTime_xpath = jsonObject['HearingTime_xpath']
ContinuedDate_xpath = jsonObject['ContinuedDate_xpath']
ContinuedTime_xpath = jsonObject['ContinuedTime_xpath']
Confirmed_xpath = jsonObject['Confirmed_xpath']
SetAside_xpath = jsonObject['SetAside_xpath']
Appealed_xpath = jsonObject['Appealed_xpath']
CountyPaid_xpath = jsonObject['CountyPaid_xpath']
StatePaid_xpath = jsonObject['StatePaid_xpath']
ExcessAppFiled_xpath = jsonObject['ExcessAppFiled_xpath']
ExcessDenied_xpath = jsonObject['ExcessDenied_xpath']
ExcessAppealed_xpath = jsonObject['ExcessAppealed_xpath']
ExcessPaid_xpath = jsonObject['ExcessPaid_xpath']

# Chrome driver configuration
options = Options()
options.add_argument(selenium_webdriver_useragent)
driver = webdriver.Chrome(options=options)

# Access the URL and wait for the page to load. Consideramos que se ha cargado cuando se muestra al final de la página la sección de paginación
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div/div/div/div[2]/div[3]/div[1]/div[1]/div[10]")))

# Create a CSV file and write the headers
with open(csv_file, "w", newline="", encoding=csv_encoding) as csv_file:
    writer = csv.writer(csv_file, delimiter="\t")

    writer.writerow(header)

    # Find the iframe
    #iframe = driver.find_elements(By.XPATH, iframe_xpath)

    # Change Selenium context to point to iframe
    #driver.switch_to.frame(iframe[0])

    # Now you can search and manipulate the elements inside the iframe
    # To know if we have reached the end, detect if there is a 'Next' button.
    #botones_siguiente = driver.find_elements(By.XPATH, "//input[@name='Next']")
    #more_cases = True
    #if len(botones_siguiente) == 0:
          #more_cases = False
          #print('No more records')

    # Find all records on the current page and write them to the CSV file
    divs = driver.find_elements(By.XPATH, "/html/body/div[3]/div/div/div/div[2]/div[3]/div[1]/div[1]")

    print("Cantidad de elementos en divs:", len(divs))

    divs_content = "\n\n\n\n\n".join([div.get_attribute("outerHTML") for div in divs])
    print(divs_content)

    for div in divs:
        inner_divs = div.find_elements(By.CLASS_NAME, "col-md-12.product-result-element.pro-element")

        for inner_div in inner_divs:
            # Realiza las operaciones deseadas con el div que tiene la clase especificada
            # por ejemplo, extraer información o interactuar con los elementos dentro del div
            # div.find_element(...) o div.text

            # Encuentra el elemento del título dentro del div
            title_element = inner_div.find_element(By.CLASS_NAME, "title")
            title = title_element.text

            # Encuentra el elemento de la descripción dentro del inner_div
            description_element = inner_div.find_element(By.CLASS_NAME, "p-desc-txt")
            description = description_element.text

            # Imprime el título y la descripción
            print("Título:", title)
            print("Descripción:", description)
            print("---")

# Close the browser
driver.quit()


import pytest
from enum import Enum
from nay.core.rules import Rule, When

# Define a fixture for creating a default Rule instance
@pytest.fixture
def default_rule():
    return Rule()

# Define a fixture for creating a Klocwork Rule instance
@pytest.fixture
def klocwork_rule():
    return Rule(
        if_statement="KLOCWORK_ISSUES > 5",
        when=When.ON_FAILURE,
        allow_failure=True,
        variables={"KLOCWORK_ISSUES": "10", "KLOCWORK_SEVERITY": "high"},
    )

# Define test cases for the Rule class
class TestRule:
    def test_never(self, default_rule):
        new_rule = default_rule.never()
        assert new_rule._when == When.NEVER

    def test_add_variables(self, default_rule):
        default_rule.add_variables(KLOCWORK_ISSUES="10", KLOCWORK_SEVERITY="high")
        assert default_rule._variables == {"KLOCWORK_ISSUES": "10", "KLOCWORK_SEVERITY": "high"}

    def test_equals(self, klocwork_rule):
        # Create two Klocwork job rules with the same conditions
        rule1 = klocwork_rule
        rule2 = klocwork_rule
        assert rule1._equals(rule2)

    def test_not_equals(self, klocwork_rule):
        # Create two Klocwork job rules with different conditions
        rule1 = klocwork_rule
        rule2 = Rule(
            if_statement="KLOCWORK_ISSUES > 3",
            when=When.ON_FAILURE,
            allow_failure=True,
            variables={"KLOCWORK_ISSUES": "5", "KLOCWORK_SEVERITY": "medium"},
        )
        assert not rule1._equals(rule2)

    def test_render_klocwork_rule(self, klocwork_rule):
        # Render the Klocwork rule
        rendered_rule = klocwork_rule.render()

        # Define the expected rendering for a Klocwork job rule
        expected_rendering = {
            "if": "KLOCWORK_ISSUES > 5",
            "when": "on_failure",
            "allow_failure": True,
            "variables": {"KLOCWORK_ISSUES": "10", "KLOCWORK_SEVERITY": "high"},
        }

        # Assert that the rendered rule matches the expected rendering
        assert rendered_rule == expected_rendering

# Define test cases for the When enum
class TestWhen:
    def test_enum_values(self):
        assert When.ALWAYS.value == "always"
        assert When.DELAYED.value == "delayed"
        assert When.MANUAL.value == "manual"
        assert When.NEVER.value == "never"
        assert When.ON_FAILURE.value == "on_failure"
        assert When.ON_SUCCESS.value == "on_success"

# Run the tests with pytest
if __name__ == "__main__":
    pytest.main()


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

# In[ ]:

# In[1]:

import numpy as np
from numpy import array, zeros, fabs

n = int(input('Enter number of unknowns: '))
a = np.zeros((n,n))
b = np.zeros(n)
x = np.zeros(n)
print('Enter Augmented Matrix Coefficients:')
for i in range(n):
    for j in range(n):
        a[i][j] = float(input( 'a['+str(i)+']['+ str(j)+']='))
    b[i] =float(input( 'b['+str(i)+']='))

n = len(b)
x = zeros(n, float)

for k in range(1,n):
    t=a[k-1][k-1]
    for j in range(k+1,n+1):
        if a[j-1][k-1]>t:
            t=j
    for i in range(k,n+1):
        temp=a[k-1][i-1]
        a[k-1][i-1]=a[t-1][i-1]
        a[t-1][i-1]=temp
    temp=b[k-1]
    b[k-1]=b[t-1]
    b[t-1]=temp

for i in range(k+1,n):
        factor = a[k,k]/a[i,k]
        for j in range(k,n):
            a[i,j] = a[k,j] - a[i,j]*factor
        b[i] = b[k] - b[i]*factor
print(a)
print(b)

x[n-1] = b[n-1] / a[n-1, n-1]
for i in range(n-2, -1, -1):
    sum_ax = 0

    for j in range(i+1, n):
        sum_ax += a[i,j] * x[j]

    x[i] = (b[i] - sum_ax) / a[i,i]

print("The solution of the system is:")
print(x)

# In[ ]:

# In[ ]:

Gauss Elimination with partial pivoting.py


from input_error import input_error
import Classes
ab = Classes.AdressBook()

def hello(*args):
    print('How can I help you ?')

def exit(*args):
    print('Good bye!')
    return False

@input_error
def add(text):
    num = text.split(' ')
    print(num)
    name_add = num[1]
    phone_add = num[2]
    name = Classes.Name(name_add)
    phone = Classes.Phone(phone_add)
    rec = Classes.Record(name, phone)
    # ab = Classes.AdressBook()
    ab.add_record(rec)
    print(ab)

# @input_error
# def change(text):
#     num = text.split(' ')
#     if num[1] in phonebook:
#         phonebook[num[1]] = num[2]
#         print(f'Номер телефона {num[1]} изменен  на {num[2]}')
#         print(phonebook)
#     else:
#         print('Такого контакта не существует')

def show_all(*args):
    if 'show all' in args:
       print(ab.show_all())
    else:
        print('----Uknown command----in show all')

def good_bye(*args):
    if 'good bye' in args:
        return False
    else:
        print('---Uknown command--- in good bye')

# @input_error
# def phone(text):
#     num = text.split(' ')
#     if num[1] in phonebook:
#        b = phonebook.get(num[1])
#        print(b)
#     else:
#         print('---Такого контакта не существует---')


from Game import *
from NeuralNet import *

def run_game_with_ML(display, clock, weights, gen):

    global max_score

    returnScore = 0

    avg_score = 0
    test_games = 1
    score1 = 0
    steps_per_game = 250000
    score2 = 0

    if gen > 10:
        steps_per_game = steps_per_game*2

    for _ in range(test_games):

        paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel, bpos, score = init()

        count_same_direction = 0
        prev_direction = 0
        returnScore = 0
        score1_old = 0
        predicted_ball_pos = 0

        for _ in range(steps_per_game):

            relpos_normalized, \
            paddle_vertical_position_normalized, \
            ball_vertical_position_normalized, \
            ball_velocity = getInputs()

            predictions = []
            predicted_direction = np.argmax(np.array(forward_propagation(np.array([relpos_normalized,
                                                                                paddle_vertical_position_normalized,
                                                                                ball_vertical_position_normalized,
                                                                                ball_velocity/40,
                                                                                predicted_ball_pos,
                                                                                prev_direction
                                                                                ]
                                                                                ).reshape(-1, 7), weights))) - 1

            if predicted_direction == prev_direction:
                count_same_direction += 1

            else:
                score1 = score1 + 5
                count_same_direction = 0
                prev_direction = predicted_direction

            if predicted_direction == 0:
                if count_same_direction >= 5:
                    score1 = score1 - 1

            if paddle_vertical_position_normalized * HEIGHT == 360:
                score1 = score1 - 1

            elif paddle_vertical_position_normalized * HEIGHT == 40:
                score1 = score1 - 1

            if ((ball_vertical_position_normalized - paddle_vertical_position_normalized)**2)**0.5 < 0.10:
                score1 = score1 + 2

            if relative_paddle_superior_position_normalized < 0.10:
                score1 = score1 + 1

            if relative_paddle_inferior_position_normalized < 0.10:
                score1 = score1 + 1

            new_direction = predicted_direction

            predicted_ctl = generate_new_direction(new_direction)

            returnScore_old = returnScore

            relpos_normalized, \
            paddle_vertical_position_normalized, \
            ball_vertical_position_normalized, \
            ball_velocity, \
            l_score, r_score, \
            returnScore, predicted_ball_pos = play_game(display, clock, gen, score, returnScore, predicted_direction, predicted_ctl)

            score = l_score + (score1-score1_old) + (returnScore - returnScore_old)*10000
            if score < 0:
                score = 0

            if score > max_score:
                max_score = score

            if r_score == 3:
                break

            score1_old = score1

    return score


class Npc:

    def __init__(self):
        self.name_npc = None
        self.hp = 0

        print('start')

    def add_nam(self, name_npc):
        self.name_npc = name_npc
        print('name_Classs')

    def name(self):
        if self.name_npc:
            print('Name -', self.name_npc.title())
        else:
            print("Upssss")

    def added_hp(self, hp):
        self.hp = self.hp + hp

    def how_hp(self):
        print('hpeshek-'+ str(self.hp))

class Npc_freands(Npc):

    def __init__(self):
        pass
        # super().__init__()

if __name__ == '__main__':

    a = Npc()
    a.add_nam('ss')
    a.added_hp(456)
    a.how_hp()

    b = Npc_freands()
    b.add_nam('asas')
    b.name()
    b.name()
    print(a.hp)


import numpy as np

def ScaMul(c, arr):
    ScalarProduct = c * arr
    return ScalarProduct

def newPowerMethod(mat, n, vec):
    eigenVector = vec
    for i in range(n):
        eigenVector = np.dot(mat, eigenVector)
        eigenVector = ScaMul((1/np.linalg.norm(eigenVector)), eigenVector)

    eigenValue = np.dot(eigenVector, np.dot(mat, eigenVector)) * (1/np.dot(eigenVector, eigenVector))

    return eigenValue


# Testing for utils

import pytest
import json
from datetime import datetime
from decimal import Decimal
from io import StringIO
from astropy.table import Table
from astrodbkit2.utils import json_serializer, get_simbad_names, _name_formatter, datetime_json_parser
try:
    import mock
except ImportError:
    from unittest import mock

@pytest.mark.parametrize('test_input, expected', [
    ('TWA  27', 'TWA 27'),
    ('HIDDEN A', None),
    ('V* V4046 Sgr', 'V4046 Sgr'),
    ('** CVN   12A', 'CVN 12A')
])
def test_name_formatter(test_input, expected):
    assert _name_formatter(test_input) == expected

def test_json_serializer():
    data = {'date': datetime(2018, 12, 6, 12, 30, 0),
            'value': Decimal(2.3),
            'integer': 4,
            'bytes': b'byte'}

    json_text = json.dumps(data, indent=4, default=json_serializer)
    with StringIO(json_text) as f:
        new_data = json.load(f)

    assert new_data['date'] == '2018-12-06T12:30:00'
    assert new_data['value'] == pytest.approx(2.3)
    assert new_data['integer'] == 4
    assert new_data['bytes'] == 'byte'

def test_datetime_json_parser():
    json_dict = {'date': '2018-12-06T12:30:00', 'name': 'TWA 23', 'number': 4.5}
    new_dict = datetime_json_parser(json_dict)
    assert new_dict['date'] == datetime.fromisoformat('2018-12-06T12:30:00')
    assert isinstance(new_dict['date'], datetime)
    assert isinstance(new_dict['name'], str)
    assert isinstance(new_dict['number'], float)

@mock.patch('astrodbkit2.utils.Simbad.query_objectids')
def test_get_simbad_names(mock_simbad):
    mock_simbad.return_value = Table({'ID': ['name 1', 'name 2', 'V* name 3', 'HIDDEN name']})
    t = get_simbad_names('twa 27')
    assert len(t) == 3
    assert t[2] == 'name 3'

    # Example with no Simbad match
    mock_simbad.return_value = None
    t = get_simbad_names('WISEU J005559.88+594745.0')
    assert len(t) == 1
    assert t[0] == 'WISEU J005559.88+594745.0'


#!/usr/bin/python

DEFAULT_DIR = "/Users/maksie/Documents/Wallpapers/Anime"

import random
import sys
import os

path = ''
choice = ''

if len(sys.argv) > 1:
    path = sys.argv[1]
else:
    path = DEFAULT_DIR

files = [x for x in os.listdir(path) if os.path.isfile(os.path.join(path, x)) and not x == '.DS_Store']
for i in range(1,3):
    choice = random.choice(files)
    full_path = os.path.join(path, choice)
    os.system("osascript -e 'tell application \"System Events\" to set picture of desktop {} to ("'"{}"'" as POSIX file as alias)'".format(i, full_path))


"""Suppoort for Ariston sensors."""
import logging
from datetime import timedelta
from copy import deepcopy

from homeassistant.const import CONF_NAME, CONF_SENSORS
from homeassistant.helpers.entity import Entity
from homeassistant.const import (
    DEVICE_CLASS_BATTERY,
    DEVICE_CLASS_CURRENT,
    DEVICE_CLASS_ENERGY,
    DEVICE_CLASS_HUMIDITY,
    DEVICE_CLASS_ILLUMINANCE,
    DEVICE_CLASS_POWER,
    DEVICE_CLASS_POWER_FACTOR,
    DEVICE_CLASS_PRESSURE,
    DEVICE_CLASS_SIGNAL_STRENGTH,
    DEVICE_CLASS_TEMPERATURE,
    DEVICE_CLASS_TIMESTAMP,
    DEVICE_CLASS_VOLTAGE,
    ENERGY_KILO_WATT_HOUR
)

from homeassistant.components.sensor import (
    STATE_CLASS_TOTAL_INCREASING
)

from .const import (
    DATA_ARISTON,
    DEVICES,
    PARAM_ACCOUNT_CH_GAS,
    PARAM_ACCOUNT_CH_ELECTRICITY,
    PARAM_ACCOUNT_DHW_GAS,
    PARAM_ACCOUNT_DHW_ELECTRICITY,
    PARAM_CH_ANTIFREEZE_TEMPERATURE,
    PARAM_CH_MODE,
    PARAM_CH_SET_TEMPERATURE,
    PARAM_CH_COMFORT_TEMPERATURE,
    PARAM_CH_ECONOMY_TEMPERATURE,
    PARAM_CH_DETECTED_TEMPERATURE,
    PARAM_CH_PROGRAM,
    PARAM_CH_WATER_TEMPERATURE,
    PARAM_COOLING_LAST_24H,
    PARAM_COOLING_LAST_7D,
    PARAM_COOLING_LAST_30D,
    PARAM_COOLING_LAST_365D,
    PARAM_COOLING_TODAY,
    PARAM_ERRORS,
    PARAM_ERRORS_COUNT,
    PARAM_DHW_COMFORT_FUNCTION,
    PARAM_DHW_MODE,
    PARAM_DHW_SET_TEMPERATURE,
    PARAM_DHW_STORAGE_TEMPERATURE,
    PARAM_DHW_COMFORT_TEMPERATURE,
    PARAM_DHW_ECONOMY_TEMPERATURE,
    PARAM_MODE,
    PARAM_OUTSIDE_TEMPERATURE,
    PARAM_HEATING_LAST_24H,
    PARAM_HEATING_LAST_7D,
    PARAM_HEATING_LAST_30D,
    PARAM_HEATING_LAST_365D,
    PARAM_HEATING_TODAY,
    PARAM_SIGNAL_STRENGTH,
    PARAM_WATER_LAST_24H,
    PARAM_WATER_LAST_7D,
    PARAM_WATER_LAST_30D,
    PARAM_WATER_LAST_365D,
    PARAM_WATER_TODAY,
    PARAM_UNITS,
    PARAM_THERMAL_CLEANSE_CYCLE,
    PARAM_DHW_PROGRAM,
    PARAM_GAS_TYPE,
    PARAM_GAS_COST,
    PARAM_ELECTRICITY_COST,
    VALUE,
    UNITS,
    ZONE_PARAMETERS,
    ZONE_TEMPLATE,
    ZONE_NAME_TEMPLATE
)

SCAN_INTERVAL = timedelta(seconds=2)

STATE_AVAILABLE = "available"

SENSOR_ACCOUNT_CH_GAS = "Account CH Gas Use"
SENSOR_ACCOUNT_CH_ELECTRICITY = "Account CH Electricity Use"
SENSOR_ACCOUNT_DHW_GAS = "Account DHW Gas Use"
SENSOR_ACCOUNT_DHW_ELECTRICITY = "Account DHW Electricity Use"
SENSOR_CH_ANTIFREEZE_TEMPERATURE = "CH Antifreeze Temperature"
SENSOR_CH_DETECTED_TEMPERATURE = "CH Detected Temperature"
SENSOR_CH_MODE = "CH Mode"
SENSOR_CH_SET_TEMPERATURE = "CH Set Temperature"
SENSOR_CH_PROGRAM = "CH Time Program"
SENSOR_CH_COMFORT_TEMPERATURE = "CH Comfort Temperature"
SENSOR_CH_ECONOMY_TEMPERATURE = "CH Economy Temperature"
SENSOR_CH_WATER_TEMPERATURE = "CH Water Temperature"
SENSOR_COOLING_LAST_24H = "Energy use for Cooling in last 24 hours"
SENSOR_COOLING_LAST_7D = "Energy use for Cooling in last 7 days"
SENSOR_COOLING_LAST_30D = "Energy use for Cooling in last 30 days"
SENSOR_COOLING_LAST_365D = "Energy use for Cooling in last 365 days"
SENSOR_DHW_COMFORT_FUNCTION = "DHW Comfort Function"
SENSOR_DHW_PROGRAM = "DHW Time Program"
SENSOR_DHW_SET_TEMPERATURE = "DHW Set Temperature"
SENSOR_DHW_STORAGE_TEMPERATURE = "DHW Storage Temperature"
SENSOR_DHW_COMFORT_TEMPERATURE = "DHW Comfort Temperature"
SENSOR_DHW_ECONOMY_TEMPERATURE = "DHW Economy Temperature"
SENSOR_DHW_MODE = "DHW Mode"
SENSOR_ERRORS = "Active Errors"
SENSOR_HEATING_LAST_24H = "Energy use for Heating in last 24 hours"
SENSOR_HEATING_LAST_7D = "Energy use for Heating in last 7 days"
SENSOR_HEATING_LAST_30D = "Energy use for Heating in last 30 days"
SENSOR_HEATING_LAST_365D = "Energy use for Heating in last 365 days"
SENSOR_MODE = "Mode"
SENSOR_OUTSIDE_TEMPERATURE = "Outside Temperature"
SENSOR_SIGNAL_STRENGTH = "Signal Strength"
SENSOR_WATER_LAST_24H = "Energy use for Water in last 24 hours"
SENSOR_WATER_LAST_7D = "Energy use for Water in last 7 days"
SENSOR_WATER_LAST_30D = "Energy use for Water in last 30 days"
SENSOR_WATER_LAST_365D = "Energy use for Water in last 365 days"
SENSOR_UNITS = "Units of Measurement"
SENSOR_THERMAL_CLEANSE_CYCLE = "Thermal Cleanse Cycle"
SENSOR_GAS_TYPE = "Gas Type"
SENSOR_GAS_COST = "Gas Cost"
SENSOR_ELECTRICITY_COST = "Electricity Cost"
SENSOR_COOLING_TODAY = "Energy use for Cooling today"
SENSOR_HETING_TODAY = "Energy use for Heating today"
SENSOR_WATER_TODAY = "Energy use for Water today"

_LOGGER = logging.getLogger(__name__)

# Sensor types are defined like: Name, units, icon
SENSORS = {
    PARAM_ACCOUNT_CH_GAS: [SENSOR_ACCOUNT_CH_GAS, None, "mdi:cash", None],
    PARAM_ACCOUNT_DHW_GAS: [SENSOR_ACCOUNT_DHW_GAS, None, "mdi:cash", None],
    PARAM_ACCOUNT_CH_ELECTRICITY: [SENSOR_ACCOUNT_CH_ELECTRICITY, None, "mdi:cash", None],
    PARAM_ACCOUNT_DHW_ELECTRICITY: [SENSOR_ACCOUNT_DHW_ELECTRICITY, None, "mdi:cash", None],
    PARAM_CH_ANTIFREEZE_TEMPERATURE: [SENSOR_CH_ANTIFREEZE_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:radiator", None],
    PARAM_CH_DETECTED_TEMPERATURE: [SENSOR_CH_DETECTED_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:thermometer", None],
    PARAM_CH_MODE: [SENSOR_CH_MODE, None, "mdi:radiator", None],
    PARAM_CH_SET_TEMPERATURE: [SENSOR_CH_SET_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:radiator", None],
    PARAM_CH_PROGRAM: [SENSOR_CH_PROGRAM, None, "mdi:calendar-month", None],
    PARAM_CH_COMFORT_TEMPERATURE: [SENSOR_CH_COMFORT_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:radiator", None],
    PARAM_CH_ECONOMY_TEMPERATURE: [SENSOR_CH_ECONOMY_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:radiator", None],
    PARAM_CH_WATER_TEMPERATURE: [SENSOR_CH_WATER_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:radiator", None],
    PARAM_COOLING_LAST_24H: [SENSOR_COOLING_LAST_24H, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_COOLING_LAST_7D: [SENSOR_COOLING_LAST_7D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_COOLING_LAST_30D: [SENSOR_COOLING_LAST_30D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_COOLING_LAST_365D: [SENSOR_COOLING_LAST_365D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_DHW_PROGRAM: [SENSOR_DHW_PROGRAM, None, "mdi:calendar-month", None],
    PARAM_DHW_COMFORT_FUNCTION: [SENSOR_DHW_COMFORT_FUNCTION, None, "mdi:water-pump", None],
    PARAM_DHW_SET_TEMPERATURE: [SENSOR_DHW_SET_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:water-pump", None],
    PARAM_DHW_STORAGE_TEMPERATURE: [SENSOR_DHW_STORAGE_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:water-pump", None],
    PARAM_DHW_COMFORT_TEMPERATURE: [SENSOR_DHW_COMFORT_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:water-pump", None],
    PARAM_DHW_ECONOMY_TEMPERATURE: [SENSOR_DHW_ECONOMY_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:water-pump", None],
    PARAM_DHW_MODE: [SENSOR_DHW_MODE, None, "mdi:water-pump", None],
    PARAM_ERRORS_COUNT: [SENSOR_ERRORS, None, "mdi:alert-outline", None],
    PARAM_HEATING_LAST_24H: [SENSOR_HEATING_LAST_24H, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_HEATING_LAST_7D: [SENSOR_HEATING_LAST_7D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_HEATING_LAST_30D: [SENSOR_HEATING_LAST_30D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_HEATING_LAST_365D: [SENSOR_HEATING_LAST_365D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_MODE: [SENSOR_MODE, None, "mdi:water-boiler", None],
    PARAM_OUTSIDE_TEMPERATURE: [SENSOR_OUTSIDE_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, "mdi:thermometer", None],
    PARAM_SIGNAL_STRENGTH: [SENSOR_SIGNAL_STRENGTH, DEVICE_CLASS_SIGNAL_STRENGTH, "mdi:signal", None],
    PARAM_WATER_LAST_24H: [SENSOR_WATER_LAST_24H, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_WATER_LAST_7D: [SENSOR_WATER_LAST_7D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_WATER_LAST_30D: [SENSOR_WATER_LAST_30D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_WATER_LAST_365D: [SENSOR_WATER_LAST_365D, DEVICE_CLASS_ENERGY, "mdi:cash", None],
    PARAM_UNITS: [SENSOR_UNITS, None, "mdi:scale-balance", None],
    PARAM_THERMAL_CLEANSE_CYCLE: [SENSOR_THERMAL_CLEANSE_CYCLE, DEVICE_CLASS_TIMESTAMP, "mdi:update", None],
    PARAM_GAS_TYPE: [SENSOR_GAS_TYPE, None, "mdi:gas-cylinder", None],
    PARAM_GAS_COST: [SENSOR_GAS_COST, None, "mdi:cash", None],
    PARAM_ELECTRICITY_COST: [SENSOR_ELECTRICITY_COST, None, "mdi:cash", None],
    PARAM_COOLING_TODAY: [SENSOR_COOLING_TODAY, DEVICE_CLASS_ENERGY, "mdi:cash", STATE_CLASS_TOTAL_INCREASING],
    PARAM_HEATING_TODAY: [SENSOR_HETING_TODAY, DEVICE_CLASS_ENERGY, "mdi:cash", STATE_CLASS_TOTAL_INCREASING],
    PARAM_WATER_TODAY: [SENSOR_WATER_TODAY, DEVICE_CLASS_ENERGY, "mdi:cash", STATE_CLASS_TOTAL_INCREASING],
}
for param in ZONE_PARAMETERS:
    if param in SENSORS:
        for zone in range(2, 4):
            SENSORS[ZONE_TEMPLATE.format(param, zone)] = (
                ZONE_NAME_TEMPLATE.format(SENSORS[param][0], zone),
                SENSORS[param][1],
                SENSORS[param][2],
                SENSORS[param][3]
            )

def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up a sensor for Ariston."""
    if discovery_info is None:
        return

    name = discovery_info[CONF_NAME]
    device = hass.data[DATA_ARISTON][DEVICES][name]
    add_entities(
        [
            AristonSensor(name, device, sensor_type)
            for sensor_type in discovery_info[CONF_SENSORS]
        ],
        True,
    )

class AristonSensor(Entity):
    """A sensor implementation for Ariston."""

    def __init__(self, name, device, sensor_type):
        """Initialize a sensor for Ariston."""
        self._name = "{} {}".format(name, SENSORS[sensor_type][0])
        self._signal_name = name
        self._api = device.api.ariston_api
        self._sensor_type = sensor_type
        self._state = None
        self._attrs = {}
        self._icon = SENSORS[sensor_type][2]
        self._device_class = SENSORS[sensor_type][1]
        self._state_class = SENSORS[sensor_type][3]

    @property
    def unique_id(self):
        """Return the unique id."""
        return f"{self._name}-{self._sensor_type}"

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._name

    @property
    def state(self):
        """Return the state of the sensor."""
        return self._state

    @property
    def native_value(self):
        """Return value of sensor."""
        return self._state

    @property
    def state_class(self):
        """State class of sensor."""
        return self._state_class

    @property
    def native_unit_of_measurement(self):
        """Return unit of sensor."""
        try:
            return self._api.sensor_values[self._sensor_type][UNITS]
        except KeyError:
            return None

    @property
    def device_class(self):
        """Return device class."""
        return self._device_class

    @property
    def extra_state_attributes(self):
        """Return the state attributes."""
        return self._attrs

    @property
    def icon(self):
        """Icon to use in the frontend, if any."""
        if self._sensor_type == PARAM_ERRORS_COUNT:
            try:
                if self._api.sensor_values[PARAM_ERRORS_COUNT][VALUE] == 0:
                    return "mdi:shield"
            except KeyError:
                pass
        return self._icon

    @property
    def unit_of_measurement(self):
        """Return the units of measurement."""
        try:
            return self._api.sensor_values[self._sensor_type][UNITS]
        except KeyError:
            return None

    @property
    def available(self):
        """Return True if entity is available."""
        return (
            self._api.available
            and not self._api.sensor_values[self._sensor_type][VALUE] is None
        )

    def _original_sensor(self, sensor):
        for param in ZONE_PARAMETERS:
            if sensor in {
                ZONE_TEMPLATE.format(param, 2),
                ZONE_TEMPLATE.format(param, 3)
                }:
                return param
        return sensor

    def update(self):
        """Get the latest data and updates the state."""
        try:
            if not self._api.available:
                return
            if not self._api.sensor_values[self._sensor_type][VALUE] is None:
                if self._original_sensor(self._sensor_type) in {PARAM_CH_PROGRAM, PARAM_DHW_PROGRAM}:
                    if self._api.sensor_values[self._sensor_type][VALUE] != {}:
                        self._state = STATE_AVAILABLE
                    else:
                        self._state = None
                else:
                    self._state = self._api.sensor_values[self._sensor_type][VALUE]
            else:
                self._state = None

            self._attrs = {}
            if self._original_sensor(self._sensor_type) in {
                PARAM_CH_SET_TEMPERATURE,
                PARAM_DHW_SET_TEMPERATURE,
                PARAM_CH_WATER_TEMPERATURE
            }:
                try:
                    self._attrs["Min"] = self._api.supported_sensors_set_values[
                        self._sensor_type
                    ]["min"]
                    self._attrs["Max"] = self._api.supported_sensors_set_values[
                        self._sensor_type
                    ]["max"]
                except KeyError:
                    self._attrs["Min"] = None
                    self._attrs["Max"] = None

            elif self._original_sensor(self._sensor_type) in {
                PARAM_ERRORS_COUNT
            }:
                self._attrs = self._api.sensor_values[PARAM_ERRORS][VALUE]

            elif self._original_sensor(self._sensor_type) in {
                PARAM_HEATING_LAST_24H,
                PARAM_WATER_LAST_24H,
                PARAM_COOLING_LAST_24H,
                PARAM_HEATING_LAST_7D,
                PARAM_WATER_LAST_7D,
                PARAM_COOLING_LAST_7D,
                PARAM_HEATING_LAST_30D,
                PARAM_WATER_LAST_30D,
                PARAM_COOLING_LAST_30D,
                PARAM_HEATING_LAST_365D,
                PARAM_WATER_LAST_365D,
                PARAM_COOLING_LAST_365D,
            }:
                list_param = self._sensor_type + "_list"
                self._attrs = self._api.sensor_values[list_param][VALUE]

            elif self._original_sensor(self._sensor_type) in {
                PARAM_CH_PROGRAM,
                PARAM_DHW_PROGRAM
            }:
                if self._state:
                    self._attrs = self._api.sensor_values[self._sensor_type][VALUE]

            elif self._original_sensor(self._sensor_type) in {
                PARAM_WATER_TODAY,
                PARAM_HEATING_TODAY,
                PARAM_COOLING_TODAY
            }:
                self._attrs["state_class"] = self._state_class

        except KeyError:
            _LOGGER.warning("Problem updating sensors for Ariston")


from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from user_profiles.models import Comment
from user_profiles.models import ProfilePost

theme = 'light'
text = 'dark'
navbar = 'primary'
theme, text = text, theme

@login_required(login_url='/login')
def user_menu(request):
    return render(request, 'user/user_menu.html')

@login_required(login_url='/login')
def notifications(request):
    context = {
        "theme": theme,
        "text": text,
    }
    return render(request, 'user/notifications.html', context)

@login_required(login_url='/login')
def post_comment(request):
    if request.method == 'POST':
        user = request.user
        cmt = request.POST.get('comment')
        path = request.POST.get('path')
        post = request.POST.get('post')
        post = ProfilePost.objects.get(id=post)
        try:
            cm = Comment(user=user, cmt=cmt, post=post)
            cm.save()
        except:
            pass
        path = request.POST.get('path')

        return redirect(f'{path}#{post}')
    else:
        return redirect('/')

@login_required(login_url='/login')
def post_comment_reply(request):
    if request.method == 'POST':
        user = request.user
        cmt_no = request.POST.get('comment')
        reply = request.POST.get('reply')
        path = request.POST.get('path')
        post = request.POST.get('post')

        post = ProfilePost.objects.get(id=post)
        cmt_no = Comment.objects.get(sno=cmt_no)

        try:
            cm = Comment(user=user, cmt=reply, post=post, parent=cmt_no)
            cm.save()
        except:
            pass
        path = request.POST.get('path')

        return redirect(f'{path}#{post}')
    else:
        return redirect('/')


lst = []
# count = 0
print("Enter names with letters not less than 1 or greater than 10")
for name in range(10):
    name = input('Enter a name:\n')
    if 10 >= len(name) > 1 and name != "":
        lst.append(name)
    else:
        while 10 < len(name) or len(name) < 2 or name == "":
            print("enter a valid name")
            name = input('Enter a name:\n')
            if 10 >= len(name) > 1 and name != "":
                lst.append(name)

print(lst)


#!/usr/bin/env python3

__author__ = "Henrique Frajacomo"

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QThreadPool, QRunnable, pyqtSignal, pyqtSlot, QObject, QThread
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QTableWidgetItem, QMessageBox
from easygui import *
import os
import ctypes

sys.path.append('EnGENE\\')
sys.path.append('EnGENE/')
sys.path.append('Rosalind\\')
sys.path.append('Rosalind/')

from EnGENE import Model
from Window import Ui_MainWindow
from Result import Result

# Stdout Supression
'''
The following block of code removes all traces of warnings and errors
from stdout and voids them.
UNCOMMENT ONLY WHEN FULL RELEASE IS READY!
'''
sys.stderr = open(os.devnull, "w")
sys.stdout = open(os.devnull, "w")

#####

# Warning Supress function
def warn(*args, **kwargs):
    pass

import warnings
warnings.warn = warn

class Win(QtWidgets.QMainWindow, Ui_MainWindow):
	def __init__(self):
		super(Win, self).__init__()
		self.setupUi(self)
		self.setup_pywin()
		self.threads = QThreadPool()

	# Setup GUI-Python integration
	def setup_pywin(self):
		self.setStyleSheet("QMainWindow {background-image: url(:/Images/Images/background.png); background-repeat: no-repeat; background-position: center;}")

		self.pushButton.clicked.connect(self.click_new)
		self.toolButton.clicked.connect(self.click_tool)
		self.tableWidget.setRowCount(0)
		self.tableWidget.setColumnCount(3)
		self.tableWidget.setHorizontalHeaderLabels(["Model name", "Filename", "Status"])
		self.tableWidget.resizeColumnsToContents()
		self.tableWidget.resizeRowsToContents()
		self.tableWidget_2.setRowCount(0)
		self.tableWidget_2.setColumnCount(5)
		self.tableWidget_2.setHorizontalHeaderLabels(["Result name", "Precision", "Recall", "Times Trained", "Associated Models"])
		self.tableWidget_2.resizeColumnsToContents()
		self.tableWidget_2.resizeRowsToContents()
		self.tableWidget_3.setRowCount(0)
		self.tableWidget_3.setColumnCount(2)
		self.tableWidget_3.setHorizontalHeaderLabels(["SNP ID", "Score"])
		self.tableWidget_3.resizeColumnsToContents()
		self.tableWidget_3.resizeRowsToContents()

		self.tableWidget.itemSelectionChanged.connect(lambda:self.model_selection_trigger(self.tableWidget.selectedItems()))
		self.tableWidget_2.itemSelectionChanged.connect(lambda:self.fill_results(self.tableWidget_2.selectedItems()))
		self.spinBox_2.valueChanged.connect(self.spinbox_end_change)
		self.spinBox_3.valueChanged.connect(self.spinbox_start_change)
		self.spinBox_4.valueChanged.connect(self.spinbox_target_change)
		self.pushButton_2.clicked.connect(self.click_select)
		self.pushButton_7.clicked.connect(self.click_target)
		self.textBrowser.setFontPointSize(11)
		self.pushButton_3.clicked.connect(self.click_dummy)
		self.spinBox_5.valueChanged.connect(self.spinbox_ova_change)
		self.pushButton_4.clicked.connect(self.click_ova)
		self.set_train_menu()
		self.toolButton_2.menu().triggered.connect(self.change_percentage)
		self.pushButton_5.clicked.connect(self.click_train)
		self.pushButton_6.clicked.connect(self.click_unload)
		self.pushButton_8.clicked.connect(lambda: self.click_cross_model(self.tableWidget.selectedItems()))
		self.pushButton_9.clicked.connect(lambda: self.click_delete(self.tableWidget_2.selectedItems()))
		self.pushButton_10.clicked.connect(lambda: self.click_cross(self.tableWidget_2.selectedItems()))
		self.pushButton_11.clicked.connect(lambda: self.click_save(self.tableWidget_2.selectedItems()))
		header = self.tableWidget.horizontalHeader()
		header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
		header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
		header2 = self.tableWidget_2.horizontalHeader()
		header2.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
		header3 = self.tableWidget_3.horizontalHeader()
		header3.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
		header3.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)

	# Checks if a model with name exists
	def __model_exist(self, name):
		if(type(Model.models.get(name, False)) == Model):
			return True
		else:
			return False

	# New Button Function
	def click_new(self):
		w = Worker("new", self.lineEdit.displayText())
		w.signals.finished_new.connect(self.set_table)
		self.threads.start(w)

	# Sets an item in QTableWidget
	def set_table(self, item1, item2, item3):
		self.update_text_browser()
		self.reset_spinboxes()
		item1 = QTableWidgetItem(item1)
		item2 = QTableWidgetItem(item2)
		item3 = QTableWidgetItem(item3)
		if(item3.text() == "Not Ready"):
			item3.setForeground(QColor(255,0,0))
		else:
			item3.setForeground(QColor(0,255,0))

		self.tableWidget.setRowCount(self.tableWidget.rowCount()+1)
		self.tableWidget.setItem(self.tableWidget.rowCount()-1,0, item1)
		self.tableWidget.setItem(self.tableWidget.rowCount()-1,1, item2)
		self.tableWidget.setItem(self.tableWidget.rowCount()-1,2, item3)
		self.tableWidget.resizeRowsToContents()

	# New function tool button
	def click_tool(self):
		global loaded_dataset
		loaded_dataset = fileopenbox(title="Load dataset", filetypes=["*.csv"], default="*.csv")

		if(loaded_dataset == None):
			loaded_dataset = ""

		self.lineEdit_2.setText(loaded_dataset)

	# Updates Model Information screen
	# Triggers for every model selection change
	def update_text_browser(self):
		if(not self.__model_exist(currently_selected_model)):
			self.textBrowser.setText("")
		else:
			self.textBrowser.setText(str(Model.models[currently_selected_model]))

	# Triggers every mouse selection in Model list
	def model_selection_trigger(self, modelname):
		global currently_selected_model
		global all_selected_models

		if(modelname == []):
			return

		elif(type(modelname) == list):
			all_selected_models = [x for x in modelname[::3]]
			currently_selected_model = modelname[-3].text()

		else:
			currently_selected_model = modelname

		self.reset_spinboxes()
		self.update_text_browser()
		self.toggle_train_tag()

	# Re-set all spinbox values
	def reset_spinboxes(self):
		self.spinBox_2.setMaximum(self.get_max_spinbox())
		self.spinBox_3.setMaximum(self.get_max_spinbox())
		self.spinBox_4.setMaximum(self.get_max_spinbox())
		self.spinBox_2.setValue(0)
		self.spinBox_3.setValue(0)
		self.spinBox_4.setValue(0)
		self.spinBox_5.setValue(0)
		self.lineEdit_3.setText("")
		self.lineEdit_4.setText("")
		self.lineEdit_5.setText("")
		self.lineEdit_6.setText("")

		if(currently_selected_model != ""):
			if(not self.__model_exist(currently_selected_model)):
				return
			if(Model.models[currently_selected_model].target_column != None):
				self.spinBox_5.setMaximum(self.get_max_spinbox_class())

	# Gets maximum number of Select and Target Spinboxes
	def get_max_spinbox(self):
		if(currently_selected_model == ""):
			return 0
		if(not self.__model_exist(currently_selected_model)):
			return 0
		return len(Model.models[currently_selected_model].data.columns)-1

	# Gets maximum number of Select to OVA Spinbox
	def get_max_spinbox_class(self):
		if(currently_selected_model == ""):
			return 0
		if(not self.__model_exist(currently_selected_model)):
			return 0
		return len(Model.models[currently_selected_model].get_classes())-1

	# Gets the header related to n element
	def get_spinbox_header(self, n):
		if(currently_selected_model == ''):
			return ""
		return Model.models[currently_selected_model].data.columns[n]

	def spinbox_end_change(self, q):
		self.lineEdit_4.setText(self.get_spinbox_header(q))
	def spinbox_start_change(self, q):
		self.lineEdit_3.setText(self.get_spinbox_header(q))
	def spinbox_target_change(self, q):
		self.lineEdit_5.setText(self.get_spinbox_header(q))
	def spinbox_ova_change(self, q):
		self.lineEdit_6.setText(Model.models[currently_selected_model].get_classes()[q])

	# Select button click
	def click_select(self):
		if(currently_selected_model != ""):
			Model.models[currently_selected_model].set_feature_range(self.spinBox_3.value(), self.spinBox_2.value())
		self.update_text_browser()

	# Target button click
	def click_target(self):
		if(currently_selected_model != ""):
			Model.models[currently_selected_model].set_target_column(self.spinBox_4.value())
		self.update_model_status(currently_selected_model)
		self.update_text_browser()

	# Dummification button click
	def click_dummy(self):
		w = Worker("dummy")
		w.signals.finished_dummy_ova.connect(self.set_dummy_ova)
		self.threads.start(w)

	# Set dummies and ova post processing
	def set_dummy_ova(self, modelname):
		self.update_text_browser()
		self.reset_spinboxes()
		self.update_model_status(modelname)

	# OVA button click
	def click_ova(self):
		w = Worker("ova", self.lineEdit_6.text())
		w.signals.finished_dummy_ova.connect(self.set_dummy_ova)
		self.threads.start(w)

	# Changes percentage of training
	def change_percentage(self, q):
		self.toolButton_2.setText(q.text())

	# Creates Train Percentage menu
	def set_train_menu(self):
		menu = QtWidgets.QMenu()

		for i in range(1, 10):
			act = menu.addAction(str(i*10) + "%")
		menu.setDefaultAction(act)
		self.toolButton_2.setText("90%")
		self.toolButton_2.setMenu(menu)

	# Train button click
	def click_train(self):
		# Cancel operation
		if(Worker.thread_control.get(currently_selected_model, False) != False):
			Worker.thread_control.pop(currently_selected_model)
			self.toggle_train_tag()

		# Train operation
		else:
			w = Worker("train", int(self.spinBox.text()), int(self.toolButton_2.text()[:-1])/100, self.radioButton.isChecked())
			w.signals.update_info.connect(self.update_text_browser)
			w.signals.update_list.connect(self.training_update)
			w.signals.finished_training.connect(self.training_post_process)
			Worker.thread_control[currently_selected_model] = True
			self.toggle_train_tag()
			self.threads.start(w)

	# After training processing
	def training_post_process(self, name, other):
		self.toggle_train_tag(name)
		self.add_result(name, other)

	# Changes Train button tag
	def toggle_train_tag(self, name=None):
		if(name == None):
			if(Worker.thread_control.get(currently_selected_model, False) != False):
				self.pushButton_5.setText("Stop Training")
				self.update_model_status(currently_selected_model)
			else:
				self.pushButton_5.setText("Train")
				self.update_model_status(currently_selected_model)
		else:
			if(Worker.thread_control.get(name, False) != False):
				self.pushButton_5.setText("Stop Training")
				self.update_model_status(name)
			else:
				self.pushButton_5.setText("Train")
				self.update_model_status(name)

	# Unload button click
	def click_unload(self):
		global all_selected_models
		global currently_selected_model

		for md in all_selected_models:
			Model.models.pop(md.text())

		delete_list = []

		for i in range(self.tableWidget.rowCount()):
			if(self.tableWidget.item(i,0).text() in [x.text() for x in all_selected_models]):
				delete_list.append(i)

		delete_list = sorted(delete_list)
		currently_selected_model = ""
		all_selected_models = []
		self.textBrowser.setText("")

		for ind in delete_list:
			self.tableWidget.removeRow(ind)
			for i in range(len(delete_list)):
				delete_list[i] -= 1

	# Returns model row index in Model list
	def get_row(self, modelname):
		for i in range(0, self.tableWidget.rowCount()):
			if(self.tableWidget.item(i,0).text() == modelname):
				return i
		return -1

	# Updates the state of a model in model list
	def update_model_status(self, modelname):
		index = self.get_row(modelname)

		if(Model.models[modelname].binary_feature_space and Model.models[modelname].binary_target_space):
			self.tableWidget.item(index,2).setText("Ready")
			self.tableWidget.item(index,2).setForeground(QColor(0,255,0))
		else:
			self.tableWidget.item(index,2).setText("Not Ready")
			self.tableWidget.item(index,2).setForeground(QColor(255,0,0))

	# Updates training routine
	def training_update(self, modelname, value):
		index = self.get_row(modelname)
		self.tableWidget.item(index,2).setText(value)
		self.tableWidget.item(index,2).setForeground(QColor(0,0,255))

	# Add result to results list
	def add_result(self, name, other):
		r = Result.results[name]

		items = []
		items.append(QTableWidgetItem(r.modelname))

		if(type(r.score[0]) == str):
			items.append(QTableWidgetItem(r.score[0]))
			items.append(QTableWidgetItem(r.score[1]))
		else:
			items.append(QTableWidgetItem('{0:.3f}'.format(float(r.score[0]*100)) + '%'))
			items.append(QTableWidgetItem('{0:.3f}'.format(float(r.score[1]*100)) + '%'))

		items.append(QTableWidgetItem(str(r.times_fit)))
		items.append(QTableWidgetItem(str(r.other_models).replace("[", "").replace("]", "")))

		if(self.__result_exists(name, other)):
			index = self.get_row_result(name)
			i = 0
			for el in items:
				self.tableWidget_2.setItem(index, i, el)
				i += 1
		else:
			self.tableWidget_2.setRowCount(self.tableWidget_2.rowCount()+1)
			i = 0
			for el in items:
				self.tableWidget_2.setItem(self.tableWidget_2.rowCount()-1, i, el)
				i += 1

	# Checks if a Result already exists
	def __result_exists(self, name, other):
		other = other.replace("[", "").replace("]", "").split(",")

		for i in range(0, self.tableWidget_2.rowCount()):
			if(self.tableWidget_2.item(i,0).text() == name):
				if(other == []):
					return True
				if(len(other) != len(self.tableWidget_2.item(i,4).text().split(","))):
					continue
				else:
					if(set(other) == set(self.tableWidget_2.item(i,4).text().replace("[", "").replace(']', '').split(","))):
						return True

		return False

	# Checks if a Result exists in Result.results
	def __vanilla_result_exists(self, name):
		if(Result.results.get(name, False) != False):
			return True
		return False

	# Finds result index in Results List
	def get_row_result(self, name):
		for i in range(0, self.tableWidget_2.rowCount()):
			if(self.tableWidget_2.item(i,0).text() == name):
				return i
		return -1

	# Inserts results elements into SNP List
	def fill_results(self, res, SIGNAL=False):
		self.tableWidget_3.clearContents()
		self.tableWidget_3.setRowCount(0)

		if(res == []):
			return

		if(not SIGNAL):
			try:
				res = Result.results[res[-5].text()].data
			except KeyError:
				return
		else:
			self.add_result(res, Result.results[res].other_models)
			res = Result.results[res].data

		i = 0
		for element in res:
			item1 = QTableWidgetItem(element[0])
			item2 = QTableWidgetItem(str(element[1]))
			self.tableWidget_3.setRowCount(self.tableWidget_3.rowCount()+1)
			self.tableWidget_3.setItem(i, 0, item1)
			self.tableWidget_3.setItem(i, 1, item2)
			i += 1

	# Cross Correlation Operation click
	def click_cross(self, selected):
		w = Worker("cross", selected)
		w.signals.finished_cross.connect(self.fill_results)
		self.threads.start(w)

	# Cross Model operation click
	def click_cross_model(self, selected):
		if(selected == []):
			return

		aux = [x.text() for x in selected[::3]]

		for model in aux:
			if(not self.__vanilla_result_exists(model)):
				return

		w = Worker("cross_models", selected)
		w.signals.finished_cross.connect(self.fill_results)
		self.threads.start(w)
		self.tabWidget.setCurrentIndex(1)

	# Deletes all selected results
	def click_delete(self, selected):
		if(selected == []):
			return

		delete_list = []

		names = [x.text() for x in selected[::5]]
		for n in names:
			Result.results[n].pop()

		for i in range(self.tableWidget_2.rowCount()):
			if(self.tableWidget_2.item(i,0).text() in names):
				delete_list.append(i)

		delete_list = sorted(delete_list)

		for ind in delete_list:
			self.tableWidget_2.removeRow(ind)
			for i in range(len(delete_list)):
				delete_list[i] -= 1

	# Saves result to a .csv file
	def click_save(self, selected):
		if(selected == []):
			return

		selected = selected[-5].text()
		Result.results[selected].save()

	# Shows an error message when something goes wrong
	# DISABLE THIS WHEN DEBUGGING OR TESTING
	def master_error_popup(self):
		error = QMessageBox()
		error.setWindowTitle("Error")
		error.setText("An unexpected error has ocurred.\nPlease restart the program.")
		error.setIcon(QMessageBox.Warning)
		error.setStandardButton(QMessageBox.Ok)
		error.buttonClicked.connect(self.master_exit)

		x = msg.exec_()

	# Quits the program when master_error_popup happens
	def master_exit(self):
		exit()

'''

Worker class for Threaded control

'''

class Worker(QRunnable):
	thread_control = {}

	def __init__(self, function, *args):
		super().__init__()
		self.function = function
		self.args = args
		self.signals = Signals()

	def run(self):
		global currently_selected_model

		if(self.function == "new"):
			displayname = self.args[0]

			if(displayname != "" and loaded_dataset != ""):
				if(Model.models.get(displayname, False) == False):
					if(os.name == 'nt'):
						data_name = loaded_dataset.split("\\")[-1]
					else:
						data_name = loaded_dataset.split("/")[-1]

					Model(displayname, loaded_dataset)

					item = displayname
					item2 = data_name

					if(Model.models[displayname].binary_feature_space and Model.models[displayname].binary_target_space):
						item3 = "Ready"
					else:
						item3 = "Not Ready"

					currently_selected_model = displayname
					self.signals.finished_new.emit(item, item2, item3)

		elif(self.function == "train"):

			if(currently_selected_model != ""):
				md = currently_selected_model

				if(Model.models[md].binary_feature_space and Model.models[md].binary_target_space):
					iterations = self.args[0]
					percentage = self.args[1]
					strat = self.args[2]

					for i in range(0, iterations):
						Model.models[md].holdout(train_s=percentage, stratify=strat)
						Model.models[md].fit()

						if(currently_selected_model == md):
							self.signals.update_info.emit()

						self.signals.update_list.emit(md, str(i+1) + "/" + str(iterations))

						# Stop proccess
						if(Worker.thread_control.get(md, False) == False):
							self.signals.finished_training.emit(md)
							return

					Model.models[md].calculate_top_snps()
					Result(md, Model.models[md].get_top_snps(top=None), times_fit=Model.models[md].times_fit, score=[Model.models[md].get_mean_precision(), Model.models[md].get_mean_recall()])
					Worker.thread_control.pop(md)

			self.signals.finished_training.emit(md, str(Result.results[md].other_models))

		elif(self.function == "dummy"):
			modelname = currently_selected_model
			if(modelname != ""):
				if(not Model.models[modelname].binary_feature_space and Model.models[modelname].target_column != None):
					Model.models[modelname].create_dummies()
			self.signals.finished_dummy_ova.emit(modelname)

		elif(self.function == "ova"):
			modelname = currently_selected_model
			if(modelname != ""):
				if(not Model.models[modelname].binary_target_space):
					Model.models[modelname].one_vs_all_transform(self.args[0])
			self.signals.finished_dummy_ova.emit(modelname)

		elif(self.function == "cross"):
			all_data = [x.text() for x in self.args[0][::5]]
			r = Result.results[all_data[0]]
			r = r.cross_check_models(all_data)
			self.signals.finished_cross.emit(r.modelname, True)

		elif(self.function == "cross_models"):
			all_data = [x.text() for x in self.args[0][::3]]
			r = Result.results[all_data[0]]
			r = r.cross_check_models(all_data)
			self.signals.finished_cross.emit(r.modelname, True)

		del(self)

'''

Worker Signals class for inter-threading communication

'''

class Signals(QObject):
	# Train operation
	update_info = pyqtSignal()
	update_list = pyqtSignal(str, str)
	finished_training = pyqtSignal(str, str)
	# New operation
	finished_new = pyqtSignal(str,str,str)
	# Dummy and OVA operation
	finished_dummy_ova = pyqtSignal(str)
	# Cross operation
	finished_cross = pyqtSignal(str, bool)

loaded_dataset = ""
version = "v1.0"
currently_selected_model = ""
all_selected_models = []
currently_selected_result = ""
Model.GUI = True

if __name__ == "__main__":
	import sys
	app = QtWidgets.QApplication(sys.argv)
	if(os.name == 'nt'):
		myappid = 'Biomal.EnGENE.Rosalind.1.0'
		ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
	ui = Win()
	ui.show()
	sys.exit(app.exec_() )


import gym
from pyvirtualdisplay import Display
from gym.envs.registration import register

def main():
    display = Display(visible=1, size=(1080, 720))
    display.start()
    register(
        id='Point-v0',
        entry_point='toy_envs.envs:PointEnv',
        max_episode_steps=200
    )
    env = gym.make('Point-v0')

    env.reset()
    while True:
        action = env.action_space.sample()
        obs, reward, done, info = env.step(action)
        env.render()
        if done:
            env.reset()

if __name__ == '__main__':
    main()


from .position import Position

class Portfolio(object):
    def __init__(self, price_handler, cash):
        """
        On creation, the Portfolio object contains no
        positions and all values are "reset" to the initial
        cash, with no PnL - realised or unrealised.

        Note that realised_pnl is the running tally pnl from closed
        positions (closed_pnl), as well as realised_pnl
        from currently open positions.
        """
        self.price_handler = price_handler
        self.init_cash = cash
        self.equity = cash
        self.cur_cash = cash
        self.positions = {}
        self.closed_positions = []
        self.realised_pnl = 0

    def _update_portfolio(self):
        """
        Updates the value of all positions that are currently open.
        Value of closed positions is tallied as self.realised_pnl.
        """
        self.unrealised_pnl = 0
        self.equity = self.realised_pnl
        self.equity += self.init_cash

        for ticker in self.positions:
            pt = self.positions[ticker]
            if self.price_handler.istick():
                bid, ask = self.price_handler.get_best_bid_ask(ticker)
            else:
                close_price = self.price_handler.get_last_close(ticker)
                bid = close_price
                ask = close_price
            pt.update_market_value(bid, ask)
            self.unrealised_pnl += pt.unrealised_pnl
            self.equity += (
                pt.market_value - pt.cost_basis + pt.realised_pnl
            )

    def _add_position(
        self, action, ticker,
        quantity, price, commission
    ):
        """
        Adds a new Position object to the Portfolio. This
        requires getting the best bid/ask price from the
        price handler in order to calculate a reasonable
        "market value".

        Once the Position is added, the Portfolio values
        are updated.
        """
        if ticker not in self.positions:
            if self.price_handler.istick():
                bid, ask = self.price_handler.get_best_bid_ask(ticker)
            else:
                close_price = self.price_handler.get_last_close(ticker)
                bid = close_price
                ask = close_price
            position = Position(
                action, ticker, quantity,
                price, commission, bid, ask
            )
            self.positions[ticker] = position
            self._update_portfolio()
        else:
            print(
                "Ticker %s is already in the positions list. "
                "Could not add a new position." % ticker
            )

    def _modify_position(
        self, action, ticker,
        quantity, price, commission
    ):
        """
        Modifies a current Position object to the Portfolio.
        This requires getting the best bid/ask price from the
        price handler in order to calculate a reasonable
        "market value".

        Once the Position is modified, the Portfolio values
        are updated.
        """
        if ticker in self.positions:
            self.positions[ticker].transact_shares(
                action, quantity, price, commission
            )
            if self.price_handler.istick():
                bid, ask = self.price_handler.get_best_bid_ask(ticker)
            else:
                close_price = self.price_handler.get_last_close(ticker)
                bid = close_price
                ask = close_price
            self.positions[ticker].update_market_value(bid, ask)

            if self.positions[ticker].quantity == 0:
                closed = self.positions.pop(ticker)
                self.realised_pnl += closed.realised_pnl
                self.closed_positions.append(closed)

            self._update_portfolio()
        else:
            print(
                "Ticker %s not in the current position list. "
                "Could not modify a current position." % ticker
            )

    def transact_position(
        self, action, ticker,
        quantity, price, commission
    ):
        """
        Handles any new position or modification to
        a current position, by calling the respective
        _add_position and _modify_position methods.

        Hence, this single method will be called by the
        PortfolioHandler to update the Portfolio itself.
        """

        if action == "BOT":
            self.cur_cash -= ((quantity * price) + commission)
        elif action == "SLD":
            self.cur_cash += ((quantity * price) - commission)

        if ticker not in self.positions:
            self._add_position(
                action, ticker, quantity,
                price, commission
            )
        else:
            self._modify_position(
                action, ticker, quantity,
                price, commission
            )


#################################################
#Author: Matt Lewis
#Department: Instructional Technology
#Institution: Eastern Washington University
##################################################
from .api_core import *
import requests
import simplejson as json

###########################################################################
################################ Outcomes #################################
###########################################################################
def getRootOutcomeGroup(domain, token, apiType):
  headers = {'Authorization':'Bearer %s'%token,'Content-Type':'application/json'}
  url = "https://%s/api/v1/%s/root_outcome_group" % (domain,apiType)
  return requests.get(url,headers=get_headers(token),verify=False).json()

###########################################################################
def getOutcome_groups(domain, token, apiType):
  # Get outcome subgroups (this needs to walk)
  groupOutcomeList = []
  all_done = False
  url = 'https://%s/api/v1/%s/outcome_groups?per_page=100' % (domain,apiType)
  while not all_done:
    response = requests.get(url,headers=get_headers(token))
    if not response.json():
      #yield []
      return
    else:
      for s in response.json():
        groupOutcomeList.append(s)
    if 'next' in response.links:
      url = response.links['next']['url']
    else:
      all_done = True
    return groupOutcomeList
###########################################################################
def getOutcomes(domain, token, apiType):
  outcomeList = []
  all_done = False
  url = 'https://%s/api/v1/%s/outcome_group_links?per_page=100' % (domain,apiType)
  #print(url)
  while not all_done:
    response = requests.get(url,headers=get_headers(token))
    #print(response.json())
    if not response.json():
      #yield []
      return
    else:
      for s in response.json():
        #t = flattenjson(s, "__")
        outcomeList.append(s)
    if 'next' in response.links:
      url = response.links['next']['url']
    else:
      all_done = True
    #print(outcomeList)
    return outcomeList

###########################################################################
def findOutcomeID(outcome_title, outcomeList):
    outcomeFound=""
    outcomeFound = {'outcomeID': 0, 'outcomeGroupID': 0, 'url': ''}
    if outcomeList:
      for outcome in outcomeList:
        #print(outcome_title, " : ", outcome['outcome']['title'])
        if outcome_title == outcome['outcome']['title']:
          outcomeFound = {'outcomeID': outcome['outcome']['id'], 'outcomeGroupID': outcome['outcome_group']['id'], 'url': outcome['outcome']['url']}
    return outcomeFound

###########################################################################
def findGroup(outcome_group_id, outcomeGroupList):
  foundGroup = False
  if not outcome_group_id:
    for group in outcomeGroupList:
      if outcome_group_id == group['id']:
        foundGroup = True
  return foundGroup

###########################################################################
def findGroupID(outcome_group, outcomeGroupList):
    groupID = ""
    for group in outcomeGroupList:
      if outcome_group == group['title']:
        groupID = group['id']
    return groupID
###########################################################################
def addGroup(domain, token, title, parent_id, apiType):
    headers = {'Authorization':'Bearer %s'%token,'Content-Type':'application/json'}
    vendor_guid = title
    if not parent_id:
      parent_id = rootOutcomeGroup['id']

    url = 'https://%s/api/v1/%s/outcome_groups/%d/subgroups' % (domain,apiType,parent_id)
    params = {'title':title,'description': '','vendor_guid':vendor_guid, 'parent_outcome_group_id': parent_id}
    r=requests.post(url,data=json.dumps(params),headers=headers)
    return r
###########################################################################
def enterOutcome(domain, token, outcome, url, callType):
    headers = {'Authorization':'Bearer %s'%token,'Content-Type':'application/json'}
    title = outcome['title']
    description = outcome['description']
    mastery_points = outcome['mastery_points']
    ratings = outcome['ratings']
    calculation_method = outcome['calculation_method']
    vendor_guid = outcome['title']
    if calculation_method == 'decaying_average' or calculation_method == 'n_mastery' :
      calculation_int = outcome['calculation_int']
      params = {'title':title,'description':description,'mastery_points': mastery_points,'ratings':ratings, 'calculation_method': calculation_method, 'calculation_int': calculation_int,'vendor_guid': vendor_guid}
    else:
      params = {'title':title,'description':description,'mastery_points': mastery_points,'ratings':ratings, 'calculation_method': calculation_method, 'vendor_guid': vendor_guid}
    if callType == 'post':
      r=requests.post(url,data=json.dumps(params),headers=headers)
    elif callType == 'put':
      r=requests.put(url,data=json.dumps(params),headers=headers)

    return r.status_code
###########################################################################
def update_outcome(domain, token, outcomeID, title, description):
    url = 'https://%s/api/v1/outcomes/%s' % (domain, outcomeID)

    outcomeParams = {'title':title,'description':description,'mastery_points':3}
    #outcomeParams = {"title": "v2 Dept Outcome42","display_name": "v2 Dept Outcome42", "description": "this is an outcome", "vendor_guid": 99, "mastery_points": 2}
    #outcomeParams = {'title':title,'description':description,'mastery_points': mastery_points,'ratings':ratings, 'calculation_method': calculation_method, 'calculation_int': calculation_int,'vendor_guid': vendor_guid}

    outcomeParams = {key: value for key, value in outcomeParams.items() if value != ""}

    r=requests.put(url,params=outcomeParams,headers=get_headers(token))

    return r.status_code
  ###########################################################################
def get_outcome(domain, token, outcomeID):
  outcomeList = []
  all_done = False
  url = 'https://%s/api/v1/outcomes/%s' % (domain, outcomeID)
  #print(url)
  while not all_done:
    response = requests.get(url,headers=get_headers(token))
    s = response.json()
    #print(s['id'])
    if not response.json():
      all_done = True
    else:
      outcomeList.append({'outcome_id': s['id'], 'context_id': s['context_id'],  'context_type': s['context_type'], 'vendor_guid': s['vendor_guid'], 'display_name': s['display_name'], 'title': s['title'], 'url': s['url'], 'can_edit': s['can_edit'], 'description': s['description'], 'calculation_method': s['calculation_method'], 'calculaation_int': s['calculation_int'], 'point_possible': s['points_possible'], 'mastery_points': s['mastery_points'], 'ratings': s['ratings'], 'assessed': s['assessed']})

    if 'next' in response.links:
      url = response.links['next']['url']
    else:
      all_done = True
    #print(outcomeList)
    return outcomeList

###########################################################################
#title,description,mastery_points,ratings,calculation_method,calculation_int,vendor_guid

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