import time
import numpy as np
import datetime as dt

class EventPoint:
    def __init__(self, price, time_of_event, is_sale=False):
        self.price = price
        self.time_of_event = time_of_event
        self.is_sale = is_sale

class QuantEngine:
    def __init__(self, allowance=100.00, is_mock=True):
        self.is_mock = is_mock
        self.funds_available = allowance
        self.seed_money = allowance
        self.min_samples = 60  # minimum number of samples required to initiate trade
        self.min_time_since_last_trade = 1  # measured in minutes
        self.time_of_last_trade = time.time()
        self.prices = []
        self.times = []
        self.data = {'x': [], 'y': [], 'x_p': [], 'y_p': []}
        self.shares_owned = 0
        self.invested = False
        self.emer_escape_threshold = .9  # default to sell as soon as there's loss
        self.last_purchase_price = None  # Don't set until you buy
        self.max_fund_value = allowance
        self.min_fund_value = allowance
        self.event_points = []
        self.name = "Unnamed"

    def should_buy(self):
        # This needs to be overridden by child
        raise Exception("not implemented")

    def buy(self):
        if self.invested:
            print("ERROR: trying to buy when you already bought")
            return

        amount_to_buy_in_dollars = self.how_much_to_buy()
        self.update_funds_available(amount_to_buy_in_dollars*-1)
        shares = amount_to_buy_in_dollars/(self.prices[-1])
        self.update_shares_owned(shares)
        self.invested = True
        self.last_purchase_price = self.prices[-1]

        print("Buying ", shares, " shares at ", self.prices[-1], " for $", amount_to_buy_in_dollars)

        event = EventPoint(price=amount_to_buy_in_dollars,
                           time_of_event=self.times[-1],
                           is_sale=False)
        self.event_points.append(event)

    def sell(self):
        if not self.invested:
            print("ERROR: trying to sell when you ain't got none")
            return

        amount_to_sell_in_dollars = self.shares_owned * self.prices[-1]
        self.update_funds_available(amount_to_sell_in_dollars)
        shares_sold = self.shares_owned
        self.update_shares_owned(self.shares_owned*-1)
        self.invested = False

        if amount_to_sell_in_dollars > self.max_fund_value:
            self.max_fund_value = amount_to_sell_in_dollars
        if amount_to_sell_in_dollars < self.min_fund_value:
            self.min_fund_value = amount_to_sell_in_dollars

        print("Sold ", shares_sold, " shares at ", self.prices[-1], " for $", amount_to_sell_in_dollars)

        event = EventPoint(price=amount_to_sell_in_dollars,
                           time_of_event=self.times[-1],
                           is_sale=True)
        self.event_points.append(event)

    def should_sell(self):
        # This needs to be overridden by child
        raise Exception("not implemented")

    def can_trade(self):
        # First make sure we have enough samples to decide
        if len(self.prices) < self.min_samples:
            msg = "Not enough samples to trade - num samples: " + len(self.prices)
            return msg

        # Next make sure that enough time has passed since the last trade
        time_now = time.time()
        elapsed_time_min = (time_now - self.time_of_last_trade)/60.0
        if elapsed_time_min < self.min_time_since_last_trade:
            msg = "Not enough time since last trade - time elapsed: " + elapsed_time_min
            return msg

        return ""

    def how_much_to_buy(self):
        # Get amount to buy. Probably all available.
        return self.funds_available

    def how_much_to_sell(self):
        # Probably all available
        return self.funds_available

    def update_funds_available(self, diff):
        # Diff positive for deposits and negative for withdrawals
        self.funds_available += diff

    def update_shares_owned(self, num_shares):
        self.shares_owned += num_shares

    def update_model(self, price, time_of_price):
        raise Exception("not implemented")

    def set_emer_escape_threshold(self, thresh):
        self.emer_escape_threshold = thresh

    def emergency_escape_bail(self, current_price):
        if not self.last_purchase_price:
            print("ERROR: last purchase price not initialized")
            return False
        if current_price <= self.last_purchase_price * self.emer_escape_threshold:
            return True
        return False

    @staticmethod
    def is_time_in_window(start_time, end_time, now_time):
        now_time = time.strftime('%H:%M:%S', time.localtime(now_time))
        datetime_object = dt.time.fromisoformat(now_time)
        if start_time < end_time:
            return start_time <= datetime_object <= end_time
        else:
            # Over midnight:
            return now_time >= start_time or now_time <= end_time

    def markets_just_closed(self):
        return self.is_time_in_window(dt.time(16, 00),
                                      dt.time(16, 30),
                                      self.times[-1])

    def markets_just_opened(self):
        return self.is_time_in_window(dt.time(8, 00),
                                      dt.time(8, 30),
                                      self.times[-1])

    def close(self):
        self.sell()
        self.exit_report()

    def exit_report(self):
        print("Engine (", self.name, ") "
              " Start: ",  self.seed_money,
              " End: ", self.funds_available,
              " Min: ", self.min_fund_value,
              " Max: ", self.max_fund_value)

class IthDerivBasedQuantEngine(QuantEngine):
    def __init__(self, deriv_dim=1, buy_threshold=0.01, sell_threshold=0):
        super().__init__()
        self.deriv_dim = deriv_dim
        self.buy_threshold = buy_threshold  # No idea if this is right or not
        self.sell_threshold = sell_threshold  # No idea if this is right or not
        self.name = str(self.deriv_dim) + 'thDeriv_buy:' + "%.2f" % buy_threshold + ',sell:' + "%.2f" % sell_threshold

    def should_buy(self):
        if len(self.data['y_p']) < 1:
            return False

        if self.invested:
            return False  # already bought

        trade_err_msg = self.can_trade()

        if self.data['y_p'][-1] >= self.buy_threshold:
            if trade_err_msg != "":
                print("Want to buy, but can't because: ", trade_err_msg)
                return False
            else:
                return True

        return False

    def should_sell(self):
        if len(self.data['y_p']) < 1:
            return False

        if not self.invested:
            return False  # already sold

        trade_err_msg = self.can_trade()

        if self.data['y_p'][-1] <= self.sell_threshold:
            if trade_err_msg != "":
                print("Want to sell, but can't because: ", trade_err_msg)
                return False
            else:
                return True

        return False

    def update_model(self, price, time_of_price):
        if len(self.times) == 0:
            # First data entry. Set as time of first trade
            self.time_of_last_trade = time_of_price

        self.prices.append(price)
        self.times.append(time_of_price)

        if len(self.prices) >= self.min_samples:
            self.data = {
                'x': self.times,
                'y': self.prices
            }
            # self.data['y_p'] = list(np.diff(self.data['y']) / np.diff(self.data['x']))
            # self.data['x_p'] = list((np.array(self.data['x'])[:-1] + np.array(self.data['x'])[1:]) / 2)

            self.data['y_p'] = list(np.diff(self.data['y'], self.deriv_dim))

            # Need to normalize derivative with respect to time units
            self.data['x_p'] = self.times[:-self.deriv_dim]

class TimeBasedQuantEngine(QuantEngine):
    def __init__(self):
        super().__init__()
        self.name = 'TimeBasedQuantEngine'

    def should_buy(self):
        if len(self.data['y_p']) < 1:
            return False

        if self.invested:
            return False  # already bought

        trade_err_msg = self.can_trade()

        if self.markets_just_closed():
            if trade_err_msg != "":
                print("Want to buy, but can't because: ", trade_err_msg)
                return False
            else:
                return True

        return False

    def should_sell(self):
        if len(self.data['y_p']) < 1:
            return False

        if not self.invested:
            return False  # already sold

        trade_err_msg = self.can_trade()

        if self.emergency_escape_bail(self.prices[-1]):
            print("Initiating sale for emergency escape")
            return True
        elif self.markets_just_opened():
            if trade_err_msg != "":
                print("Want to sell, but can't because: ", trade_err_msg)
                return False
            else:
                print("Initiating sale for market open")
                return True

        return False

    def update_model(self, price, time_of_price):
        if len(self.times) == 0:
            # First data entry. Set as time of first trade
            self.time_of_last_trade = time_of_price

        self.prices.append(price)
        self.times.append(time_of_price)

        if len(self.prices) >= self.min_samples:
            self.data = {
                'x': self.times,
                'y': self.prices
            }
            self.data['y_p'] = list(np.diff(self.data['y']) / np.diff(self.data['x']))
            self.data['x_p'] = list((np.array(self.data['x'])[:-1] + np.array(self.data['x'])[1:]) / 2)

class BaselineQuantEngine(QuantEngine):
    def __init__(self):
        super().__init__()
        self.name = 'BaselineQuantEngine'

    def should_buy(self):
        # Buy immediately
        if self.invested:
            return False  # already bought

        return True

    def should_sell(self):
        # Never sell
        return False

    def update_model(self, price, time_of_price):
        if len(self.times) == 0:
            # First data entry. Set as time of first trade
            self.time_of_last_trade = time_of_price

        self.prices.append(price)
        self.times.append(time_of_price)


import argparse
import sys
import matplotlib
#matplotlib.use('agg')
import matplotlib.pyplot as plt
import re
import matplotlib.pylab as pylab

def parselogfile(logfile):
    with open(logfile) as f:
        lines = [line.rstrip("\n") for line in f.readlines()]
    iters = []
    train_loss = []
    valid_loss = []
    for line in lines:
        if len(line) == 0:
            continue
        parts = re.split(" ", line)
        if "iters:" in parts and "train_loss:" in parts and "valid_loss:" in parts:
            for i in range(len(parts)):
                if parts[i]=="iters:":
                    iters.append(int(parts[i+1]))
                if parts[i]=="train_loss:":
                    train_loss.append(float(parts[i+1]))
                if parts[i]=="valid_loss:":
                    valid_loss.append(float(parts[i+1]))
        else:
            continue
    return iters, train_loss, valid_loss

def main(argv):

    ap = argparse.ArgumentParser()
    ap.add_argument("--log1", required=True, help = "path to log file")
    ap.add_argument("--log2", required=True, help = "path to log file")
    args = ap.parse_args()

    iters1, train1, valid1 = parselogfile(args.log1)
    iters2, train2, valid2 = parselogfile(args.log2)

    params = {'legend.fontsize': 'xx-large',
              'figure.figsize': (15, 5),
              'axes.labelsize': 'xx-large',
              'axes.titlesize':'xx-large',
              'xtick.labelsize':'xx-large',
              'ytick.labelsize':'xx-large'}
    pylab.rcParams.update(params)

    plt.plot(iters1[3:60], valid1[3:60], 'r', label="Loss = log1_valid_loss", linewidth=5.0)
    plt.plot(iters2[3:60], valid2[3:60], 'g', label="Loss = log2_valid_loss", linewidth=5.0)

    plt.xlabel('Epochs', fontsize=20)
    plt.ylabel('Validation loss', fontsize=20)
    plt.grid()
    plt.legend(loc='upper right')
    plt.show()

