import os
import re
import errno
import sys
import shutil
import time
import sqlite3
from stat import S_IFDIR, S_ISDIR, S_ISREG
from fnmatch import fnmatch

from fofix.core import Version

_mountTable = {}

class Mount(object):
    '''Implementation of a mount point in the VFS root.'''

    def __init__(self):
        # List of read-only backing directories, in decreasing order of priority.
        self.readOnly = []
        # List of writable backing directories, in decreasing order of priority.
        self.writable = []

    def resolveRead(self, path):
        '''
        Resolve a path to a file that the user wants to read.
        @param path:   Virtual path within this mount
        @return:       Physical path to the file
        @raise OSError(ENOENT): if file does not exist
        '''
        for p in (self.writable + self.readOnly):
            candidate = os.path.join(p, path).rstrip(os.sep)
            if os.path.exists(candidate):
                return candidate
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), path)

    def resolveWrite(self, path):
        '''
        Resolve a path to a file that the user wants to create or modify.
        Copies files to the most recently mounted writable directory if
        necessary.  If a path is returned, it is guaranteed to be in the
        most recently mounted writable directory.
        @param path:   Virtual path within this mount
        @return:       Physical path to the file
        @raise OSError(EROFS): if all mounted directories are read-only
        '''
        if len(self.writable) == 0:
            raise OSError(errno.EROFS, os.strerror(errno.EROFS))

        wpath = os.path.join(self.writable[0], path).rstrip(os.sep)
        if os.path.exists(wpath):
            return wpath

        try:
            rpath = self.resolveRead(path)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise
            rpath = None

        if not os.path.isdir(os.path.dirname(wpath)):
            os.makedirs(os.path.dirname(wpath))
        if rpath is not None:
            shutil.copy2(rpath, wpath)
        return wpath

    def listdir(self, path):
        '''
        List the contents of a directory within this mountpoint.
        @param path:   Virtual path within this mount to list
        @return:       List of entries (excluding '.' and '..')
        '''
        contents = set()
        for p in (self.writable + self.readOnly):
            candidate = os.path.join(p, path)
            if os.path.isdir(candidate):
                contents.update(os.listdir(candidate))
        return list(contents)

def mount(dir, mountpt):
    '''
    Mount a directory read-only.
    The virtual directory provides the union of the contents of all
    directories mounted on it.
    @param dir:       Directory to mount
    @param mountpt:   Virtual directory to mount it onto
    '''
    if mountpt not in _mountTable:
        _mountTable[mountpt] = Mount()
    _mountTable[mountpt].readOnly.append(dir)

def mountWritable(dir, mountpt):
    '''
    Mount a directory and allow writing.
    The most recent writable-mounted directory on a given
    mountpoint receives all writes made to the mountpoint.
    @param dir:       Directory to mount
    @param mountpt:   Virtual directory to mount it onto
    '''
    if mountpt not in _mountTable:
        _mountTable[mountpt] = Mount()
    _mountTable[mountpt].writable.append(dir)

def _convertPath(path):
    '''
    Validate and convert a VFS path to a mount point and a native path
    fragment suitable for passing to the mount point's methods.
    @param path:  VFS path
    @return:      2-tuple of mount and native path fragment to pass to the mount
    @raise OSError(EINVAL): on syntactically invalid VFS path
    '''
    if re.match('^/[^:\\\\]*$', path) is None or re.match('/\\.\\.?(/|$)', path) is not None:
        raise OSError(errno.EINVAL, os.strerror(errno.EINVAL))
    while '//' in path:
        path = path.replace('//', '/')
    components = path.lstrip('/').split('/')
    if components[0] not in _mountTable:
        raise OSError(errno.ENOENT, os.strerror(errno.ENOENT))
    return _mountTable[components[0]], os.sep.join(components[1:])

def resolveRead(path):
    '''
    Convert a VFS path into a real path that is usable to access an
    already-existing file or directory.
    @param path:    VFS path
    @return:        Real path
    @raise OSError(ENOENT): if path does not exist
    '''
    mount, frag = _convertPath(path)
    return mount.resolveRead(frag)

def resolveWrite(path):
    '''
    Convert a VFS path that the user wishes to write a file to into a real
    writable path.  Copies a file from a read-only area to a read-write area
    if necessary.
    @param path:   VFS path
    @return:       Real path
    '''
    mount, frag = _convertPath(path)
    return mount.resolveWrite(frag)

class StatResult(object):
    '''
    C{stat()} result for an object in the virtual filesystem.
    This was originally a hack to give synthesized C{stat()} results for / so
    things worked right in the test code, but it's left in because if you
    can stat anything else in the VFS, you should be able to stat / too.

    For all practical purposes, this object is compatible with the return type
    of C{os.stat()}.  Fields of the result can be accessed either as attributes
    or via numeric indices.
    '''

    def __init__(self, path):
        '''
        Set the object up with C{os.stat()} results of C{path} or
        synthesized properties if the VFS root is statted.
        @param path:   Path to operate on
        '''
        self._attrs = ('st_mode', 'st_ino', 'st_dev', 'st_nlink', 'st_uid',
          'st_gid', 'st_size', 'st_atime', 'st_mtime', 'st_ctime')
        if path == '/':
            self.st_mode = S_IFDIR | 0o555
            self.st_ino = 0
            self.st_dev = 0
            self.st_nlink = 2 + len(_mountTable)
            self.st_uid = 0
            self.st_gid = 0
            self.st_size = 4096
            self.st_atime = time.time()
            self.st_mtime = self.st_atime
            self.st_ctime = self.st_atime
        else:
            s = os.stat(resolveRead(path))
            for a in self._attrs:
                setattr(self, a, getattr(s, a))

    # Implement the sequence protocol (os.stat() returns a tuple-like object)
    def __len__(self):
        return len(self._attrs)

    def __getitem__(self, idx):
        return getattr(self, self._attrs[idx])

    # Show our contents when repr()'d.
    def __repr__(self):
        return str(tuple(self))

def stat(path):
    '''
    Get some properties of the specified path, much like C{os.stat()}.
    @param path:   Path to operate on
    @return:       L{StatResult} for the path
    '''
    return StatResult(path)

def listdir(path):
    '''
    List the contents of a virtual directory, much like C{os.listdir()}.
    @param path:   Path to list
    @return:       List of names of objects in the directory
                   (excludes '.' and '..')
    '''
    if path == '/':
        return list(_mountTable.keys())
    else:
        mount, frag = _convertPath(path)
        return mount.listdir(frag)

def glob(pattern):
    '''
    List object names that match a glob pattern.

    Only the portion after the final slash will be treated as a glob pattern.
    @param pattern: The glob pattern
    @return:        List of matching names
    '''
    rmatch = re.match('^(/(?:.*/)?)(.*?)$', pattern)
    if rmatch is None:
        raise OSError(errno.EINVAL, os.strerror(errno.EINVAL))
    dirname, basename = rmatch.group(1), rmatch.group(2)
    return [dirname + name for name in listdir(dirname) if fnmatch(name, basename)]

def unlink(path):
    '''
    Delete a virtual file.

    Note: If the virtual file exists in one of the read-only backing
    directories of the mount in which the file is deleted, the file
    will instead appear to revert to the read-only version.
    @param path:   Path to delete
    '''
    os.unlink(resolveWrite(path))

def mkdir(path):
    '''
    Create a virtual directory.  Also creates any directories leading
    up to it that are missing (like C{os.makedirs()}).
    @param path:   Path at which to create a directory
    '''
    os.makedirs(resolveWrite(path))

def rmdir(path):
    '''
    Remove a virtual directory.  The directory must be empty.
    @param path:   Path to directory to remove
    '''
    os.rmdir(resolveWrite(path))

def rename(src, dest):
    '''
    Rename or move a virtual object.
    @param src:    Path to rename from
    @param dest:   Path to rename to
    '''
    os.rename(resolveWrite(src), resolveWrite(dest))

def exists(path):
    '''
    Check the existence of a virtual object at a given path.
    @param path:   Path to check for existence
    @return:       True if object exists, False otherwise
    '''
    try:
        stat(path)
        return True
    except OSError as e:
        if e.errno == errno.ENOENT:
            return False
        raise

def isfile(path):
    '''
    Check whether a virtual path represents a file.
    @param path:   Path to check for file-ness
    @return:       True if it is a file, False otherwise
    '''
    try:
        return S_ISREG(stat(path).st_mode)
    except OSError as e:
        if e.errno == errno.ENOENT:
            return False
        raise

def isdir(path):
    '''
    Check whether a virtual path represents a directory.
    @param path:   Path to check for dir-ness
    @return:       True if it is a dir, False otherwise
    '''
    try:
        return S_ISDIR(stat(path).st_mode)
    except OSError as e:
        if e.errno == errno.ENOENT:
            return False
        raise

_realopen = open
def open(path, mode='r'):
    '''
    Open a virtual file, much like the built-in C{open()} function.
    @param path:   Path to open
    @param mode:   File mode
    @return:       File object of the appropriate physical file
    '''
    if mode in ('r', 'rb'):
        return _realopen(resolveRead(path), mode)
    else:
        return _realopen(resolveWrite(path), mode)

def openSqlite3(path):
    '''
    Open a virtual file as a writable SQLite database.
    @param path:  Path to open
    @return:      C{sqlite3.Connection} object for the file
    '''

    # There is a bug in the sqlite3 module's handling of path names containing
    # unicode characters, so work around that by temporarily changing directory
    # so we access the file with just its base name.
    oldcwd = os.getcwd()
    try:
        dbName = resolveWrite(path)
        os.chdir(os.path.dirname(dbName))
        return sqlite3.Connection(os.path.basename(dbName))
    finally:
        os.chdir(oldcwd)

#stump: VFS does this now too; it's just a case of converting stuff to use it
def getWritableResourcePath():
    """
    Returns a path that holds the configuration for the application.
    """
    path = "."
    appname = Version.PROGRAM_UNIXSTYLE_NAME
    if os.name == "posix":
        path = os.path.expanduser("~/." + appname)
        # evilynux - MacOS X, putting config files in the standard folder
        if os.uname()[0] == "Darwin":
            path = os.path.expanduser("~/Library/Preferences/" + appname)
    elif os.name == "nt":
        try:
            path = os.path.join(os.environ["APPDATA"], appname)
        except:
            pass
    try:
        os.mkdir(path)
    except:
        pass
    return path

# TODO: Function to perform all overlay mounts called for by the
# active configuration: /data will become /data overlaid by the
# current theme overlaid by any active mods and /songs will be the
# song folder.  Note that said function is fully intended to be
# called again if said configuration is modified in such a way that
# it changes what should appear in /data or /songs.  Other code
# shouldn't really care if the VFS changes out from under it (the
# testing code might, but that's kind of a special case...) -
# VFS.open() returns real file objects that aren't tied to the
# current VFS state.
#
# There are some decisions that must be made before doing this;
# hence, we're leaving it undone presently.
#
# Note that unless the mount tables are modified directly, /data
# and /userdata are guaranteed to exist and point to the proper
# places: /data contains at least the contents of the main /data
# and is read-only, and /userdata points to the user-specific
# configuration area (%APPDATA%\fofix, ~/Library/Preferences/fofix,
# ~/.fofix, or what-have-you) and is read-write.  /gameroot also
# always points (read-only) to the root of the game installation
# (though please try to avoid using it directly when the data you
# want is available elsewhere in the VFS!)

# Figure out where to map /userdata to.
if os.name == 'nt':
    # Find the path to Application Data, and do it the Right Way(tm).
    # The APPDATA envvar isn't guaranteed to be reliable.
    # Use ctypes so we don't have to drag in win32com.
    import ctypes
    import ctypes.wintypes
    _appdata = (ctypes.c_char * ctypes.wintypes.MAX_PATH)()
    # [WinSDK]/include/shlobj.h: #define CSIDL_APPDATA 26
    ctypes.windll.shell32.SHGetFolderPathA(None, 26, None, None, _appdata)
    _writePath = os.path.join(_appdata.value, Version.PROGRAM_UNIXSTYLE_NAME)
