#Xiangzhen Sun
#ISC5307
#Project 5 - Mummy

import vtk
import sys
from Tkinter import *
###### Read the Data File ######

reader = vtk.vtkStructuredPointsReader()
reader.SetFileName("mummy.128.vtk")

###### Transfer Functions ######

opacityTransferFunction = vtk.vtkPiecewiseFunction()
opacityTransferFunction.AddPoint(0, 0.0)
opacityTransferFunction.AddPoint(75, 0.0)
opacityTransferFunction.AddPoint(95, 0.0)
opacityTransferFunction.AddPoint(110, 0.4)
opacityTransferFunction.AddPoint(120, 0.6)
opacityTransferFunction.AddPoint(145, 1.0)
opacityTransferFunction.AddPoint(255, 1.0)

colorTransferFunction = vtk.vtkColorTransferFunction()
colorTransferFunction.AddRGBPoint(75.0, 0.4, 0.4, 0.4)
colorTransferFunction.AddRGBPoint(95.0, 0.8, 0.8, 0.8)
colorTransferFunction.AddRGBPoint(110.0, 0.6, 0.6, 0.6)
colorTransferFunction.AddRGBPoint(120.0, 0.6, 0.6, 0.6)
colorTransferFunction.AddRGBPoint(145.0, 0.4, 0.4, 0.4)
colorTransferFunction.AddRGBPoint(255.0, 0.2, 0.2, 0.2)

#Volume Properties

volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.ShadeOn()

#Set Raycasting Variables

MIPFunction = vtk.vtkVolumeRayCastMIPFunction()
volumeMapper = vtk.vtkVolumeRayCastMapper()
volumeMapper.SetInputConnection(reader.GetOutputPort())
volumeMapper.SetVolumeRayCastFunction(MIPFunction)

volumeMapper.SetSampleDistance(0.5)
#volumeMapper.SetSampleDistance(1.0)
#volumeMapper.SetSampleDistance(2.0)
#volumeMapper.SetSampleDistance(4.0)

###### Create Volume ######

volume = vtk.vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

###### Render, Window, Interactor ######

ren1 = vtk.vtkRenderer()
ren1.SetBackground(0, 0, 0)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren1)
renWin.SetSize(512, 512)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

###### Borrow From camframe.tcl ######
frame = 0

w2if = vtk.vtkWindowToImageFilter()
writer = vtk.vtkPNGWriter()

def saveFrame():
	global frame
	name = "Frame{:0>3}.png".format(frame)
	w2if.SetInput(renWin)
	writer.SetInputConnection(w2if.GetOutputPort())
	writer.SetFileName(name)
	writer.Write()
	frame = frame + 1
	name = "Frame{:0>3}.png".format(frame)
	save.config(text = "save {0!s}".format(name))

def Quit():
    sys.exit()

#name = "frame{:0>3}.ppm"
save = Button(text = "Save Frame000.ppm", command = saveFrame)
quit = Button(text = "Quit", command = Quit)

###### Pack GUI Objects ######

save.pack()
quit.pack()

#def leftButtonPressEvent(self):
#	self.OnLeftButtonDown()
#	return

ren1.AddVolume(volume)
renWin.Render()
#iren.AddObserver("LeftButtonPressEvent", leftButtonPressEvent)
iren.SetDesiredUpdateRate(1.0)
iren.Initialize()
#iren.Start()
mainloop()


import pygame
from game_logic import sound_tools

class Menu:
    PINK = (248, 53, 158)
    YELLOW = (255, 255, 0)
    GREEN = (15, 239, 145)
    FONT = 'data/fff-forward.regular.ttf'

    def __init__(self, screen):
        self.screen = screen
        self.title = []
        self.buttons = []

    def render_title(self):
        for i in self.title:
            title = i[0]
            color = i[1]
            size_font = i[2]
            x, y = i[3]
            title_label = pygame.font.Font(self.FONT, size_font)
            label = title_label.render(title, False, color)
            self.screen.blit(label, (x, y))

    def event_handler(self, event):
        if event:
            if event.type == pygame.MOUSEBUTTONDOWN:
                return self.get_click(event.pos)

    def get_move(self, mouse_pos):
        pos_x, pos_y = mouse_pos
        for i in self.buttons:
            x, y, w, h = i[3]
            if x <= pos_x <= x + w and y <= pos_y <= y + h:
                title = i[0]
                color = i[1]
                size_font = i[2]
                title_label = pygame.font.Font(self.FONT, size_font)
                label = title_label.render(title, False, color)
                self.screen.blit(label, (x, y))

    def get_click(self, mouse_pos):
        pos_x, pos_y = mouse_pos
        for i in self.buttons:
            x, y, w, h = i[3]
            if x <= pos_x <= x + w and y <= pos_y <= y + h:
                sound_tools.click.play()
                if i[4]:
                    return i[4]


a = input()
huruf = [0] * 26
for x in a:
    huruf[ord(x)-97] += 1
while 0 in huruf:
    huruf.remove(0)
if max(huruf) - min(huruf) >= 1: print ("NO")
else: print("YES")

s = input()
distinctList = []
countList = []
for c in s:
    if c not in distinctList: distinctList.append(c)
for d in distinctList:
    count = s.count(d)
    countList.append(count)
key = countList[0]
flags = 0
for count in countList:
    if(key != count): flags+=1
if(flags > 1): print("NO")
else: print("YES")


import sys
sys.path.append('..')
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.sql import text
from config import conf

def simple_query(query_string, args={}):
    engine = create_engine(conf['db_string'])
    statement = text(query_string)
    with engine.connect() as connection:
        result = connection.execute(statement, args)

    results_list = []
    for row in result:
        results_list.append(dict(row.items()))
    return results_list

def delete_row(query_string, args={}):
    engine = create_engine(conf['db_string'])
    statement = text(query_string)
    with engine.connect() as connection:
        result = connection.execute(statement, args)
    return result.rowcount

def insert_row(query_string, args={}):
    engine = create_engine(conf['db_string'])
    statement = text(query_string)
    with engine.connect() as connection:
        result = connection.execute(statement, args)
    row = result.fetchone()
    return row[0]

def update_row(query_string, args={}):
    engine = create_engine(conf['db_string'])
    statement = text(query_string)
    with engine.connect() as connection:
        result = connection.execute(statement, args)
    return result.rowcount

if __name__ == "__main__":
    # test the methods...

    results = simple_query("SELECT * FROM test.entree")
    print("Found rows: %s" % results)

    inserted_id = insert_row("INSERT INTO test.entree (entree_name) VALUES ('Fake food') RETURNING entree_id")
    print("Inserted entree_id %d" % inserted_id)

    db_params = {'entree_id': inserted_id}

    updated_rows = update_row("UPDATE test.entree SET entree_name = 'Pasta' WHERE entree_id = :entree_id", db_params)
    print("Updated %d records." % updated_rows)

    deleted_rows = delete_row("DELETE FROM test.entree WHERE entree_id = :entree_id", db_params)
    print("Deleted %d records." % deleted_rows)


#!/usr/bin/env python3
"""
Created on Sun Feb  7 08:51:25 2021

@author: mmacferrin
"""
import argparse
import datetime
import os

import click

from antarctica_today import (
    compute_mean_climatology,
    generate_antarctica_today_map,
    generate_gap_filled_melt_picklefile,
    melt_array_picklefile,
    plot_daily_melt_and_climatology,
    tb_file_data,
)

def preprocessing_main():
    """When we get new data (or new versions of the data), do all the things to get it ingested.

    1) Read all the .bin files and put them into the array picklefile
    2) Compute climatology and daily-melt over the baseline period.
    3) Recompute annual melt and annual anomaly geo-tiffs.
    """
    # 1) Read all the .bin files and put them into the array picklefile
    melt_array_picklefile.save_model_array_picklefile()

    # 2) Compute climatology and daily-melt over the baseline period.
    compute_mean_climatology.save_climatologies_as_CSV(gap_filled=False)
    compute_mean_climatology.save_daily_melt_numbers_to_csv(gap_filled=False)
    compute_mean_climatology.create_baseline_climatology_tif(gap_filled=False)

    # 3) Recompute annual melt and annual anomaly geo-tiffs.
    compute_mean_climatology.create_annual_melt_sum_tif(year="all", gap_filled=False)

    compute_mean_climatology.compute_daily_climatology_pixel_averages()
    compute_mean_climatology.compute_daily_sum_pixel_averages()

    # 4) Compute the gap-filled daily melt values (substituting averages)
    generate_gap_filled_melt_picklefile.save_gap_filled_picklefile()

    # 3) Recompute annual melt and annual anomaly geo-tiffs.
    compute_mean_climatology.create_annual_melt_sum_tif(year="all", gap_filled=True)

    # 5) Re-do the mean climatologies with the gap-filled averages.
    compute_mean_climatology.save_climatologies_as_CSV(gap_filled=True)
    compute_mean_climatology.save_daily_melt_numbers_to_csv(gap_filled=True)
    compute_mean_climatology.create_baseline_climatology_tif(gap_filled=True)

    # 6) Loop through all the years. Any "blank" years will simply be ignored.
    for year in range(1979, datetime.datetime.today().year + 1):
        compute_mean_climatology.create_annual_melt_anomaly_tif(year, gap_filled=True)

def generate_all_plots_and_maps_main():
    """After all the preprocessing, re-generate all the plots and maps.

    4) Re-run the climatology & daily-melt plots for each year.
    5) Generate new annual maps.
    """
    # 4) Re-run the climatology & daily-melt plots for each year. Years with no data will be skipped (useful if we accidentally go 1 year too far).
    for year in range(1979, datetime.datetime.today().year + 1):
        for region in range(0, 7 + 1):
            fname = os.path.join(
                tb_file_data.climatology_plots_directory,
                "R{0}_{1}-{2}.png".format(region, year, year + 1),
            )

            plot_daily_melt_and_climatology.plot_current_year_melt_over_baseline_stats(
                datetime.datetime(year=year + 1, month=4, day=30),
                region_num=region,
                outfile=fname,
            )

    # 5) Get a quick status check on the dates coverage.
    plot_daily_melt_and_climatology.simple_plot_date_check()

    # 6) Generate new annual maps.
    mapper = generate_antarctica_today_map.AT_map_generator(gap_filled=True)
    mapper.generate_annual_melt_map(dpi=300, year="all", reset_picklefile=True)

    mapper.generate_anomaly_melt_map(dpi=300, year="all", reset_picklefile=True)

    # Create the latest anomaly map for a partial year (useful during the melt season).
    mapper.generate_latest_partial_anomaly_melt_map(dpi=300)