if __name__ == "__main__":
    main(sys.argv)


import pygame

# Initialize Pygame
pygame.init()

# Set up the screen
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Moving Ball")
# icon = pygame.image.load(r'C:\Users\Batyrkhan\OneDrive\Рабочий стол\PYTHON GITHUB\TSIS_7\ball movement\Fasticon-Angry-Birds-Red-bird.32.png')
# pygame.display.set_icon(icon)
# Set up the ball
ball_radius = 25
ball_pos_x = screen_width // 2
ball_pos_y = screen_height // 2
ball_color = (255, 0, 0)  # Red
ballX_change = 0
ballY_change = 0

# Main game loop
running = True
while running:
    # Event handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # if keystroke is pressed check whether its right or left
        if event.type ==pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                ballX_change = -0.3
            if event.key == pygame.K_RIGHT:
                ballX_change = 0.3
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                ballX_change = 0

        if event.type ==pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                ballY_change = -0.3
            if event.key == pygame.K_DOWN:
                ballY_change = 0.3
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                ballY_change = 0

    ball_pos_x += ballX_change
    ball_pos_y += ballY_change

    if ball_pos_x <= 25:
        ball_pos_x = 25
    elif ball_pos_x >= 775:
        ball_pos_x = 775
    if ball_pos_y >= 572:
        ball_pos_y = 572
    elif ball_pos_y <= 25:
        ball_pos_y = 25

    # Fill the screen with white color
    screen.fill((255, 255, 255))

    # Draw the ball
    pygame.draw.circle(screen, ball_color, (ball_pos_x, ball_pos_y), ball_radius)

    # Update the screen
    pygame.display.flip()

# Quit Pygame
pygame.quit()


import os
import sys
import numpy as np
from numpy.testing import assert_allclose
import porespy as ps
import openpnm as op
from pathlib import Path

class ExportTest():

    def setup_class(self):
        self.path = os.path.dirname(os.path.abspath(sys.argv[0]))

    def test_export_to_palabos(self):
        X = Y = Z = 20
        S = X * Y * Z
        im = ps.generators.blobs(shape=[X, Y, Z], porosity=0.7, blobiness=1)
        tmp = os.path.join(self.path, 'palabos.dat')
        ps.io.to_palabos(im, tmp, solid=0)
        assert os.path.isfile(tmp)
        with open(tmp) as f:
            val = f.read().splitlines()
        val = np.asarray(val).astype(int)
        assert np.size(val) == S
        assert np.sum(val == 0) + np.sum(val == 1) + np.sum(val == 2) == S
        os.remove(tmp)

    def test_to_vtk_2d(self):
        im = ps.generators.blobs(shape=[20, 20])
        ps.io.to_vtk(im, filename='vtk_func_test')
        assert os.stat('vtk_func_test.vti').st_size == 831
        os.remove('vtk_func_test.vti')

    def test_to_vtk_3d(self):
        im = ps.generators.blobs(shape=[20, 20, 20])
        ps.io.to_vtk(im, filename='vtk_func_test')
        assert os.stat('vtk_func_test.vti').st_size == 8433
        os.remove('vtk_func_test.vti')

    def test_dict_to_vtk(self):
        im = ps.generators.blobs(shape=[20, 20, 20])
        ps.io.dict_to_vtk({'im': im}, filename="dictvtk")
        a = os.stat('dictvtk.vti').st_size
        os.remove('dictvtk.vti')
        ps.io.dict_to_vtk({'im': im, 'im_neg': ~im}, filename="dictvtk")
        b = os.stat('dictvtk.vti').st_size
        assert a < b
        os.remove('dictvtk.vti')

    def test_to_stl(self):
        im = ps.generators.blobs(shape=[50, 50, 50])
        ps.io.to_stl(im, filename="im2stl")
        os.remove("im2stl.stl")

    def test_spheres_to_comsol_radii_centers(self):
        radii = np.array([10, 20, 25, 5])
        centers = np.array([[0, 10, 3],
                            [20, 20, 13],
                            [40, 25, 55],
                            [60, 0, 89]])
        ps.io.spheres_to_comsol(filename='sphere_pack', centers=centers, radii=radii)
        # os.remove("sphere_pack.mphtxt")

    def test_spheres_to_comsol_im(self):
        im = ps.generators.overlapping_spheres(shape=[100, 100, 100],
                                               r=10, porosity=0.6)
        ps.io.spheres_to_comsol(filename='sphere_pack', im=im)
        # os.remove("sphere_pack.mphtxt")

    def test_zip_to_stack_and_folder_to_stack(self):
        p = Path(os.path.realpath(__file__),
                 '../../../test/unit/blobs_layers.zip').resolve()
        im = ps.io.zip_to_stack(p)
        assert im.shape == (100, 100, 10)
        p = Path(os.path.realpath(__file__),
                 '../../../test/unit/blobs_layers').resolve()
        im = ps.io.folder_to_stack(p)
        assert im.shape == (100, 100, 10)

if __name__ == "__main__":
    t = ExportTest()
    self = t
    t.setup_class()
    for item in t.__dir__():
        if item.startswith("test"):
            print(f"Running test: {item}")
            t.__getattribute__(item)()


from pytz import utc
from datetime import datetime

from django.utils import timezone
from django.utils.timezone import utc
from rest_framework import serializers

GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'

def time_to_gmt(value):
    """
    :param value: datetime()
    :return:
        GMT time string
    """
    try:
        return serializers.DateTimeField(format=GMT_FORMAT, default_timezone=utc).to_representation(value)
    except Exception as e:
        return ''

def datetime_from_gmt(value):
    """
    :param value: gmt格式时间字符串
    :return:
        datetime() or None
    """
    try:
        t = datetime.strptime(value, GMT_FORMAT)
        return t.replace(tzinfo=utc)
    except Exception as e:
        return None

def time_to_local_naive_by_utc(value=None):
    '''
    时间转本地时间,如果无时区信息默认按utc时间

    :param value: datetime对象
    :return: datetime对象
    '''
    if value is None:
        value = timezone.now()

    # 无时区信息按UTC
    if timezone.is_naive(value):
        value = value.replace(tzinfo=utc)

    return timezone.localtime(value)

def to_localtime_string_naive_by_utc(value, fmt="%Y-%m-%d %H:%M:%S"):
    '''
    时间转本地时间字符串,如果无时区信息默认按utc时间

    :param value: datetime对象
    :param fmt: 时间格式字符串
    :return: 错误返回空字符串
    '''
    try:
        time = time_to_local_naive_by_utc(value).strftime(fmt)  # 本地时区时间
    except:
        time = ''
    return time

def to_django_timezone(value):
    """
    转换datetime到django设置的当前时区

    :return:
        若django未设置时区， 返回不带时区的datetime
        若django设置时区， 返回带时区的datetime
        如转换错误，返回原datetime
    """
    ctz = timezone.get_current_timezone()

    if ctz is not None:
        if timezone.is_aware(value):
            try:
                return value.astimezone(ctz)
            except OverflowError as e:
                return value
        try:
            return timezone.make_aware(value, ctz)
        except ValueError as e:
            return value
    elif (ctz is None) and timezone.is_aware(value):
        return timezone.make_naive(value, utc)
    return value


#!/usr/bin/python

import smtplib
import base64

filename = "G:\Py\Add.py"

# Read a file and encode it into base64 format
fo = open(filename, "rb")
filecontent = fo.read()
encodedcontent = base64.b64encode(filecontent)  # base64

sender = 'bhavy.rajgupta@gmail.com'
reciever = 'bhavy.rajgupta@gmail.com'

marker = "AUNQUEMARKER"

body ="""
This is a test mail to send an attachement.
"""
# Define the main headers.
part1 = """From: FroPerson <me@fromdomain.net>
To: To Person <amrod.admin@gmail.com>
Subject: SendingAttachement
MIME-Version: .0
Content-Type:multipart/mixed; boundary=%s
--%s
""" % (marker, marker)

# Define the message action
part2 = """Cotent-Type: text/plain
Content-Trnsfer-Encoding:8bit

%s
--%s
""" % (body,marker)

# Define the attachment section
part3 = """Content-Type: multipart/mixed; name=\"%s\"
Content-Transfer-Encodingbase64
Content-Disposition: attacment; filename=%s

%s
--%s--
""" %(filename, filename, encodedcontent, marker)
message = part1 + part2 + part3

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, reciever, message)
   print("Successfully sent email")
except Exception:
   print("Error: unable to send email")


import pygame
import standard_colors

class Game:

    def __init__(self):
        pygame.init()
        pygame.display.set_caption('Pygame window')
        dimensions = 640, 360
        self.application_surface = pygame.display.set_mode(dimensions)
        self.background_color = standard_colors.YELLOW

        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.running = False
                    elif event.key == pygame.K_r:
                        self.background_color = standard_colors.RED
                    elif event.key == pygame.K_g:
                        self.background_color = standard_colors.GREEN

            self.application_surface.fill(self.background_color)
            pygame.display.update()

if __name__ == "__main__":
    Game()


import random
from pprint import pprint

import chardet
import requests
from datetime import date, timedelta
from Crawler.settings import CRAWL_DELAY_DAY