elif sys.platform == 'darwin':
    _writePath = os.path.expanduser(os.path.join('~', 'Library', 'Preferences', Version.PROGRAM_UNIXSTYLE_NAME))
else:
    _writePath = os.path.expanduser(os.path.join('~', '.'+Version.PROGRAM_UNIXSTYLE_NAME))
mountWritable(_writePath, 'userdata')
if not isdir('/userdata'):
    mkdir('/userdata')

# Map /data and /gameroot.
#FIXME - OSX Support
_gameRoot = os.path.abspath('.')
mount(_gameRoot, 'gameroot')
mount(os.path.join(_gameRoot, 'data'), 'data')


# 根据每日 气温 列表，请重新生成一个列表，对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高，请在该位置用 0 来代替。

# 例如，给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73]，你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

# 提示：气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度，都是在 [30, 100] 范围内的整数。

# 来源：力扣（LeetCode）
# 链接：https://leetcode-cn.com/problems/daily-temperatures
# 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

## 暴力求解，rot
class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        temp = []
        lt = len(T)
        for i in range(lt):
            if i>=1:
                if T[i] == T[i-1]:
                    temp.append(temp[-1]-1 if temp[-1] > 0 else 0)
                    continue
            flag = False
            for j in range(i+1, lt):
                if T[i] < T[j]:
                    temp.append(j-i)
                    flag = True
                    break
            if not flag:
                temp.append(0)

        return temp

## 用 stack

class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        if not T:
            return []
        lt = len(T)
        temp = [(T[-1], lt-1)]

        rev = [0]
        i = lt-2
        while i >= 0:
            ltemp = len(temp)
            flag = False
            for j in range(ltemp-1, -1, -1):
                if temp[j][0] > T[i]:
                    rev.append(temp[j][1] - i)
                    flag = True
                    break
                else:
                    temp.pop()
            if not flag:
                rev.append(0)

            temp.append((T[i], i))
            i -= 1

        return rev[::-1]


from celery import shared_task
from .models import Draft
from subscribe.models import Group, Subscriber
from decouple import config
import boto3
import time
import random
import math
import json

client = boto3.client(
    'ses',
    region_name='eu-west-1',
    aws_access_key_id=config('aws_key'),
    aws_secret_access_key=config('aws_secret')
)

# creates email template
# this is because bulk mail demands it
def create_template(draft):
    tname = str(draft.id) + '-' + str(random.random())[2:]
    print(tname, 'creating template')

    # fit the attachments
    tbody = draft.body
    tbody += '
Attachments:
'
    tbody += '
'
    files = draft.files.all()

    for file in files:
        print(file)
        tbody += '
{}
'.format(
            config('hostname') + 'media/', file.file, str(file.file).split('/').pop())
    tbody += '
'

    if not files:
        tbody += '
none
'

    tbody += '''

            unsubscribe from our mailing list

    '''.format(config('hostname'))

    response = client.create_template(
        Template={
            'TemplateName': tname,
            'SubjectPart': draft.subject,
            'HtmlPart': tbody,
            'TextPart': tbody
        }
    )
    print(tname, 'template created')
    print(response)
    return tname

def create_destination(email):
    return {
        "Destination": {
            "BccAddresses": [email]
        },
        "ReplacementTemplateData": json.dumps({ "email": email})
    }

# this divides the subs into batches of size = aws allowed sending freq/sec
# and sends the mail with the help of the template
def send_mails_finally(subs, tname):
    bs = int(config('batch_size'))
    l = math.ceil(len(subs)/bs)
    subs = [subs[x*bs-bs: x*bs] for x in range(1, l+1)]

    source = config('from')

    for batch in subs:
        destinations = [create_destination(x) for x in batch]
        time.sleep(1)
        response = client.send_bulk_templated_email(
            Source=source,
            Template=tname,
            Destinations=destinations,
            DefaultTemplateData="{}"
        )
        print(response)

# it coordinates the above 2 funcs
# and updates the draft status to 2 = sent
@shared_task
def start_bulk_mail(draft, groups):
    draft = Draft.objects.get(pk=draft)
    subs = []
    group_names = []

    print(groups)
    for group_id in groups:
        group = Group.objects.get(id=group_id)
        group_names.append(group.name)
        filter_subs = group.subs.filter(flag=False, verified=True)
        subs.extend(filter_subs)

    subs = [x.email for x in subs]
    subs = list(set(subs))
    print('sending to', len(subs))
    print(subs)

    # update the info to the draft
    draft.group = ', '.join(group_names)
    draft.sentTo = len(subs)
    draft.save()

    # create the template
    tname = create_template(draft)

    # create batches and send mails
    send_mails_finally(subs, tname)

    # set draft status to sent

    draft.status = 2
    draft.save()
    print('killed bulk mail')

# handles bounced mail
# it block the email which got bounced
@shared_task
def handle_bounce_async(msg):
    msg = json.loads(msg)

    try:
        emails = msg['bounce']['bouncedRecipients']
        emails = [x['emailAddress'] for x in emails]

        for email in emails:
            subs = Subscriber.objects.filter(email=email)
            for sub in subs:
                sub.status = 'bounced'
                sub.flag = True
                sub.save()

        print('bounce', emails)
    except:
        print(msg)

# handles complaint mail
# it block the email which got complainted
@shared_task
def handle_complaint_async(msg):
    msg = json.loads(msg)

    try:
        emails = msg['complaint']['complainedRecipients']
        emails = [x['emailAddress'] for x in emails]

        for email in emails:
            subs = Subscriber.objects.filter(email=email)
            for sub in subs:
                sub.status = 'complaint'
                sub.flag = True
                sub.save()

        print('complaint', emails)
    except:
        print(msg)


print('''======
  PA3.0
  ======''')

ter = int(input('Digite o primeiro termo: '))
raz = int(input('Digite a razão: '))
con = 0
v = 10
v2 = 1
while v2 != 0:
    while con < v:
        print('{} => '.format(ter), end='')
        ter += raz
        con += 1
    print('...')
    if con == v:
        v2 = int(input('\nQuer ver mais termos? quantos?\n para encerra digite 0: ', ))
        v += v2

print('\n\nA progressão foi encerrado com {} termos mostrados'.format(con))


import sqlite3

miConexion = sqlite3.connect("BBDD/nuevaBBDD")

miCursor = miConexion.cursor()
#miCursor.execute("Create Table Productos (ID INTEGER, NOMBRE VARCHAR(50), PRECIO INTEGER, SECCION VARCHAR(20))")
#miCursor.execute("INSERT INTO Productos(ID,NOMBRE,PRECIO,SECCION)values(1,'Camiseta',5000,'Moda')")
#miCursor.execute("INSERT INTO Productos values(1,'Camiseta',5000,'Moda')")

#muchosproductos = [
#    (2,"Patin",3000,"Deportes"),
#    (3,"Cenisero",200,"ceramica"),
#    (4,"pantalon",3420,"vestimenta")
#]

#miCursor.executemany("Insert into Productos values(?,?,?,?)",muchosproductos)
#miConexion.commit()

miCursor.execute("Select * from Productos")

muchos = miCursor.fetchall()

print(muchos)

miCursor.close()

miConexion.close()


import configparser
import psycopg2
from time import time
from connect import connect
from sql_queries import copy_table_queries, insert_table_queries, schema_queries

def load_staging_tables(cur, conn):
    """Loads the staging tables
    COPYs the data from S3 to staging table.

    Keyword arguments:
    cur -- the cursor for interating with the PostgreSQL database.
    con - the connection object for the PostgreSQL database.
    """
    for idx, query in enumerate(copy_table_queries):
        print('Executing COPY query {}/{}...'.format(idx+1, len(copy_table_queries)), end='', flush=True)
        t0 = time()
        cur.execute(query)
        conn.commit()
        load_time = time() - t0
        print('done! Took: {0:.2f} sec'.format(load_time))

def insert_tables(cur, conn):
    """Fills the fact and dimension tables
    INSERTs the data from staging table into fact and dimension tables.

    Keyword arguments:
    cur -- the cursor for interating with the PostgreSQL database.
    con - the connection object for the PostgreSQL database.
    """
    for idx, query in enumerate(insert_table_queries):
        print('Executing INSERT query {}/{}...'.format(idx+1, len(insert_table_queries)), end='', flush=True)
        t0 = time()
        cur.execute(query)
        conn.commit()
        load_time = time() - t0
        print('done! Took: {0:.2f} sec'.format(load_time))

def main():
    """Copies data from S3 .json files into the staging tables,
    then inserts data into fact and dimension tables.
    """
    cur, conn = connect('dwh.cfg')

    set_schema = schema_queries[1]
    cur.execute(set_schema)

    print('Loading Staging Tables.')
    load_staging_tables(cur, conn)

    print('Inserting Rows.')
    insert_tables(cur, conn)

    conn.close()

if __name__ == "__main__":
    main()


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

# In[1]:

import pandas as pd
from math import log2
from operator import itemgetter

# In[2]:

df = pd.read_csv('campus_party.csv')

# In[3]:

def entropia(p0, p1):
    if p0 == 0 or p1 == 0: # Todos os exemplos positivos ou negativos
        return 0
    if p0 == p1: # Quantidade de exemplos positivos igual a quantidade de exemplos negativos
        return 1
    return (-(p1 * log2(p1)) - (p0 * log2(p0)))

# In[4]:

df.head()

# In[5]:

def ID3(df, label):

    sucesso = df[label]
    df1 = df.drop(label, axis = 1)

    dict_ganhos = {}

    for coluna in df1.columns: # Percorre as colunas do DataFrame
        dict_atributos = {} # O dicionario e formado por:
                            # 'chave (valor da coluna)':[exemplos negativos, exemplos positivos]
        for i in range (0, len(df1[coluna])): # Percore cada valor da coluna
            valor = df1[coluna][i]

            # Verifica os possiveis valores e soma-os como exemplos positivos ou negativos
            if not valor in dict_atributos:
                # Adiciona a chave no dicionario
                dict_atributos[valor] = [0, 0]

            # Soma os exemplos positivos
            if sucesso[i] == 'SIM':
                dict_atributos[valor][1] += 1
            # Soma os exemplos negativos
            else:
                dict_atributos[valor][0] += 1

        #print (coluna)
        #print(dict_atributos)

        ganho = 0
        aux = 0

        for key in dict_atributos.keys():
            total_exemplos = dict_atributos[key][1] + dict_atributos[key][0]
            exemplos_positivos = dict_atributos[key][1] / total_exemplos
            exemplos_negativos = dict_atributos[key][0] / total_exemplos
            porcentagem  = ((total_exemplos)/len(df1[coluna]))
            ganho +=  porcentagem * entropia(exemplos_positivos, exemplos_negativos)
            #aux =   entropia(exemplos_positivos, exemplos_negativos)
            #print(dict_atributos[key] + ' : ' + str(aux))
            #print(f'{dict_atributos[key]} -> {aux}: {total_exemplos}')

        dict_ganhos[coluna] = 1 - ganho

    return dict_ganhos

# In[6]:

v = ID3(df, "Let's go party")

# In[7]:

s = sorted(v.items(), key = itemgetter(1), reverse = True)

# In[8]:

print(s)


# Your ParkingSystem object will be instantiated and called as such:
# obj = ParkingSystem(big, medium, small)
# param_1 = obj.addCar(carType)

# LeetCode 1603. Design Parking System