# def generate_all_plots_for_a_given_year_main(year=2021):
#     """After all the pre-processing, generate the plots and maps (in both PNG and SVG).

#     NOTE: I never finished all this"""
#     for region in range(0,7+1):

#         fname = os.path.join(tb_file_data.climatology_plots_directory, "R{0}_{1}-{2}.png".format(region, year, year+1))
#         plot_daily_melt_and_climatology.plot_current_year_melt_over_baseline_stats(\
#                             datetime.datetime(year=year+1, month=4, day=30),
#                             region_num=region,
#                             outfile = fname)

#         fname_svg = os.path.join(tb_file_data.climatology_plots_directory, "R{0}_{1}-{2}.svg".format(region, year, year+1))
#         plot_daily_melt_and_climatology.plot_current_year_melt_over_baseline_stats(\
#                             datetime.datetime(year=year+1, month=4, day=30),
#                             region_num=region,
#                             outfile = fname_svg)

#     # TODO: Finish if you want.

@click.group()
def cli():
    """Antarctica Today."""
    pass

@cli.command()
def preprocess():
    """Perform pre-processing steps for Antarctica Today data.

    This includes:
        - ...
        - ...
    """
    preprocessing_main()

@cli.command()
def process():
    """Perform processing steps for Antarctica Today data.

    This includes:
        - ...
        - ...
    """
    generate_all_plots_and_maps_main()

if __name__ == "__main__":
    cli()


#!/usr/bin/env python
import os
import time
import random
from threading import Lock
from flask import Flask, render_template, session
from flask_socketio import SocketIO, emit

async_mode = None

# This variable keeps a track of the number of events that has occur
event_counter = 0
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()

def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        socketio.sleep(10)
        count += 1

@app.route('/')
def index():
    return render_template('index.html', async_mode=socketio.async_mode)

@socketio.on('on_click')
def kill_server():
    global event_counter

    funny_statements = ['The Server Died',
                        'You Eliminated the server',
                        'What the HELL !! You killed the server']

    session['receive_count'] = session.get('receive_count', 0) + 1

    # Increment counter by 1 cause an event occurred
    event_counter += 1

    # Raise an event with a random choice of statement from the list
    emit('response', {'data': random.choice(funny_statements)})

    # The event takes sometime to be raised .. to avoid UNDEF behaviour this is
    # added
    time.sleep(1)

    # if a event is occurred and handle close the server
    if event_counter >= 1:
        os._exit(0)

@socketio.on('connect')
def connect():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(background_thread)

if __name__ == '__main__':
    socketio.run(app, debug=True)


class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
        n = len(graph)-1
        ans = []

        def dfs(node, arr):
            arr1 = arr.copy()
            arr1.append(node)

            if node == n: #basecase
                ans.append(arr1)
                return

            for neighbor in graph[node]:
                dfs(neighbor, arr1)

        dfs(0,[])
        return ans


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

from argparse import ArgumentParser

def parse():
    parser = ArgumentParser(
        description='Computing the greatest common divisor of 2 numbers.')
    parser.add_argument('first', type=int, nargs=1,
                        help='First argumet, must be an integer number.')
    parser.add_argument('second', type=int, nargs=1,
                        help='Second argumet, must be an integer number.')
    args = parser.parse_args()
    return args

def gcd(num1, num2):
    """Computing the greatest common divisor
    https://en.wikipedia.org/wiki/Greatest_common_divisor
    https://en.wikipedia.org/wiki/Euclidean_algorithm """
    while num2 > 0:
        num1, num2 = num2, num1 % num2
    return num1

def main():
    args = parse()
    number1 = args.first[0]
    number2 = args.second[0]
    gcd_number = gcd(number1, number2)
    print('GCD for {} & {} is {}.'.format(number1, number2, gcd_number))

if __name__ == '__main__':
    main()


import sys
import pygame

from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from time import sleep
from game_stats import GameStats
from button import Button
from scoreboard import Scoreboard

class AlienInvasion:
    # для управления поведением игры

    def __init__(self):
    #Создание игрового окна
        pygame.init()
        self.settings = Settings()

        # Оконный режим
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))

        # Полноэкранный режим
        # self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption('Kill Aliens')
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()
        self.create_fleet()

        #Создание кнопки 'Play'
        self.play_button = Button(self, "Play")

    def shit_hit(self):
        #Проверка "жизней"
        if self.stats.ship_left > 0:
            #Обработка столкновения корабль-пришелец
            self.stats.ship_left -= 1
            self.sb.prep_ship()
            #Очистка списков пришелцев и снарядов
            self.aliens.empty()
            self.bullets.empty()
            #Создание новго флота и пришелцев
            self.create_fleet()
            self.ship.center_ship()
            sleep(1)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def create_fleet(self):
        #Создание пришельца
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        # Доступное пространство(от ширины экрана отняли двух ширину двух пришельцев для отступов)
        available_space_x = self.settings.screen_width - (2 * alien_width)
        # Количество пришельцев - делим простарвно на удвоенного пришельца(между пришельцами пустое пространство равно
        # пришельцу)
        number_aliens_x = available_space_x // (2 * alien_width)

        #Количество рядов
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height)
        number_rows = available_space_y // (2 * alien_height)

        #Создание рядов пришельцев
        for row in range(number_rows):
            for alien_number in range(number_aliens_x):
                self.create_aliens(alien_number, row)

    def create_aliens(self, alien_number, row):
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row
        self.aliens.add(alien)

    def check_fleet_edges(self):
        #проверка достижения края экрана
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self.change_fleet_direction()
                break

    def change_fleet_direction(self):
        #Опускает флот вниз при достижения края жкрана
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= - 1

    def run(self):
    #Запуск оснвого цикла
        while True:
            self.check_events()

            if self.stats.game_active:
                self.ship.update()
                self.update_bullet()
                self.update_aliens()

            self.update_screen()

    def update_aliens(self):
        self.check_fleet_edges()
        self.aliens.update()

        #Проверка столкновения корабль-пришельцы
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self.shit_hit()

        #Проверка добралиьс ли пришельцы до нижнего края экрана
        self.check_aliens_bottom()

    def check_events(self):
        # обработка нажатия клавиш и мышки
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            # проверка нажатие клавиши и перемещение корабля
            elif event.type == pygame.KEYDOWN:
                self.check_keydown_enevts(event)
            # если отпустить <- или -> то корабль перестанет двигаться
            elif event.type == pygame.KEYUP:
                self.check_keyup_enevets(event)
            #Отслеживание мышки
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self.check_play_button(mouse_pos)

    def check_play_button(self, mouse_pos):
        #Запуск игры при нажатии на 'Play'
        button_click = self.play_button.rect.collidepoint(mouse_pos)
        if button_click and not self.stats.game_active:
            #Сброс игровых настроек
            self.settings.initialize_dynamic_settings()
            #Сброс предыдущей статистики
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ship()
            #Очитска списков пришелцев и пуль
            self.aliens.empty()
            self.bullets.empty()
            #Создание ногво флота и корабля
            self.create_fleet()
            self.ship.center_ship()
            #Скрывает указатель мыши
            pygame.mouse.set_visible(False)

    def check_keydown_enevts(self, event):
        # логоика нажатия клавиш
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self.fire_bullet()

    def check_keyup_enevets(self, event):
        # логика если отпустить клавишу
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def fire_bullet(self):
        #создание пули
        if len(self.bullets) < self.settings.bullet_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def update_bullet(self):
        #Обновление позиции пули
        self.bullets.update()

        # Удаление пуль при достижение верха экрана
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        self.check_bullet_alien_collissions()

    def check_bullet_alien_collissions(self):
        # Проверка попадания(при попадании удалить снаряд и пришельца)
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self .settings.alien_points * len(aliens)
            self.stats.score += self.settings.alien_points
            self.sb.prep_score()
            self.sb.check_high_score()

        #Создание нового флота при уничтожении старого
        if not self.aliens:
            self.bullets.empty()
            self.create_fleet()
            self.settings.increase_speed()

            #Увеличение уровня сложности
            self.stats.level += 1
            self.sb.prep_level()

    def check_aliens_bottom(self):
        #Проверка на достижения пришельцем нижнего края экрана
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                #то же что и кораблем(задержка, потом появляеться новый флот и корабль становиться на середину)
                self.shit_hit()
                break

    def update_screen(self):
        # Обновляет изображения на экране
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)
        self.sb.show_score()
        #Отоброжение кнопки 'Play' только в том случае, если игра не активна
        if not self.stats.game_active:
            self.play_button.draw_button()

        pygame.display.flip()

if __name__ == '__main__':
    ai = AlienInvasion()
    ai.run()


from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
    path('',views.index, name="index"),
    path('sec/',views.sec, name="sec"),
    path('login/',views.signin, name="login"),
    path('register/',views.register, name="register"),
    path('logout/',views.Logout,name="Logout"),
]


'''
You are given an array of strings names, and an array heights that consists of distinct positive integers. Both arrays are of length n.

For each index i, names[i] and heights[i] denote the name and height of the ith person.

Return names sorted in descending order by the people's heights.

Example 1:

Input: names = ["Mary","John","Emma"], heights = [180,165,170]
Output: ["Mary","Emma","John"]
Explanation: Mary is the tallest, followed by Emma and John.
Example 2:

Input: names = ["Alice","Bob","Bob"], heights = [155,185,150]
Output: ["Bob","Alice","Bob"]
Explanation: The first Bob is the tallest, followed by Alice and the second Bob.

Constraints:

n == names.length == heights.length
1 <= n <= 103
1 <= names[i].length <= 20
1 <= heights[i] <= 105
names[i] consists of lower and upper case English letters.
All the values of heights are distinct.
'''
import unittest

from typing import *

class Solution:
    def sortPeople(self, names: List[str], heights: List[int]) -> List[str]:
        return [n for _, n in sorted(list(zip(heights, names)), reverse=True)]

class TestSolution(unittest.TestCase):

    def test_case(self):
        examples = (
            ((["Mary","John","Emma"],[180,165,170]),["Mary","Emma","John"]),
        )
        for first, second in examples:
            self.assert_function(first, second)

    def assert_function(self, first, second):
        self.assertEqual(Solution().sortPeople(*first), second,
                         msg="first: {}; second: {}".format(first, second))

unittest.main()