class TengxunExpend:

    def returnThemeCode(self, theme):  # 这个是有用的，用来组合主题代码url的
        ent_Theme = 1537876288634
        sport_Theme = 1537877689177
        finance_Theme = 1537878365483
        tech_Theme = 1537879684280
        auto_Theme = 1537887032223
        house_Theme = 1537887128904
        news_Theme = 1537874915062
        if theme == 'news':
            return news_Theme
        if theme == 'ent':
            return ent_Theme
        if theme == 'sports':
            return sport_Theme
        if theme == 'tech':
            return tech_Theme
        if theme == 'auto':
            return auto_Theme
        if theme == 'house':
            return house_Theme
        if theme == 'finance':
            return finance_Theme

    def getThemeUrl(self, theme, today, pageNumber):
        rawUrl = "http://roll.news.qq.com/interface/cpcroll.php"
        rawReferer = '.qq.com/articleList/rolls/'  # 'http://news   前面还有这个东西
        print(theme)
        print(today)
        print(pageNumber)

        my_headers = [
            'Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30',
            'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0',
            'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)',
            'Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.9.168 Version/11.50',
            'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
            'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)']
        headers = {"User-Agent": random.choice(my_headers), 'Referer': 'http://' + theme + rawReferer}  # 默认值
        rawUrl = rawUrl + "?callback=rollback&mode=1&cata=&_=" + str(
            self.returnThemeCode(theme)) + "&site=" + theme + "&page=" + str(pageNumber) + "&date=" + today
        print(rawUrl)
        try:
            rawhtml = requests.get(rawUrl, headers=headers, allow_redirects=False,
                                   timeout=30)  # 一般提取文本的话，那就用text，如果是文件就content
            rawhtml.encoding = chardet.detect(rawhtml.content)['encoding']
            # print(rawhtml.url)
            print("状态码" + str(rawhtml.status_code))
            if rawhtml.status_code == 504:
                print(504)
                return
            print("页面的读取结果为")
            # print(rawhtml.text)
            if rawhtml.text.find('rollback') == 0:
                jsonString = rawhtml.text.split("rollback")[1]  # 把js提取出来就可以了
            else:
                jsonString = rawhtml.text
            print(jsonString)
            dicData = eval(jsonString)
            print(type(jsonString))
            print(jsonString)
            # print(dicData['data']['article_info'])
            print(len(dicData['data']['article_info']))
            if dicData['data'] == "":
                print("超过了最大页数了，跳出了就可以了")
                return
            urllist = []
            for one in dicData['data']['article_info']:
                # print(one['url'])
                print(one['url'].replace("\\", "/"))  # 还需要检查一下这个和之前的那种野蛮是不是一样的
                urllist.append(one['url'].replace("\\", "/"))
            return urllist
        except Exception as e:
            # print(e)
            return []

    def pageUrlMain(self, date=(date.today() + timedelta(days=-CRAWL_DELAY_DAY)).strftime("%Y-%m-%d") ):  # 写入url进入数据库，并且写入分类
        resultUrlDic = {}  # 写入数据库使用这个
        tempList = []
        themeList = ['news', 'ent', 'tech', 'auto', 'house', 'finance', 'sports']  # 一共有7个主题，其实不止这7个的
        for theme in themeList:
            print("第一个主题是")
            tempDList = []
            for i in range(1, 12):  # 一般是10页就很多的了。10页以内
                print("第" + str(i) + "页")
                responseList = self.getThemeUrl(theme, date, i)
                if len(responseList) == 0:
                    print("最大页数为" + str(i - 1) + "页")
                    break
                else:
                    tempList = tempList + responseList
                    tempDList += responseList
            resultUrlDic[theme] = tempDList
            print(resultUrlDic)
        tempList = set(tempList)
        count = 0
        print("列表的url数量有：" + str(len(tempList)))
        for key in resultUrlDic:
            count += len(resultUrlDic[key])
        print("url总共有" + str(count))

        print("这个是PageUrls内的提取到的url")
        # pprint(resultUrlDic)
        print(len(resultUrlDic))

        print("这个开始是list类型的结果")
        # print(tempList)

        pprint(tempList)

        # self.dbhelper.saveDicToMysql(resultUrlDic,date,"tengxun")   #参数，字典结果集，时间，分类,这儿是不需要写的。
        return list(tempList)  # 直接这儿去重后

class WangyiExpend:  # 这个是网易爬虫需要获得新闻页面的拓展的部分，直接构造成start_urls,再来做别的操作。
    def getRollUrlList(self,date=(date.today() + timedelta(days=-CRAWL_DELAY_DAY)).strftime("%Y-%m-%d") ):  #这个打开会是手机端的东西    #又重写了一遍了这个东西
        rollLatest = "http://news.163.com/latest/"  #这个就是默认新闻
        requestURL ="http://news.163.com/special/0001220O/news_json.js?0.3699326344116929"

        my_headers = [                       #这边为了得到直接的手机端的页面代码返回，直接使用手机ua
            'Mozilla/5.0 (Linux; Android 7.1.1; MI 6 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043508 Safari/537.36 MicroMessenger/6.5.13.1100 NetType/WIFI Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 7.1.1; MI 6 Build/NMF26X) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 Mobile Safari/537.36 Maxthon/3047',
            # 'Mozilla/5.0 (iPhone 84; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 MQQBrowser/7.8.0 Mobile/14G60 Safari/8536.25 MttCustomUA/2 QBWebViewType/1 WKType/1',
            'Mozilla/5.0 (Linux; U; Android 7.0; zh-cn; STF-AL00 Build/HUAWEISTF-AL00) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.9 Mobile Safari/537.36',
            'Mozilla/5.0 (Linux; U; Android 6.0.1; zh-CN; SM-C7000 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.6.2.948 Mobile Safari/537.36',
            'Mozilla/5.0 (Linux; Android 7.0; STF-AL10 Build/HUAWEISTF-AL10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043508 Safari/537.36 V1_AND_SQ_7.2.0_730_YYB_D QQ/7.2.0.3270 NetType/4G WebP/0.3.0 Pixel/1080']

        headers = {"User-Agent": random.choice(my_headers), 'Referer': "http://news.163.com/latest/"}  # 默认值

        try:
            rawhtml = requests.get(requestURL, headers=headers, allow_redirects=False,
                                   timeout=30)  # 一般提取文本的话，那就用text，如果是文件就content
            rawhtml.encoding = "GBK"  ##gbk>gb2312   使用这种方式尚且还有乱码的情况，部分乱码，那就是gbk可以修复
            # print(chardet.detect(rawhtml.content)['encoding'])
            if rawhtml.status_code == 504:
                print(504)
                return
            # print(rawhtml.url)
            print("状态码" + str(rawhtml.status_code))
            # print("页面的读取结果为")
            html = rawhtml.text

            result10=[]
            if html.find('"news":')!=-1:
                rawjsonString = html.split('"news":')[1].replace("};","")
                jsDic = eval("("+rawjsonString+")")
                for i in jsDic:
                    if len(i)!=0:
                        for content in i:
                            if content['p'].split(" ")[0]==date:   #这个是今天的
                                url = content['l']
                                if url.find("photoview")==-1:            #不是图片的写入这儿
                                    result10.append(content['l'])
                                else:
                                    pass

                # print("插入了"+str(len(result10)))
                print(result10)
                # self.saveListToMysql(result10, date)  # todo  这儿做了注释，不写入数据库，方便进行测试/

                return result10          #这个是返回前一天的所有的url链接放在这儿，大概200条以内，又变少了啊
        except Exception as e:
            print(e)
            return   #返回为空
if __name__ == '__main__':
    # 腾讯的获得新闻列表的模块测试
    # tengxun_expend =TengxunExpend()
    # tengxun_expend.pageUrlMain()

    # 网易的获得新闻的列表的模块测试
    wangyi_expend =WangyiExpend()
    print(wangyi_expend.getRollUrlList())  # 默认都是获得昨天的新闻。


from collections import defaultdict
from classes import Star, Plus, Optional, Sequence

def split_grammar(grammar):
    no_cycle_grammar = defaultdict(list)
    leftover_grammar = defaultdict(list)
    for nonterminal, alternatives in grammar.items():
        for alternative in alternatives:
            if not isinstance(alternative, Sequence):
                alternative = Sequence( [alternative] )

            multiple_options = False
            new_alternative = []

            for element in alternative.get_arg():
                if isinstance(element, Optional) or isinstance(element, Star):
                    multiple_options = True

                elif isinstance(element, Plus):
                    multiple_options = True
                    new_alternative.append(element.get_arg())

                else:
                    new_alternative.append(element)

            if multiple_options:
                if True:
                    new_alternative = Sequence( new_alternative )
                    if not new_alternative.contains_cycle(nonterminal, [], grammar):
                        no_cycle_grammar[nonterminal].append(new_alternative)
                    else:
                        leftover_grammar[nonterminal].append(new_alternative)
                leftover_grammar[nonterminal].append(alternative)
            else:
                if alternative.contains_cycle(nonterminal, [], grammar):
                    leftover_grammar[nonterminal].append(alternative)
                else:
                    no_cycle_grammar[nonterminal].append(alternative)

    return no_cycle_grammar, leftover_grammar


import random
from enum import Enum

class Orientation(Enum):
    Right = 0
    Down = 1
    Left = 2
    Up = 3

    def turn(self, clockwise):
        orientations = list(Orientation)
        index = (self.value + (1 if clockwise else -1)) % len(orientations)
        return orientations[index]

class Cell:
    def __init__(self, row, col):
        self.row = row
        self.col = col
        self.color = 0 if random.random() < 0.5 else 1
        # next cell based on orientation order: right, down, left, up
        self.direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]

    def flip(self):
        self.color = 1 - self.color

    def iswhite(self):
        return self.color == 0

    def get_loc(self):
        return (self.row, self.col)

    def next_loc(self, orientation):
        r, c = self.direction[orientation.value]
        return (self.row + r, self.col + c)

    def __str__(self):
        return f"({self.row}, {self.col}) {self.color}"

class Ant:
    def __init__(self):
        self.cell = Cell(0, 0)
        self.orientation = Orientation.Right
        self.traces = {}
        self.traces[self.cell.get_loc()] = self.cell
        self.bounds = [0, 0, 0, 0]      # top, bottom, left, right

    def move(self):
        self.turn_orientation()
        print(self.cell, self.orientation.name)
        self.update_cell()

    def turn_orientation(self):
        clockwise = self.cell.iswhite()
        self.orientation = self.orientation.turn(clockwise)

    def update_cell(self):
        self.cell.flip()
        loc = self.cell.next_loc(self.orientation)
        if loc not in self.traces:
            self.traces[loc] = Cell(loc[0], loc[1])
        self.cell = self.traces[loc]
        self.update_bounds(loc)

    def update_bounds(self, loc):
        r, c = loc
        if r < self.bounds[0]:
            self.bounds[0] = r
        elif r > self.bounds[1]:
            self.bounds[1] = r
        if c < self.bounds[2]:
            self.bounds[2] = c
        elif c > self.bounds[3]:
            self.bounds[3] = c

    def print_board(self):
        top, bottom, left, right = self.bounds
        board = []
        for i in range(top, bottom + 1):
            row = []
            for j in range(left, right + 1):
                cell = self.traces.get((i, j), Cell(i, j))
                row.append(str(cell.color))
            board.append(' '.join(row))
        print('\n'.join(board))

def langtons_ant(k):
    ant = Ant()
    for _ in range(k):
        ant.move()
    print(ant.cell)
    ant.print_board()

langtons_ant(6)


import numpy as np
import matplotlib.pyplot as plt

fig, ax1 = plt.subplots()

r2 = 0.05
r3 = 0.0075
r4 = 0.0025

i = np.linspace(0, 20, 20)
iQuadrat = np.square(i)

p2 = iQuadrat*r2
p3 = iQuadrat*r3
p4 = iQuadrat*r4

u2 = i*r2*1000
u3 = i*r3*1000
u4 = i*r4*1000