class ParkingSystem:

    def __init__(self, big: int, medium: int, small: int):
        """
        Constructor: initiate two arrays, one to store the limit and one to store the count
        """

        # this is not to modifies, this keeps account of how many lots there are for each type of car
        self.limit = [big, medium, small]

        # starts at 0 because there are no cars in the beginning
        self.count = [0, 0, 0]

    def addCar(self, carType: int) -> bool:
        """
        carType : int, what type of car (1 - big; 2 - medium; 3 - small)
        return True if there are available space; False otherwise
        """

        index = carType - 1
        if self.count[index] < self.limit[index]:
            self.count[index] += 1
            return True

        return False

leetcode/easier daily challenges & other problems/1603_parking_system/ParkingSystem.py


from contextlib import suppress
from functools import reduce
from operator import or_

import django
from django.db.models import Count, Q

from mainapp.models import Teacher, Cathedra, Faculty
from parserapp.parser.processing.utils import try_, async_bunch
from parserapp.parser.scrappers import get_teacher, get_teachers

async def update_all_teachers(session, only_without_fullname=False):
    print("update_all_teachers")

    tasks = [
        update_teacher(teacher, session)
        for teacher in Teacher.objects.all()
        if not (only_without_fullname and teacher.name_full)
    ]
    for i, task in enumerate(async_bunch(tasks)):
        await task
        print(i, len(tasks))

async def update_teacher(teacher_model, session):
    try:
        full_name, cathedras, groups = await try_(lambda t=teacher_model.url_rozklad: get_teacher(session, t))
    except:
        return

    teacher_model.name_full = full_name
    teacher_model.cathedras_rozklad = "\n".join(cathedras)

    await _add_campus_info(teacher_model)

    teacher_model.save()

async def _add_campus_info(teacher_model):
    campus_teachers = await get_teachers(teacher_model.name_full)

    if len(campus_teachers) == 0:
        return print("no campus teacher", teacher_model.name_full)

    if len(campus_teachers) == 1:
        return _merge_teacher(teacher_model, campus_teachers[0])

    # todo match by cathedras

    print(campus_teachers)

def _merge_teacher(rozklad, campus):
    for i in ('id_campus', 'slug_campus', 'name_campus'):
        setattr(rozklad, i, getattr(campus, i))
    for c in campus._catherdas:
        with suppress(django.db.utils.IntegrityError):
            rozklad.cathedras.add(c)

    return rozklad

def _get_cathedras(cathedras_names, groups):
    def _cathedra_name_2_regex(cathedra_name):
        translation_dict = {
            ' №': '.*',
            'МАтаТІ': 'МАтаТЙ',
        }.items()
        cathedra_name = reduce(lambda a, i: a.replace(i[0], i[1]), translation_dict, cathedra_name)
        return '^' + cathedra_name

    def find_faculties():
        def find_faculties_():
            groups_ = list(groups)
            if not groups_:
                return []
            return Faculty.objects.filter(reduce(or_, [
                Q(cathedras__groups__name=g)
                for g in groups_
            ])).annotate(cnt=Count('id_campus')).order_by('-cnt').values_list('id_campus', flat=True)

        if not getattr(find_faculties, 'res', None):
            find_faculties.res = find_faculties_()
        return find_faculties.res

    def get_cathedra(cathedra_name):
        cathedras_ = Cathedra.objects.filter(name_short__iregex=_cathedra_name_2_regex(cathedra_name))
        if cathedras_.count() == 0:
            return None
        if cathedras_.count() == 1:
            return cathedras_[0]
        faculties = find_faculties()
        if not faculties:
            return None
        cathedras_ = cathedras_.filter(faculty__id_campus__in=find_faculties())
        if cathedras_.count() == 0:
            return None
        return cathedras_[0]

    return filter(None, [get_cathedra(cathedra_name) for cathedra_name in cathedras_names])


r"""
c4dtools.resource
~~~~~~~~~~~~~~~~~
"""

import os
import re
import c4d
import json
import inspect
import warnings
import functools

from c4dtools import utils
from c4dtools import helpers

def load(filename, use_cache=True, cache_suffix='cache'):
    r"""
    Load the symbols of a Cinema 4D resource file. The symbols will be
    loaded directly from the symbols file when *use_cache* is False. In
    the other case, the symbols are loaded from the cached symbols if
    the symbols haven't changed since the cache has been generated. If
    the cache is not available, it will be generated when *use_cache*
    is True.

    The advantage of caching the symbols in a seperate file is the
    improved speed of reading in the symbols.

    *Changed in 1.3.1*: The :func:`load` function now returns a tuple of
    three values instead of two. The ``missing_permissions`` element has been
    added to the end of the tuple.

    .. note::

        The ``missing_permissions`` element of the returned tuple is only
        True if the *use_cache* is passed True **and** the cache could
        not be written.

    :Returns: ``(symbols_dict, changed)``
    :Raises:  OSError if *filename* does not exist or does not point to a
              file.
    """

    if not os.path.isfile(filename):
        raise OSError('passed filename does not exist or does not point to '
                      'a file: %s' % filename)

    cache_name = utils.change_suffix(filename, cache_suffix)

    # Load the cache if desired and available.
    load_from_source = True
    original_changed = False
    load_from_cache = False
    missing_permissions = False

    if use_cache and os.path.isfile(cache_name):
        original_changed = utils.file_changed(filename, cache_name)
        load_from_cache = not original_changed

    if load_from_cache:
        fp = open(cache_name, 'rb')
        data = None
        try:
            data = json.load(fp)
        except ValueError as exc:
            warnings.warn(exc.message + '. Loading symbols from source.')
        finally:
            fp.close()

        if isinstance(data, dict):
            # Convert every key in the dictionary from unicode to
            # a string.
            for key, value in data.items():
                del data[key]
                data[key.encode('utf-8')] = value

            load_from_source = False
            symbols = data
        elif data is not None:
            message = 'loaded %s, expected dict from JSON. Loading symbols ' \
                      'from source.'
            message = message % data.__class__.__name__
            warnings.warn(message)

    # If the cache could not be loaded, load the symbols from the
    # original file.
    if load_from_source:
        fp = open(filename, 'rb')
        try:
            symbols = parse_symbols(fp.read())
        finally:
            fp.close()

        # If the cache should be used, we will now generate it.
        if use_cache:
            try:
                with open(cache_name, 'wb') as cache_fp:
                    json.dump(symbols, cache_fp)
            except IOError as exc:
                missing_permissions = True

    return symbols, original_changed, missing_permissions

def parse_symbols(string):
    r"""
    Parse symbols from the passed string containing the enumerations
    to load.
    """

    # Remove all comments from the source.
    string = ' '.join(line.split('//')[0] for line in string.splitlines())
    string = ' '.join(re.split(r'\/\*.*\*\/', string))

    # Extract all enumeration declarations from the source.
    enumerations = [
        text.split('{')[1].split('}')[0]
        for text in re.split(r'\benum\b', string)[1:]
    ]

    # Load the symbols.
    symbols = {}
    for enum in enumerations:
        last_value = -1
        for name in enum.split(','):
            if '=' in name:
                name, value = name.split('=')
                value = int(value)
            else:
                value = last_value + 1

            name = name.strip()
            if name and name not in symbols:
                last_value = value
                symbols[name] = value

    return symbols

class Resource(object):
    r"""
    An instance of this class is used to store the symbols of a
    C4D symbols file and several other information to work with
    the resource of a plugin, such as easily grabbing files from
    that folder, etc.

    .. attribute:: dirname

        The directory name of the resource-folder. Not garuanteed to
        exist!

    .. attribute:: c4dres

        The :class:`c4d.plugins.GeResource` object passed on construction.
        This is usually the ``__res__`` variable passed through from a
        Python plugin.

    .. attribute:: string

        A :class:`StringLoader` instance associated with the resource
        object. Used to load resource strings.

        .. code-block:: python

            # Load a resource-string with the IDC_MYSTRING symbol-name
            # without formatting arguments.
            res.string.IDC_MYSTRING()

            # Or call the str() function on the returned ResourceString
            # instance.
            str(res.string.IDC_MYSTRING)

            # Format the resource string by replacing the hashes in
            # the string with the passed arguments.
            res.string.IDC_FILENOTFOUND(filename)

            # Unpack the tuple returned by the `both` property.
            # Shortcut for:
            #   container.SetString(
            #       res.IDC_CONTEXTMENU_1,
            #       res.string.IDC_CONTEXTMENU_1())
            container.SetString(*res.string.IDC_CONTEXTMENU_1.both)

    The following attributes are only treated correctly if the :func:`load`
    function was used to construct the Resource object.

    .. attribute:: changed

        This attribute is set by the :func:`load` function and is only
        True when the symbols had been cached but the original symbols file
        has been modified. The resource has been reloaded in that case and
        the cache re-written (if specified). If symbol-caching is not
        activated, this field is False always.

        It can be used to recognize the change of a description or symbols
        header file during development.

        The default value of this field is False.

    .. attribute:: missing_permissions

        This field is True if the program has insufficient permissions to
        write any of the caches in :func:`load`.
    """

    @classmethod
    def from_resource_folder(cls, dirname, c4dres, cache=True,
                             parse_description=False):
        r"""
        *New in 1.3.1* Parses a Cinema 4D resource folder structure and
        its descriptions and returns a :class:`Resource` instance.

        :param dirname: The name of the resource directory to parse. It
                should contain a ``c4d_symbols.h`` file, otherwise the
                directory is assumed invalid and the returned Resource
                object contains no symbols at all.
        :param c4dres: A :class:`c4d.plugins.GeResource` instance. Can be
                passed None. This instance will directly correlate to the
                constructor of the :class:`Resource` class.
        :param cache: True if the caching should be done, False if not.
                This parameter is passed to :func:`load`.
        :param parse_description: If this parameter is passed a True
                value, the description resources are parsed additionally
                to the ``c4d_symbols.h`` file.
        :raise OSError: If *dirname* does not point to a directory.
        """

        if not os.path.isdir(dirname):
            raise OSError("'%s' is not a directory." % dirname)

        res = cls(dirname, c4dres, {})

        c4d_symbols = os.path.join(dirname, 'c4d_symbols.h')
        if not os.path.isfile(c4d_symbols):
            return res

        symbols, changed, missing_permissions = load(c4d_symbols, cache)
        res.add_symbols(symbols)
        res.changed |= changed

        if parse_description:
            files = glob.glob(os.path.join(dirname, 'description', '*.h'))
            for filename in files:
                res, changed, perms = load(filename, cache)
                res.add_symbols(symbols)
                res.changed |= changed
                missing_permissions |= perms

        res.missing_permissions = missing_permissions
        return res

    def __init__(self, dirname, c4dres, symbols={}):
        super(Resource, self).__init__()
        self.dirname = dirname
        self.c4dres = c4dres
        self.string = StringLoader(self)
        self.symbols = symbols
        self.changed = False
        self.missing_permissions = False

    def __getattr__(self, name):
        return self.symbols[name]

    def __getitem__(self, name):
        r"""
        *New in 1.3.0*: Shortcut for accessing the :class:`StringLoader`
        in the :class:`Resource` instance. Returns a :class.`ResourceString`
        instance. You can pass a tuple where the first element is a the
        name of the resource symbol and the others serve as substitution.
        """

        if isinstance(name, tuple):
            name, args = name[0], name[1:]
        else:
            args = ()

        return self.string.get(name)(*args)

    @property
    def symbols(self):
        return self._symbols

    @symbols.setter
    def symbols(self, symbols):
        self.highest_symbol = -100000
        self._symbols = {}
        self.add_symbols(symbols)

    def get(self, name):
        r"""
        Returns the value of the symbol with the passed name, or raises
        KeyError if no symbol was found.
        """
        return self.symbols[name]

    def has_symbol(self, name):
        return name in self.symbols

    def add_symbols(self, symbols):
        r"""
        Add the dictionary *symbols* to the resources symbols.

        Raises: TypeError if *symbols* is not a dict instance.
                KeyError if a key in *symbols* is already defined in the
                resource and their value differs.
        """

        utils.ensure_type(symbols, dict)

        res_symbols = self.symbols
        for key, value in symbols.iteritems():
            utils.ensure_type(key, basestring, name='dict-key')
            utils.ensure_type(value, int, name='dict-value')
            if key in res_symbols and res_symbols[key] != value:
                msg = 'key %r already defined in the resource and ' \
                      'the value differs from the updating symbols.'
                raise KeyError(msg % key)
            if value > self.highest_symbol:
                self.highest_symbol = value

        res_symbols.update(symbols)

    def new_symbols(self, *symbols):
        r"""
        *New in 1.3.0*. Adds new symbols to the :class:`Resource` instance.
        Each element in the *\*symbols* parameter may be a string or a tuple.
        If it's a tuple, the name of the symbol is the first name, otherwise
        it will be the string itself. The second element in the tuple must be
        the value.
        """

        l = []
        for symbol in symbols:
            if isinstance(symbol, tuple):
                symbol, value = symbol
            else:
                if self.symbols:
                    value = max(self.symbols.itervalues()) + 1
                else:
                    value = 10000

            self.add_symbols({symbol: value})
            l.append(self.get(symbol))
        return l

    def get_symbol_name(self, id_):
        r"""
        Returns the name of the passed symbol id.
        """

        for k, v in self.symbols.iteritems():
            if v == id_:
                return k

    def file(self, *path_parts):
        r"""
        Concatenate the resource folders path with the passed filename.
        """
        return os.path.join(self.dirname, *path_parts)