# -*- coding: utf-8 -*-
# @File    : StickersToSpellWord.py
# @Date    : 2020-10-09
# @Author  : tc
"""
题号 691. 贴纸拼词
我们给出了 N 种不同类型的贴纸。每个贴纸上都有一个小写的英文单词。
你希望从自己的贴纸集合中裁剪单个字母并重新排列它们，从而拼写出给定的目标字符串 target。
如果你愿意的话，你可以不止一次地使用每一张贴纸，而且每一张贴纸的数量都是无限的。
拼出目标 target 所需的最小贴纸数量是多少？如果任务不可能，则返回 -1。

示例 1：

输入：

["with", "example", "science"], "thehat"
输出：

3
解释：

我们可以使用 2 个 "with" 贴纸，和 1 个 "example" 贴纸。
把贴纸上的字母剪下来并重新排列后，就可以形成目标 “thehat“ 了。
此外，这是形成目标字符串所需的最小贴纸数量。
示例 2：
输入：
["notice", "possible"], "basicbasic"

输出：
-1
解释：

我们不能通过剪切给定贴纸的字母来形成目标“basicbasic”。

提示：
解法1
stickers 长度范围是 [1, 50]。
stickers 由小写英文单词组成（不带撇号）。
target 的长度在 [1, 15] 范围内，由小写字母组成。
在所有的测试案例中，所有的单词都是从 1000 个最常见的美国英语单词中随机选取的，目标是两个随机单词的串联。
时间限制可能比平时更具挑战性。预计 50 个贴纸的测试案例平均可在35ms内解决。

参考：https://leetcode.com/problems/stickers-to-spell-word/discuss/108318/C%2B%2BJavaPython-DP-%2B-Memoization-with-optimization-29-ms-(C%2B%2B)

解法2
状态压缩DP
设置状态数组dp[i],dp的大小是 N = 2^n, 其中n是target的大小。怎么理解？
将dp的索引i进行二进制拆解，i的每一个bit表示的是target对应位置的字符是否得到了满足。
比如n=3时，dp数组的大小N=8，对应的状态有 000,001,010,011,100,101,110,111.
举个例子，i=3 (即011)表示target的末两位的字符得到了满足，但第一位的字符还没有得到满足。
dp[i]表示在状态i下，需要的sticker的最少数目。

参考：https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/691.Stickers-to-Spell-Word
"""
from typing import List
import sys

class Solution:
    def minStickers(self, stickers: List[str], target: str) -> int:
        m = len(stickers)
        mp = [[0] * 26 for y in range(m)]
        for i in range(m):
            for c in stickers[i]:
                mp[i][ord(c) - ord('a')] += 1
        dp = {}
        dp[""] = 0

        def helper(dp, mp, target):
            if target in dp:
                return dp[target]
            n = len(mp)
            tar = [0] * 26
            for c in target:
                tar[ord(c) - ord('a')] += 1
            ans = sys.maxsize
            for i in range(n):
                if mp[i][ord(target[0]) - ord('a')] == 0:
                    continue
                s = ''
                for j in range(26):
                    if tar[j] > mp[i][j]:
                        s += chr(ord('a') + j) * (tar[j] - mp[i][j])
                tmp = helper(dp, mp, s)
                if (tmp != -1):
                    ans = min(ans, 1 + tmp)
            dp[target] = -1 if ans == sys.maxsize else ans
            return dp[target]

        return helper(dp, mp, target)

    def minStickers(self, stickers: List[str], target: str) -> int:
        n = len(target)
        dp = [float("inf")] * (1 << n)
        dp[0] = 0

        for state in range(1 << n):
            if dp[state] == float("inf"):
                continue
            for sticker in stickers:
                new_state = self.findNextStatusByUsingStr(state, target, sticker)
                dp[new_state] = min(dp[new_state], dp[state] + 1)
        return -1 if dp[(1 << n) - 1] == float("inf") else dp[(1 << n) - 1]

    def findNextStatusByUsingStr(self, status, target, sticker):
        n = len(target)
        for ch in sticker:
            for k in range(n):
                if ((status >> k) & 1) == 0 and target[k] == ch:
                    status = status + (1 << k)
                    break
        return status

if __name__ == '__main__':
    pass


# -*- coding: utf-8 -*-

"""
Created on 06/04/2015

@author: david
"""
import logging
from os import system
from os.path import exists

from flight.driving.sysfs_writer import SysfsWriter

class Motor(object):
    """
    Controls a single motor
    """

    KEY_PWM_ID = "pwmId"
    KEY_PIN_ID = "pinId"

    #BeagleBone's config.
    #TODO 20150408 DPM - Include this configuration in such a settings file
    _pins = [{KEY_PWM_ID: 6, KEY_PIN_ID: "P8.13"},
             {KEY_PWM_ID: 5, KEY_PIN_ID: "P8.19"},
             {KEY_PWM_ID: 4, KEY_PIN_ID: "P9.16"},
             {KEY_PWM_ID: 3, KEY_PIN_ID: "P9.14"}]

    PERIOD = 20000000 #nanoseconds = 50Hz

    MIN_DUTY = 1000000 #nanoseconds
    MAX_DUTY = 2000000 #nanoseconds

    RANGE_DUTY = (MAX_DUTY - MIN_DUTY) / 100.0

    MAX_THROTTLE = 80.0 #percentage

    def __init__(self, motorId):
        """
        Constructor

        @param motorId: Identificator of the motor. A number between 0 to 3 (in case of quadcopter)
        """

        pinIndex = motorId
        self._pwmId = Motor._pins[pinIndex][Motor.KEY_PWM_ID]
        self._pinId = Motor._pins[pinIndex][Motor.KEY_PIN_ID]

        self._motorId = motorId

        self._throttle = 0.0
        self._duty = 0

    def start(self):
        """
        Starts the motor up
        """

        if not exists("/sys/class/pwm/pwm{0}".format(self._pwmId)):
            system("config-pin {0} pwm".format(self._pinId))
            #SysfsWriter.writeOnce("pwm", "/sys/devices/ocp.*/{0}_pinmux.*/state".format(self._pinId))
            SysfsWriter.writeOnce(str(self._pwmId), "/sys/class/pwm/export")

        SysfsWriter.writeOnce("0", "/sys/class/pwm/pwm{0}/duty_ns".format(self._pwmId))
        SysfsWriter.writeOnce("0", "/sys/class/pwm/pwm{0}/run".format(self._pwmId))
        SysfsWriter.writeOnce(str(Motor.PERIOD), "/sys/class/pwm/pwm{0}/period_ns".format(self._pwmId))
        SysfsWriter.writeOnce("1", "/sys/class/pwm/pwm{0}/run".format(self._pwmId))

        self._sysfsWriter = SysfsWriter("/sys/class/pwm/pwm{0}/duty_ns".format(self._pwmId))

        logging.info("motor {0}: started".format(self._motorId))

    def setThrottle(self, throttle):
        """
        Sets the motor's throttle

        @param throttle: Motor power as percentage
        """

        self._throttle = float(throttle)

        if self._throttle >= 0.0 and self._throttle <= Motor.MAX_THROTTLE:

            self._duty = int((Motor.RANGE_DUTY * self._throttle) + Motor.MIN_DUTY)
            #logging.debug("motor {0}: duty={1}; throttle={2}".format(self._motorId, self._duty, self._throttle))

            self._sysfsWriter.write(str(self._duty))

        #else:
        #    logging.debug("motor {0}: duty={1}; throttle={2} (virtual)".format(self._motorId, self._duty, self._throttle))

    def getThrottle(self):

        return self._throttle

    def addThrottle(self, increment):
        """
        Increases or decreases the motor's throttle

        @param increment: Value added to the current throttle percentage. This can be negative to decrease.
        """

        self.setThrottle(self._throttle + increment)

    def setMaxThrottle(self):
        """
        Sends the max throttle signal (useful for calibrating process)
        """

        #logging.debug("motor {0}: max-throttle".format(self._motorId))

        self._throttle = 100.0
        self._duty = Motor.MAX_DUTY

        self._sysfsWriter.write(str(Motor.MAX_DUTY))

    def setMinThrottle(self):
        """
        Sends the min throttle signal (useful for calibrating process, or setting the motor in stand-by state)
        """

        #logging.debug("motor {0}: min-throttle".format(self._motorId))

        self._throttle = 0.0
        self._duty = Motor.MIN_DUTY

        self._sysfsWriter.write(str(Motor.MIN_DUTY))

    def standBy(self):
        """
        Set the motor in stand-by state
        """

        logging.info("motor {0}: stand-by".format(self._motorId))
        self.setMinThrottle()

    def idle(self):
        """
        Set the motor in idle state
        """

        logging.info("motor {0}: idle".format(self._motorId))

        self._throttle = 0.0
        self._duty = 0

        self._sysfsWriter.write("0")

    def stop(self):
        """
        Stops the motor
        """

        logging.info("motor {0}: stop".format(self._motorId))

        self._throttle = 0.0
        self._duty = 0

        self._sysfsWriter.close()
        SysfsWriter.writeOnce("0", "/sys/class/pwm/pwm{0}/run".format(self._pwmId))


import logging
from typing import Tuple, NewType

import requests
from requests.exceptions import HTTPError, ConnectionError, Timeout, RequestException

from constants import VERSION as CURRENT_VERSION

logger = logging.getLogger(__name__)

Version = NewType("Version", Tuple[int, ...])

def get_latest_ver(
    url: str = "https://api.github.com/repos/dylarm/TeamsAtlasBridge/releases/latest"
) -> Tuple[Version, str]:
    latest_version: Version = Version(
        (0, 0, 0)
    )  # Will always cause version check to be false if not updated
    latest_url: str = ""
    try:
        response = requests.get(url)
        response.raise_for_status()  # For any HTTP Errors
        latest_version = Version(
            tuple(int(x) for x in response.json()["tag_name"].lstrip("v").split("."))
        )
        latest_url = response.json()["html_url"]
    except HTTPError as e:
        logger.warning(f"A HTTP Status error occurred while checking for updates:\n{e}")
    except (ConnectionError, Timeout) as e:
        logger.warning(f"A Connection error occurred while checking for updates:\n{e}")
    except RequestException as e:
        logger.warning(
            f"A potentially serious error occurred while checking for updates:\n{e}"
        )
    return latest_version, latest_url

def update_available(
    current_ver: str = CURRENT_VERSION, latest_ver: Version = get_latest_ver()[0]
) -> bool:
    current_ver_tuple = tuple(int(x) for x in current_ver.lstrip("v").split("."))
    return latest_ver > current_ver_tuple


# INSERE DADOS DAS IMAGENS DE CADA SKU

# ======================================
exit(0)
# ======================================

from libs import *

mydb = mysql_connect('database_v')

table_skus = 'skus'
table_skus_imgs = 'skus_imgs'

sql = ' select * ' \
      ' from ' + table_skus + \
      ' order by id_sku;'
mycursor = mydb.cursor()
mycursor.execute(sql)
skus = mycursor.fetchall()

skus_num = len(skus)
skus_digits = len(str(skus_num))

count_skus_imgs = 0