color = 'tab:red'
ax1.set_xlabel('Strom [A]')
ax1.set_ylabel('Verlustleistung [W]', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax1.set_ylim(0,2)

ax1.plot(i, p2, marker='x', color=color, label='0.05 $\Omega$')
ax1.plot(i, p3, marker='^', color=color, label='0.0075 $\Omega$')
ax1.plot(i, p4, marker='s', color=color, label='0.0025 $\Omega$')

plt.legend(loc='upper left')

ax2 = ax1.twinx()

color = 'tab:blue'
ax2.set_ylabel('Spannungsfall [mV]', color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim(0,200)

ax2.plot(i, u2, marker='x', color=color, label='0.05 $\Omega$')
ax2.plot(i, u3, marker='^', color=color, label='0.0075 $\Omega$')
ax2.plot(i, u4, marker='s', color=color, label='0.0025 $\Omega$')

plt.legend(loc='upper right')

plt.tight_layout()

#plt.show()

plt.savefig('results/shunt_loss.svg', format='svg', dpi=1200)
plt.clf()


import unittest

from spn.algorithms.Inference import likelihood, log_likelihood
from spn.structure.Base import Context
from spn.structure.StatisticalTypes import MetaType
from spn.structure.leaves.histogram.Histograms import create_histogram_leaf
from spn.structure.leaves.histogram.Inference import add_histogram_inference_support
from spn.structure.leaves.parametric.Parametric import *
import numpy as np

class TestParametric(unittest.TestCase):
    def setUp(self):
        add_histogram_inference_support()

    def test_Histogram_discrete_inference(self):
        data = np.array([1, 1, 2, 3, 3, 3]).reshape(-1, 1)
        ds_context = Context([MetaType.DISCRETE])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False)
        prob = np.exp(log_likelihood(hist, data))

        self.assertAlmostEqual(float(prob[0]), 2 / 6)
        self.assertAlmostEqual(float(prob[1]), 2 / 6)
        self.assertAlmostEqual(float(prob[2]), 1 / 6)
        self.assertAlmostEqual(float(prob[3]), 3 / 6)
        self.assertAlmostEqual(float(prob[4]), 3 / 6)
        self.assertAlmostEqual(float(prob[5]), 3 / 6)

        data = np.array([1, 1, 2, 3, 3, 3]).reshape(-1, 1)
        ds_context = Context([MetaType.DISCRETE])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=True)
        # print(np.var(data.shape[0]))
        prob = np.exp(log_likelihood(hist, data))
        self.assertAlmostEqual(float(prob[0]), 3 / 9)
        self.assertAlmostEqual(float(prob[1]), 3 / 9)
        self.assertAlmostEqual(float(prob[2]), 2 / 9)
        self.assertAlmostEqual(float(prob[3]), 4 / 9)
        self.assertAlmostEqual(float(prob[4]), 4 / 9)
        self.assertAlmostEqual(float(prob[5]), 4 / 9)

    def test_spike(self):
        np.random.seed(17)
        data = np.random.normal(10, 0.01, size=200).tolist() + np.random.normal(30, 10, size=200).tolist()
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        x = np.linspace(0, 60, 1000).tolist() + data[:, 0].tolist()
        x = np.sort(x)
        from scipy.stats import norm

        y = 0.5 * norm.pdf(x, 10, 0.01) + 0.5 * norm.pdf(x, 30, 10)
        ye = likelihood(hist, x.reshape((-1, 1)))
        error = np.sum(np.abs(ye[:, 0] - y))
        self.assertLessEqual(error, 900)
        # print(error)

        # import matplotlib.pyplot as plt
        # fig, ax = plt.subplots()
        # ax.plot(x, y, color="r", label="real", linestyle='--', dashes=(5, 1))
        # ax.plot(x, ye, color="b", label="estimated", linestyle='--', dashes=(5, 1))
        # plt.legend()
        # plt.show()

    def test_mixture_gaussians(self):
        np.random.seed(17)
        data = np.random.normal(10, 1, size=200).tolist() + np.random.normal(30, 1, size=200).tolist()
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        x = np.linspace(0, 60, 1000).tolist() + data[:, 0].tolist()
        x = np.sort(x)
        from scipy.stats import norm

        y = 0.5 * norm.pdf(x, 10, 1) + 0.5 * norm.pdf(x, 30, 1)
        ye = likelihood(hist, x.reshape((-1, 1)))
        error = np.sum(np.abs(ye[:, 0] - y))
        # print(error)
        self.assertLessEqual(error, 7)

    def test_valid_histogram(self):
        np.random.seed(17)
        data = [1] + [5] * 20 + [7] + [10] * 50 + [20] + [30] * 10
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)

        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        self.assertGreater(len(hist.bin_repr_points), 1)

if __name__ == "__main__":
    unittest.main()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
易盾反垃圾云服务图片结果查询接口python示例代码
接口文档: http://dun.163.com/api.html
python版本：python3.7
运行:
    1. 修改 SECRET_ID,SECRET_KEY,BUSINESS_ID 为对应申请到的值
    2. $ python image_query.py
"""
__author__ = 'yidun-dev'
__date__ = '2019/11/27'
__version__ = '0.2-dev'

import hashlib
import time
import random
import urllib.request as urlrequest
import urllib.parse as urlparse
import json
from gmssl import sm3, func

class ImageQueryByTaskIdsDemo(object):
    """易盾图片离线查询结果获取接口示例代码"""

    API_URL = "http://as.dun.163.com/v1/image/query/task"
    VERSION = "v1"

    def __init__(self, secret_id, secret_key, business_id):
        """
        Args:
            secret_id (str) 产品密钥ID，产品标识
            secret_key (str) 产品私有密钥，服务端生成签名信息使用
            business_id (str) 业务ID，易盾根据产品业务特点分配
        """
        self.secret_id = secret_id
        self.secret_key = secret_key
        self.business_id = business_id

    def gen_signature(self, params=None):
        """生成签名信息
        Args:
            params (object) 请求参数
        Returns:
            参数签名md5值
        """
        buff = ""
        for k in sorted(params.keys()):
            buff += str(k) + str(params[k])
        buff += self.secret_key
        if "signatureMethod" in params.keys() and params["signatureMethod"] == "SM3":
            return sm3.sm3_hash(func.bytes_to_list(bytes(buff, encoding='utf8')))
        else:
            return hashlib.md5(buff.encode("utf8")).hexdigest()

    def query(self, params):
        """请求易盾接口
        Args:
            params (object) 请求参数
        Returns:
            请求结果，json格式
        """
        params["secretId"] = self.secret_id
        params["businessId"] = self.business_id
        params["version"] = self.VERSION
        params["timestamp"] = int(time.time() * 1000)
        params["nonce"] = int(random.random() * 100000000)
        # params["signatureMethod"] = "SM3"  # 签名方法，默认MD5，支持SM3
        params["signature"] = self.gen_signature(params)

        try:
            params = urlparse.urlencode(params).encode("utf8")
            request = urlrequest.Request(self.API_URL, params)
            content = urlrequest.urlopen(request, timeout=10).read()
            return json.loads(content)
        except Exception as ex:
            print("调用API接口失败:", str(ex))

if __name__ == "__main__":
    """示例代码入口"""
    SECRET_ID = "your_secret_id"  # 产品密钥ID，产品标识
    SECRET_KEY = "your_secret_key"  # 产品私有密钥，服务端生成签名信息使用，请严格保管，避免泄露
    BUSINESS_ID = "your_business_id"  # 业务ID，易盾根据产品业务特点分配
    api = ImageQueryByTaskIdsDemo(SECRET_ID, SECRET_KEY, BUSINESS_ID)

    # 私有请求参数
    taskIds: list = ['093238e25fa54a3993849e72eb6040af', '8d26fded48d74263a9ad30e8199fdac7']  # 查询参数taskIds
    params = {
        "taskIds": taskIds
    }

    ret = api.query(params)

    code: int = ret["code"]
    msg: str = ret["msg"]
    if code == 200:
        resultArray: list = ret["result"]
        for result in resultArray:
            name: str = result.get("name", "")
            taskId: str = result["taskId"]
            status: int = result["status"]
            labelArray: list = result["labels"]
            print("taskId: %s, status: %s, name: %s, labels: %s" % (taskId, status, name, labelArray))
            maxLevel: int = -1
            # 产品需根据自身需求，自行解析处理，本示例只是简单判断分类级别
            for labelItem in labelArray:
                label: int = labelItem["label"]
                level: int = labelItem["level"]
                rate: float = labelItem["rate"]
                print("label: %s, level: %s, rate: %s" % (label, level, rate))
                maxLevel = level if level > maxLevel else maxLevel
            if maxLevel == 0:
                print("#图片查询结果: 最高等级为\"正常\"\n")
            elif maxLevel == 1:
                print("#图片查询结果: 最高等级为\"嫌疑\"\n")
            elif maxLevel == 2:
                print("#图片查询结果: 最高等级为\"确定\"\n")
    else:
        print("ERROR: code=%s, msg=%s" % (ret["code"], ret["msg"]))


import logging
import os
import shutil
import html
from os import path

from fetcherd.settings import Settings
from fetcherd.util import get_path, get_path_regex, load_source, load_providers

class Fetcherd:

    def __init__(self, args, config):
        self.logger = logging.getLogger('fetcherd')
        self.args = args
        self.config = config
        self.fetch_lock = False
        self.sort_lock = False

        loaded_source = load_source(config.source['modules_path'],
                                    config.source['class'])
        self.source = loaded_source(config.source['settings'])
        self.logger.info("Current source {}"
                         .format(self.config.source['class']))

        self.providers = load_providers(self.config.providers['modules_path'])

    def sort(self, source=None):
        if source is None:
            source = self.source

        logger = logging.getLogger('sort')

        if self.sort_lock:
            raise Exception("Sort is already in use")

        try:
            self.sort_lock = True

            for series in source.get_series():
                logger.info('Sorting {}'.format(series['title']))
                base_save_path = get_path(series['media_type'],
                                          self.config.sort['save_paths'],
                                          default=self.config.sort['save_path_default'])

                os.makedirs(base_save_path, exist_ok=True)

                search_title = series['title']
                if 'search_title' in series:
                    if series['search_title'] != '':
                        search_title = series['search_title']

                save_path = series['title']
                if 'save_path' in series:
                    if series['save_path'] != '':
                        save_path = series['save_path']

                save_path = path.join(base_save_path,
                                      save_path)

                for search_path in self.config.sort['search_paths']:
                    logger.info("Searching in {}".format(search_path))

                    for root, dirs, files in os.walk(search_path):
                        for f in files:
                            if search_title in f:
                                os.makedirs(save_path, exist_ok=True)
                                if not path.isfile(path.join(save_path, f)):
                                    logger.info('Found {}'.format(f))

                                    if 'providers_to_move' in self.config.sort \
                                       and series['provider'] in self.config.sort['providers_to_move']:
                                        shutil.move(path.join(root, f), save_path)
                                        op = 'Moving '
                                    else:
                                        shutil.copy(path.join(root, f), save_path)
                                        op = 'Copying'

                                    logger.info('{} {} to {}'
                                                .format(op, f, save_path))

        except Exception as e:
            logging.error('Error: {}'.format(str(e)))
        finally:
            self.sort_lock = False

    def fetch(self, source=None, base_providers=None):
        if source is None:
            source = self.source

        if base_providers is None:
            base_providers = self.providers

        if self.fetch_lock:
            raise Exception("Fetch is already in use")

        try:
            self.fetch_lock = True
            providers = {}
            logger = logging.getLogger('fetcher')

            for prov in source.get_base_providers():
                if prov['name'] not in base_providers:
                    logger.warning('Unsupported Base Provider: {0}'.format(prov['name']))
                else:
                    logger.info('Loaded {}'.format(prov['name']))

            for prov in source.get_providers():
                if prov['base_provider'] in base_providers:
                    providers.update({prov['id']:
                                      base_providers[prov['base_provider']](prov)})
                    logger.info('Loaded {} with options {}'
                                .format(prov['name'],
                                        prov['base_provider_options']))
                else:
                    logger.warning('Unsupported Base Provider \"{0}\" used by {1}'
                                    .format(prov['base_provider'], prov['name']))

            for series in source.get_series():
                if series['provider_id'] in providers:
                    logger.info("Fetching {}"
                                .format(html.unescape(series['title'])))
                    provider = providers[series['provider_id']]
                    current = series['current_count']

                    for ep in provider.fetch(series):
                        numb, link, title = ep
                        current = max(numb, current)
                        if numb > series['current_count']:
                            logger.info('Downloading {}'.format(title))
                            (dwn, name) = provider.download(link, self.config)
                            self.download(dwn, name)

                    if current > series['current_count']:
                        logging.info('Updating {} to episode count {}'
                                     .format(series['title'], current))
                        source.post_update_episode_count(series['id'], current)

                else:
                    logger.warning("Unsupported provider id: {}"
                                   .format(series['provider_id']))
        except Exception as e:
            logging.error('Error: {}'.format(str(e)))
        finally:
            self.fetch_lock = False

    def download(self, stream, filename):
        logger = logging.getLogger('downloads')
        path = get_path_regex(filename, self.config.fetch['save_paths'],
                              default=self.config.fetch['save_path_default'])

        logger.info("Downloading {} to {}".format(filename, path))

        with open(os.path.join(path, filename), 'wb') as f:
            for chunk in stream:
                if chunk:
                    f.write(chunk)
                    f.flush()

    def start(self):
        if self.config.webui['enable']:
            logging.debug("Setting up WebUI")
            from fetcherd.webui import WebUI
            self.webui = WebUI(self, self.config)
            logging.debug("Starting WebUI")
            self.webui.run()

    def reload_providers(self):
        self.logger.info("Reloading proivders")
        self.providers = load_providers(self.config.providers['modules_path'])

    def reload_source(self):
        self.logger.info("Reloading source")

        loaded_source = load_source(self.config.source['modules_path'],
                                    self.config.source['class'])
        self.source = loaded_source(self.config.source['settings'])
        self.logger.info("Current source {}"
                         .format(self.config.source['class']))

    def reload_config(self):
        self.logger.info("Reloading config")

        self.config = Settings(self.args['--config'])


"""
.. topic:: objetos (views)

    Os objetos são objetos que a coordenação necessita de um registro mínimo para referência em demandas.

    Um objeto tem atributos que são registrados no momento de sua criação. Todos são obrigatórios:

    * Título
    * Contraparte
    * Número do processo SEI
    * Data de início
    * Data de término
    * Valor associado
    * Descrição