class StringLoader(object):
    r"""
    This class is used for conveniently loading strings from the
    c4d_strings.str file. It is basically a wrapper for the
    ``c4d.plugin.GeLoadString`` function. Accessing an attribute on
    an instance of this class will return a callable object accepting
    the same parameters as the previously mentioned API call, but with
    the symbol-id already passed.
    """

    def __init__(self, resource):
        r"""
        Initialize the StringLoader instance with an instance of the
        Resource class.

        Raises: TypeError when *resource* is not a Resource instance.
        """

        if not isinstance(resource, Resource):
            raise TypeError('expected %s.Resource instance.' %
                            inspect.getmodule(Resource))

        self.resource = resource

    def __getattr__(self, name):
        r"""
        Load a string from the resource by the given *name*. Returns
        a :class:`ResourceString` object.

        .. code-block:: python

            id = res.IDC_MYSTRING
            name = res.string.IDC_MYSTRING()
            # same as
            id, name = res.string.IDC_MYSTRING.tuple
        """

        symbol_id = self.resource.get(name)
        return ResourceString(symbol_id, self.resource.c4dres)

    def get(self, name):
        if isinstance(name, int):
            return ResourceString(name, self.resource.c4dres)

        return getattr(self, name)

    def has_symbol(self, name):
        return self.resource.has_symbol(name)

class ResourceString(object):
    r"""
    This class represents a resource-string loaded from plugin resource.
    """

    def __init__(self, id, c4dres):
        super(ResourceString, self).__init__()
        self.id = id
        self.c4dres = c4dres

    def __call__(self, *args):
        r"""
        Wrapper for the :func:`c4d.plugins.GeLoadString` function for
        loading the actual string from the resource.
        """

        string = self.c4dres.LoadString(self.id)

        # Simulate the behaviour of c4d.plugins.GeLoadString by replacing
        # all hashes (`#`) with a passed arguments.
        for arg in args:
            string = string.replace('#', str(arg), 1)

        return string

    def __str__(self):
        r"""
        New in 1.2.8. Equal to :met:`__call__` without passing parameters.
        """

        return self()

    @property
    def both(self):
        r"""
        Returns a tuple of the ``(id, string)`` where *string* is
        loaded from the plugin's resource.
        """
        return self.id, self()


"""
* 筛选器模块
* 为对采集到的数据进行筛选/过滤提供支持
"""

from designPattern import addGetInstanceFunc
from urllib import parse
from multiple import asyncRunFunc
import shutil
import os
from time import sleep
from V3_0.Spider.api import getHtmlTextData
from V3_0.Spider.Config.api import getDomain
from V3_0.Setting.api import asynFlag, poolNum
from V3_0.Storer.api import getDataBasePath, makeDir
from os.path import join
from V3_0.Selector.api import findAllWithRe

@addGetInstanceFunc
class selector:
	"""
    本类用于采集期间进行的数据筛选/过滤操作
    本类采用单例模式（通过designPattern.singleton装饰器来新建类的_instance属性，重写new方法，并对外提供getInstance接口）
    """
	def __init__(self):
		# 创建原始数据网页文件保存的根目录
		self.htmlsRootPath = join(getDataBasePath(), 'htmls')
		makeDir(self.htmlsRootPath)
		self.indexHtmlsRootPath = self.htmlsRootPath + '//0000index'
		makeDir(self.indexHtmlsRootPath)
		# 创建pkl文件保存的根目录
		self.pklsRootPath = join(getDataBasePath(), 'pkls')
		makeDir(self.pklsRootPath)

	def reSelect(self, flag, subjectsInfoPklPath):
		if flag:
			shutil.rmtree(self.pklsRootPath)
			if os.path.exists(subjectsInfoPklPath):
				os.remove(subjectsInfoPklPath)
			self.__init__()

	# 获取每一个学科类别的所有机构名
	def getInstitutionsName(self, SCs_data):
		data = {}
		for SC_code in SCs_data:
			value = SCs_data[SC_code]
			SC_name = value[0]
			index_htmls_Path = join(self.indexHtmlsRootPath, '%s-%s' % (SC_code, SC_name))
			self.storerIns.makeDir(index_htmls_Path)
			pagesURL = self._getPagesUrl(value)
			ins = [SC_name]
			temp = self._getInstitutions(pagesURL, index_htmls_Path)
			for t in temp:
				ins.append((t))
			dic = {SC_code: ins}
			data.update(dic)
		return data

	def _getPagesUrl(self, SC_data):
		urls = []
		# print(SC_data)
		max = int(SC_data[2])
		li = range(1, max + 1)
		for i in li:
			urls.append(SC_data[1] + '&pageno=' + str(i))
		return urls

	def _getInstitutions(self, pagesURL, index_htmls_Path):
		res2 = []
		cnt = 1
		for url in pagesURL:
			text = getHtmlTextData(url, index_htmls_Path + '//' + str(cnt))
			pattern = '\((\d+?)\)(.+?)'
			res = self._findAllWithRe(text, pattern)
			res2.append(res)
			cnt += 1
		return res2

	def getAllSCInfo(self, SC_data):
		# 从pkl文件中获取逐一获取每一个学科类别的所有招生机构的招生数据
		final = []
		for SC_code in SC_data:
			value = SC_data[SC_code]
			SC_name = value[0]
			data = self._getSCInfoFromPklFile(SC_code, value)
			final.append(data)
		return final

	def _getSCInfoFromPklFile(self, SC_code, value):
		SC_code_and_name = SC_code + '-' + value[0]
		pkl_SC_path = self.pklsRootPath + '\\' + SC_code_and_name + '.pkl'
		para = (SC_code, value)
		return self.storerIns.getPickleFileDataFromOtherData(pkl_SC_path, self._getSCInfoFromHtmls, para)

	def _getSCInfoFromHtmls(self, para):
		"""
        :return:
            类型：列表
            元素：第一个元素为哨兵（保存学科类别代码与名称），其余元素为数据项
                其中：其余所有数据项为：datum = asyncRunFunc(self._asyncGetInstitutionInfo, paraList, asyn=False)
        """
		(SC_code, value) = para
		SC_name = value[0]
		SC_code_and_name = SC_code + '-' + SC_name
		htmls_SC_Path = self.htmlsRootPath + '\\' + SC_code_and_name
		self.storerIns.makeDir(htmls_SC_Path)
		SC_instutions = value[1:]
		paraList = []
		final = (SC_code, SC_name)
		for page in SC_instutions:
			for ins in page:
				if ins == '':
					break
				ins_code = ins[0]
				ins_name = ins[1]
				ins_url = self._getInstitutionURL(SC_code, ins_name)
				html_ins_Path = htmls_SC_Path + '\\' + ins_code + '-' + ins_name
				para = (ins_code, ins_name, ins_url, html_ins_Path, htmls_SC_Path)
				paraList.append(para)
		datum = asyncRunFunc(self._asyncGetInstitutionInfo, paraList, poolNum=poolNum, asyn=asynFlag)
		datum.insert(0, final)
		return datum

	def _getInstitutionURL(self, SC_code, ins_name):
		url = getDomain() + '/zsml/querySchAction.do?dwmc='
		url += parse.quote(ins_name)
		url = url + '&yjxkdm=' + SC_code
		return url

	def _asyncGetInstitutionInfo(self, para):
		(ins_code, ins_name, ins_url, html_ins_Path, htmls_SC_Path) = para
		data = self._getInstitutionInfo(ins_code, ins_name, ins_url, html_ins_Path, htmls_SC_Path)
		return data

	def _getInstitutionInfo(self, ins_code, ins_name, ins_url, html_ins_Path, htmls_SC_Path):
		"""
        :return:
            类型：列表
            元素：第一个元素为哨兵（保存机构代码与机构名），其余元素为数据项（每一个研究方向的具体信息）
                其中：每个数据项为：data = self._getResearchAreaData(i, htmls_RA_scopePath)
        """
		# RA: resarch area
		htmls_RA_scope_Root_Path = htmls_SC_Path + '\\Scope'
		self.storerIns.makeDir(htmls_RA_scope_Root_Path)
		htmls_RA_scopePath = htmls_RA_scope_Root_Path + '\\' + ins_code + '-' + ins_name
		self.storerIns.makeDir(htmls_RA_scopePath)
		text = getHtmlTextData(ins_url, html_ins_Path)
		# ins_url = 'http://yz.chsi.com.cn/zsml/querySchAction.do?dwmc=%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6&yjxkdm=0252'
		# 获取表格
		pattern = '
(.+?)
'
		temp = self._findAllWithRe(text, pattern)[0]
		# 获取表格里的所有条数据
		pattern = '
(.+?)
'
		researchAreas_data = self._findAllWithRe(temp, pattern)
		# 从每一条数据里筛选出需要的信息
		final = []
		temp = [ins_code, ins_name, ins_url]
		final.append(temp)
		for i in researchAreas_data:
			data = self._getResearchAreaInfo(i, htmls_RA_scopePath)
			final.append(data)
		return final

	def _getResearchAreaInfo(self, rawData, htmls_RA_scopePath):
		"""
        :return:
            类型：列表
            列表内元素：考试方式、院系所、专业、研究方向、学习方式、指导教师、拟招生人数、考试范围的id、跨专业、备注、考试范围
                其中：为字符类型的有：考试方式、院系所、专业、研究方向、学习方式、指导教师、拟招生人数、考试范围的id、跨专业、备注
                    为元组类型的有：考试范围
        """
		# 筛选出：考试方式、院系所、专业、研究方向、学习方式
		pattern = '>(.+?)	'
		temp = findAllWithRe(rawData, pattern)
		final = temp[:5]
		temp = temp[5:]
		# 筛选出：指导教师
		pattern = '(.+?)'
		t = findAllWithRe(temp[0], pattern)
		final.append(t[0])
		temp = temp[1:]
		# 筛选出：拟招生人数
		pattern = "document.write\(cutString\(\'(.+?)\'"
		t = findAllWithRe(temp[0], pattern)
		final.append(t[0])
		temp = temp[1:]
		# 筛选出：考试范围的id及URL
		pattern = 'id=(.+?)"'
		scope_id = findAllWithRe(temp[0], pattern)[0]
		scope_url = getDomain() + '/zsml/kskm.jsp?id=' + scope_id
		schoolDepartment = final[1]
		schoolDepartment = schoolDepartment.replace('/', '或')
		researchArea = final[3]
		researchArea = researchArea.replace('/', '或')
		researchArea = researchArea.replace('\\', '或')
		researchArea = researchArea.replace('*', '')
		researchArea = researchArea.replace('?', '')
		researchArea = researchArea.replace('\n', '')
		researchArea = researchArea.replace('\t', '')
		researchArea = researchArea.replace('|', '_')
		scope_name = schoolDepartment + '-' + final[2] + '-' + researchArea
		scope_path = htmls_RA_scopePath + '\\' + scope_name
		if scope_url == getDomain() + '/zsml/kskm.jsp?id=':
			print(scope_url)
			print(scope_path)
			sleep(9999999999999)
		final.append(scope_id)
		temp = temp[1:]
		# 筛选出：跨专业
		pattern = '>(.+?)'
		t = findAllWithRe(temp[0], pattern)
		final.append(t[0])
		temp = temp[1:]
		# 筛选出：备注
		pattern = "document.write\(cutString\(\'(.+?)\'"
		t = findAllWithRe(temp[0], pattern)
		final.append(t[0])
		temp = temp[1:]
		# 获取考试范围
		scopeData = self._getExamScope(scope_url, scope_path)
		final.append(scopeData)
		return final

	def _getExamScope(self, scope_url, scope_path):
		text = getHtmlTextData(scope_url, scope_path)
		# 获取表头
		pattern = '(.+?)	'
		thead = findAllWithRe(text, pattern)
		# 获取表格内容
		pattern = '