print()
for sku in skus:

    for i in range(0, 6):

        id_img = str(count_skus_imgs + 1).rjust(9, '0')
        id_sku = str(sku[0]).rjust(9, '0')
        id_num = str(i + 1).rjust(2, '0')
        url = str.replace(sku[17+i], '"', "")
        ext = url.split(".")[-1]
        filename = id_img + '_' + id_sku + '_' + id_num + '.' + ext

        sql = ' insert into ' + table_skus_imgs + \
              ' (id_sku, id_num, url, name) ' \
              ' values (%s, %s, %s, %s);'

        values = (id_sku, id_num, '%s' % url, '%s' % filename)
        mycursor = mydb.cursor()
        mycursor.execute(sql, values)

        count_skus_imgs += 1

    if (sku[0] % 5000 == 0) or (sku[0] == skus_num):

        mydb.commit()

        print('[' + str(sku[0]).rjust(skus_digits, '0') + '/' + str(len(skus)) + '] - Insertion OK')

mydb.close()

print('\nfinished')


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

class SVM():
    '''
    SVM的简单实现，使用线性核
    '''
    def __init__(self):
        self.w = None
        self.b = None
        self.alpha = None

    def get_w(self,alpha,x,y):
        n = x.shape[-1]
        temp = np.multiply(alpha,y) # shape = (m,1)
        result = np.multiply(temp,x).sum(axis=0).reshape(n,1)
        return result

    def get_g(self,w,x,b):
        m = x.shape[0]
        g = x@w + b
        g = g.reshape(m,1)
        return g

    def k(self,x1,x2):
        result = x1.T @ x2
        return result

    def get_loss(self,w,alpha):
        temp1 = w.T @ w     # 注意：temp1.shape = (1,1)
        temp1 = temp1[0,0] / 2
        temp2 = alpha.sum()
        result = temp1 - temp2
        return result

    def fit(self,x:'shape=(m,n)',y:'shape=(m,1)',C:">0",epsilon:'小正数 训练精度',max_iters:'最大迭代次数'):
        '''
        x.shape = (m,n)
        y.shape = (m,1)
        C 实数  对软间隔的惩罚系数  C越大、对误分类的容忍程度越小、超平面和分隔平面之间越“紧凑”、支持向量越少
        epsilon 实数 训练精度
        max_iters 最大迭代次数，避免因C值过大或epsilon过小而陷入死循环
        '''
        m,n = x.shape
        # 初始化拉格朗日算子 alpha
        alpha_new = np.zeros_like(y)
        alpha_new = alpha_new.astype(np.float64)
        # 因为这里alpha初始化为0向量，所以w也为0向量，损失函数也是0，省去一步运算
        w_new = np.zeros((n,1)).astype(np.float64)
        loss_new = 0
        b_new = 0
        # -----开始SMO算法-----
        # 根据KKT条件得出以下关于最优解的停机条件：
        #   当 alpha = 0 时，    y(w.T@x+b) > 1
        #   当 0 < alpha < C 时，y(w.T@x+b) = 1
        #   当 alpha > C 时，    y(w.T@x+b) < 1
        # 当然，上述条件只需要在精度 epsilon 范围内满足就可以
        iters = 0
        while 1:
            alpha = alpha_new
            w = w_new
            b = b_new
            loss = loss_new
            support_samples_violate_KKT = {} # 存储违反KKT条件的支持向量样本 key=样本索引 value=违反KKT的程度
            common_samples_violate_KKT = {}
            g = self.get_g(w,x,b) # w.T@x+b
            values_compare_with_1 = np.multiply(y,g) # y(w.T@x+b)
            # --寻找违反KKT条件的样本并按支持向量和普通样本分开存储--
            for i in range(m):
                a = alpha[i,0]
                v = values_compare_with_1[i,0]
                if a == 0:
                    if v < 1-epsilon:
                        common_samples_violate_KKT[i] = 1-epsilon-v
                elif a > 0 and a < C:
                    if v < 1-epsilon or v > 1+epsilon:
                        support_samples_violate_KKT[i] = max(v-1-epsilon,1-epsilon-v)
                elif a == C:
                    if v > 1+epsilon:
                        support_samples_violate_KKT[i] = v-1-epsilon
            # 字典按值降序排列
            support_samples_violate_KKT = {i[0]:i[1] for i in sorted(support_samples_violate_KKT.items(),key=lambda x:x[1],reverse=True)}
            common_samples_violate_KKT = {i[0]:i[1] for i in sorted(common_samples_violate_KKT.items(),key=lambda x:x[1],reverse=True)}
            # 字典合并：支持向量在前，普通样本在后；违反KKT严重的在前，不严重的在后
            all_samples_violate_KKT = support_samples_violate_KKT.copy()
            all_samples_violate_KKT.update(common_samples_violate_KKT)
            error = g-y # 误差
            print('The amount of samples violate KKT: %s' % str(len(all_samples_violate_KKT)))
            if not all_samples_violate_KKT:
                # 达到停机条件
                self.w = w
                self.b = b
                self.alpha = alpha
                print('所有样本均在精度 %s 下满足KKT条件' % str(epsilon))
                print('迭代次数：%s' % str(iters))
                return
            if iters == max_iters:
                self.w = w
                self.b = b
                self.alpha = alpha
                print('程序达到最大迭代次数而退出')
                return
            for s_1 in all_samples_violate_KKT.keys():
                # 用 s_1 表示选取的第一个样本
                print('Try_Sample_One: %s' % str(s_1))
                alpha_1 = alpha[s_1,0]
                e_1 = error[s_1,0]
                x1 = x[s_1]
                y1 = y[s_1,0]
                abs_all_sub_e1 = np.abs(error-e_1)
                # 将所有样本按 |e_1 - e_2| 降序排序
                abs_all_sub_e1 = [i[0] for i in sorted(enumerate(abs_all_sub_e1[:,0]),key=lambda x:x[1],reverse=True)]
                abs_all_sub_e1.remove(s_1)
                min_loss = loss
                found_sample_2 = -1
                for s_2 in abs_all_sub_e1:
                    if (x[s_2]==x[s_1]).all():
                        continue
                    print('For_Sample_One: %s -- Try_Sample_Two: %s' % (str(s_1),str(s_2)))
                    e_2 = error[s_2,0]
                    alpha_2 = alpha[s_2,0]
                    x2 = x[s_2]
                    y2 = y[s_2,0]
                    alpha_1_new_unc = alpha_1 - y1*(e_1-e_2)/(self.k(x1,x1)+self.k(x2,x2)-2*self.k(x1,x2))
                    low = min(alpha_1+alpha_2*y1*y2, alpha_1+alpha_2*y1*y2-C*y1*y2)
                    high = max(alpha_1+alpha_2*y1*y2, alpha_1+alpha_2*y1*y2-C*y1*y2)
                    L = max(0,low)
                    H = min(C,high)
                    # 裁剪alpha1
                    alpha_1_new = np.clip(alpha_1_new_unc,L,H)
                    alpha_2_new = (alpha_1-alpha_1_new)*y1*y2 + alpha_2
                    w_temp = w + y1*x1.reshape(n,1)*(alpha_1_new-alpha_1) + y2*x2.reshape(n,1)*(alpha_2_new-alpha_2)
                    alpha_temp = alpha.copy()
                    alpha_temp[s_1,0] = alpha_1_new
                    alpha_temp[s_2,0] = alpha_2_new
                    loss_temp = self.get_loss(w_temp,alpha_temp)
                    if loss_temp < min_loss:
                        found_sample_2 = s_2
                        min_loss = loss_temp
                        loss_new = loss_temp
                        w_new = w_temp
                        alpha_new = alpha_temp
                        b1 = y1 - x1.reshape(1,n)@w_new
                        b2 = y2 - x2.reshape(1,n)@w_new
                        b1 = b1[0,0]
                        b2 = b2[0,0]
                        if alpha_1_new > 0 and alpha_1_new < C:
                            b_new = b1
                        elif alpha_2_new > 0 and alpha_2_new < C:
                            b_new = b2
                        else:
                            b_new = (b1+b2) / 2
                if found_sample_2 != -1:
                    # 说明找到了恰当的alpha2，跳出循环，进行下一次迭代
                    print('Found_Sample_One: %s -- Found_Sample_Two: %s' % (str(s_1),str(found_sample_2)))
                    print('alpha_%s: %s --> %s' % (str(s_1),str(alpha_1),str(alpha_new[s_1,0])))
                    print('alpha_%s: %s --> %s' % (str(found_sample_2),str(alpha[s_2,0]),str(alpha_new[s_2,0])))
                    break
                else:
                    # 说明没有找到恰当的alpha2，更换alpha1后重试
                    continue
            if found_sample_2 == -1:
                # 说明遍历所有样本都没有使目标函数下降
                # 接下来会进入死循环，应退出
                self.w = w
                self.b = b
                self.alpha = alpha
                print('程序在陷入死循环前退出，考虑降低C值或提高epsilon值')
                print('迭代次数：%s' % str(iters))
                return
            iters += 1

    def predict(self,x):
        x = np.array(x)
        m = x.shape[0]
        y = x@self.w + self.b
        y = np.array([1 if i>=0 else -1 for i in y]).reshape(m,1)
        return y

if __name__ == '__main__':
    data = pd.read_csv("iris.data",header=None,names=['x1','x2','x3','x4','y'])
    data = data[data.y != 'Iris-setosa']
    m = data.shape[0]
    y = data.values[:,-1]
    y = np.array([1 if i=='Iris-versicolor' else -1 for i in y]).reshape(m,1)
    # 选两个特征测试
    f1 = 'x1'
    f2 = 'x3'
    x = data.loc[:,[f1,f2]].values
    model = SVM()
    model.fit(x, y, C=1, epsilon=0.001, max_iters=1000)
    g = model.predict(x)
    print('accuracy:%.2f%%' % ((g==y).sum()*100/m))
    w = model.w
    b = model.b
    y0 = -(w[0,0]/w[1,0])*data[f1]-b/w[1,0]
    y1 = -(w[0,0]/w[1,0])*data[f1]-(b-1)/w[1,0]
    y_1 = -(w[0,0]/w[1,0])*data[f1]-(b+1)/w[1,0]
    plt.scatter(data[data['y']=='Iris-versicolor'][f1],data[data['y']=='Iris-versicolor'][f2],c='red')
    plt.scatter(data[data['y']=='Iris-virginica'][f1],data[data['y']=='Iris-virginica'][f2],c='green')
    plt.plot(data[f1],y0,c='blue')
    plt.plot(data[f1],y1,c='red')
    plt.plot(data[f1],y_1,c='green')
    plt.xlabel(f1)
    plt.ylabel(f2)
    plt.show()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# (c) University of St Andrews 2022