.. topic:: Ações relacionadas aos objetos

    * Listar objetos: lista_objetos
    * Atualizar/visualizar dados de um objeto: update
    * Registrar um objeto no sistema: cria_objeto
    * Listar demandas de um determinado objeto: objeto_demandas

"""

# views.py na pasta objetos

from flask import render_template,url_for,flash, redirect,request,Blueprint, abort
from flask_login import current_user,login_required
from sqlalchemy import func, distinct, cast, Integer
from sqlalchemy.sql import label
from project import db
from project.models import User, Demanda, Coords, Objeto
from project.objetos.forms import objetoForm, ListaForm
from project.demandas.views import registra_log_auto

import locale
from datetime import datetime, date
from dateutil.rrule import rrule, MONTHLY

objetos = Blueprint('objetos',__name__,
                            template_folder='templates/objetos')

#
def none_0(a):
    '''
    DOCSTRING: Transforma None em 0.
    INPUT: campo a ser trandormado.
    OUTPUT: 0, se a entrada for None, caso contrário, a entrada.
    '''
    if a == None:
        a = 0
    return a

@objetos.route('/<lista>/<coord>/lista_objetos', methods=['GET', 'POST'])
def lista_objetos(lista,coord):
    """
    +---------------------------------------------------------------------------------------+
    |Apresenta uma lista dos objetos.                                                       |
    |                                                                                |
    |O objeto é algo tratado pela área técnica que justifica um registro específico.        |
    |Um contratao é um exemplo de objeto.                                                   |
    |                                                                                |
    |No topo da tela há a opção de se inserir um novo objeto e o número sequencial          |
    |de cada objeto (#), ao ser clicado, permite que seus dados possam ser editados.        |
    |                                                                                |
    +---------------------------------------------------------------------------------------+
    """

    hoje = datetime.today().date()

    form = ListaForm()

    coords = db.session.query(Coords.id,Coords.sigla)\
                       .order_by(Coords.sigla).all()
    lista_coords = [(c.id,c.sigla) for c in coords]
    lista_coords.insert(0,('',''))

    form.coord.choices = lista_coords

    if form.validate_on_submit():

        coord = form.coord.data

        if coord == '' or coord == None:
            coord = '*'

        return redirect(url_for('objetos.lista_objetos',lista=lista,coord=coord))

    else:

        if coord == '*':

            form.coord.data = ''

            coordenacao = db.session.query(Coords.id,
                                           Coords.sigla)\
                                    .subquery()

        else:

            form.coord.data = coord

            coordenacao = db.session.query(Coords.id,
                                           Coords.sigla)\
                                    .filter(Coords.id == cast(coord,Integer))\
                                    .subquery()

        if lista == 'todos':
            objetos_v = db.session.query(Objeto.id,
                                         Objeto.coord,
                                         Objeto.nome,
                                         Objeto.contraparte,
                                         Objeto.sei,
                                         Objeto.descri,
                                         Objeto.data_inicio,
                                         Objeto.data_fim,
                                         Objeto.valor,
                                         coordenacao.c.sigla)\
                                  .join(coordenacao, coordenacao.c.id == cast(Objeto.coord,Integer))\
                                  .order_by(Objeto.nome).all()

        elif lista == 'em execução':
            objetos_v = db.session.query(Objeto.id,
                                              Objeto.coord,
                                              Objeto.nome,
                                              Objeto.contraparte,
                                              Objeto.sei,
                                              Objeto.descri,
                                              Objeto.data_inicio,
                                              Objeto.data_fim,
                                              Objeto.valor,
                                              coordenacao.c.sigla)\
                                       .join(coordenacao, coordenacao.c.id == cast(Objeto.coord,Integer))\
                                       .filter(Objeto.data_fim >= hoje,
                                               Objeto.data_inicio <= hoje)\
                                       .order_by(Objeto.data_fim,Objeto.nome).all()

        quantidade = len(objetos_v)

        return render_template('lista_objetos.html', objetos=objetos_v,quantidade=quantidade,lista=lista,form=form)

### ATUALIZAR objeto

@objetos.route("/<int:objeto_id>/update", methods=['GET', 'POST'])
@login_required
def update(objeto_id):
    """
    +---------------------------------------------------------------------------------------+
    |Permite atualizar os dados de um objeto selecionado na tela de consulta.          |
    |                                                                                |
    |Recebe o ID do objeto como parâmetro.                                             |
    +---------------------------------------------------------------------------------------+
    """

    objeto = Objeto.query.get_or_404(objeto_id)

    form = objetoForm()

    if form.validate_on_submit():

        objeto.coord       = form.coord.data
        objeto.nome        = form.nome.data
        objeto.sei         = form.sei.data
        objeto.contraparte = form.contraparte.data
        objeto.data_inicio = form.data_inicio.data
        objeto.data_fim    = form.data_fim.data
        objeto.valor       = float(form.valor.data.replace('.','').replace(',','.'))
        objeto.descri      = form.descri.data

        db.session.commit()

        registra_log_auto(current_user.id,None,'itm')

        flash('objeto atualizado!')
        return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))
    # traz a informação atual do objeto
    elif request.method == 'GET':
        form.coord.data        = objeto.coord
        form.nome.data         = objeto.nome
        form.sei.data          = objeto.sei
        form.contraparte.data  = objeto.contraparte
        form.data_inicio.data  = objeto.data_inicio
        form.data_fim.data     = objeto.data_fim
        form.valor.data        = locale.currency( objeto.valor, symbol=False, grouping = True )
        form.descri.data       = objeto.descri

    return render_template('add_objeto.html', title='Update',
                           form=form, id=objeto_id)

### CRIAR objeto

@objetos.route("/criar", methods=['GET', 'POST'])
@login_required
def cria_objeto():
    """
    +---------------------------------------------------------------------------------------+
    |Permite registrar os dados de um objeto.                                               |
    +---------------------------------------------------------------------------------------+
    """

    form = objetoForm()

    coords = db.session.query(Coords.id,Coords.sigla)\
                       .order_by(Coords.sigla).all()
    lista_coords = [(c.id,c.sigla) for c in coords]
    lista_coords.insert(0,('',''))

    form.coord.choices = lista_coords

    if form.validate_on_submit():
        objeto = Objeto(coord       = form.coord.data,
                        nome        = form.nome.data,
                        contraparte = form.contraparte.data,
                        sei         = form.sei.data,
                        data_inicio = form.data_inicio.data,
                        data_fim    = form.data_fim.data,
                        valor       = float(form.valor.data.replace('.','').replace(',','.')),
                        descri      = form.descri.data)

        db.session.add(objeto)
        db.session.commit()

        registra_log_auto(current_user.id,None,'Objeto registrado!')

        flash('Objeto registrado!')
        return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))

    return render_template('add_objeto.html', form=form, id=0 )

# lista das demandas relacionadas a um objeto

@objetos.route('/<objeto_id>/objeto_demandas')
def objeto_demandas (objeto_id):
    """+--------------------------------------------------------------------------------------+
       |Mostra as demandas relacionadas a um objeto quando seu NUP é selecionado em uma  |
       |lista de objetos.                                                                |
       |Recebe o id do objeto como parâmetro.                                            |
       +--------------------------------------------------------------------------------------+
    """

    objeto_SEI = db.session.query(Objeto.sei,Objeto.nome).filter_by(id=objeto_id).first()

    SEI = objeto_SEI.sei
    SEI_s = str(SEI).replace('/','_')

    demandas_count = Demanda.query.filter(Demanda.sei.like('%'+SEI+'%')).count()

    demandas = Demanda.query.filter(Demanda.sei.like('%'+SEI+'%'))\
                            .order_by(Demanda.data.desc()).all()

    autores=[]
    for demanda in demandas:
        autores.append(str(User.query.filter_by(id=demanda.user_id).first()).split(';')[0])

    dados = [objeto_SEI.nome,SEI_s,'0','0']

    return render_template('SEI_demandas.html',demandas_count=demandas_count,demandas=demandas,sei=SEI, autores=autores,dados=dados)

#
#removendo uma atividade do plano de trabalho

@objetos.route('/<int:objeto_id>/delete', methods=['GET','POST'])
@login_required
def delete_objeto(objeto_id):
    """+----------------------------------------------------------------------+
       |Permite que o chefe, se logado, a remova um um objeto.           |
       |                                                                      |
       |Recebe o ID do objeto como parâmetro.                            |
       +----------------------------------------------------------------------+

    """
    if current_user.ativo != 1 or current_user.despacha != 1 or current_user.role != 'admin':
        abort(403)

    objeto = Objeto.query.get_or_404(objeto_id)

    nome = objeto.nome

    db.session.delete(objeto)
    db.session.commit()

    registra_log_auto(current_user.id,None,'Objeto ' + nome + ' excluído.')

    flash ('objeto ' + nome + ' excluído!','sucesso')

    return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))


import os
import numpy as np
from gym import utils, spaces
from gym.envs.mujoco import mujoco_env
from mujoco_py.builder import MujocoException

from .assets import kuka_asset_dir
from gym_kuka_mujoco.controllers import controller_registry

class KukaEnv(mujoco_env.MujocoEnv, utils.EzPickle):
    default_info = dict()
    def __init__(self,
                 controller,
                 controller_options,
                 model_path='full_kuka_no_collision_no_gravity.xml',
                 frame_skip=20,
                 time_limit=3.,
                 timestep=0.002,
                 random_model = False,
                 random_target = False,
                 quadratic_pos_cost = True,
                 quadratic_vel_cost = False):
        '''
        Constructs the file, sets the time limit and calls the constructor of
        the super class.
        '''
        self.random_model = random_model
        self.random_target = random_target
        self.quadratic_pos_cost = quadratic_pos_cost
        self.quadratic_vel_cost = quadratic_vel_cost

        utils.EzPickle.__init__(self)

        full_path = os.path.join(kuka_asset_dir(), model_path)

        self.time_limit = time_limit

        # Parameters for the cost function
        self.state_des = np.zeros(14)
        self.Q_pos = np.diag([1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.])
        self.Q_vel = np.diag([0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.])

        # Call the super class
        self.initialized = False
        mujoco_env.MujocoEnv.__init__(self, full_path, frame_skip)
        self.model.opt.timestep = timestep
        self.initialized = True

        # Create the desired controller.
        controller_cls = controller_registry[controller]
        self.controller = controller_cls(sim=self.sim, **controller_options)

        # Take the action space from the controller.
        self.action_space = self.controller.action_space

        self.last_action = None

    def viewer_setup(self):
        '''
        Overwrites the MujocoEnv method to make the camera point at the base.
        '''
        self.viewer.cam.trackbodyid = 0

    '''
    Step and helper methods. Only overwrite the helpers in the subclasses.
    '''
    def step(self, action, render=False):
        '''
        Simulate for `self.frame_skip` timesteps. Calls _update_action() once
        and then calls _get_torque() repeatedly to simulate a low-level
        controller.
        Optional argument render will render the intermediate frames for a smooth animation.
        '''
        # Hack to return an observation during the super class __init__ method.
        if not self.initialized:
            return self._get_obs(), 0, False, {}

        # Set the action to be used for the simulation.
        self._update_action(action)
        self.last_action = action

        # Get the reward from the state and action.
        state = np.concatenate((self.sim.data.qpos[:], self.sim.data.qvel[:]))

        # Simulate the low level controller.
        dt = self.sim.model.opt.timestep

        try:
            total_reward = 0
            total_reward_info = dict()
            for _ in range(self.frame_skip):
                torque = self._get_torque()
                self.sim.data.ctrl[:] = np.clip(torque, -300, 300)
                self.sim.data.qfrc_applied[:] = self._get_random_applied_force()
                self.sim.step()
                if not np.all(np.isfinite(self.sim.data.qpos)):
                    print("Warning: simulation step returned inf or nan.")
                reward, reward_info = self._get_reward(state, action)
                total_reward += reward*dt
                for k, v in reward_info.items():
                    if 'reward' in k:
                        total_reward_info[k] = total_reward_info.get(k,0) + v*dt
                if render:
                    self.render()

            # Get observation and check finished
            done = (self.sim.data.time > self.time_limit) or self._get_done()
            obs = self._get_obs()
            info = self._get_info()
            info.update(total_reward_info)
        except MujocoException as e:
            print(e)
            reward = 0
            obs = np.zeros_like(self.observation_space.low)
            done = True
            info = self.default_info

        return obs, total_reward, done, info

    def _update_action(self, a):
        '''
        This function is called once per step.
        '''
        self.controller.set_action(a)

    def _get_torque(self):
        '''
        This function is called multiple times per step to simulate a
        low-level controller.
        '''
        return self.controller.get_torque()

    def _get_obs(self):
        '''
        Return the full state as the observation
        '''

        if self.random_target:
            return np.concatenate((self._get_state_obs(), self._get_target_obs()))
        else:
            return self._get_state_obs()

    def _get_state_obs(self):
        '''
        Return the observation given by the state.
        '''
        if not self.initialized:
            return np.zeros(14)

        return np.concatenate([self.sim.data.qpos[:], self.sim.data.qvel[:]])

    def _get_target_obs(self):
        '''
        Return the observation given by the goal for the episode.
        '''
        return self.state_des[:7]

    def _get_reward(self, state, action):
        '''
        Compute single step reward.
        '''
        # quadratic cost on the state error
        reward_info = dict()
        reward = 0.

        err = self.state_des - state
        if self.quadratic_pos_cost:
            reward_info['quadratic_pos_cost'] = -err.dot(self.Q_pos).dot(err)
            reward += reward_info['quadratic_pos_cost']

        if self.quadratic_vel_cost:
            reward_info['quadratic_vel_cost'] = -err.dot(self.Q_vel).dot(err)
            reward += reward_info['quadratic_vel_cost']

        return reward, reward_info

    def _get_done(self):
        '''
        Check the termination condition.
        '''
        return False

    def _get_info(self):
        '''
        Get any additional info.
        '''
        q_err = self.state_des[:7] - self.sim.data.qpos
        v_err = self.state_des[7:] - self.sim.data.qvel
        dist = np.sqrt(q_err.dot(q_err))
        velocity = np.sqrt(v_err.dot(v_err))
        return {
            'distance': dist,
            'velocity': velocity
        }

    def _get_random_applied_force(self):
        return np.zeros(self.model.nv)

    '''
    Reset and helper methods. Only overwrite the helper methods in subclasses.
    '''
    def reset_model(self):
        '''
        Overwrites the MujocoEnv method to reset the robot state and return the observation.
        '''
        while(True):
            try:
                if self.random_model:
                    self._reset_model_params()
                if self.random_target:
                    self._reset_target()
                self._reset_state() # Always reset the state after the target is reset.
                self.sim.forward()
            except MujocoException as e:
                print(e)
                continue
            break

        return self._get_obs()

    def _reset_state(self):
        '''
        Reset the state of the model (i.e. the joint positions and velocities).
        '''
        qpos = 0.1*self.np_random.uniform(low=self.model.jnt_range[:,0], high=self.model.jnt_range[:,1], size=self.model.nq)
        qvel = np.zeros(7)
        self.set_state(qpos, qvel)

    def _reset_target(self):
        '''
        Reset the goal parameters. Target pose for the base environment, but may change with subclasses.
        '''
        self.state_des[:7] = self.np_random.uniform(self.model.jnt_range[:,0], self.model.jnt_range[:,1])

    def _reset_model_params(self):
        '''
        TODO: implement this for domain randomization.
        '''
        raise NotImplementedError


# References:
# https://www.geeksforgeeks.org/how-to-extract-text-from-images-with-python/
# https://pyimagesearch.com/2021/08/30/detecting-and-ocring-digits-with-tesseract-and-python/
# https://www.ShellHacks.com

from PIL import Image, ImageEnhance, ImageFilter
from pytesseract import pytesseract
import easyocr
import numpy as np
import cv2
import matplotlib.pyplot as plt
from selenium import webdriver
import calendar;
import time;
import pyautogui
import keyboard
import re #REGEX

# Counting thingy
import random
import numpy as np

# HTTP POST
import requests

# TELE
def send_to_telegram(message):

    apiToken = '5987706548:AAE89QD39pc_skzmSUYYTtGZg4xgcwQVSwc'
    chatID = '-877502094'
    apiURL = f'https://api.telegram.org/bot{apiToken}/sendMessage'

    try:
        response = requests.post(apiURL, json={'chat_id': chatID, 'text': message})
        print(response.text)
    except Exception as e:
        print(e)

arr = [0 for _ in range(21)]
chk_arr = [0 for _ in range(21)]
curr = 1 # curent tick
prev = 1 # last tick
mem = 1 # prev floor
counter = 0
offend = -1
flag = False # check if stop is same stop ('A'*5 = 'A'*n, n > 5)

# PyTesserect
path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
pytesseract.tesseract_cmd = path_to_tesseract
image_path = r'C:\Users\tanhs\Workspace\Projects\PythonScripts\hackandroll\imgs\latest_img.png'

firstx = 0
firsty = 0
secx = 0
secy = 0

while True:  # making a loop
    if keyboard.is_pressed('1'):
        firstx = pyautogui.position()[0]
        firsty = pyautogui.position()[1]
        break
while True:  # making a loop
    if keyboard.is_pressed('2'):
        secx = pyautogui.position()[0]
        secy = pyautogui.position()[1]
        break
print(f"{firstx}, {firsty}, {secx}, {secy}")

while True:
    gmt = time.gmtime()
    ts = calendar.timegm(gmt)
    im = pyautogui.screenshot()

    # Processing
    left = firstx
    top = firsty
    right = secx
    bottom = secy

    #Grayscale
    im = im.crop((left, top, right, bottom))
    im = im.convert('L')

    #Sharpened
    enhancer = ImageEnhance.Contrast(im)
    im = enhancer.enhance(3)

    im = im.filter(ImageFilter.GaussianBlur(radius=2))
    im = im.filter(ImageFilter.SMOOTH_MORE)
    im = im.filter(ImageFilter.EDGE_ENHANCE)

    display(im)

    # PYTESSERACT
    text = pytesseract.image_to_string(im, config='--psm 7 digits')
    print(f"text: {text}")
    if (text=="" or not any(c.isdigit() for c in text)):
        time.sleep(0.33)
        continue

    curr = int(re.findall("\d+", text)[0])
    print("Current Floor:", curr)
    if curr > 21:
        time.sleep(0.33)
        continue

    if prev == curr:
        counter += 1
    else:
        counter = 1
    if prev == curr and mem < curr and counter > 8:
        chk_arr[curr-1] = 1
        if flag == False and chk_arr[curr-2]==1:
            arr[curr-1] += 1
            arr[curr-2] += 1
            arr[0] = 0
            flag = True
    if prev != curr:
        mem = prev
        flag = False
        chk_arr[curr-3] = 0
    prev = curr
    print(arr)
    if max(arr) != 0:
        max_offending_floor = np.argmax(arr)+1
        print("Max Offending Floor:", max_offending_floor)
        if offend != max_offending_floor:
            r = requests.post('http://192.168.137.157:80/post', data="{'floor':"+str(max_offending_floor)+"}")
            print("POST SENT")
            send_to_telegram(f"OFFENDING FLOOR: {max_offending_floor}, NUMBER OF OFFENCES: {arr[max_offending_floor-1]}")
            print("TELEGRAM SENT")
            offend = max_offending_floor
    time.sleep(0.33)


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

#打开文件对话框

import wx
import os

def ShowColourDialog():
	dialog = wx.ColourDialog(None, "hello world")
	dialog.ShowModal()
	dialog.Destroy()
if __name__ == "__main__":
	app = wx.PySimpleApp()
	ShowColourDialog()


from ast import main
from json import load
import json
from random import randint
import pygame
import sys
from models.BugsStatic import BugStatic
from models.Bullet import Bullet
from models.Button import Button
from models.Platform import Platform
from models.Point import Point
from models.Text import Text
from colors import *
from Config import *

def exit():
    """Exits the game and prints a farewell message."""
    print('See you soon!')
    pygame.quit()
    sys.exit()

def randIntPos(axis: str, size):
    """Generates a random integer position within the specified axis and size limits."""
    if axis == 'x':
        return randint(size, LIMITWIDTHGROUND-size)
    else:
        return randint(150 + size, LIMITHEIGHTGROUND-size)

def createScreen():
    """Initializes the game screen and sets its caption."""
    try:
        screen = pygame.display.set_mode(SCREENSIZE)
        screen.fill(WHITE, pygame.Rect(
            0, 0, SCREENWIDTH, SCREENHEIGHT))
        pygame.display.set_caption("PokeBug")
        pygame.display.set_icon(pygame.image.load(
            os.path.join('assets', 'images', 'totodyle.png')))
        return screen
    except pygame.error as e:
        errMsg(e)

def cleanScreen(screen):
    """Clears the game screen by filling it with black color."""
    screenBackroundRect = pygame.Rect(0, 0, SCREENWIDTH, SCREENHEIGHT)
    screen.fill(BLACK, screenBackroundRect)

def drawBackground(screen: pygame.display, background):
    """Draws the specified background image on the game screen."""
    screenBackroundRect = pygame.Rect(0, 0, SCREENWIDTH, SCREENHEIGHT)
    screen.blit(background, screenBackroundRect)

def controlesMenu(screen, levelCanvas):
    """Displays the controls menu and handles user interaction."""
    image = BACKGROUNDCONTROLES
    rectImage = image.get_rect(center=(SCREENWIDTH/2, SCREENHEIGHT/2))
    screen.blit(image, rectImage)

    ButtonCross = Button(40, 40, rectImage.left+70, rectImage.top+70,
                         'X', screen, DARKBLUE, WHITE, 20)
    ButtonCross.CreateButtonMenu()
    pygame.display.flip()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
                if event.key == pygame.K_p:
                    return
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if ButtonCross.buttonPressed():
                        return Pause(screen, levelCanvas)

def Pause(screen, levelCanvas):
    """Displays the pause menu and handles user interaction."""
    muteValue = levelCanvas.getMuteValue()
    if muteValue:
        str = 'Mute On'
    else:
        str = 'Mute Off'

    image = BACKGROUNDPAUSE
    rectImage = image.get_rect(center=(SCREENWIDTH/2, SCREENHEIGHT/2))
    screen.blit(image, rectImage)
    ButtonCross = Button(40, 40, rectImage.left+70, rectImage.top+100,
                         'X', screen, DARKBLUE, WHITE, 20)
    ButtonCross.CreateButtonMenu()

    buttonMute = Button(150, 80, rectImage.centerx - 200, rectImage.centery+80,
                        f'{str}', screen, DARKBLUE, WHITE, 14)
    buttonMute.setFont(14)
    buttonMute.CreateButtonMenu()
    buttonControles = Button(180, 80, rectImage.centerx + 200, rectImage.centery+80,
                             'Controls', screen, DARKBLUE, WHITE, 14)
    buttonControles.setFont(14)
    buttonControles.CreateButtonMenu()

    pygame.display.flip()
    while True:
        if muteValue == False or muteValue == None:
            # ButtonMute.colorText = GREEN
            buttonMute.setText('Mute On', RED)
            # ButtonMute.CreateButtonMenu()
        else:
            # ButtonMute.colorText = RED
            buttonMute.setText('Mute Off', GREEN)
            # ButtonMute.CreateButtonMenu()
            # pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
                if event.key == pygame.K_p:
                    return
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if buttonMute.buttonPressed():
                        muteValue = not muteValue
                        buttonMute.setFont(14)
                        buttonMute.CreateButtonMenu()
                        pygame.display.flip()
                    if buttonControles.buttonPressed():
                        controlesMenu(screen, levelCanvas)
                    if ButtonCross.buttonPressed():
                        return

def mainMenu(screen, mainMusic, muteValue: bool):

    if muteValue:
        mainMusic.set_volume(0)
    else:
        mainMusic.set_volume(0.5)
    """Displays the main menu and handles user interaction,game settings and credits screen."""
    background = BACKGROUNSEADAY
    drawBackground(screen, background)
    muteValue = False if muteValue == None else True
    ButtonStart = Button(BUTTONWIDTH, BUTTONHEIGHT,
                         (SCREENWIDTH)/2, (BUTTONHEIGHT*3), 'Start', screen)
    ButtonStart.CreateButtonMenu()
    ButtonOptions = Button(BUTTONWIDTH, BUTTONHEIGHT,
                           (SCREENWIDTH)/2, (SCREENHEIGHT)/2, 'Options', screen)
    ButtonOptions.CreateButtonMenu()
    ButtonExit = Button(BUTTONWIDTH, BUTTONHEIGHT,
                        (SCREENWIDTH)/2, (SCREENHEIGHT-BUTTONHEIGHT*3), 'Exit', screen)
    ButtonExit.CreateButtonMenu()
    pygame.display.flip()
    while True:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
            if event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1:
                    if ButtonStart.buttonPressed():
                        # enviar al usuario al level selector
                        return muteValue
                        # return muteValue
                    if ButtonOptions.buttonPressed():
                        optionMenu(screen, mainMusic, muteValue)
                        return
                    if ButtonExit.buttonPressed():
                        exit()

def optionMenu(screen, mainMusic, muteValue: bool):
    """Displays the options menu and handles user interaction."""
    muteValue = True if muteValue == None else False
    drawBackground(screen, BACKGROUNSEADAY)
    ButtonBack = Button(BUTTONWIDTH, BUTTONHEIGHT,
                        (SCREENWIDTH)/2, (BUTTONHEIGHT*3), 'Back', screen)
    ButtonBack.CreateButtonMenu()
    ButtonCredits = Button(BUTTONWIDTH, BUTTONHEIGHT, (SCREENWIDTH)/2,
                           (SCREENHEIGHT-BUTTONHEIGHT*3), 'Credits', screen)
    ButtonCredits.CreateButtonMenu()

    ButtonMute = Button(BUTTONWIDTH, BUTTONHEIGHT,
                        (SCREENWIDTH)/2, (SCREENHEIGHT)/2, f'Mute', screen, colorText=GREEN)
    ButtonMute.CreateButtonMenu()
    pygame.display.flip()

    while True:
        if muteValue == False or muteValue == None:
            # ButtonMute.colorText = GREEN
            ButtonMute.setText('Mute', RED)
            # ButtonMute.CreateButtonMenu()
        else:
            # ButtonMute.colorText = RED

            ButtonMute.setText('Mute', GREEN)
            # ButtonMute.CreateButtonMenu()
            # pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if ButtonBack.buttonPressed():
                        mainMenu(screen, mainMusic, muteValue)
                        return
                    if ButtonCredits.buttonPressed():
                        creditsMenu(screen, mainMusic, muteValue)
                        return
                    if ButtonMute.buttonPressed():
                        muteValue = not muteValue
                        ButtonMute.CreateButtonMenu()
                        pygame.display.flip()

def creditsMenu(screen, mainMusic, muteValue: bool):
    """Displays the credits menu and handles user interaction."""
    background = BACKGROUNSEANIGHT
    drawBackground(screen, background)
    muteValue = muteValue

    ButtonBack = Button(BUTTONWIDTH, BUTTONHEIGHT-20,
                        (BUTTONWIDTH), (SCREENHEIGHT-BUTTONHEIGHT*1.5), 'Back', screen)
    ButtonBack.CreateButtonMenu(BLACK, borderRadius=8)

    ButtonExit = Button(BUTTONWIDTH, BUTTONHEIGHT-20, (SCREENWIDTH -
                        BUTTONWIDTH), (SCREENHEIGHT-BUTTONHEIGHT*1.5), 'Exit', screen)
    ButtonExit.CreateButtonMenu(BLACK, borderRadius=8)

    copywriteImg = loadImage('gameFreak.png')
    copyImgRect = copywriteImg.get_rect()
    copyImgRect = copywriteImg.get_rect(
        center=(copyImgRect.centerx, copyImgRect.centery))
    copyImgRect.center = (((SCREENWIDTH / 2), (0+BUTTONHEIGHT*3)))
    screen.blit(copywriteImg, copyImgRect)

    Text('Juego creado por Mateo Barbato', WHITE, 24, False).blitText(
        screen, (SCREENWIDTH/2, SCREENHEIGHT/2.5), None)
    Text('Idea originada con Pokemon dandole una vuelta creativa', WHITE,
         24, False).blitText(screen, (SCREENWIDTH/2, SCREENHEIGHT/2.25), None)
    Text('Assets obtenidos de la pagina Sprite Database', WHITE, 24,
         False).blitText(screen, (SCREENWIDTH/2, SCREENHEIGHT/2), None)

    pygame.display.flip()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
            if event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1:
                    if ButtonBack.buttonPressed():
                        optionMenu(screen, mainMusic, muteValue)
                        return
                    if ButtonExit.buttonPressed():
                        sys.exit()

def levelSelector(screen, dataStars):
    """Loads the specified level into the game.

    Parameters:
        spriteGroupAll (pygame.sprite.Group): The group of all sprites in the game.
        map (list of lists): The level map.

    Additional Explanation:
        This function reads the level map and creates the corresponding sprites for the level.
        It also sets the starting positions of the player and other objects in the level.
    """

    drawBackground(screen, BRACKGROUNDGRASS)
    drawBackground(screen, BRACKGROUNDTREES)
    ButtonHeight = 90
    ButtonWidth = 130
    ButtonCross = Button(40, 40, 150, 120,
                         'X', screen, colorbackground=LAVENDER, fontSize=20)
    # -------------------------------------------------------------------------
    Level1 = Button(ButtonWidth, ButtonHeight, SCREENWIDTH/3 - 80,
                    SCREENHEIGHT/2.5, 'Level 1', screen, GREENMENU, WHITE)
    Text(f'{dataStars["1"]}/3 Stars', YELLOW, 24, False).blitText(
        screen, (SCREENWIDTH/3 - 80, (SCREENHEIGHT/2.5)+70), None)
    # -------------------------------------------------------------------------
    Level2 = Button(ButtonWidth, ButtonHeight, SCREENWIDTH/2,
                    SCREENHEIGHT/2.5, 'Level 2', screen, GREENMENU, WHITE)
    Text(f'{dataStars["2"]}/3 Stars', YELLOW, 24, False).blitText(
        screen, (SCREENWIDTH/2, (SCREENHEIGHT/2.5)+70), None)
    # -------------------------------------------------------------------------
    Level3 = Button(ButtonWidth, ButtonHeight, SCREENWIDTH - SCREENWIDTH/3 + 80,
                    SCREENHEIGHT / 2.5, 'Level 3', screen, GREENMENU, WHITE)
    Text(f'{dataStars["3"]}/3 Stars', YELLOW, 24, False).blitText(
        screen, (SCREENWIDTH - SCREENWIDTH/3 + 80, (SCREENHEIGHT/2.5)+70), None)
    # -------------------------------------------------------------------------
    Level1.CreateButtonMenu()
    Level2.CreateButtonMenu()
    Level3.CreateButtonMenu()
    ButtonCross.CreateButtonMenu(borderRadius=5)
    pygame.display.flip()
    while True:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
            if event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1:
                    if Level1.buttonPressed():
                        return False, 1
                    if Level2.buttonPressed():
                        if dataStars['1'] > 1:
                            return False, 2
                        else:
                            pass
                    if Level3.buttonPressed():
                        if dataStars['2'] > 1:
                            return False, 3
                        else:
                            pass
                    if ButtonCross.buttonPressed():
                        return True, 0

# def loadLevel(spriteGroupAll, map):
def levelFinished(screen, background, currentLevel, lastScore, bestScores):
    """Displays the level finished screen and handles user interaction.

    Parameters:
        screen (pygame.Surface): The pygame Surface object representing the game screen.
        background (pygame.Surface): The background image to draw.
        currentLevel (int): The current level number.
        lastScore (int): The score for the current level.
        bestScores (list of dicts): The list of best scores for each level.

    Return Value:
        A tuple of two booleans:
            * The first boolean indicates whether to restart the current level.
            * The second boolean indicates whether to go to the level selector.

    Additional Explanation:
        This function displays the level finished screen, showing the player's score and the best scores.
        It handles user interaction by checking for mouse clicks on the buttons.
    """
    drawBackground(screen, background)
    if bestScores == 0:
        pass
    else:
        highScores = bestScores
    Text('Your score', WHITE, 42, False).blitText(
        screen, (SCREENWIDTH/2, SCREENHEIGHT/5), WHITE)
    Text(str(lastScore), WHITE, 42, True).blitText(
        screen, (SCREENWIDTH/2, SCREENHEIGHT/4), WHITE)
    print(len(highScores))
    for i, value in enumerate(highScores, 1):

        Text(f'Player {i} : {value["score"]}', WHITE, 22, True).blitText(
            screen, (SCREENWIDTH/2, SCREENHEIGHT/4 + 80*i), WHITE)

    ButtonLevels = Button(180, 40, 150, 120,
                          'Levels', screen, colorbackground=LAVENDER, fontSize=20)
    Restart = Button(160, 70, SCREENWIDTH/2 - 250,
                     SCREENHEIGHT-SCREENHEIGHT/7, 'Restart', screen)
    Continue = Button(160, 70, SCREENWIDTH/2 + 250,
                      SCREENHEIGHT-SCREENHEIGHT/7, 'Continue', screen)
    Restart.setFont(18)
    Restart.CreateButtonMenu()
    Continue.setFont(18)
    Continue.CreateButtonMenu()
    ButtonLevels.CreateButtonMenu(borderRadius=5)
    pygame.display.flip()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit()
            if event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1:
                    if Restart.buttonPressed():
                        return True, (currentLevel)
                    if Continue.buttonPressed():
                        if currentLevel == 1:
                            newLevel = 2
                            if lastScore > 60:
                                return True, newLevel
                            else:
                                pass
                        if currentLevel == 2:
                            newLevel = 3
                            if lastScore > 60:
                                return True, newLevel
                            else:
                                pass
                        if currentLevel == 3:
                            return False, 0

                    if ButtonLevels.buttonPressed():
                        return False, 0

def saveScores(data, scoreTotal, levelSelected):
    """
    This function saves the scores of the game in a JSON file.

    Args:
        data (dict): The JSON data that contains the scores of the game.
        scoreTotal (int): The score of the current game.
        levelSelected (int): The level of the game that was played.

    Returns:
        list: The list of the top 5 scores for the selected level.
    """
    if levelSelected == 1:
        scoreList = data['Level 1']
    elif levelSelected == 2:
        scoreList = data['Level 2']
    elif levelSelected == 3:
        scoreList = data['Level 3']
    saved = False
    scoreList = sorted(
        scoreList, key=lambda k: k['score'], reverse=True)
    for i in range(len(scoreList)):
        if scoreList[i]['score'] < scoreTotal and saved == False:
            aux = dict()
            aux['score'] = scoreTotal
            scoreList.append(aux)
            saved = True
    scoreList = sorted(
        scoreList, key=lambda k: k['score'], reverse=True)

    if levelSelected == 1:
        data['Level 1'] = scoreList[0:5]
    elif levelSelected == 2:
        data['Level 2'] = scoreList[0:5]
    elif levelSelected == 3:
        data['Level 3'] = scoreList[0:5]

    try:
        with open(r"./db.json", 'w') as dataEnd:
            json.dump(data, dataEnd, indent=2)
    except OSError.filename as Err:
        errMsg(
            "Error while writing the scores to the datafile. The score wont be saved")
        print(Err)
        errMsg(
            'Please validate the files and check again. If the problem persist re-install the files')
    return scoreList[0:5]

def saveScoresLevel(dataStars, lastScore, levelSelected):
    # dict['1'] : 0, 112, '1'
    levelSelected = str(levelSelected)
    dictionarioLevel = dataStars
    if lastScore > 60 and lastScore < 120:
        dictionarioLevel[levelSelected] = 1
    elif lastScore > 120 and lastScore < 180:
        dictionarioLevel[levelSelected] = 2
    elif lastScore > 180:
        dictionarioLevel[levelSelected] = 3
    else:
        dictionarioLevel[levelSelected] = 0

    try:
        with open(r"./dbLevel.json", 'w') as dataEnd:
            json.dump(dictionarioLevel, dataEnd, indent=2)
    except OSError.filename as Err:
        errMsg(
            "Error while writing the scores to the datafile. The score wont be saved")
        print(Err)
        errMsg(
            'Please validate the files and check again. If the problem persist re-install the files')

    pass

def createDefaultDb():
    """
    This function creates a default JSON file with empty data for the scores of the game.

    Returns:
        dict: The JSON data with the empty scores.
    """
    data = dict()

    for i in range(1, 4):
        arrLevel = []
        for j in range(1, 6):
            arr = dict()
            arr['score'] = 0
            arrLevel.append(arr)
        data[f'Level {i}'] = arrLevel
    return data

def loadDb():
    try:
        # Intento abrir la base de datos.
        with open('./db.json') as db:
            data = json.load(db)
        # Si abre asigno los datos a las variables del juego ( maxScore y Attempts a superar el max score)
        return data
    except FileNotFoundError as Err:
        # Si falla por no encontrar el archivo me guardo el mensaje del except como Err
        # Despues creo una base de datos nueva (todo en 0) y la utilizo para cargar los datos a mis variables
        # (tambien podes hacer esto al final de juego, yo lo hice del principio para atajarme de errores en medio de la partida)
        data = createDefaultDb()
        with open('./db.json', 'w') as file:
            json.dump(data, file, indent=2)
        # Le muestro los mensajes default y el mensaje de Err que me viene del except
        # la funcion errMsg es una funcion propia que solo aniade espacios arriba y abajo para que sea mas legible todo pero nada mas
        errMsg("Error while trying to read data for the scores")
        print(Err)
        errMsg('Please validate the install and try again. The game can run without it but the db has been reseted to default (0)')
        # por ultimo asigno los datos de la nueva base a las nuevas variables
        return data

def createDefaultLevelDb():
    """
    This function creates a default JSON file with empty data for the scores of the Levels.

    Returns:
        dict: The JSON data with the empty scores.
    """
    data = dict()

    for i in range(1, 4):
        data[f'{i}'] = 0
    return data

def loadLevelDb():
    try:
        # Intento abrir la base de datos.
        with open('./dbLevel.json') as db:
            data = json.load(db)
        # Si abre asigno los datos a las variables del juego ( maxScore y Attempts a superar el max score)
        return data
    except FileNotFoundError as Err:
        # Si falla por no encontrar el archivo me guardo el mensaje del except como Err
        # Despues creo una base de datos nueva (todo en 0) y la utilizo para cargar los datos a mis variables
        # (tambien podes hacer esto al final de juego, yo lo hice del principio para atajarme de errores en medio de la partida)
        data = createDefaultLevelDb()
        with open('./dbLevel.json', 'w') as file:
            json.dump(data, file, indent=2)
        # Le muestro los mensajes default y el mensaje de Err que me viene del except
        # la funcion errMsg es una funcion propia que solo aniade espacios arriba y abajo para que sea mas legible todo pero nada mas
        errMsg("Error while trying to read data for the scores")
        print(Err)
        errMsg('Please validate the install and try again. The game can run without it but the db has been reseted to default (0)')
        # por ultimo asigno los datos de la nueva base a las nuevas variables
        return data