(.+?)
'
		tbody = findAllWithRe(text, pattern)
		temp = []
		temp.append(thead)
		for i in tbody:
			pattern = '.+?(\(.+?)\n.+?(.+?).+?'
			t = findAllWithRe(i, pattern)
			temp.append(t)
		return tuple(temp)


#!/usr/bin/env python
# hypsometric.py
import numpy as num

def hypsometric(pressure,temperature,mixing_ratio,surface_altitude):
  """altitude = hypsometric(pressure,temperature,mixing_ratio,surface_altitude)

NAME:
      geopotential_altitude   - Paul van Delst's name of the routine
                      (DT renamed it to this).

PURPOSE:
 This function calculates geopotential altitudes using the hypsometric equation.
 It is like the "hypsometric" function I have implemented, but this one
 also accounts for water vapor in the atmosphere.

CATEGORY:
      Meteorology

CALLING SEQUENCE:
      altitude = hypsometric( pressure, $          ; Input
                              temperature, $       ; Input
                              mixing_ratio, $      ; Input
                              surface_altitude, $  ; Input

INPUTS:
      pressure:        Array of pressure in mb
      temperature:     Array of temperature in K
      mixing_ratio:    Array of water vapor mixing ratio in g/kg
      surface_height:  Height of surface in km.

KEYWORD PARAMETERS:
      None.

OUTPUTS:
      altitude:        Geopotential altitudes in km in the same order as the
                       input data.

CALLS:
      None.

COMMON BLOCKS:
      None

SIDE EFFECTS:
      None

RESTRICTIONS:
   - Input pressure, temperature and mixing_ratio MUST be arrays with at
     LEAST two elements where the element with the highest pressure corresponds
     to the surface altitude passed.
   - Input surface height must be > or = to 0.0km and a SCALAR.
   - No allowance is made, yet, for the change in the acceleration due to
     gravity with altitude.

PROCEDURE:
      Geopotential heights are calculated using the hypsometric equation:

                        -
                   Rd * Tv    [  p1  ]
        z2 - z1 = --------- ln[ ---- ]
                      g       [  p2  ]

      where Rd    = gas constant for dry air (286.9968933 J/K/kg),
            g     = acceleration due to gravity (9.80616m/s^2),
            Tv    = mean virtual temperature for an atmospheric layer,
            p1,p2 = layer boundary pressures, and
            z1,z2 = layer boundary heights.

      The virtual temperature, the temperature that dry air must have in
      order to have the same density as moist air at the same pressure, is
      calculated using:

                 [      1 - eps      ]
        Tv = T * [ 1 + --------- * w ]
                 [        eps        ]

  where T   = temperature,
        w   = water vapor mixing ratio, and
        eps = ratio of the molecular weights of water and dry air (0.621970585).

EXAMPLE:
      Given arrays of pressure, temperature, and mixing ratio:

        IDL> PRINT, p, t, mr
              1015.42      958.240
              297.180      291.060
              7.83735      5.71762

      the geopotential altitudes can be found by typing:

        IDL> result = geopotential_altitude( p, t, mr, 0.0, alt )
        IDL> PRINT, result, alt
               1      0.00000     0.500970

MODIFICATION HISTORY:
      Written by:     Paul van Delst, CIMSS/SSEC, 08-Dec-1997

Log: hypsometric.pro,m
converted to matlab code - leslie moy 02-02-02

$Log: hypsometric2.pro,v $
Revision 1.1  2002/01/16 13:28:15  dturner
Initial revision

Revision 1.1  1999/03/03 16:24:55  paulv
Adapted from pressure_height.pro. Improved input argument checking.
  """
  #----------------------------------------------------------------------------
  #                      -- Declare some constants --
  #
  #  Parameter         Description                 Units
  #  ---------   ---------------------------     -----------
  #     Rd       Gas constant for dry air        J/degree/kg
  #
  #     g        Acceleration due to gravity       m/s^2
  #
  #    eps       Ratio of the molec. weights        None
  #              of water and dry air
  #
  #----------------------------------------------------------------------------
  Rd  = 286.9968933
  g   = 9.80616
  eps = 0.621970585
  #----------------------------------------------------------------------------
  # Calculate average dP
  # --------------------
  n_levels = pressure.size
  dp_average = (num.sum(pressure[0:n_levels-1]-pressure[1:n_levels]) /
               (n_levels))
  # ---------------------------------------------------
  # Sort arrays based on  average pressure differential
  # ---------------------------------------------------
  if ( dp_average < 0.0 ):
    p  = pressure[::-1]
    t  = temperature[::-1]
    mr = mixing_ratio[::-1]
    sort  = 1;
  else:
    p  = pressure
    t  = temperature
    mr = mixing_ratio
    sort  = 0
  #----------------------------------------------------------------------------
  #                   -- Calculate average temperature --
  #----------------------------------------------------------------------------
  t_average = num.zeros((n_levels))
  for i in range(0,n_levels):
    t_average[i] = 0.5 * (t[i] + t[i-1])

  #----------------------------------------------------------------------------
  #       -- Calculate average mixing ratio (in kg/kg - hence --
  #       -- the divisor of 2000.0 instead of 2.0 )           --
  #----------------------------------------------------------------------------
  mr_average = num.zeros((n_levels))
  for i in range(0,n_levels):
    mr_average[i] = 0.0005 * (mr[i] + mr[i-1])

  #----------------------------------------------------------------------------
  #                 -- Calculate virtual temperature --
  #----------------------------------------------------------------------------
  ratio     = (1.0-eps) / eps
  t_virtual = t_average * (1.0+(ratio*mr_average))

  #----------------------------------------------------------------------------
  #         -- Calculate altitudes (divide by 1000.0 to get km) --
  #         -- Make sure the data is returned in an order       --
  #         -- consistent with the input                        --
  #----------------------------------------------------------------------------

  # -- Calculate layer thicknesses
  altitude = num.zeros((n_levels))
  altitude[0] = surface_altitude
  for i in range(1,n_levels):
    altitude[i] = (altitude[i-1] + 0.001 *
           ((Rd/g)*t_virtual[i]*num.log(p[i-1]/p[i])))

  # -- Reverse array order if required
  if ( sort == 1 ):
    altitude = altitude[::-1]

  return altitude

if __name__ == '__main__':
  print(hypsometric.__doc__)
  p = num.array(
      ( 1012.0, 991.3, 969.1, 945.5, 920.4, 893.8, 865.7, 836.1, 805.1, 772.8,
         739.5, 705.2, 670.3, 635.0, 599.7, 564.5, 529.8, 495.7, 462.6, 430.7,
         400.0, 370.8, 343.0, 316.7, 292.0, 266.8, 247.2, 227.0, 208.2, 190.8,
         174.7, 159.9, 146.2, 133.6, 121.9, 111.3, 101.5,  92.6,  84.4,  76.9,
          70.0 ))
  t = num.array(
      ( 24.54, 23.16, 21.67, 20.23, 18.86, 17.49, 16.10, 14.69, 13.22, 11.52,
         9.53,  7.24,  4.80,  2.34,  0.04, -2.29, -4.84, -7.64,-10.66,-13.95,
       -17.54,-21.45,-25.58,-29.90,-34.33,-38.94,-43.78,-48.80,-53.94,-58.79,
       -63.27,-67.32,-70.74,-73.62,-75.74,-77.07,-77.43,-76.63,-75.06,-73.14,
       -71.43 ))
  t = t + 273.15
  r = num.array(
      ( 17.78, 16.92, 15.93, 14.87, 13.78, 12.70, 11.84, 10.96, 10.15,  9.31,
         8.46,  7.73,  7.05,  6.32,  5.62,  4.91,  4.10,  3.30,  2.67,  2.15,
         1.66,  1.26,  0.95,  0.68,  0.45,  0.28,  0.17,  0.10,  0.06,  0.04,
         0.02,  0.02,  0.01,  0.01,  0.01,  0.01,  0.01,  0.01,  0.01,  0.01,
         0.02 ))
  print(p)
  print(t)
  print(r)
  h = hypsometric(p,t,r,0.001)
  print(h)
  p = p[::-1]
  t = t[::-1]
  r = r[::-1]
  h = hypsometric(p,t,r,0.001)
  print(h)


import pandas as pd
import requests
import plotly.plotly
import os
import json
## function to fetch 30 days worth of data for a state,
## subset by the top 10 sites with the most # of species
## return json object with location name, lat longs, & #
## of species & json object with top 5 most observed birds
## at each location
def getRegionData(Region):
    #Define regions
    regDict = {
        "PacificNorthwest": ["WA", "OR"],
        "NorthernPlains": ["ID", "MT", "WY", "ND", "SD"],
        "PacificSouthwest": ["CA", "NV"],
        "SouthernRockies": ["UT", "CO", "AZ", "NM"],
        "CentralPlains": ["NE", "KS", "OK"],
        "SouthernPlains": ["TX"],
        "Ozarks": ["MO", "AR", "LA", "MS", "AL", "TN"],
        "Southeast": ["FL", "GA"],
        "MidAtlantic": ["SC", "NC", "VA", "WV", "KY"],
        "PrairiePeninsula": ["IA", "IL", "IN"],
        "GreatLakes": ["MN", "WI", "MI"],
        "Northeast": ["PA", "NY", "NJ", "CT", "RI", "MA", "NH", "VT", "ME"]
    }
    ebird_token = os.getenv('ebird_token')
    headers = {'X-eBirdApiToken': ebird_token}

    target = regDict[Region]

    response_list = []
    #if statement that locates matches user input to region
    for state in target:
        url = f"https://ebird.org/ws2.0/data/obs/US-"+state+"/recent/?back=30"
#             print(url)
        local_response = requests.get(url, headers=headers)
        data = local_response.text
        response_list.append(data)

    totallist = []
    for idx,item in enumerate(response_list):
        item = json.loads(item)
        for resp_dict in item:
            totallist.append(resp_dict)
    df = pd.DataFrame(totallist)
    return(df)