# (c) University of Strathclyde 2022
# (c) James Hutton Institute 2022
#
# Author:
# Emma E. M. Hobbs
#
# Contact
# eemh1@st-andrews.ac.uk
#
# Emma E. M. Hobbs,
# Biomolecular Sciences Building,
# University of St Andrews,
# North Haugh Campus,
# St Andrews,
# KY16 9ST
# Scotland,
# UK
#
# The MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Get the protein sequencse of all CE19 proteins associated with at least one RCSB PDB IDs in
the local CAZyme database"""

from pdb import Pdb
import pandas as pd

from argparse import Namespace
from datetime import datetime
from pathlib import Path

from Bio import SeqIO
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from sqlalchemy import select
from sqlalchemy.orm import aliased
from tqdm import tqdm

from cazy_webscraper import connect_existing_db
from cazy_webscraper.sql.sql_orm import (
    Pdb,
    Genbank,
    CazyFamily,
    Session,
)

FAM = "CE19"
SEQ_PATH = Path("data/ce19_prot_seqs.fasta")
DB_PATH = Path("database/cazy_db")

def main():
    time_stamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")  # used in naming files
    start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")  # used in terminating message
    start_time = pd.to_datetime(start_time)

    argsdict = {
        "args": Namespace(
            database=DB_PATH,
            sql_echo=False,
            verbose=False,
        )
    }

    db_connection, logger_name, cache_dir = connect_existing_db(
        argsdict["args"],
        time_stamp,
        start_time,
    )

    # Get the GBK accessions for proteins in the family of interest
    inner_stmt = select(CazyFamily.family).where(CazyFamily.family == FAM)
    subq = inner_stmt.subquery()
    aliased_families = aliased(CazyFamily, subq)
    stmt = select(aliased_families)

    with Session(bind=db_connection) as session:
        gbk_query = session.query(Genbank, Pdb).\
            join(Pdb, Genbank.pdbs).\
            filter(CazyFamily.family.in_(stmt)).\
            all()

    protein_seqs = []
    for record in gbk_query:
        if record[1].pdb_accession is not None and record[0].sequence is not None:
            protein_seqs.append(
                SeqRecord(id=record[0].genbank_accession, seq=Seq(record[0].sequence))
            )

    with open(SEQ_PATH, "w") as output_handle:
        SeqIO.write(protein_seqs, output_handle, "fasta")

if __name__ == "__main__":
    main()


import numpy as np
from functools import partial

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchmetrics
import pytorch_lightning as pl
from transformers import logging, Blip2VisionModel, BlipImageProcessor

from base_cbm import LitBaseCBM
from utils import get_named_module, log_level

class BLIP2Classifier(nn.Module):
    def __init__(self, latent_dim, num_classes, freeze_proj=True, concept_act='sigmoid'):
        super().__init__()
        self.latent_dim = latent_dim
        self.num_classes = num_classes

        with log_level(logging.ERROR):
            self.vision_projector = Blip2VisionModel.from_pretrained("Salesforce/blip2-opt-2.7b")
            if freeze_proj:
                for param in self.vision_projector.parameters():
                    param.requires_grad = False

        self.linear = nn.Linear(self.vision_projector.config.hidden_size,
                                self.latent_dim)
        if concept_act == 'sigmoid':
            self.act = nn.Sigmoid()
        elif concept_act == 'relu':
            self.act = nn.ReLU()
        elif (concept_act == 'None') or (concept_act is None):
            self.act = nn.Identity()
        else:
            raise NotImplementedError

        self.classification = nn.Linear(self.latent_dim, self.num_classes)

    def load_weight(self, module_name, weight_npy_path):
        module = get_named_module(self, module_name)
        weight = np.load(weight_npy_path)
        weight_pt = torch.from_numpy(weight).to(next(module.parameters()).device)
        with torch.no_grad():
            assert module.weight.shape == weight_pt.shape
            module.weight = nn.Parameter(weight_pt)
        print(f"Loaded {module_name} weights from {weight_npy_path}.")

    def forward(self, x, return_concept=False):
        # expect x is the output of BlipImageProcessor
        x = self.vision_projector(**x) # {'last_hidden_state': [B, ViT_N_TOKENS, HIDDEN_SIZE]', 'pooler_output': [B, PROJECTION_DIM]}
        c = self.linear(x['pooler_output']) # weight: PROJECTION_DIM * d -> d concept
        x = self.act(c)
        x = self.classification(x) # weight d * c -> c class

        if return_concept:
            return c, x
        else:
            return x

class LitBlip2CBM(LitBaseCBM):
    @staticmethod
    def add_model_specific_args(parent_parser):
        parent_parser = LitBaseCBM.add_model_specific_args(parent_parser)

        parser = parent_parser.add_argument_group("LitBlip2CBM")
        parser.add_argument("--load_linear_path", type=str, default=None)
        parser.add_argument("--freeze_linear", action="store_true")
        parser.add_argument("--load_classification_path", type=str, default=None)
        parser.add_argument("--freeze_classification", action="store_true")

        return parent_parser

    @staticmethod
    def load_checkpoint_as_model(ckpt_path, strict=False):
        self = LitBlip2CBM.load_from_checkpoint(ckpt_path, strict=strict)
        return self.model

    @staticmethod
    def get_processor():
        return BlipImageProcessor.from_pretrained("Salesforce/blip2-opt-2.7b")

    def initialize_model(self):
        self.model = BLIP2Classifier(latent_dim=self.hparams.latent_dim,
                                     num_classes=self.hparams.num_classes,
                                     concept_act=self.hparams.concept_act)

        if hasattr(self.hparams, "load_linear_path") and \
                (self.hparams.load_linear_path is not None):
            self.model.load_weight('linear', self.hparams.load_linear_path)
        if hasattr(self.hparams, "freeze_linear") and \
                self.hparams.freeze_linear:
            self.model.linear.weight.requires_grad = False
        if hasattr(self.hparams, "load_classification_path") and \
                self.hparams.load_classification_path is not None:
            self.model.load_weight('classification', self.hparams.load_classification_path)
        if hasattr(self.hparams, "freeze_classification") and \
                self.hparams.freeze_classification:
            self.model.classification.weight.requires_grad = False

        return self.model


from task import Task
import random
import discord
import asyncio
from stringtools import *

class Happyness(Task):

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

		self.aliases = ["happy", "sad"]

	############################
	# use this task function
	async def start(self, msg, cli):

		# if this isn't for this task give up
		if (self.isAlias(msg.content) == False):
			#print(msg.content + " Not in " + str(self.aliases))
			return

		print("Running Happyness!")

		jokes = ["your a good person", "everythings fine", "your not a loser", "believe in yourself", "think happy thoughts"]

		await cli.sendMessage(random.choice(jokes))

		while True:

			more = (await cli.getResponse("Would you like another happy quote?")).content

			# if user wants another joke
			if (findWordString(more, "more") != -1 or findWordString(more, "another") != -1 or findWordString(more, "yes") != -1):

				await cli.sendMessage(random.choice(jokes))

			# if user wants no more jokes
			else:
				await cli.sendMessage("Sorry to see you go")
				break


import requests
import string
import pandas as pd

url = 'http://www.ncbc.nic.in/SearchService.asmx/GetCompanyInfo'
obc_caste_list = []

def obc_caste(search_name):
    data = {"prefixText": search_name, "count": 10, "contextKey": "WORKS_CAST,CastEnglish,CastEnglish"}
    res = requests.post(url, json=data)
    for val in res.json().values():
        if len(val):
            print(val)
            obc_caste_list.append(val)

if __name__ == '__main__':
    # for search_name in range(0, 10):
    #     obc_caste(search_name)
    obc_caste('C')
    for search_name in string.ascii_uppercase:
        obc_caste(search_name)

    obc_caste('C')
    df = pd.DataFrame(obc_caste_list)
    df.to_csv('caste.csv', encoding='utf-8')


import numpy as np
import json
import pandas as pd
import torch
import torchtext
import collections

vectors=torchtext.vocab.Vectors(name='./glove/glove.42B.300d.txt')
counter=collections.Counter(vectors.itos)
vocab=torchtext.vocab.Vocab(counter,vectors=vectors)
vectors=vocab.vectors

def split_words(x):
    for dots in [',','.','!',')',';',':']:
        x=x.replace(dots,'')
    x=x.lower()
    x=x.split(' ')
    return x

def get_embedding(x):
    vec=torch.tensor([0.0 for i in range(300)])
    if len(x)==0:
        return vec
    for i in range(len(x)):
        vec+=vectors[vocab.stoi[x[i]]]
    vec=vec/len(x)
    return vec

src=[]
dst=[]
ts=[]
src_label=[]
src_label_name=[]
dst_label=[]
dst_label_name=[]

label={}
id_label={}
label_first_time={}
label_data_num=[0 for i in range(10000)]
label_data_set=[set() for i in range(10000)]
selected_label=set([])
selected_new_label_month={}
selected_new_label_month_name={}
new_label_month={}
new_label_month_set={}
new_label_month_edge={}
post={}
post_label_name={}
post_vectors={}
post_comments_num={}
author={}
author_post_last_time={}
num_post=0
num_label=0

limit_cnt={}

year='2009'
st_mon=7
n_month=12
per_class=3
mx_time=2592000/31*7

ob=open('ob'+year+".txt",'w')

for mon in range(st_mon,n_month+1):
    new_label_month[mon]={}
    new_label_month_set[mon]={}
    selected_new_label_month[mon]=set([])
    selected_new_label_month_name[mon]=set([])
    if mon <10:
        month="0"+str(mon)
    else:
        month=str(mon)
    with open("./reddit/2009/RC_2009-"+month,'r') as f:
        line=f.readline()
        while line:
            comment=json.loads(line)
            t=comment['created_utc']
            t=int(t)-1230768002
            sr=comment['subreddit']
            a=comment['author']
            p=comment['link_id']

            if a!='[deleted]':
                if sr not in label:
                    num_label+=1
                    label[sr]=num_label
                    id_label[num_label]=sr
                    label_first_time[num_label]=t
                label_data_set[label[sr]].add(p)
                label_data_num[label[sr]]=len(label_data_set[label[sr]])

                if sr not in new_label_month[mon]:
                    new_label_month_set[mon][sr]=set()
                    new_label_month[mon][sr]=0
                new_label_month_set[mon][sr].add(p)
                new_label_month[mon][sr]=len(new_label_month_set[mon][sr])

            line=f.readline()

        new_label_month[mon]=sorted(new_label_month[mon].items(), key=lambda x: x[1], reverse=True)

        for x in new_label_month[mon][20:100]:
            if x[0] == 'Marijuana' or x[0] == 'nsfw':
                continue
            flag=0
            for k,v in selected_new_label_month_name.items():
                if x[0] in v:
                    flag=1
                    break
            if flag==0:
                selected_new_label_month[mon].add(x)
                selected_new_label_month_name[mon].add(x[0])
            if len(selected_new_label_month[mon])>=per_class:
                print(selected_new_label_month[mon])
                break

print("number of classes:",len(label))
print("node per class(all):",sorted(label_data_num,reverse=True))

for mon in range(st_mon, n_month+1):
    new_label_month_edge[mon]={}
    heter=0
    if mon <10:
        month="0"+str(mon)
    else:
        month=str(mon)
    with open("./reddit/2009/RC_2009-"+month,'r') as f:
        line=f.readline()
        while line:
            comment=json.loads(line)
            t=comment['created_utc']
            t=int(t)-1230768002
            sr=comment['subreddit']
            a=comment['author']
            p=comment['link_id']

            if a!='[deleted]':

                if sr not in selected_new_label_month_name[mon]:
                    line=f.readline()
                    continue

                body=split_words(comment['body'])
                vec=get_embedding(body)

                if p not in post:
                    num_post+=1
                    post[p]=num_post
                    post_label_name[num_post]=sr
                    post_comments_num[num_post]=0
                    post_vectors[num_post]=torch.tensor([0.0 for i in range(300)])

                post_comments_num[num_post]+=1
                post_vectors[num_post]+=vec

                if a not in author:
                    author[a]=set([])
                    author_post_last_time[a]=({})
                author[a].add(p)
                author_post_last_time[a][post[p]]=t

                for k in author[a].copy():
                    s=post[p]
                    d=post[k]
                    if t- author_post_last_time[a][d]>mx_time:
                        author[a].remove(k)
                        continue
                    if s==d:
                        continue

                    ls=label[post_label_name[s]]
                    ld=label[post_label_name[d]]

                    if ls not in limit_cnt:
                        limit_cnt[ls]=1
                    if ld not in limit_cnt:
                        limit_cnt[ld]=1
                    limit_cnt[ls]+=1
                    limit_cnt[ld]+=1

                    mx = 10000
                    if (limit_cnt[ls] > mx or limit_cnt[ld] > mx) and ls==ld:
                        continue

                    # if ls!=ld:
                    #     continue

                    if ls!=ld:
                        heter+=1

                    if post_label_name[s] not in new_label_month_edge[mon]:
                        new_label_month_edge[mon][post_label_name[s]]=0
                    if post_label_name[d] not in new_label_month_edge[mon]:
                        new_label_month_edge[mon][post_label_name[d]]=0

                    new_label_month_edge[mon][post_label_name[s]]+=1
                    new_label_month_edge[mon][post_label_name[d]]+=1

                    src.append(s)
                    dst.append(d)
                    ts.append(t)
                    src_label.append(label[post_label_name[s]])
                    src_label_name.append(post_label_name[s])
                    dst_label.append(label[post_label_name[d]])
                    dst_label_name.append(post_label_name[d])

            line=f.readline()

        new_label_month_edge[mon]=sorted(new_label_month_edge[mon].items(), key=lambda x: x[1], reverse=True)
        print(new_label_month_edge[mon])
        print('heter edge:', heter)

idx=list(range(len(src)))
df=pd.DataFrame({"u":src,"i":dst,"label_u":src_label,"label_name_u":src_label_name,"label_i":dst_label,"label_name_i":dst_label_name,"ts":ts,"idx":idx})
df.to_csv("./reddit/2009_processed/reddit_2009_half.csv",index=False)

sd=set(src+dst)
sd=sorted(list(sd))
mem=[]
mem.append(torch.tensor([0.0 for i in range(300)]).tolist())
for key in sd:
    tmp=post_vectors[key]/post_comments_num[key]
    mem.append(tmp.tolist())
mem=np.array(mem)
np.save("./reddit/2009_processed/reddit_2009_half_node.npy",mem)

print(mem.shape)
print("number of interactions:",len(src))
print("number of nodes:",len(sd))


# 5 Kyu - Rot13
def rot13(message):
    # Create empty result string
    result = ""
    # Iterate over each character in the message string
    for char in message:
        # If the character is a letter, apply the ROT13 cipher
        if char.isalpha():
            # Determine the new position of the letter in the alphabet
            new_pos = ord(char) + 13
            if char.islower():
                # Wrap around to 'a' if the new position goes beyond 'z'
                new_pos = (new_pos - ord('a')) % 26 + ord('a')
            else:
                # Wrap around to 'A' if the new position goes beyond 'Z'
                new_pos = (new_pos - ord('A')) % 26 + ord('A')
            # Convert the new position back to a letter and append it to the result string
            result += chr(new_pos)
        else:
            # Append non-letter characters to the result string unchanged
            result += char
    return result

print(rot13("Test text"))


n = int(input())
a = list(map(int, input().split()))

a = list(set(a))
a.sort()

for i in a:
    print(i, end=" ")
print()

'''
6-5 중복 빼고 정렬하기
https://www.acmicpc.net/problem/10867
'''


from __future__ import division
import numpy as np
from astropy.io import fits
from hxmtpy.Events import Events
import numba

__all__ = ['binary']

#correcting_method = ["Reggio", "Sanna", "DT"]
correcting_method = ["BT", "Deeter"]

class binary(Events):
    """
    class inherited from Events class for binary pulsar analysis

    """

    def __init__(self, arr_events):
        if arr_events.dtype == '>f8':
            self.events = numba.float64(arr_events) # transfer big-endian dtype to non big-endian dtype
        else:
            self.events = arr_events

    def orbit_cor_bt(self, Porb, axsini, e, omega, Tw, gamma):
        """
        use numerical method to solve Kepler equation and calculate delay
        BT model (Blandford & Teukolsky, 1976)

        Parameters
        -----------------
        Porb : float
            The period of binary motion (in units of second)

        axsini : float
            Projected semi-major orbital axis (in units of light-sec)

        e : float
            The orbital eccentricity

        omega : float
            Longitude of periastron

        Tw : float
            The epoch of periastron passage (in units of seconds, same time system with parameter t)

        gamma ; float
            the coefficient measures the combined effect of gravitational redshift and time dilation

        Returns
        -------------
        new_t : array-like
            The time series after the binary correction

        """
        t = self.events
        x = axsini
        gamma = 0

        if e == 0:
            E = 2*np.pi*(t-Tw)/Porb;
        else:
            E = _solve_kepler_equation(t, Porb, e, Tw, dE=1e-3)
            #E = np.array([])
            ##solve Kepler Equation
            #dE = 1e-3
            #E_min = 2*np.pi*(t-Tw)/Porb - e
            #E_max = 2*np.pi*(t-Tw)/Porb + e
            #for i in range(len(E_min)): #TODO:the numerical method need to optimize!
            #    E_arr = np.arange(E_min[i], E_max[i], dE)

            #    equation_left = E_arr - e*np.sin(E_arr)
            #    equation_right= 2*np.pi*(t[i]-Tw)/Porb
            #    residual = np.abs(equation_left - equation_right)
            #    min_index = np.where(residual == min(residual))

            #    E = np.append(E, E_arr[min_index])

        #calculate time delay by orbit
        #factor1
        factor1 = x*np.sin(omega)*(np.cos(E)-e) + (x*np.cos(omega)* ((1-e**2)**0.5) + gamma )*np.sin(E)
        #factor2
        factor2 = 1- (2*np.pi/Porb)* (x*np.cos(omega)*((1-e**2)**0.5)-x*np.sin(omega)*np.sin(E)) * (1-e*np.cos(E))**(-1)
        factor = factor1 * factor2
        new_t = t + factor #NOTE:pulsar proper Time = time + facotr
        print(factor)
        return new_t

    def orbit_cor_deeter(self, Porb, axsini, e, omega, Tnod):
        """
        Correct the photon arrival times to the photon emission time
        Deeter model (see, e.g., Deeter et al. 1981)

        Parameters
        -----------------
        Porb : float
            The period of binary motion (in units of second)

        axsini : float
            Projected semi-major orbital axis (in units of light-sec)

        e : float
            The orbital eccentricity

        omega : float
            Longitude of periastron

        Tnod : float
            The epoch of ascending node passage (in units of seconds, same time system with parameter t)

        Returns
        -------------
        t_em : array-like
            The photon emission time

        """
        time = self.events
        A = axsini
        mean_anomaly = 2*np.pi*(time-Tnod)/Porb

        term1 = np.sin(mean_anomaly + omega)
        term2 = (e/2)*np.sin(2*mean_anomaly + omega)
        term3 = (-3*e/2)*np.sin(omega)

        t_em = time - A * (term1 + term2 + term3)
        return t_em

    def fre_doppler_cor(self, f0, f1, f2, axsini, Porb, omega, e, T_halfpi):
        """
        correct the observed freqency of neutron star,
        convert the frequency moduled by the binary orbital Doppler effect to
        the intrinsic frequency of NS
        (Galloway 2005)

        Parameters
        --------------
        f0 : float
            the observed frequency at reference epoch t0

        f1 : float
            the observed frequency derivative at reference epoch t0

        f2 : float
            the observed frequency second derivative at reference epoch t0

        axsini : float
            Projected semi-major orbital axis (in units of light-sec)

        Porb : float
            The period of binary motion (in units of second)

        omega : float
            Longitude of periastron

        e : float
            The orbital eccentricity

        T_halfpi : float
           The mean longitude, with T_halfpi the epoch at which the mean longitude is pi/2
           (in units of second)

        Returns
        -------------
        f_intri : array-like
            The corrected intrinsic frequecy of neutron star

        """
        time = self.events
        t0 = min(time) # set reference time as the start of time
        f_spin = f0 + f1*(time-t0) + 0.5*f2*(time-t0)**2
        f_dopp = self._get_fdopp(f0, axsini, Porb, omega, e, T_halfpi)

        f_intri = f_spin - f_dopp
        return f_intri

    def _get_fdopp(self, f0, axsini, Porb, omega, e, T_halfpi):
        """
        calculate the frequency modulated by Doppler effect
        """
        time = self.events
        l = 2* np.pi * (time-T_halfpi)/Porb + np.pi/2
        g = e*np.sin(omega)
        h = e*np.cos(omega)
        f_dopp = (2 * np.pi * f0 * axsini / Porb) * (np.cos(l) + g*np.sin(2*l) + h*np.cos(2*l) )
        return f_dopp

@numba.njit
def _solve_kepler_equation(t, Porb, e, Tw, dE=1e-3):
    """
    get the Eccentricity of Kepler Equation
    """

    E_min = 2*np.pi*(t-Tw)/Porb - e
    E_max = 2*np.pi*(t-Tw)/Porb + e
    E = np.zeros(len(E_min))
    for i in range(len(E_min)): #TODO:the numerical method need to optimize!
        print(i/len(E_min))
        E_arr = np.arange(E_min[i], E_max[i], dE)

        equation_left = E_arr - e*np.sin(E_arr)
        equation_right= 2*np.pi*(t[i]-Tw)/Porb
        residual = np.abs(equation_left - equation_right)
        min_index = np.argmin(residual)

        E[i] = E_arr[min_index]
    return E

if __name__ == "__main__":
    hdulist = fits.open("../test/HE_screen_test.fits")
    time = hdulist[1].data.field("Time")
    print(len(time))
    he = binary(time)
    print(he.orbit_cor_bt(22, 104,  0.1, 0.1, 55927, 1))


def write_config(config, filename, dir='/tmp/'):

    with open(dir+filename, 'w') as fid:
        for key in config.keys():
            fid.write(key + ' ' + config[key] + '\n')
    fid.close()

    return dir+filename

def read_config(filename):

    config = {}
    with open(filename, 'r') as fid:
        for line in fid.readlines():
            line_split = line.split(' ')
            config[line_split[0]] = line_split[1].rstrip()
    fid.close()

    return config

if __name__ == '__main__':

    a = {'test1': 'test2', 'test3': 'test4'}
    fname = write_config(a, 'test.config')
    b = read_config(fname)

    assert a==b


"""
###############################################################################
    Uniform Manifold Approximation and Projection (UMAP) Implementation