# Part 2 - Get top 10 locations
def getTop10(df):
    # create subset of columns to evaluate
    df_s = df.loc[:,['locName', 'lat', 'lng','comName']]
    # remove duplicate records
    df_s = df_s.drop_duplicates()
    # create count of species observations from each location
    counts = df_s.groupby(['locName', 'lat', 'lng'])['locName'].count()
    # sort by the species count
    counts = counts.sort_values(ascending = False)
    # subset for top 10
    top_ten = counts[0:10]
    # rename the series
    top_ten = top_ten.rename('species_number')
    # convert series to dataframe
    top_ten = pd.DataFrame(top_ten)
    # reset index
    top_ten = top_ten.reset_index()
    # convert to json
    top_tenj = top_ten.to_json(orient='records', force_ascii=False)
    top_tenj = top_tenj.replace("\\","")
    return(top_tenj)

    # Part 3 - Get top 5 species at each location
    # subset original df for the top 10 locations
def getBirds(df):
   sp = df.loc[:,['comName', 'howMany', 'locName']]
   # group species to sum the total # of each species
   # has been recorded at that location
   sp = pd.DataFrame(sp.groupby(['comName'])['howMany'].sum())
   # reset index
   sp = sp.reset_index()
   # sort by location name & howMany
   sp = sp.sort_values(by = ['howMany'], ascending = False)
   # filter for species level identifications
   spFilter = sp.comName.str.contains('sp\\.')
   spFilter = spFilter[spFilter == False]
   spLevel = sp.filter(items = spFilter.index, axis=0)
   # subset for top 5 species at each location
   topsp = spLevel.head(5)
   # convert to json
   topsp_j = topsp.to_json(orient='records', force_ascii=False)
   topsp_j = topsp_j.replace("\\","")
   topsp_j

   return(topsp_j)


import os
import sys
import pkg_resources

SOCKS_RELAYS = set()

for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx.servers', 'socksplugins'):
    if file.find('__') >= 0 or file.endswith('.py') is False:
        continue
    # This seems to be None in some case (py3 only)
    # __spec__ is py3 only though, but I haven't seen this being None on py2
    # so it should cover all cases.
    try:
        package = __spec__.name  # Python 3
    except NameError:
        package = __package__    # Python 2
    __import__(package + '.' + os.path.splitext(file)[0])
    module = sys.modules[package + '.' + os.path.splitext(file)[0]]
    pluginClass = getattr(module, getattr(module, 'PLUGIN_CLASS'))
    SOCKS_RELAYS.add(pluginClass)


# Gram-Schmidt algorithm produces an prthonormal collection of vectors
# GS正交化算法, 注意，正交的是行向量，若要正交列向量，需要转置一下
# GS算法不是为了求一组矩阵的基，而是用来正则化一组基向量，顺便测试他是否满足一个基

import numpy as np

def GramSchmidt(array):
    A = array.astype(np.float64)
    Q = np.zeros_like(A, dtype=np.float64)
    for k, a in enumerate(A):
        q = a
        for i in range(k):
            qi = Q[i]
            q -= np.dot(qi, a)*qi
        if q.any() == 0:
            raise ValueError('输入的向量组不满足线性无关')
        else:
            q = q/np.sum(q**2)**0.5
            Q[k] = q
    return Q

# fuck! Debug了一个多小时，发现原来是数据类型的问题！！！！


import unittest

data = (("cc", 2), ("j", 1), ("leetcode", 2), ("abbcccddddeeeeedcba", 5))

class Solution:
    def maxPower(self, s: str) -> int:
        if len(s) == 1:
            return 1

        max_power = 0
        current_power = 1
        prev_char = s[0]
        for current_char in s[1:]:
            if current_char != prev_char:
                max_power = max(max_power, current_power)
                prev_char = current_char
                current_power = 1
            else:
                current_power += 1

        max_power = max(max_power, current_power)

        return max_power

class TestCase(unittest.TestCase):
    def test_solution(self):
        s = Solution()

        for input_data, expected in data:
            self.assertEqual(expected, s.maxPower(input_data))

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


from django.shortcuts import render,HttpResponse
from .models import Employee,Role,Department
from datetime import datetime
from django.db.models import Q

# Create your views here.
def index(request):
    return render(request,'index.html')

def view_emp(request):
    emps=Employee.objects.all()
    context={
        'emps' : emps
    }
    return render(request,'view_emp.html',context)

def add_emp(request):
    if request.method=='POST':
        first_name=request.POST['first_name']
        last_name=request.POST['last_name']
        dept=int(request.POST['dept'])
        salary=int(request.POST['salary'])
        bonus=int(request.POST['bonus'])
        role=int(request.POST['role'])
        phone=int(request.POST['phone'])
        hire_date=request.POST['hire_date']
        new_emp=Employee(first_name=first_name, last_name=last_name, dept_id=dept, salary=salary,
                         bonus=bonus, role_id=role, phone=phone, hire_date=hire_date)
        new_emp.save()
        return HttpResponse('
Employee detail added successfully
')
    elif request.method=='GET':
       return render(request,'add_emp.html')

    else:
        return HttpResponse('exception')

def remove_emp(request,emp_id = 0):
    if emp_id:
        try:
            employee_to_be_removed=Employee.objects.get(id=emp_id)
            employee_to_be_removed.delete()
            return HttpResponse('
Employee deleted successfully
')
        except:
            return HttpResponse('plz enter valid id')

    emps=Employee.objects.all()
    contex={
        'emps': emps
    }

    return render(request,'remove_emp.html',contex)

def filter_emp(request):
    if request.method == 'POST':
        name=request.POST['name']
        dept=request.POST['dept']
        role=request.POST['role']
        emps=Employee.objects.all()
        if name:
            emps= emps.filter(Q(first_name__icontains = name) | Q(last_name__icontains = name))

        if dept:
            emps = emps.filter(dept__name = dept)

        if role:
            emps = emps.filter(role__name = role)

        context = {
            'emps': emps
        }
        return render(request,'view_emp.html',context)

    elif request.method == 'GET':
        return render(request,'filter_emp.html')

    else:
        return HttpResponse('An exception occured')


import torch
import torch.optim as optim
import torch.nn as nn
from PIL import Image
from torchvision import transforms
from torchvision.utils import save_image
from math import log10
import os
import re
from typing import List, Optional, Tuple, Union
from glob import glob
import dnnlib
import numpy as np
import legacy
import mapping_net_opt
import pickle
import lpips

def PSNR(mse, flag = 0):
    #flag = 0 if a single image is used and 1 if loss for a batch of images is to be calculated
    if flag == 0:
        psnr = 10 * log10(1 / mse.item())
    return psnr

def parse_range(s: Union[str, List]) -> List[int]:
    '''Parse a comma separated list of numbers or ranges and return a list of ints.

    Example: '1,2,5-10' returns [1, 2, 5, 6, 7]
    '''
    if isinstance(s, list): return s
    ranges = []
    range_re = re.compile(r'^(\d+)-(\d+)$')
    for p in s.split(','):
        m = range_re.match(p)
        if m:
            ranges.extend(range(int(m.group(1)), int(m.group(2))+1))
        else:
            ranges.append(int(p))
    return ranges

def parse_vec2(s: Union[str, Tuple[float, float]]) -> Tuple[float, float]:
    '''Parse a floating point 2-vector of syntax 'a,b'.

    Example:
        '0,1' returns (0,1)
    '''
    if isinstance(s, tuple): return s
    parts = s.split(',')
    if len(parts) == 2:
        return (float(parts[0]), float(parts[1]))
    raise ValueError(f'cannot parse 2-vector {s}')

def make_transform(translate: Tuple[float,float], angle: float):
    m = np.eye(3)
    s = np.sin(angle/360.0*np.pi*2)
    c = np.cos(angle/360.0*np.pi*2)
    m[0][0] = c
    m[0][1] = s
    m[0][2] = translate[0]
    m[1][0] = -s
    m[1][1] = c
    m[1][2] = translate[1]
    return m

#----------------------------------------------------------------------------

def generate_images(network_pkl, z, translate=(0,0), rotate=0):
    device = torch.device('cuda')
    with dnnlib.util.open_url(network_pkl) as f:
        G = legacy.load_network_pkl(f)['G_ema'].to(device) # type: ignore

    if hasattr(G.synthesis, 'input'):
        m = make_transform(translate, rotate)
        m = np.linalg.inv(m)
        G.synthesis.input.transform.copy_(torch.from_numpy(m))

    img = G.synthesis(z)

    return img

def embedding_function():

    device = torch.device('cuda')
    os.environ["CUDA_VISIBLE_DEVICES"] = "1"
    transform = transforms.Compose([transforms.Resize(1024), transforms.ToTensor()])
    latents_list = []
    imgdir = sorted(glob('./frame_angry_cut/*.png'))

    for i in range(954):
        print(imgdir[i])
        image = Image.open(imgdir[i])
        image = image.convert("RGB")
        image = transform(image)
        image = image.unsqueeze(0)
        image = image.to(device)

        # MSE loss object
        MSE_loss = nn.MSELoss(reduction="mean")

        model = mapping_net_opt.MappingNetwork()
        model.load_state_dict(torch.load("./model_last_5000.pth"))
        model.to(device)
        model.eval()
        if i == 0 or i == 115 or i == 232 or i == 336 or i == 447 or i == 569 or i == 699 or i == 822: # angry
        # if i == 0 or i == 105 or i == 212 or i == 316 or i == 419 or i == 529 or i == 648 or i == 773: # calm
        # if i == 0 or i == 115 or i == 231 or i == 347 or i == 461 or i == 589 or i == 711 or i == 831: # disgust
        # if i == 0 or i == 109 or i == 217 or i == 319 or i == 429 or i == 578 or i == 704 or i == 822: # fearful
        # if i == 0 or i == 103 or i == 206 or i == 311 or i == 421 or i == 530 or i == 638 or i == 755: # happy
        # if i == 0 or i == 98 or i == 197 or i == 294: # neutral
        # if i == 0 or i == 114 or i == 220 or i == 324 or i == 424 or i == 537 or i == 647 or i == 758: # sad
        # if i == 0 or i == 101 or i == 198 or i == 303 or i == 400 or i == 502 or i == 608 or i == 712: #surprise
            latents = model.forward(image)
            latents_copy = latents.clone().detach()
            latents_copy = torch.reshape(latents_copy, (1, 16, 512))
            latents_copy.requires_grad = True
        #latents_rand = torch.zeros((1, 512), requires_grad=True, device=device)

        # Optimizer to change latent code in each backward step
        optimizer = optim.Adam({latents_copy}, lr=0.01, betas=(0.9, 0.999), eps=1e-8)
        #optimizer = optim.Adam({latents_rand}, lr=0.01, betas=(0.9, 0.999), eps=1e-8)

        # Loop to optimise latent vector to match the generated image to input image
        loss_ = []
        loss_psnr = []
        for e in range(1500):
            optimizer.zero_grad()
            syn_img = generate_images(network_pkl="https://api.ngc.nvidia.com/v2/models/nvidia/research/stylegan3/versions/1/files/stylegan3-r-ffhq-1024x1024.pkl", z=latents_copy)
            #syn_img = generate_images(network_pkl="https://api.ngc.nvidia.com/v2/models/nvidia/research/stylegan3/versions/1/files/stylegan3-r-ffhq-1024x1024.pkl", z=latents_rand)
            syn_img = (syn_img + 1.0) / 2.0
            mse = MSE_loss(syn_img, image)
            loss_fn_alex = lpips.LPIPS(net='alex')
            loss_fn_alex.to(device)
            p = loss_fn_alex(syn_img, image)
            psnr = PSNR(mse, flag=0)
            loss = mse + p
            if loss < 0.03:
                save_image(syn_img.clamp(0, 1), "./opt_angry/optimized_angry{frame:04d}_{epoch}.png".format(frame=i, epoch=e + 1))
                break
            loss.backward()
            optimizer.step()
            loss_np = loss.detach().cpu().numpy()
            loss_np = loss_np[0,0,0,0]
            print(loss_np)
            loss_psnr.append(psnr)
            loss_.append(loss_np)
            if e+1 == 1500:
                save_image(syn_img.clamp(0, 1), "./opt_angry/optimized_angry{frame:04d}_{epoch}.png".format(frame=i, epoch=e + 1))

        latents_copy_list = latents_copy.detach().clone()
        latents_list.append(latents_copy_list)

    with open('latents_angry.pkl', 'wb') as f:
        pickle.dump(latents_list, f)

if __name__ == "__main__":
    embedding_function()


from __future__ import annotations

import argparse
import sys
from pathlib import Path

from .constants import DESCRIPTION, EPILOG, PROGNAME, __VERSION__

class ShowSupportedFormatsAndExit(argparse.Action):
    @staticmethod
    def show() -> None:
        print('目前支持的加密类型（使用正则表达式表示）：\n\n'
              '    NCM:   *.ncm *.uc!\n'
              '    QMCv1: *.qmc[0-9] *.qmcflac *.qmcogg *.qmcra\n'
              '    QMCv2: *.mflac[0-9a-zA-Z]? *.mgg[0-9a-zA-Z]?'
              )

    def __call__(self, parser, namespace, values, option_string=None):
        self.show()
        sys.exit()

try:
    ap = argparse.ArgumentParser(prog=PROGNAME,
                                 add_help=False,
                                 formatter_class=argparse.RawTextHelpFormatter,
                                 description=DESCRIPTION,
                                 epilog=EPILOG,
                                 exit_on_error=False
                                 )
except TypeError:
    ap = argparse.ArgumentParser(prog=PROGNAME,
                                 add_help=False,
                                 formatter_class=argparse.RawTextHelpFormatter,
                                 description=DESCRIPTION,
                                 epilog=EPILOG
                                 )

positional_args = ap.add_argument_group(title='必要的位置参数')
positional_args.add_argument('srcfilepaths',
                             metavar='PATH',
                             nargs='+',
                             type=Path,
                             help='源文件或目录的路径'
                             )
help_options = ap.add_argument_group(title='帮助信息')
help_options.add_argument('-h', '--help',
                          action='help',
                          help='显示帮助信息并退出'
                          )
help_options.add_argument('-V', '--version',
                          action='version',
                          version=f'%(prog)s {__VERSION__}',
                          help='显示版本信息并退出'
                          )
help_options.add_argument('--formats',
                          nargs=0,
                          action=ShowSupportedFormatsAndExit,
                          help='显示支持的加密类型，然后退出'
                          )

options = ap.add_argument_group(title='可选参数')
destdir_options = options.add_mutually_exclusive_group()
destdir_options.add_argument('-d', '--dest',
                             metavar='DESTPATH',
                             dest='destdirpath',
                             action='store',
                             type=Path,
                             default=Path.cwd(),
                             help="将所有输出文件放置在指定目录下；\n"
                                  "与 '--ds, --dest-source' 冲突"
                             )
destdir_options.add_argument('--ds', '--dest-source',
                             dest='destdirpath_is_srcfiledirpath',
                             action='store_true',
                             help="将每一个输出文件放置在源文件所在目录下；\n"
                                  "与 '-d, --dest' 冲突"
                             )
options.add_argument('-r', '--recursive',
                     action='store_true',
                     help='如果 PATH 中存在目录，那么递归处理目录下的文件\n'
                          '（不包括子目录）'
                     )
options.add_argument('--np', '--no-parallel',
                     dest='enable_multiprocessing',
                     action='store_false',
                     help='不使用并行模式'
                     )
options.add_argument('-t', '--test',
                     dest='probe_only',
                     action='store_true',
                     help='仅测试输入文件是否受支持，不进行解密'
                     )
options.add_argument('-q', '--quiet',
                     dest='keep_quiet',
                     action='store_true',
                     help='不显示任何信息，仅根据退出状态码表示运行结果'
                     )
tag_options = ap.add_argument_group(title='标签信息和封面相关选项')
tag_options.add_argument('--notag',
                         dest='with_tag',
                         action='store_false',
                         help='不要为输出文件补充缺失的标签'
                         )
tag_options.add_argument('--avoid-search-tag',
                         dest='search_tag',
                         action='store_false',
                         help="不要在网络上查找缺失的标签和封面信息；\n"
                              "仅在未添加 '--notag' 选项时有效"
                         )


import pandas as pd
import numpy as np
import plotly.express as px
import streamlit as st
import sqlite3
import pydeck as pdk

####################
#################### HISTOGRAMME
####################

# Lire les données depuis la base de données
connexion = sqlite3.connect('bdd.db')
df = pd.read_sql_query("SELECT * FROM objet", connexion)

# Convertir la colonne 'date' en format datetime
df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y')

# Créer une liste des types d'objet uniques
types_objet = df['type'].unique()

st.title("Nombre d'objets trouvés par semaine (total)")
# Sélectionner les types d'objet à afficher
selected_types = st.multiselect('Sélectionner les types d\'objet à afficher', types_objet, default=types_objet[:])

# Filtrer les données en fonction des types d'objet sélectionnés
df_filtered = df[df['type'].isin(selected_types)]

# Regrouper les données par semaine et compter le nombre d'objets trouvés
df_weekly = df_filtered.groupby(pd.Grouper(key='date', freq='W')).count()['id'].reset_index()

# Créer un histogramme avec Plotly
fig = px.bar(df_weekly, x='date', y='id', color='id', color_continuous_scale='Plasma')

# Afficher le graphique avec Streamlit
st.plotly_chart(fig)

####################
#################### CARTE
####################

# Connexion à la base de données
connexion = sqlite3.connect('bdd.db')

# Récupération des données de la table objet
query_objet = "SELECT * FROM objet"
df_objet = pd.read_sql_query(query_objet, connexion)

# Récupération des données de la table gare
query_gare = "SELECT * FROM gare"
df_gare = pd.read_sql_query(query_gare, connexion)

# Fermeture de la connexion à la base de données
connexion.close()

# Sélection de l'année et du type d'objet avec des widgets Streamlit
annees = ['2019', '2020', '2021', '2022']
annee_selectionnee = st.selectbox("Sélectionnez l'année :", annees, key=1)

st.title("Nombre d'objets trouvés par année pour 1 million de voyageurs")
types = df_objet['type'].unique().tolist()
types_selectionnes = st.multiselect("Sélectionnez les types d'objets :", types, default=types[:], key=3)

# Filtrage des données en fonction de la sélection de l'utilisateur
df_objet_filtre = df_objet[(df_objet['type'].isin(types_selectionnes)) & (df_objet['date'].str[-4:] == annee_selectionnee)]
df_gare_filtre = df_gare[['gare', 'lat', 'lon', 'frequentation_' + annee_selectionnee]]
df_gare = df_gare.sort_values('gare').reset_index().drop(columns='index')
# Calcul du nombre d'objets trouvés des types sélectionnés pour chaque gare
df_nb_objets_par_gare = df_objet_filtre.groupby('gare')['id'].count().reset_index().rename(columns={'id': 'nb_objets'})

# Calcul du ratio fréquentation / nombre d'objets trouvés
df_gare['ratio_freq_objets'] = round((df_nb_objets_par_gare.nb_objets * 1_000_000) / df_gare['frequentation_' + annee_selectionnee])

import colorcet as cc

def plasma_color(value, min_value, max_value):
    value_normalized = (value - min_value) / (max_value - min_value)
    color_index = int(value_normalized * 255)
    hex_color = cc.palette["CET_C1"][color_index]
    rgb_color = tuple(int(hex_color[i:i+2], 16) for i in (1, 3, 5))
    return list(rgb_color)

# Calcul du ratio fréquentation / nombre d'objets trouvés
df_gare['ratio_freq_objets'] = round((df_nb_objets_par_gare.nb_objets * 1_000_000 / df_gare['frequentation_' + annee_selectionnee]))

# Générer les couleurs Plasma pour chaque gare en fonction du ratio
min_ratio = df_gare['ratio_freq_objets'].min()
max_ratio = df_gare['ratio_freq_objets'].max()
df_gare['plasma_color'] = df_gare['ratio_freq_objets'].apply(lambda x: plasma_color(x, min_ratio, max_ratio))
df_gare['rgb_color'] = df_gare['plasma_color'].apply(lambda x: tuple(x))

# Création de la carte de Paris avec les barres représentant le ratio
view_state = pdk.ViewState(
    # map_style=None,
    longitude=df_gare['lon'].mean(),
    latitude=df_gare['lat'].mean(),
    zoom=12,
    pitch=45
)
layer = pdk.Layer(
    'ColumnLayer',
    data=df_gare,
    get_position='[lon, lat]',
    get_elevation='ratio_freq_objets',
    elevation_scale=25,
    get_fill_color='rgb_color',
    pickable=True,
    auto_highlight=True,
    extruded=True,
    coverage=0.3,
    disk_resolution=50,
    opacity=0.8,
)
tooltip = {
    "html": "Gare : {gare}
Nombre d'objets trouvés sur 1 million de voyageurs : {ratio_freq_objets} objets",
    "style": {"backgroundColor": "black", "color": "white"}
}
r = pdk.Deck(layers=[layer], initial_view_state=view_state, tooltip=tooltip)
st.pydeck_chart(r)


import time

print("Welcome to my Ultraman Quiz!")

start = input("Are you ready to begin? Type 'Yes' or 'No': ")
start = start.lower()

#The initial question if the user wants to take the quiz or not
while start != 'yes':
    if start == 'no':
        print("Ok, well see you later I guess...")
        quit()
    else:
        start = input("What the heck is even that? Please enter in an option like 'Yes' or 'No': ")
        start = start.lower()

print("All right let's go!!")
print("...")

time.sleep(3)

while True:
    playerScore = 0

    possibleAnswers = ['a', 'b', 'c', 'd']

    #Question 1
    print()
    print("Question 1: Who was the first multi-type Ultraman?")
    time.sleep(1)

    print("A: Ultraman Trigger \nB: Ultraman Dyna \nC: Ultramn Hikari\nD: Ultraman Tiga")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'd':
            playerScore += 1

    #Question 2
    print()
    print("Question 2: How many different looks did the original Ultraman have in his 1960s TV show?")
    time.sleep(1)

    print("A: 1 \nB: 2 \nC: None\nD: 4")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'b':
            playerScore += 1

    #Question 3
    print()
    print("Question 3: What is true about Ultraman Mebius and Ultraman Hikari?")
    time.sleep(1)

    print("A: They both have swords \nB: Their first designs didn't have eyes \nC: They are brothers\nD: They are both multi-type Ultramen")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'a':
            playerScore += 1

    #Question 4
    print()
    print("Question 4: How many Ultramen have numbers in their names?")
    time.sleep(1)

    print("A: None (That's ridiculous!) \nB: 3 \nC: 14\nD: 1")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'b':
            playerScore += 1

    #Question 5
    print()
    print("Question 5: Which Ultraman was the first to have Horns?")
    time.sleep(1)

    print("A: Horns? \nB: Ultraman Trigger \nC: Ultraman Taro\nD: Ultraman Horns")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'c':
            playerScore += 1

    #Question 6
    print()
    print("Question 6: Which Ultraman has a villian named after him?")
    time.sleep(1)

    print("A: Ultraseven \nB: Ultraman Cosmos \nC: Ultraman Gaia\nD: Ultraman Ace")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'd':
            playerScore += 1

    #Question 7
    print()
    print("Question 7: Is every Ultraman born on their home planet?")
    time.sleep(1)

    print("A: No \nB: Yes")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'a':
            playerScore += 1

    #Question 8
    print()
    print("Question 8: Which Ultraman wields the Ultra Bracelet?")
    time.sleep(1)

    print("A: Ultraman Jack \nB: Ultraman Ginga \nC: Ultra Father\nD: Ultraman the Next")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'a':
            playerScore += 1

    #Question 9
    print()
    print("Question 9: Which Ultraman made their debut in 2004?")
    time.sleep(1)

    print("A: Ultra Mother \nB: Ultraman Agul \nC: Ultraman Zearth\nD: Ultraman Nexus")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'd':
            playerScore += 1

    #Question 10
    print()
    print("Question 10: Which Ultraman video game has air combat mechanics?")
    time.sleep(1)

    print("A: Ultraman Fighting Evolution: Rebirth \nB: None of them \nC: Ultraman Fighting Evolution 3\nD: Ultraman Nexus")
    print()
    answer = input("Please input the letter of your answer: ")

    while answer.lower() not in possibleAnswers:
        answer = input("Hey, that's not an answer choice! Try again please: ")

    if answer.lower() == 'd':
            playerScore += 1

    #Score calculation
    print()
    print("You got " + str(playerScore) + " out of 10 question correct")

    if (playerScore < 4):
        print("You got some learning to do!")
        time.sleep(1)
    elif playerScore >= 4 and playerScore <= 7:
        print("Ok you know some Ultraman knowledge!")
        time.sleep(1)
    elif playerScore >= 8:
        print("Wow, get a life nerd!!")
        time.sleep(1)

    print()
    answer = input("Do you want to play again?: ")

    while answer.lower() != 'yes':
        if answer.lower() == 'no':
            print("All right, thanks for playing!!")
            quit()

        answer = input("Ok man, that's not an answer that we're looking for. Please try again: ")

    print("Ok, let's run it again...")
    print()

    time.sleep(2)


class Solution:
    def numOfSubarrays(self, arr, k, threshold):
        def sums(arr,k):
            start, running_total, n, output = 0, 0, len(arr), [0]*(n-k+1)
            for x in range(n):
                running_total += arr[x]
                while x - start == k-1:
                    output[start] = running_total / k
                    running_total -= arr[start]
                    start += 1
            return output
        tally = 0
        for i in sums(arr,k):
            if i >= threshold:
                tally += 1
        return tally

Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold.py


import cv2
import numpy as np
import math
import matplotlib.pyplot as plt

img = cv2.imread('ABC01.jpg', cv2.IMREAD_GRAYSCALE) #讀入灰階字母樣本

def pret(img):#撰寫產生4X4方向直方圖描述子的程式
    #img = cv2.resize(img, (16, 16), interpolation=cv2.INTER_AREA) #縮小至 16×16 像素尺寸
    k=1 #畫圖初始值
    cell_size = 4 #將影像分成 4×4 區域
    all_cell = np.zeros( shape = ( 4, 4, 4) ) #特徵向量儲存
    for i in range(cell_size):
        for j in range(cell_size):
            cell=np.zeros(((cell_size),(cell_size)),dtype=np.uint16)
            cell=img[4*i:4+4*i,4*j:4+4*j]
            grad,phase =sobel(cell) #這 16 個像素的梯度絕對值 M 與方向角
            bin = hog(grad,phase)#2.5 繪製直方圖
            plt.subplot(4,4,k)#2.5 繪製直方圖
            draw(bin)
            k+=1
            all_cell[i][j] = bin
    #plt.show()
    return all_cell

def sobel(img): #Sobel 垂直與水平邊緣檢測的結果(不要做二值化)
    gradient_values_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
    gradient_values_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
    gradient_magnitude=abs(gradient_values_x)+abs(gradient_values_y)
    #gradient_magnitude = (gradient_magnitude * 255 / np.max(gradient_magnitude)).astype(np.uint8)

    sobel_phase=np.zeros(((img.shape[0]),(img.shape[1])),dtype=np.uint16)
    for x in range(img.shape[0]):
        for y in range(img.shape[1]):
            sobel_phase[x][y] = (math.atan2(gradient_values_y[x][y],gradient_values_x[x][y])/math.pi*180) % 180 #弧度轉角度

    return gradient_magnitude,sobel_phase

def hog(grad,phase):
    angle_unit = 180 / 4 #以 45 度為間隔
    binn = np.zeros(4)
    for i in range(grad.shape[0]):
        for j in range(grad.shape[1]):
            if grad[i,j]>0:
                binn[np.int16( phase[i,j] / angle_unit)] += 1 #int(grad[i,j])
    return binn

def draw(bin):#2.4 繪製直方圖
    x = np.arange(4)
    str1 = ( '1', '2', '3', '4')
    plt.bar( x, height = bin, width = 0.8, label = 'cell histogram', tick_label = str1)
    plt.ylim(0,20)

def input(num): #2.1撰寫主程式 讀取字母編號

    c='ABC'+str(num).rjust(2,'0')+'.jpg' #2.2 生成檔名字串
    img = cv2.imread(c, cv2.IMREAD_GRAYSCALE) #讀取樣本
    img = cv2.resize(img, (16, 16), interpolation=cv2.INTER_AREA) #2.3 讀取灰階字母樣本，縮小至 16×16 像素尺寸
    hog_vector=pret(img) #2.4&2.5 套用前述的HOG函式，獲得字母樣本HOG向量 繪製直方圖

    test_img = cv2.imread('t2.jpg', cv2.IMREAD_GRAYSCALE) #2.6 讀取樣本
    test_img = cv2.resize(test_img, (128, 128), interpolation=cv2.INTER_AREA) #2.6 縮小至 128×128 像素尺寸
    L2_result = np.zeros( shape = ( 8, 8) ) #儲存結果

    for i in range(8): #2.7 用迴圈讀取測試影像不同位置的ROI,ROI的大小為16X16像素
        for j in range(8):
            roiImg=test_img[16*i:16+16*i,16*j:16+16*j]
            roiImg_vector=pret(roiImg)# 2.8 套用前述的HOG函式，獲得ROI區域的向量
            L2=np.sqrt(np.sum((hog_vector.flatten()- roiImg_vector.flatten())**2)) #2.9 計算字母樣本與ROI區域的HOG的L2距離
            L2_result[i][j]=L2 #儲存L2距離結果

    # #2.10
    L2_flatten = np.array(L2_result.flatten())
    arr_p = findThreeSmallest(L2_flatten)

    #製作紅色遮罩
    mask_img = np.zeros((16, 16, 3), np.uint8)
    mask_img[0:16, 0:16, :] = [0, 0, 255]

    test2_img = cv2.cvtColor(test_img, cv2.COLOR_GRAY2RGB)
    for i in range(3):

        row = np.int(arr_p[i]/8)
        col = np.int(arr_p[i] % 8)
        print('row',row,'col',col)

        roiImg_change=test_img[16*row:16+16*row,16*col:16+16*col]
        image = cv2.cvtColor(roiImg_change, cv2.COLOR_GRAY2RGB)
        mask_img_result = cv2.add(image, mask_img)
        test2_img[16*row:16+16*row,16*col:16+16*col]=mask_img_result

        cv2.imshow("roi", mask_img_result)
        cv2.waitKey(0)

    cv2.imshow('Image', test2_img)
    cv2.waitKey(0)

def findSmallest(arr):
    smallest = arr[0] #儲存最小的直
    smallest_index = 0 #儲存位置
    for i in range(1,len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def findThreeSmallest(arr):
    arr_p = np.zeros(3)
    for i in range(len(arr_p)):
        idx = findSmallest(arr)
        arr_p[i]=idx+i
        arr = np.delete(arr, idx)
    return arr_p

input(15)

#cv2.imshow('Image', test_img)
# cv2.imwrite("Image-test.jpg", img)
#cv2.waitKey(0)


import os
import streamlit.components.v1 as components
from enum import Enum

_RELEASE = True

if not _RELEASE:
    _component_func = components.declare_component(
        "steps",
        url="http://localhost:3000",
    )
else:
    parent_dir = os.path.dirname(os.path.abspath(__file__))
    build_dir = os.path.join(parent_dir, "design/build")
    _component_func = components.declare_component("steps", path=build_dir)

class StepStatus(str, Enum):
    WAIT = "wait"
    PROCESS = "process"
    FINISH = "finish"

def steps(choose_status, find_status, explore_status, rate_status, key=None):
    component_value = _component_func(
        choose_status = choose_status,
        find_status = find_status,
        explore_status = explore_status,
        rate_status = rate_status,
        key = key,
    )
    return component_value

if not _RELEASE:
    import streamlit as st

    st.subheader("Component with constant args")

    with st.container():
        st.markdown("---")
        _ = steps(
            choose_status = StepStatus.FINISH,
            find_status = StepStatus.FINISH,
            explore_status = StepStatus.PROCESS,
            rate_status = StepStatus.WAIT,
        )
        st.markdown("---")

    st.markdown("---")
    st.subheader("Component with variable args")

    find_status_input = st.text_input("Enter a status", value=StepStatus.FINISH.value)
    _ = steps(
        choose_status = StepStatus.FINISH,
        find_status = find_status_input,
        explore_status = StepStatus.PROCESS,
        rate_status = StepStatus.WAIT,
        key="variable_args"
    )


"""
Helper python script to create the Request JSON body needed by Vertex AI
BatchPredictions REST API.

Given a configuration YAML file,
returns the Request JSON body file that can be used by Vertex AI API to send batch
prediction requests.

The script takes the following positional arguments:

- config_filepath: filepath to the configuration YAML file (incl. extension)
- output_folder [optional, default = "json_files"]: filepath to folder where to save the JSON file

To run:

```shell
cd inference_pipeline_new_content
python utils/create_json_request_body.py \
  "utils/request_json_config.yml"
```

References
https://cloud.google.com/vertex-ai/docs/predictions/get-predictions#retrieve_batch_prediction_results
https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations.batchPredictionJobs#instanceconfig
https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations.models#Model.FIELDS.supported_input_storage_formats
https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations.batchPredictionJobs#instanceconfig
https://cloud.google.com/vertex-ai/docs/predictions/get-predictions#aiplatform_batch_predict_custom_trained-drest
https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/prediction/custom_batch_prediction_feature_filter.ipynb

Note from:
https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/BigQueryDestination
When only the project is specified, the Dataset and Table is created. When the full table reference is specified,
the Dataset must exist and table must not exist.
"""

import json
import yaml
import typer
from pathlib import Path

def main(
    config_filepath: Path = typer.Argument(..., exists=True, dir_okay=False),
    output_filepath: Path = typer.Argument(
        "json_files/request_daily_ner.json", dir_okay=False
    ),
) -> None:
    """
    Given a a configuration YAML file,
    returns the Request JSON body file that can be used by Vertex AI API to send batch
    prediction requests for that part of page.

    Args:
      config_filepath: filepath to the configuration YAML file (incl. extension)
      output_folder: filepath to the output JSON file (default: 'json_files/request_daily_ner.json')

    Returns:
      None. Saved the output JSON to the specified output_filepath.
    """

    with open(config_filepath, "r") as file:
        config = yaml.safe_load(file)

    input = config["input"]

    json_string = {
        "displayName": f"{input['BATCH_JOB_NAME']}",
        "model": f"projects/{input['PROJECT_ID']}/locations/{input['REGION']}/models/{input['MODEL_ID']}",
        "inputConfig": {
            "instancesFormat": input["INPUT_FORMAT"],
            "bigquerySource": {"inputUri": input["INPUT_TABLE_URI"]},
        },
        "outputConfig": {
            "predictionsFormat": input["OUTPUT_FORMAT"],
            "bigqueryDestination": {"outputUri": input["OUTPUT_TABLE_URI"]},
        },
        "dedicatedResources": {
            "machineSpec": {
                "machineType": input["MACHINE_TYPE"],
            },
            "startingReplicaCount": input["MIN_NODES"],
            "maxReplicaCount": input["MAX_NODES"],
        },
        "manualBatchTuningParameters": {"batch_size": input["BATCH_SIZE"]},
        "instanceConfig": {
            "instanceType": "object",
            "includedFields": input["INCLUDED_FIELDS"],
        },
    }

    with open(f"{output_filepath}", "w") as outfile:
        json.dump(json_string, outfile)

if __name__ == "__main__":  # noqa: C901
    typer.run(main)