###############################################################################

    Author: Eric Johnson
    Date Created: Thursday, October 21, 2021
    Email: ericjohnson1.2015@u.northwestern.edu

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

    In this file, I want to define a class to wrap around the UMAP class in
    umap-learn so as to work best with the EMBEDR workflow.  In the future,
    I would like to restructure the algorithm so that different numbers of
    nearest neighbors can be supplied for each sample in the dataset, but this
    seems very complicated at the moment.

    ALSO: They literally just rolled out a version that allows for
    precomputed_kNN!  However, this isn't part of an official release yet, so
    I won't rely on it staying there.  Too bad.

###############################################################################
"""

from umap import UMAP

def _initialize_UMAP_embed(n_neighbors=15,
                           n_components=2,
                           metric='euclidean',
                           metric_kwds=None,
                           output_metric='euclidean',
                           output_metric_kwds=None,
                           n_epochs=None,
                           learning_rate=1.0,
                           init='random',
                           min_dist=0.1,
                           spread=1.0,
                           low_memory=True,
                           n_jobs=-1,
                           set_op_mix_ratio=1.0,
                           local_connectivity=1.0,
                           repulsion_strength=1.0,
                           negative_sample_rate=5,
                           transform_queue_size=4.0,
                           a=None, b=None,
                           random_state=None,
                           angular_rp_forest=False,
                           target_n_neighbors=-1,
                           target_metric='categorical',
                           target_metric_kwds=None,
                           target_weight=0.5,
                           transform_seed=42,
                           transform_mode='embedding',
                           force_approximation_algorithm=False,
                           verbose=False,
                           unique=False,
                           densmap=False,
                           dens_lambda=2.0,
                           dens_frac=0.3,
                           dens_var_shift=0.1,
                           output_dens=False,
                           disconnection_distance=None):

    return UMAP(n_neighbors=n_neighbors,
                n_components=n_components,
                metric=metric,
                metric_kwds=metric_kwds,
                output_metric=output_metric,
                output_metric_kwds=output_metric_kwds,
                n_epochs=n_epochs,
                learning_rate=learning_rate,
                init=init,
                min_dist=min_dist,
                spread=spread,
                low_memory=low_memory,
                n_jobs=n_jobs,
                set_op_mix_ratio=set_op_mix_ratio,
                local_connectivity=local_connectivity,
                repulsion_strength=repulsion_strength,
                negative_sample_rate=negative_sample_rate,
                transform_queue_size=transform_queue_size,
                a=a, b=b,
                random_state=random_state,
                angular_rp_forest=angular_rp_forest,
                target_n_neighbors=target_n_neighbors,
                target_metric=target_metric,
                target_metric_kwds=target_metric_kwds,
                target_weight=target_weight,
                transform_seed=transform_seed,
                transform_mode=transform_mode,
                force_approximation_algorithm=force_approximation_algorithm,
                verbose=bool(verbose),
                unique=unique,
                densmap=densmap,
                dens_lambda=dens_lambda,
                dens_frac=dens_frac,
                dens_var_shift=dens_var_shift,
                output_dens=output_dens,
                disconnection_distance=disconnection_distance)


"""
NotificationChannelProvider to integrate with the Urban Airship mobile push
notification services
"""

import json
import logging

import six
import requests
from requests.auth import HTTPBasicAuth
from requests.exceptions import RequestException

from edx_notifications.channels.channel import BaseNotificationChannelProvider

# system defined constants that only we should know about
UA_API_PUSH_ENDPOINT = 'https://go.urbanairship.com/api/push/'
PUSH_REQUEST_HEADER = {
    'Content-Type': 'application/json',
    'Accept': 'application/vnd.urbanairship+json; version=3;'
}

log = logging.getLogger(__name__)

class UrbanAirshipNotificationChannelProvider(BaseNotificationChannelProvider):
    """
    Implementation of the BaseNotificationChannelProvider abstract interface
    """

    def __init__(self, name=None, display_name=None, display_description=None, link_resolvers=None):
        """
        Initializer
        """
        super().__init__(
            name=name,
            display_name=display_name,
            display_description=display_description,
            link_resolvers=link_resolvers
        )

    def dispatch_notification_to_user(self, user_id, msg, channel_context=None):
        """
        Send a notification to a user. It is assumed that
        'user_id' and 'msg' are valid and have already passed
        all necessary validations
        :param user_id:
        :param msg:
        :param channel_context:
        :return:
        """
        payload = self.create_payload(msg, user_id)
        payload = json.dumps(payload)
        api_credentials = channel_context.get('api_credentials') if channel_context else None
        return self.call_ua_push_api(payload, api_credentials)

    @staticmethod
    def create_payload(msg, user_id):
        """
        Creates payload for UA push request for single named user
        :param msg:
        :param user_id:
        :return:
        """
        assert msg.payload['title'], 'Notification title not available in payload'
        assert user_id, 'No user id given'
        obj = {
            "notification": {"alert": msg.payload['title']},
            "audience": {"named_user": str(user_id)},
            "device_types": ["ios", "android"]
        }

        return obj

    def call_ua_push_api(self, payload, api_credentials):
        """
        Calls Urban Airship push API to send push notifications
        :param payload: json payload to be passed to push notifications API
        :param api_credentials: dict containing provider id and secret key
        Returns: json response sent by UA
        """
        resp = {}
        try:
            resp = requests.post(
                UA_API_PUSH_ENDPOINT,
                payload,
                headers=PUSH_REQUEST_HEADER,
                auth=HTTPBasicAuth(api_credentials["provider_key"], api_credentials["provider_secret"])
            )
            resp = resp.json()
            if not resp['ok']:
                log.error(
                    "Urban Airship push notifications API failed. Details: %s Error: %s",
                    resp.get('details'), resp.get('error')
                )

        except RequestException as ex:
            log.error("Urban Airship push notifications API failed with error %s", str(ex))
        return resp

    def bulk_dispatch_notification(self, user_ids, msg, exclude_user_ids=None, channel_context=None):
        """
        Perform a bulk dispatch of the notification message to
        all user_ids that will be enumerated over in user_ids.
        :param user_ids:
        :param msg:
        :param exclude_user_ids:
        :param channel_context:
        :return:
        """
        if 'tag_group' in msg.payload:
            payload = self.create_tag_group_payload(msg)
        elif 'send_to_all' in msg.payload and msg.payload['send_to_all'] is True:
            payload = self.create_all_user_payload(msg)
        else:
            exclude_user_ids = exclude_user_ids if exclude_user_ids else []
            actual_user_ids = []
            for user_id in user_ids:
                if user_id not in exclude_user_ids:
                    actual_user_ids.append(user_id)
            payload = self.create_bulk_user_payload(actual_user_ids, msg)

        self._add_type_in_payload(msg, payload)
        payload = json.dumps(payload)
        api_credentials = channel_context.get('api_credentials') if channel_context else None
        return self.call_ua_push_api(payload, api_credentials)

    def _add_type_in_payload(self, msg, payload):
        """
        Adds a notification type in payload if notification_type is present in the message

        Notification types:
            - courseannouncement

        :param msg:
        :param payload:
        """
        if 'notification_type' in msg.payload:
            extra = {
                "extra": {
                    "notification_type": msg.payload['notification_type']
                }
            }

            ios_android_extras = {
                "ios": extra,
                "android": extra,
            }
            payload['notification'].update(ios_android_extras)

    @staticmethod
    def create_tag_group_payload(msg):
        """
        Creates payload for UA push request for tag group
        :param msg:
        :return:
        """
        assert msg.payload['title'], 'Notification title not available in payload'
        alert = msg.payload['title']
        group = msg.payload.get('tag_group', 'enrollments')
        tag = msg.payload.get('tag', msg.namespace)

        obj = {
            "notification": {
                "alert": alert,
            },
            "device_types": "all",
            "audience": {
                "group": group,
                "tag": tag
            }
        }
        if 'open_url' in msg.payload:
            obj["notification"]["actions"] = {
                "open": {
                    "type": "url",
                    "content": msg.payload['open_url']
                }
            }

        return obj

    @staticmethod
    def create_bulk_user_payload(user_ids, msg):
        """
        Creates payload to send UA push notification to list of users
        :param user_ids: list of user ids
        :param msg:
        :return:
        """
        assert user_ids, 'List of user ids is empty'
        assert msg.payload['title'], 'Notification title not available in payload'

        obj = {
            "notification": {
                "alert": msg.payload['title']
            },
            "device_types": ["ios", "android"],
            "audience": {
                "named_user": [str(user_id) for user_id in user_ids]
            }
        }

        return obj

    @staticmethod
    def create_all_user_payload(msg):
        """
        Creates payload to send UA push notification to all users
        :param msg:
        :return:
        """
        assert msg.payload['title'], 'Notification title not available in payload'

        obj = {
            "notification": {
                "alert": msg.payload['title']
            },
            "device_types": "all",
            "audience": "all"
        }

        return obj

    def resolve_msg_link(self, msg, link_name, params, channel_context=None):
        """
        Generates the appropriate link given a msg, a link_name, and params
        """
        # Click through links do not apply for mobile push notifications
        return None


import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)

y = np.sin(x)

print(x)
print(y)

plt.xlabel("x")
plt.ylabel("sin(x)")
plt.title("y = sin(x)")
plt.plot(x, y)


import dicom2nifti
import nibabel as nib
import os
import numpy as np
from PIL import Image
import zipfile
import h5py
import json

def adequate_ircad():

    dir_data = "/media/juliosilva/Seagate Portable Drive/LIVIA/Datasets/UniversalOrganSegmentation/06_3D-IRCADb/"

    classes_dict = {'artery': 1, 'bone': 2, 'leftkidney': 3, 'leftlung': 4, 'liver': 5, 'liverkyst': 6, 'livertumor': 7,
                    'portalvein': 8, 'rightkidney': 9, 'rightlung': 10, 'skin': 11, 'spleen': 12, 'venoussystem': 13,
                    'gall': 14, 'stomach': 15, 'pancreas': 16, 'lungs': 17, }
    with open(dir_data + 'labels_indexes.txt', "w") as fp:
        json.dump(classes_dict, fp)

    if not os.path.exists(dir_data + 'img/'):
        os.mkdir(dir_data + 'img/')

    files = os.listdir(dir_data + 'data/')
    for iFile in files:
        print(iFile)

        # Unzip images and labels
        with zipfile.ZipFile(dir_data + 'data/' + iFile + '/LABELLED_DICOM.zip', 'r') as zip_ref:
            zip_ref.extractall(dir_data + 'data/' + iFile)
        with zipfile.ZipFile(dir_data + 'data/' + iFile + '/MASKS_DICOM.zip', 'r') as zip_ref:
            zip_ref.extractall(dir_data + 'data/' + iFile)

        # Dicom image to .nii and save
        if not os.path.isfile(dir_data + 'img/' + iFile.replace('.', '_') + '.nii.gz'):
            dicom2nifti.convert_dicom.dicom_series_to_nifti(dir_data + 'data/' + iFile + '/LABELLED_DICOM/',
                                                            dir_data + 'img/' + iFile.replace('.','_') + '.nii.gz')

        # Convert masks to .nii volumes
        if not os.path.isfile(dir_data + 'data/' + iFile + '/MASKS_NII/'):
            os.mkdir(dir_data + 'data/' + iFile + '/MASKS_NII/')

            masks_files = os.listdir(dir_data + 'data/' + iFile + '/MASKS_DICOM/')
            for iMask in masks_files:
                dicom2nifti.convert_dicom.dicom_series_to_nifti(dir_data + 'data/' + iFile + '/MASKS_DICOM/' + iMask,
                                                                dir_data + 'data/' + iFile + '/MASKS_NII/' + iMask + '.nii.gz')

def adequate_ircad_2():

    dir_data = "/media/juliosilva/Seagate Portable Drive/LIVIA/Datasets/UniversalOrganSegmentation/06_3D-IRCADb/"

    all_annotations = []
    files = os.listdir(dir_data + 'data/')
    for iFile in files:
        print(iFile)

        # Merge masks into one unique file
        masks_files_nii = os.listdir(dir_data + 'data/' + iFile + '/MASKS_NII/')
        for iMask in masks_files_nii:

            if ('tumor' not in iMask.split('.')[0]) and ('portalvein' not in iMask.split('.')[0]):
                all_annotations.append(iMask.split('.')[0])
            elif 'livertumor' in iMask.split('.')[0]:
                all_annotations.append('livertumor')
            elif iMask.split('.')[0] == 'tumor':
                all_annotations.append('tumor')
            elif 'portalvein' in iMask.split('.')[0]:
                all_annotations.append('portalvein')

    unique_organs, counts = np.unique(all_annotations, return_counts=True)
    unique_organs, counts = list(unique_organs), list(counts)

    # Create dictionary by importance sorting
    idx = list(np.argsort(counts))
    idx.reverse()
    annotations_dict = {}
    c = 0
    for i in idx:
        c+=1
        annotations_dict[unique_organs[i]] = c

def adequate_ircad_3():

    dir_data = "/media/juliosilva/Seagate Portable Drive/LIVIA/Datasets/UniversalOrganSegmentation/06_3D-IRCADb/"

    if not os.path.exists(dir_data + 'post_label/'):
        os.mkdir(dir_data + 'post_label/')

    # Unique, different categories found in the dataset
    cats_ircad = {'livertumor': 1, 'skin': 2, 'bone': 3, 'liver': 4, 'portalvein': 5, 'artery': 6, 'venoussystem': 7,
                  'venacava': 8, 'gallbladder': 9, 'leftkidney': 10, 'rightkidney': 11, 'spleen': 12, 'rightlung': 13,
                  'leftlung': 14, 'leftsurrenalgland': 15, 'lungs': 16, 'pancreas': 17, 'stomach': 18,
                  'rightsurrenalgland': 19, 'heart': 20, 'biliarysystem': 21, 'bladder': 22, 'tumor': 23, 'uterus': 24,
                  'colon': 25, 'smallintestin': 26, 'livercyst': 27, 'kidneys': 28, 'surrenalgland': 29,
                  'liverkyst': 30, 'liverkyste': 31, 'metal': 32, 'metastasectomie': 33, 'Stones': 34}

    files = os.listdir(dir_data + 'data/')
    for iFile in files:
        print(iFile)

        # Merge masks into one unique file
        masks_files_nii = os.listdir(dir_data + 'data/' + iFile + '/MASKS_NII/')
        annotations = []
        cats = []
        for iMask in masks_files_nii:
            vol = nib.load(dir_data + 'data/' + iFile + '/MASKS_NII/' + iMask)
            vol_values = np.array(vol.dataobj) // 255

            annotations.append(vol_values)

            if ('tumor' not in iMask.split('.')[0]) and ('portalvein' not in iMask.split('.')[0]):
                cats.append(iMask.split('.')[0])
            elif 'livertumor' in iMask.split('.')[0]:
                cats.append('livertumor')
            elif iMask.split('.')[0] == 'tumor':
                cats.append('tumor')
            elif 'portalvein' in iMask.split('.')[0]:
                cats.append('portalvein')

        out = np.zeros([len(cats_ircad)] + list(annotations[0].shape))
        for i in np.arange(0, len(annotations)):
            out[cats_ircad[cats[5]], :, :, :] += annotations[i]
        out = np.expand_dims(out, axis=0)

        with h5py.File(dir_data + 'post_label/' + iFile.replace('.', '_') + '.h5', 'w') as f:
            f.create_dataset('post_label', data=out.astype(np.uint8), compression='gzip', compression_opts=9)
            f.close()

        #nifti_file = nib.Nifti1Image(np.int32(out[0, :, :, :]), affine=vol.affine)
        nib.save(vol, dir_data + 'label/' + iFile.replace('.', '_') + '.nii.gz')

def adequate_tcia():

    dir_data = "E:/LIVIA/Datasets/UniversalOrganSegmentation/02_TCIA_Pancreas-CT/volumes/"
    dir_out = "C:/Users/jusir/Documents/Research/Projects/UniversalModel/temp/"

    files = os.listdir(dir_data)

    for iFile in files:
        path_1 = os.listdir(dir_data + iFile)
        path_2 = os.listdir(dir_data + iFile + "/" + path_1[-1])
        path_volume = dir_data + iFile + "/" + path_1[-1] + "/" + path_2[-1]

        if not os.path.isfile(dir_out + iFile + '.nii.gz'):
            dicom2nifti.convert_dicom.dicom_series_to_nifti(path_volume, dir_out + iFile + '.nii.gz')

def adequate_lits():

    dir_in = "C:/Users/jusir/Desktop/lits_raw/segmentations/"
    dir_out = "C:/Users/jusir/Documents/Research/Projects/UniversalModel/temp/label/"

    files = os.listdir(dir_in)
    for iFile in files:
        print(iFile)

        id = iFile.split('-')[-1].split('.')[0]
        new_name = 'liver_' + id + '.nii'

        vol = nib.load(dir_in + iFile)
        nib.save(vol, dir_out + new_name + '.gz')

def adequate_chaos():

    dir_data = "E:/LIVIA/Datasets/UniversalOrganSegmentation/03_CHAOS/raw/"
    dir_out = "C:/Users/jusir/Documents/Research/Projects/UniversalModel/temp/"
    modalities = ["CT"]
    partitions = ["Train_Sets"]

    for iPartition in partitions:
        for iModality in modalities:

            if not os.path.exists(dir_out + iModality.lower()):
                os.mkdir(dir_out + iModality.lower())
                os.mkdir(dir_out + iModality.lower() + "/img/")
                os.mkdir(dir_out + iModality.lower() + "/label/")

            files = os.listdir(dir_data + iPartition + "/" + iModality + "/")

            for iFile in files:
                print(iFile)

                # Volume
                path_volume = dir_data + iPartition + "/" + iModality + "/" + iFile + "/DICOM_anon/"
                if not os.path.isfile(dir_out + iModality.lower() + "/img/" + iFile + "_image.nii.gz"):
                    dicom2nifti.convert_dicom.dicom_series_to_nifti(path_volume,
                                                                    dir_out + iModality.lower() + "/img/" + iFile + '_image.nii.gz')

                # Labels
                path_volume = dir_data + iPartition + "/" + iModality + "/" + iFile + "/Ground/"
                if not os.path.isfile(dir_out + iModality.lower() + "/label/" + iFile + "_segmentation.gz"):

                    annotations = os.listdir(path_volume)
                    vol_segm = []

                    for iSlide in annotations:
                        im = np.int32(np.asarray(Image.open(path_volume + iSlide)))
                        im = np.rot90(im, 3, (0, 1))
                        vol_segm.append(np.expand_dims(im, axis=-1))

                    vol_segm.reverse()
                    vol = np.concatenate(vol_segm, -1)
                    nifti_file = nib.Nifti1Image(vol, affine=None)
                    nib.save(nifti_file, dir_out + iModality.lower() + "/label/" + iFile + "_segmentation.nii.gz")

def adequate_kits():

    dir_data = "C:/Users/jusir/Documents/Research/Projects/UniversalModel/temp/kits21/"

    files = os.listdir(dir_data + "kits21/data/")
    for iFile in files:
        print(iFile, end='\n')

        if 'case' in iFile:
            id = iFile.split('_')[-1][1:]

            vol = nib.load(dir_data + "kits21/data/" + iFile + "/imaging.nii.gz")
            nib.save(vol, dir_data + "/img/" + "img" + id + ".nii.gz")

            label = nib.load(dir_data + "kits21/data/" + iFile + "/aggregated_MAJ_seg.nii.gz")
            nib.save(label, dir_data + "/label/" + "label" + id + ".nii.gz")