# -*- coding: utf-8 -*-
"""
Created on Sat Dec  3 22:34:00 2016

@author: iralp
"""
import pandas as pd
from copy import deepcopy
from sklearn import preprocessing
import warnings
from scipy import spatial
import numpy as np
import operator
from sklearn import decomposition

warnings.filterwarnings("ignore")
#Data Science Project
#For a given pair of players,get the most comparable players

playerDataBat = None
playerDataPitch = None

def normalizeColumns(playerDataBatCopy,reqColumns):
    for each_column in reqColumns:
        #replace invalid values with valid ones
        for indx in range(len(playerDataBatCopy)):
            if playerDataBatCopy.iloc[indx][each_column] == 'NULL':
                playerDataBatCopy.iloc[indx][each_column] = 0
        #processing for Nans
        playerDataBatCopy[each_column] = playerDataBatCopy[each_column].fillna(value = 0)
        print('column  :',each_column)
        #preprocessing.normalize(playerDataBatCopy[each_column],axis = 0)
        #print(" Values : ",len(playerDataBatCopy[each_column]))
        #playerDataBatCopy[each_column] = preprocessing.normalize(playerDataBatCopy[each_column],axis = 0)
        print(len(playerDataBatCopy[each_column]))
    print('Normalization Done!')

def scoreWithBatters(playerID,playerDataBatCopy,reqColumns,year_of_trade):
    #count = 0
    #sum_ = 0
    reqColumns = ['WAR']
    #, 5, 6, 7, 8, 9
    dict_of_scores = {}
    print('player1 : ',playerID)
    #get the player data
    player1_ = playerDataBatCopy[playerDataBatCopy['player_ID'] == playerID]
    player1_data = player1_[player1_['year_ID'] <= year_of_trade]
    print('player1_data : ',len(player1_data))
    #print('player1_data : ',player1_data)

    #sort by age
    player1_data = player1_data.sort(['age'])
    #for each year,get the corresponding similarity score
    for indx in range(len(player1_data)):
        #get the age
        age = player1_data.iloc[indx]['age']
        vec1 = player1_data.iloc[indx][reqColumns]
        #print('age : ',age)

        #get rows with same age
        rows_ = playerDataBatCopy[playerDataBatCopy['age'] == age]
        rows_with_age = rows_[rows_['player_ID'] != playerID]

        for index,row in rows_with_age.iterrows():
            #print('row : ',row)
            name = row['name_common']
            #print('name : ',name,' age:',age,' WAR : ',row['WAR'])
            vec2 = row[reqColumns]
            #print('vec1 :',np.array(vec1))
            #print('vec2: ',np.array(vec2))
            score = 1 - spatial.distance.cosine(np.array(vec1),np.array(vec2))
            #print('score : ',score)
            if name not in dict_of_scores.keys():
                dict_of_scores[name] = (score,1)
            else:
                tup = dict_of_scores[name]
                no = tup[1] + 1
                sco = (tup[0] + score)
                dict_of_scores[name] = (sco,no)

    for each_key in dict_of_scores:
        tp = dict_of_scores[each_key]
        dict_of_scores[each_key] = ((tp[0]/tp[1]),no)

    #return the top ten most comparable players
    sorted_dict = sorted(dict_of_scores.items(),key = operator.itemgetter(1),reverse = True)
    return sorted_dict[:10]

def getNextWAR(playerID,pl1_comparables,playerDataBatCopy,year_of_trade):
    #get the current age of player1
    player1_ = playerDataBatCopy[playerDataBatCopy['player_ID'] == playerID]
    player1_data = player1_[player1_['year_ID'] <= year_of_trade]

    #sort by age
    player1_data = player1_data.sort(['age'],ascending=False)
    if len(player1_data) == 0:
        print('No comparables')
        return

    age_p1 = player1_data.iloc[0]['age']
    WAR_years = []
    #print('comparables : ',pl1_comparables)
    #average the WAR for this for all the 10 most comparables
    for ind in range(1,4):
        cosine_sum = 0
        next_age = age_p1 + ind
        WAR_ = 0.0
        count = 0

        for indx in range(len(pl1_comparables)):

            each_player = pl1_comparables[indx][0]
            #print('each_player : ',each_player)
            player_ = playerDataBatCopy[playerDataBatCopy['name_common'] == each_player]
            player_data = player_[player_['age'] == next_age]
            if len(player_data) == 0:
                continue

            print('player_data[WAR] : ',player_data['copied_WAR'])
            WAR_ += (player_data.iloc[0]['copied_WAR'])
            cosine_sum += pl1_comparables[indx][1][0]
            count += 1
            print('WAR_predict : ',WAR_)
        if cosine_sum == 0:
            cosine_sum = 1
        if count == 0:
            count = 1
        WAR_ = WAR_/count
        WAR_years.append(WAR_)

    return WAR_years

def getComparablePlayers(playerID,year_of_trade):
    #Use all features and compute some similarity score after normalizing the features=>
    #but consider only data corresponding to the same age
    global playerDataBat
    global playerDataPitch
    #load all the data
    playerDataBat = pd.DataFrame().from_csv(r'C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/player_daily_bat_Normalized.csv',encoding='utf8',index_col = False)
    playerDataPitch = pd.DataFrame().from_csv(r'C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/player_daily_pitch_Normalized.csv',encoding='utf8',index_col = False)
    playerDataBatCopy = deepcopy(playerDataBat)
    playerDataPitchCopy = deepcopy(playerDataPitch)

    playerID = str(playerID).strip()
    print('get comparable players for : ',playerID)

    #Now determine if either player is a hitter or a pitcher
    player1_rows = playerDataBat[playerDataBat['player_ID'] == playerID]

    print('player1 length : ',len(player1_rows))

    if len(player1_rows) == 0:
        player1_rows = playerDataPitch[playerDataPitch['player_ID'] == playerID]

    print('player1 length : ',len(player1_rows))

    #Normalize the required columns for batters
    reqColumns = list(playerDataBat.columns)
    reqColumns.remove('name_common')
    reqColumns.remove('age')
    reqColumns.remove('mlb_ID')
    reqColumns.remove('player_ID')
    reqColumns.remove('year_ID')
    reqColumns.remove('team_ID')
    reqColumns.remove('stint_ID')
    reqColumns.remove('lg_ID')
    reqColumns.remove('salary')
    reqColumns.remove('pitcher')
    reqColumns.remove('teamRpG')
    reqColumns.remove('oppRpG')
    reqColumns.remove('oppRpPA_rep')
    reqColumns.remove('oppRpG_rep')
    reqColumns.remove('pyth_exponent')
    reqColumns.remove('pyth_exponent_rep')

    #Normalize the required columns for batters
    reqColumns_pitchers = list(playerDataPitchCopy.columns)
    reqColumns_pitchers.remove('name_common')
    reqColumns_pitchers.remove('age')
    reqColumns_pitchers.remove('mlb_ID')
    reqColumns_pitchers.remove('player_ID')
    reqColumns_pitchers.remove('year_ID')
    reqColumns_pitchers.remove('team_ID')
    reqColumns_pitchers.remove('stint_ID')
    reqColumns_pitchers.remove('lg_ID')
    reqColumns_pitchers.remove('salary')

    playerDataBatCopy['copied_WAR'] = playerDataBatCopy['WAR']
    playerDataPitchCopy['copied_WAR'] = playerDataPitchCopy['WAR']
    normalizeColumns(playerDataBatCopy,['WAR'])
    normalizeColumns(playerDataPitchCopy,['WAR'])
    '''matrix_of_batters = np.matrix(playerDataBatCopy[reqColumns])
    pca = decomposition.PCA(n_components = 5)
    pca_fit_batters = pca.fit_transform(matrix_of_batters)
    print(pca_fit_batters.shape)

    matrix_of_pitchers = np.matrix(playerDataPitchCopy[reqColumns_pitchers])
    pca = decomposition.PCA(n_components = 5)
    pca_fit_pitchers = pca.fit_transform(matrix_of_pitchers)
    print(pca_fit_pitchers.shape)

    pitchers_frame = pd.DataFrame(pca_fit_pitchers)
    pitchers_frame['age'] = playerDataPitchCopy['age']
    pitchers_frame['name_common'] = playerDataPitchCopy['name_common']
    pitchers_frame['player_ID'] = playerDataPitchCopy['player_ID']
    pitchers_frame['year_ID'] = playerDataPitchCopy['year_ID']
    print(pitchers_frame.columns)

    batters_frame = pd.DataFrame(pca_fit_batters)
    batters_frame['age'] = playerDataBatCopy['age']
    batters_frame['name_common'] = playerDataBatCopy['name_common']
    batters_frame['player_ID'] = playerDataBatCopy['player_ID']
    batters_frame['year_ID'] = playerDataBatCopy['year_ID']
    print(batters_frame.columns)
    '''

    pl1_comparables = None
    pl1_WAR = None

    #check if the player is a pitcher or a batter
    if len(player1_rows) == 0:
        return None
    player1IsPitcher = player1_rows.iloc[0]['pitcher']

    #if batter consider the rows corresponding to war_bat.csv
    if player1IsPitcher == 'N':
        pl1_comparables = scoreWithBatters(playerID,playerDataBatCopy,reqColumns,year_of_trade)
        pl1_WAR = getNextWAR(playerID,pl1_comparables,playerDataBatCopy,year_of_trade)
    else:
        pl1_comparables = scoreWithBatters(playerID,playerDataPitchCopy,reqColumns_pitchers,year_of_trade)
        pl1_WAR = getNextWAR(playerID,pl1_comparables,playerDataPitchCopy,year_of_trade)

    print('pl1_WAR : ',pl1_WAR)
    return pl1_WAR

#averaged over 3 years
def getActualWAR(playerID,year):
    playerID = str(playerID).strip()
    print('get comparable players for : ',playerID)

    #Now determine if either player is a hitter or a pitcher
    player1_rows = playerDataBat[playerDataBat['player_ID'] == playerID]

    print('player1 length : ',len(player1_rows))

    if len(player1_rows) == 0:
        player1_rows = playerDataPitch[playerDataPitch['player_ID'] == playerID]

    print('player1 length : ',len(player1_rows))

    actual_WAR = []
    #Now get the average WAR over next 3 years
    for ind in range(1,4):
        print('n th  year : ',ind)
        yr = year + ind
        row = player1_rows[player1_rows['year_ID'] == yr]
        if len(row) == 0:
            actual_WAR.append(0.0)
            continue
        WAR = row['WAR']
        WAR = str(WAR).split()
        actual_WAR.append(float(WAR[1]))

    return actual_WAR

def rmse(predictions, targets):
    return np.sqrt(((np.array(predictions) - np.array(targets)) ** 2).mean())

def getrmse(players_results,predict,actual):
    predicted = []
    targets = []

    for indx in range(len(players_results)):
        if players_results.iloc[indx][predict] != None and players_results.iloc[indx][predict] != 'nan':
            try:
                predicted.append(float(players_results.iloc[indx][predict]))
            except :
                predicted.append(0.0)
        else:
            predicted.append(0.0)

        if players_results.iloc[indx][actual] != None and players_results.iloc[indx][predict] != 'nan':
            try:
                targets.append(float(players_results.iloc[indx][actual]))
            except:
                targets.append(0.0)
        else:
            targets.append(0.0)

    print('players_results predict: ',players_results[predict])
    print('players_results actual: ',players_results[actual])

    rmse_score = rmse(np.array(predicted),np.array(targets))
    return rmse_score

def validatePreviousData():
    players_results = pd.DataFrame(columns = ['playerID','player_name','predicted WAR_1',\
    'actual WAR_1','predicted WAR_2','actual WAR_2','predicted WAR_3','actual WAR_3',\
    'start_year','trade_year','from_team','to_team','transaction-ID','rmse_scores_1',\
    'rmse_scores_2','rmse_scores_3'])
    columns = ['primary-date',  'time', 'approximate-indicator',  'secondary-date',  'approximate-indicator (for secondary-date)',\
               'transaction-ID',  'player', 'type',  'from-team',  'from-league',  \
               'to-team',  'to-league','draft-type',  \
               'draft-round', 'pick-number',  'info']

    file_count = 0
   #load the csv into a data frame
    data = pd.read_csv('C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/transactions/tran.txt',header = 0,\
       parse_dates = True,names = columns)
    #data cleaning
    data['time'].fillna(0,inplace = True)
    data['approximate-indicator'].fillna(0,inplace = True)
    data['secondary-date'].fillna(0,inplace = True)
    data['approximate-indicator (for secondary-date)'].fillna(0,inplace = True)
    data['draft-round'].fillna("NA",inplace = True)
    data['info'].fillna("NA",inplace = True)
    data['pick-number'].fillna("NA",inplace = True)
    data['draft-type'].fillna("NA",inplace = True)

    years = [int(str(x)[:4]) for x in data['primary-date']]
    months = [int(str(x)[4:6]) for x in data['primary-date']]

    #create a new column with year,month of trade
    data['year'] = years
    data['month'] = months

    #load the master data to get player name from his id
    master_data = pd.read_csv('C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/baseballdatabank-master/core/Master.csv',\
        index_col = False)
    #usecols = ['retroID','nameGiven']

    #consider trades in ranges 2005-2010
    data_temp = data[data['year'] >= 2010]
    data_trades_05_10 = data_temp[data_temp['year'] <= 2012]

    transactions = set(data_trades_05_10['transaction-ID'])
    count = 0

    for indx,row in data_trades_05_10.iterrows():
        #for each trade,get the players => calculate their WAR for next 1-3 years and validate with original WAR
        #for each transaction id get the players involved
            for each_trade in transactions:
                #get the cooresponding rows
                trades = data_trades_05_10[data_trades_05_10['transaction-ID'] == each_trade]
                #check the trade type and skip if not T
                if trades.iloc[0]['type'] != 'T ':
                    continue
                #get the players

                for indx,each_ in trades.iterrows():
                    playerID = each_['player']
                    #get the player name from
                    print('playerID: ',playerID)
                    player_data_indx = master_data[master_data['retroID'] == playerID].index
                    if player_data_indx == None:
                        continue
                    print('player_data : ',player_data_indx)
                    playerName = master_data.iloc[player_data_indx]['playerID']
                    print('playerName : ',playerName)
                    playr_ID = str(playerName).split()
                    #TODO get the comparable players also
                    player_WAR = getComparablePlayers(playr_ID[1],each_['year'])

                    if player_WAR == None:
                        continue

                    #computer the actual WAR average for next three years
                    actual_WAR = getActualWAR(playr_ID[1],each_['year'])

                    player_result = []
                    player_result.append(playr_ID[1] + " ")
                    player_result.append(master_data.iloc[player_data_indx]['nameGiven'])
                    player_result.append(str(player_WAR[0]) + "")
                    player_result.append(str(actual_WAR[0]) + "")
                    player_result.append(str(player_WAR[1]) + "")
                    player_result.append(str(actual_WAR[1]) + "")
                    player_result.append(str(player_WAR[2]) + "")
                    player_result.append(str(actual_WAR[2]) + "")

                    player_result.append(str(int(each_['year']) + 1)  + " ")
                    player_result.append(each_['year'])
                    player_result.append(each_['from-team'])
                    player_result.append(each_['to-team'])
                    player_result.append(each_trade)
                    player_result.append("0")
                    player_result.append("0")
                    player_result.append("0")

                    players_results.loc[count] = player_result

                    count += 1
                    print('length of frame :',len(players_results))
                    if count == 100:
                        rmse_score_1 = getrmse(players_results,'predicted WAR_1','actual WAR_1')
                        rmse_score_2 = getrmse(players_results,'predicted WAR_2','actual WAR_2')
                        rmse_score_3 = getrmse(players_results,'predicted WAR_3','actual WAR_3')
                        players_results['rmse_scores_1'] = [rmse_score_1]*100
                        players_results['rmse_scores_2'] = [rmse_score_2]*100
                        players_results['rmse_scores_3'] = [rmse_score_3]*100

                        players_results.to_csv('C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/Results_'+str(file_count)+'.csv',encoding = 'utf8')
                        count = 0
                        file_count += 1

    return players_results

data_results = validatePreviousData()
#data_results.to_csv('C:/Personal_Docs/Course_Work/Data Science/Course_Project/Data/Results_5.csv',encoding = 'utf8')
print('Done!!')


from django.contrib import admin
from django.urls import path
from dashboard.views import *
urlpatterns = [
    path('',index,name="index" ),
    path('details/',details,name="details" ),
    path('services/',myservices,name="details" ),
    path('contact/',contactus,name="contactus" ),
    path('login/',loginUser,name="loginUser" ),
    path('logout/',logoutUser,name="logoutUser" ),

]


from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from db import database, PROVIDERS

bp_provider = Blueprint('provider', __name__, url_prefix='/provider')

@bp_provider.route('/providers', methods=['POST','GET'])
def provider():
    if request.method == 'POST':
        if request.args['option'] == 'new':
            r = request.form
            new_provider = PROVIDERS(NAME=r['NAME'], NAME_CONTACT=r['NAME_CONTACT'],
                                ADDR_STREET=r['ADDR_STREET'],
                                ADDR_CITY=r['ADDR_CITY'],
                                #  ADDR_COUNTRY=r['ADDR_COUNTRY'],
                                PHONE=r['PHONE'],
                                EMAIL=r['EMAIL'],
                                CUIT=r['CUIT'] if r['CUIT'] != "" else None,
                                BUSINESS_REF=g.session)
            database.session.add(new_provider)
            database.session.commit()
            flash(f"Proveedor cargado correctamente.", "success")

        if request.args['option'] == 'update':
            id = request.args['values']
            r = request.form
            c = PROVIDERS.query.filter_by(ID=id).first()
            c.NAME = r['NAME'] if r['NAME'] != c.NAME else c.NAME
            c.NAME_CONTACT = r['NAME_CONTACT'] if r['NAME_CONTACT'] != c.NAME_CONTACT else c.NAME_CONTACT
            c.CUIT = r['CUIT'] if r['CUIT'] != c.CUIT else c.CUIT
            c.ADDR_STREET = r['ADDR_STREET'] if r['ADDR_STREET'] != c.ADDR_STREET else c.ADDR_STREET
            c.ADDR_CITY = r['ADDR_CITY'] if r['ADDR_CITY'] != c.ADDR_CITY else c.ADDR_CITY
            c.PHONE = r['PHONE'] if r['PHONE'] != c.PHONE else c.PHONE
            c.EMAIL = r['EMAIL'] if r['EMAIL'] != c.EMAIL else c.EMAIL
            database.session.add(c)
            database.session.commit()
            flash('Datos actualizados correctamente.','success')

    else:
        try:
            if request.args['option'] == 'delete':
                r = request.args['values']
                c = PROVIDERS.query.filter_by(ID=r).first()
                database.session.delete(c)
                database.session.commit()
                message = f'Proveedor "{c.NAME}" eliminado con éxito'
                flash(message,'success')
        except:
            flash('No se encontraron datos a eliminar.','warning')

    return redirect(url_for('application.application', business=g.session, checker=g.user,action='providers'))


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

# Learn more: https://github.com/kennethreitz/setup.py

from setuptools import setup, find_packages

with open('README.rst') as f:
    readme = f.read()

with open('LICENSE') as f:
    license = f.read()

setup(
    name='keras_bc6_track1',
    version='0.1.0',
    description='BioCreative 6 track1 BioId Assignment',
    long_description=readme,
    author='nsx',
    author_email='ningshixian@mail.dlut.edu.cn',
    url='https://github.com/ningshixian/keras_bc6_track1',
    license=license,
    packages=find_packages(exclude=('tests', 'docs'))
)


from django.db import models
from rest_framework import status

from oarndb.models.base_model import BaseModel
from oarndb.models import Organization, OrganizationPersonRole

class Person(BaseModel):
    """
    The most important table of the whole system.
    All children, adults, and staff have a person record.
    """

    person_id = models.AutoField('person_id', primary_key=True)

    first_name = models.CharField('first_name', max_length=35, null=False)

    middle_name = models.CharField('middle_name', max_length=35, null=True, blank=True)

    last_name = models.CharField('last_name', max_length=35, null=False)

    # 'Jr.', 'III', etc.
    generation_code = models.CharField('generation_code', max_length=10, null=True, blank=True)

    prefix = models.CharField('prefix', max_length=30, null=True, blank=True)

    birth_date = models.DateField('birth_date', auto_now=False, auto_now_add=False, null=True, blank=True)

    ref_gender = models.ForeignKey('RefGender', verbose_name='ref_gender',
                                   blank=True, null=True, on_delete=models.SET_NULL)

    organization = models.ManyToManyField(Organization, through='OrganizationPersonRole', related_name='organizations')

    def get_instance_access(self, user):
        """
        Returns the read/write access for this instance and this user.

        :param user: django.contrib.auth.models.User
        :return: {read: Boolean, write: Boolean}
        """
        # Global admins can read anything:
        if user.groups.filter(name='global_admin').count() > 0:
            return {'read': True, 'write': True}
        # Does the user have admin or read/write access to this Person's org?
        elif (Organization.objects.get_readwrite_orgs(user) & self.organization.all()).count() > 0:
            return {'read': True, 'write': True}
        # Does the user have read-only rights to this Person's org?
        elif (Organization.objects.get_read_orgs(user) & self.organization.all()).count() > 0:
            return {'read': True, 'write': False}
        # If nothing else, is the user a member of global_readonly?
        elif user.groups.filter(name='global_readonly').count() > 0:
            return {'read': True, 'write': False}
        else:
            return {'read': False, 'write': False}

    @staticmethod
    def get_validated_data_access(user, validated_data):
        """
        Returns details on whether the supplied user has the write permissions needed
        to update/create with this validated_data

        As a model with a many-to-many relationship, Person requires a POST with

        :param user: django.contrib.auth.models.User
        :param validated_data: from the serializer
        :return: {write:Boolean, error: Boolean, error_msg: String, status_code: rest_framework.status}
        """
        # Creating a person record requires only that the user has *some* writable permissions.
        # The key will be in the linking of the new Person record with an organization, which must
        # be done via a POST to the OrganizationPersonRole view - without that, the new Person record
        # will not be visible to the user who created it. (This is not an ideal way to approach this,
        # in my view - we should be able to POST nested JSON data to a single endpoint and have the
        # nested data result in new records in both tables, but DRF currently appears only to support
        # hackish solutions to this problem, so we'll do it in two POSTs to two endpoints for now.)
        # Once a Person record is linked to an organization, updates require write access to that
        # organization.

        # Does the validated data reference an existing record?
        pk = validated_data.get('person_id')
        if pk is None:
            return {'write':False, 'error': True, 'error_msg': 'it is None!', 'status_code': status.HTTP_400_BAD_REQUEST}
        else:
            return {'write':False, 'error': True, 'error_msg': pk, 'status_code': status.HTTP_400_BAD_REQUEST}

    class Meta:
        db_table = "person"
        ordering = ["last_name", "first_name"]

    def __str__(self):
        return self.first_name + " " + self.last_name + " (" + str(self.person_id) + ")"

class Child(BaseModel):
    """
    Allows us to separate children from the set of person records.
    """

    person = models.OneToOneField('Person', primary_key=True, verbose_name='person')

    class Meta:
        db_table = "child"

    def __str__(self):
        return self.person.__str__()

class Adult(BaseModel):
    """
    Allows us to separate adults from the set of person records.
    """

    person = models.OneToOneField('Person', primary_key=True, verbose_name='person')

    class Meta:
        db_table = "adult"

    def __str__(self):
        return self.person.__str__()

class PersonRace(BaseModel):
    """
    The federal categories for race.
    """

    person = models.OneToOneField('Person', primary_key=True, verbose_name='person')

    hispanic_latino_ethnicity = models.BooleanField('hispanic_latino_ethnicity', default=False)

    american_indian = models.BooleanField(default=False)

    asian = models.BooleanField(default=False)

    black = models.BooleanField(default=False)

    pacific = models.BooleanField(default=False)

    white = models.BooleanField(default=False)

    multiracial = models.BooleanField(default=False)

    unreported = models.BooleanField(default=False)

    other = models.BooleanField(default=False)

    other_details = models.CharField(max_length=100, null=True, blank=True)

    class Meta:
        db_table = "person_race"

    def __str__(self):
        race_list = ""

        if self.american_indian:
            race_list = race_list + 'american_indian; '

        if self.asian:
            race_list = race_list + 'asian; '

        if self.black:
            race_list = race_list + 'black; '

        if self.pacific:
            race_list = race_list + 'pacific; '

        if self.white:
            race_list = race_list + 'white; '

        if self.other:
            race_list = race_list + 'other; '

        return self.person.__str__() + ': ' + race_list

class Family(BaseModel):
    """
    The family table acts as a hub around which any number of person
    records may be associated.
    """

    family_id = models.AutoField('family_id', primary_key=True)

    notes = models.CharField('notes', max_length=10000, null=True, blank=True)

    organizations = models.ManyToManyField("Organization", through="OrganizationFamilyLink")

    class Meta:
        db_table = "family"

    def __str__(self):
        return str(self.family_id)

class AdultFamilyRelationship(BaseModel):
    """
    Describes a relationship between an individual adult and a family.
    """

    adult_family_relationship_id = models.AutoField('adult_family_relationship_id', primary_key=True)

    adult = models.ForeignKey('Adult', verbose_name='adult')

    family = models.ForeignKey('Family', verbose_name='family')

    ref_adult_family_relationship_type = models.ForeignKey(
        'RefAdultFamilyRelationshipType',
        verbose_name='ref_adult_family_relationship_type_id',
        null=True,  # This may not be a necessary field at all, so nullable for now
        blank=True,
        on_delete=models.SET_NULL
    )

    primary_adult = models.BooleanField('primary_adult', default=False)

    relationship_begin_date = models.DateField(
        'relationship_begin_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    relationship_end_date = models.DateField(
        'relationship_end_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    notes = models.CharField('notes', max_length=10000, null=True, blank=True)

    class Meta:
        db_table = 'adult_family_relationship'

    def __str__(self):
        return self.adult.__str__() + ' linked to family ' + self.family.__str__()

class ChildFamilyRelationship(BaseModel):
    """
    Describes a relationship between an individual child and a family.
    This is where foster or adoptive relationships can be modeled.
    """

    child_family_relationship_id = models.AutoField('child_family_relationship_id', primary_key=True)

    child = models.ForeignKey('Child', verbose_name='child')

    family = models.ForeignKey('Family', verbose_name='family')

    ref_child_family_relationship_type = models.ForeignKey(
        'RefChildFamilyRelationshipType',
        verbose_name='ref_child_family_relationship_type',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )

    relationship_begin_date = models.DateField(
        'relationship_begin_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    relationship_end_date = models.DateField(
        'relationship_end_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    notes = models.CharField('notes', max_length=10000, null=True, blank=True)

    class Meta:
        db_table = 'child_family_relationship'

    def __str__(self):
        return self.child.__str__() + ' linked to family ' + self.family.__str__()

class AdultChildRelationship(BaseModel):
    """
    Describes the relationship between a given adult and a given child.
    """
    adult_child_relationship_id = models.AutoField('adult_child_relationship_id', primary_key=True)

    adult = models.ForeignKey('Adult', verbose_name='adult')

    child = models.ForeignKey('Child', verbose_name='child')

    ref_adult_child_relationship_type = models.ForeignKey(
        'RefAdultChildRelationshipType',
        verbose_name='ref_adult_child_relationship_type',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )

    can_pick_up = models.BooleanField('can_pick_up', default=True)  # Do we want to whitelist?

    legal_custody = models.BooleanField('legal_custody', default=True)  # Do we want to whitelist?

    physical_custody = models.BooleanField('physical_custody', default=True)  # Do we want to whitelist?

    relationship_begin_date = models.DateField(
        'relationship_begin_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    relationship_end_date = models.DateField(
        'relationship_end_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    notes = models.CharField('notes', max_length=10000)

    class Meta:
        db_table = 'adult_child_relationship'

    def __str__(self):
        return self.adult.__str__() + ' linked to child ' + self.child.__str__()

class PersonDemographicRace(BaseModel):
    """
    A lookup table for race as opposed to ethnicity, following CEDS and the
    federal guidelines.
    """

    person_demographic_race_id = models.AutoField('person_demographic_race_id', primary_key=True)

    person = models.ForeignKey('Person', verbose_name='person')

    ref_race = models.ForeignKey('RefRace', verbose_name='ref_race',
                                 blank=True, null=True, on_delete=models.SET_NULL)

    class Meta:
        db_table = 'person_demographic_race'

        # a person cannot be a given race multiple times:
        unique_together = (("person", "ref_race"))

    def __str__(self):
        return self.person.__str__() + ': ' + self.ref_race.__str__()

class PersonLanguage(BaseModel):
    """
    Represents a language spoken by a person.
    """

    person_language_id = models.AutoField('person_language_id', primary_key=True)

    person = models.ForeignKey('Person', verbose_name='person')

    ref_language = models.ForeignKey('RefLanguage', verbose_name='ref_language_id',
                                     blank=True, null=True, on_delete=models.SET_NULL)

    other_details = models.CharField(max_length=100, null=True, blank=True)

    ref_language_use_type = models.ForeignKey(
        'RefLanguageUseType',
        verbose_name='ref_language_use_type',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )

    class Meta:
        db_table = 'person_language'

        # a person cannot be assigned the same language twice:
        unique_together = (("person", "ref_language"))

    def __str__(self):
        return self.person.__str__() + ': ' + self.ref_language.__str__() \
               + ' at ' + self.ref_language_use_type.__str__()

class PersonPregnancy(BaseModel):
    """
    An adult may be associated with a pregancy record.
    """

    person_pregnancy_id = models.AutoField('person_pregnancy_id', primary_key=True)

    adult = models.ForeignKey('Adult', verbose_name='adult')

    pregnancy_end_date = models.DateField(
        'pregnancy_end_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    pregnancy_notes = models.CharField('pregnancy_notes', max_length=5000)

    class Meta:
        db_table = 'person_pregnancy'

    def __str__(self):
        return self.adult.__str__() + ': person_pregnancy_id (' + \
               str(self.person_pregnancy_id) + ')'

class ChildPregnancyRelationship(BaseModel):
    """
    A pregnancy may result in more than one child.
    """

    child_pregnancy_relationship_id = models.AutoField(
        'child_pregnancy_relationship_id',
        primary_key=True
    )

    person_pregnancy = models.ForeignKey(
        "PersonPregnancy",
        verbose_name='person_pregnancy'
    )

    child = models.ForeignKey(
        "Child",
        verbose_name='child'
    )

    class Meta:
        db_table = 'child_pregnancy_relationship'

    def __str__(self):
        return self.child.__str__() + ': ' + \
               self.person_pregnancy.__str__()

class PersonTelephone(BaseModel):
    """
    A person may be linked to zero or more telephone numbers.
    """

    person_telephone_id = models.AutoField(
        'person_telephone_id',
        primary_key=True
    )

    person = models.ForeignKey("Person", verbose_name='person')

    telephone_number = models.CharField('telephone_number', max_length=24, null=False, blank=False)

    ref_person_telephone_number_type = models.ForeignKey(
        "RefPersonTelephoneNumberType",
        verbose_name='ref_person_telephone_number_type_id',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )

    class Meta:
        db_table = 'person_telephone'

    def __str__(self):
        return self.person.__str__() + ': ' + self.telephone_number + \
               ' (' + self.ref_person_telephone_number_type.__str__() + ')'

class PersonEmailAddress(BaseModel):
    """
    A person may be linked to zero or more email addresses.
    """

    person_email_address_id = models.AutoField(
        'person_email_address_id',
        primary_key=True
    )

    person = models.ForeignKey("Person", verbose_name='person')

    email_address = models.EmailField('email_address', max_length=75)

    ref_email_type = models.ForeignKey("RefEmailType", verbose_name='ref_email_type',
                                       blank=True, null=True)

    class Meta:
        db_table = 'person_email_address'

    def __str__(self):
        return self.person.__str__() + ': ' + self.email_address + \
               ' (' + self.ref_email_type.__str__() + ')'

class FamilyAddress(BaseModel):
    """
    A family may be lined to zero or more physical/mailing addresses.
    """
    family_address_id = models.AutoField('family_address_id', primary_key=True)

    family = models.ForeignKey("Family", verbose_name='family')

    ref_location_type = models.ForeignKey(
        "RefLocationType",
        verbose_name='ref_location_type',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )

    street_number_and_name = models.CharField('street_number_and_name', max_length=40)

    apartment_room_or_suite_number = models.CharField(
        'apartment_room_or_suite_number',
        max_length=30,
        null=True,
        blank=True
    )

    city = models.CharField('city', max_length=30)

    ref_state = models.ForeignKey(
        "RefState",
        verbose_name='ref_state',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )

    postal_code = models.CharField('postal_code', max_length=17, null=True, blank=True)

    # Dropped from the SQL 'address_county_name' - this should be solely by reference table lookup.
    ref_county = models.ForeignKey("RefCounty", verbose_name='ref_county',
                                   blank=True, null=True, on_delete=models.SET_NULL)

    residence_end_date = models.DateField(
        'residence_end_date',
        auto_now=False,
        auto_now_add=False,
        null=True,
        blank=True
    )

    # Should this address appear in the family summary view?
    primary_address = models.BooleanField('primary_address', default=False)

    notes = models.CharField('notes', max_length=10000, blank=True, null=True)

    class Meta:
        db_table = 'family_address'

    def __str__(self):
        return 'Family ID ' + self.family.__str__() + ': ' +  self.street_number_and_name


import sys
import threading
import time
import math
import cv2
import pyzbar.pyzbar as pyzbar
from PyQt5.uic.uiparser import QtCore
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import uic
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

form_class = uic.loadUiType("QR_code.ui")[0]

class MainWindow(QMainWindow, form_class):

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.initUI()

    def initUI(self):

        self.pb_camOn.clicked.connect(self.start)
        self.pb_camOff.clicked.connect(self.stop)

    def video(self):
        #print(dtype(running))
        global running
        self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

        while running:
            self.ret, self.frame = self.cap.read()

            if self.ret:
                #self.frame = self.read_qrcode
                self.read_qrcode()
                #print(self.frame)
                self.frame = cv2.resize(self.frame, dsize=(640, 480), interpolation=cv2.INTER_AREA)
                self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
                qframe = QImage(self.frame, self.frame.shape[1], self.frame.shape[0], QImage.Format_RGB888)
                pixmap = QPixmap.fromImage(qframe)
                self.lb_video.setPixmap(pixmap)

        self.cap.release()
        self.lb_video.setPixmap(QPixmap.fromImage(QImage()))
        print("thread end")

    def read_qrcode(self):
        self.font = cv2.FONT_HERSHEY_SIMPLEX

        self.barcodes = pyzbar.decode(self.frame)

        for self.barcode in self.barcodes:

            self.x, self.y, self.w, self.h = self.barcode.rect
            self.barcode_info = self.barcode.data.decode('utf-8')

            cv2.rectangle(self.frame, (self.x, self.y), (self.x + self.w, self.y + self.h), (0, 0, 255), 2)

            cv2.putText(self.frame, self.barcode_info, (self.x, self.y - 20), self.font, 0.5, (0, 0, 255), 1)

    def start(self):
        global running
        running = True
        th = threading.Thread(target=self.video)
        th.start()
        print("Start")

    def stop(self):
        global running
        running = False
        print("Stop")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
running = False


import torch
import torch.nn as nn

def train():
    model = nn.Linear(in_features=4, out_features=2)

    criterion = nn.MSELoss()
    optimizer = torch.optim.SGD(params=model.parameters(), lr=0.1)

    for epoch in range(10):
        # Converting inputs and labels to Variable
        inputs = torch.Tensor([0.8,0.4,0.4,0.2])
        labels = torch.Tensor([1, 0])

        # Clear gradient buffers because we don't want any gradient from previous epoch to carry forward
        optimizer.zero_grad()

        # Get output from the model, given the inputs
        outputs = model(inputs)

        # Get loss for the predicted output
        loss = criterion(outputs, labels)
        print("loss: ", loss)

        # Get gradients w.r.t. to parameters
        loss.backward()

        # Update parameters
        optimizer.step()

        print("epoch {} :: loss {}".format(epoch, loss.item()))

if __name__ == "__main__":
    train()


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

# # －實作程式輔助判斷藥物造成SJS/TEN之可能性
# ## 本程式整合Naranjo score及ALDEN score，藉由輸入藥物資訊、病人資料及相關問題
# ## 經由分析後，即可比較各藥物間之懷疑程度，同時輸出藥物使用表格

# ### 讀取藥物資料(存於csv檔中)：
# * acetaminophen, 500 mg 1# QID, 2020/6/8-2020/6/10
# * prednisolone, 5 mg 2# QID, 2020/6/12-2020/6/24
# * prednisolone, 5 mg 1# QID, 2020/6/30-2020/7/4
# * TMP-SMX, 2# BID, 2020/6/12-2020/6/24

# In[1]:

input('歡迎使用Naranjo與ALDEN量表輔助工具\n')
Drug_list = []  # ['acetaminophen', 'prednisolone', 'TMP-SMX']
Drug_info_list = [] # [['500 mg 1# QID'], ['5 mg 2# QID', '5 mg 1# QID'], ['2# BID']]
Drug_date_list = [] # [['2020/6/8-2020/6/10'], ['2020/6/12-2020/6/24', '2020/6/30-2020/7/4'], ['2020/6/12-2020/6/24']]
Drug_score_list = []

print('讀取import.csv...\n')
with open('./import.csv', encoding='utf-8') as f:
    lines = f.readlines()
    for l in lines:
        l = l.replace('\n','')
        name = l.split(',')[0]
        info = l.split(',')[1]
        date = l.split(',')[2]

        print('讀取藥物: %s, 劑量: %s, 服用期間: %s' % (name, info, date))

        if name in Drug_list:  # 若該藥物已出現過
            drug_index = Drug_list.index(name)
            Drug_info_list[drug_index].append(info)
            Drug_date_list[drug_index].append(date)
        else:
            Drug_list.append(name)
            Drug_info_list.append([info])
            Drug_date_list.append([date])
print('\n')

# ### 輸入不良反應發生日期及症狀緩解日

# In[2]:

Index_day = input('請輸入不良反應發生日期(index day): ')
Resolution_day = input('請輸入症狀緩解日: ')

# ### ALDEN score & naranjo score

# In[3]:

import datetime
from dateutil.relativedelta import relativedelta

def transform_time(date):
    return datetime.datetime.strptime(date, '%Y/%m/%d')

def difference_day(date1, date2):
    try: diff = int(str(date1 - date2).split(' ')[0])
    except: diff = 0
    return diff

def ask_YN(question):
    ans = input(question).upper()
    if ans == 'Y' or ans == 'N':
        pass
    else:
        print('輸入錯誤，請再試一次')
        ans = ask_YN(question)
    return ans

def ask_YNU(question):
    ans = input(question).upper()
    if ans == 'Y' or ans == 'N' or ans == 'U':
        pass
    else:
        print('輸入錯誤，請再試一次')
        ans = ask_YNU(question)
    return ans

def ask_number(question):
    ans = input(question)
    try: ans = float(ans)
    except:
        print('輸入錯誤，請再試一次')
        ans = ask_number(question)

    return ans

def ask_SaSiO(question):
    ans = input(question).upper()
    if ans == 'SA' or ans == 'SI' or ans == 'O':
        pass
    else:
        print('輸入錯誤，請再試一次')
        ans = ask_SaSiO(question)
    return ans

PLACEBO = ask_YN('是否有任何一個藥物給予安慰劑，以測試不良反應是否有發生? (Y/N) ')  # Q6
TDM = ask_YN('是否有任何一個藥物監測濃度，以測試是否超出治療區間? (Y/N) ')  # Q7
OBJ = ask_YNU('此項不良反應是否有客觀的證據證明是藥品引起的？("Y"es/ "N"o/ "U"nknown) ')  #Q10

def analysis(drug, date_lst):
    Alden_score = []
    Naranjo_score = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    start_day = transform_time(date_lst[0].split('-')[0])
    end_day = transform_time(date_lst[0].split('-')[1])
    rechallenge = len(date_lst)
    if rechallenge > 1:
        restart_day = transform_time(date_lst[1].split('-')[0])
        reend_day = transform_time(date_lst[1].split('-')[1])
    index_day = transform_time(Index_day)
    resolution_day = transform_time(Resolution_day)
    s_to_idx_day = difference_day(index_day, start_day) # index day - start_day的天數
    e_to_res_day = difference_day(resolution_day, end_day)
    idx_to_e_day = difference_day(end_day, index_day)

    print('----------------------')
    print('目前評分藥物: %s, 使用日期: %s, 不良反應發生日期: %s, 症狀緩解日期: %s' % (drug, ', '.join(date_lst), Index_day, Resolution_day))

#     先評估Naranjo score

#     Nq1在C5

#     Nq2在C1
    if rechallenge == 1:
        if e_to_res_day > 0: Naranjo_score[2] = (1, 'Y')
        else:
            Nq3 = ask_YNU('　當停藥或服用此藥之解藥，不良反應是否減輕？("Y"es/ "N"o/ "U"nknown) ')
            if Nq3 == 'Y': Naranjo_score[2] = (1, 'Y')
            elif Nq3 == 'N': Naranjo_score[2] = (0, 'N')
            elif Nq3 == 'U': Naranjo_score[2] = (0, 'U')
    else:
        Nq3 = ask_YNU('　當停藥或服用此藥之解藥，不良反應是否減輕？("Y"es/ "N"o/ "U"nknown) ')
        if Nq3 == 'Y': Naranjo_score[2] = (1, 'Y')
        elif Nq3 == 'N': Naranjo_score[2] = (0, 'N')
        elif Nq3 == 'U': Naranjo_score[2] = (0, 'U')

    if rechallenge == 1: Naranjo_score[3] = (0, 'U')
    else:
        Nq4 = ask_YNU('　停藥一段時間再重新服用此藥，同樣的不良反應是否再度發生？ ("Y"es/ "N"o/ "U"nknown) ')
        if Nq4 == 'Y': Naranjo_score[3] = (2, 'Y')
        elif Nq4 == 'N': Naranjo_score[3] = (-1, 'N')
        elif Nq4 == 'U': Naranjo_score[3] = (0, 'U')

#     Nq5後面再評分

    if PLACEBO == 'Y':
        Nq6 = ask_YNU('　當給予安慰劑時，此項不良反應是否會再度發生？ ("Y"es/ "N"o/ "U"nknown) ')
        if Nq6 == 'Y': Naranjo_score[5] = (-1, 'Y')
        elif Nq6 == 'N': Naranjo_score[5] = (1, 'N')
        elif Nq6 == 'U': Naranjo_score[5] = (0, 'U')
    elif PLACEBO == 'N':
        Naranjo_score[5] = (0, 'U')

    if TDM == 'Y':
        Nq7 = ask_YNU('　此藥物的血中濃度是否達到中毒劑量？ ("Y"es/ "N"o/ "U"nknown) ')
        if Nq7 == 'Y': Naranjo_score[6] = (1, 'Y')
        elif Nq7 == 'N': Naranjo_score[6] = (0, 'N')
        elif Nq7 == 'U': Naranjo_score[6] = (0, 'U')
    elif TDM == 'N':
        Naranjo_score[6] = (0, 'U')

    if rechallenge == 1:
        Naranjo_score[7] = (0, 'U')
    else:
        Nq8 = ask_YNU('　對此病人而言，藥物劑量與不良反應的程度是否成正向關係？("Y"es/ "N"o/ "U"nknown) ')
        if Nq8 == 'Y': Naranjo_score[7] = (1, 'Y')
        elif Nq8 == 'N': Naranjo_score[7] = (0, 'N')
        elif Nq8 == 'U': Naranjo_score[7] = (0, 'U')

#   Nq9在C3

    if OBJ == 'Y': Naranjo_score[9] = (1, 'Y')
    elif OBJ == 'N': Naranjo_score[9] = (0, 'N')
    elif OBJ == 'U': Naranjo_score[9] = (0, 'U')

#   Criterion 1: Delay from initial drug component intake to onset of reaction (index day)

    if s_to_idx_day <= 28 and s_to_idx_day >= 5:
#       * Suggestive +3 (From 5 to 28 days)
        Alden_score.append(3)
        Naranjo_score[1] = (2, 'Y')

    elif s_to_idx_day <= 56 and s_to_idx_day >= 29:
#       * Compatible +2 (From 29 to 56 days)
        Alden_score.append(2)
        Naranjo_score[1] = (2, 'Y')

    elif s_to_idx_day <= 4 and s_to_idx_day >= 1:
#       * Likely +1 (From 1 to 4 days)
        Alden_score.append(1)
        Naranjo_score[1] = (2, 'Y')

    elif s_to_idx_day > 56:
#       * Unlikely −1 (>56 Days)
        Alden_score.append(-1)
        Naranjo_score[1] = (2, 'Y')

    else:
#       * Excluded −3 (Drug started on or after the index day)
        Alden_score.append(-3)
        Naranjo_score[1] = (-1, 'N')

#   Criterion 2: Drug present in the body on index day
    On_index_day = False
    if end_day == index_day or idx_to_e_day >= 0:
#       Index day 仍然服用藥物
        On_index_day = True

    if On_index_day == False:
        halflife = ask_number('　Index day 時無服用藥物, 請輸入藥物半衰期(hr): ')
        x5_halflife = halflife * 5 / 24
        End_day_plus_halflife = (end_day + datetime.timedelta(days=x5_halflife)).strftime("%Y/%m/%d")
        print('　%s 經過5倍半衰期後: %s ' % (end_day.strftime("%Y/%m/%d"), End_day_plus_halflife))
        end_day_plus_halflife = transform_time(End_day_plus_halflife)

        if end_day_plus_halflife == index_day or difference_day(end_day_plus_halflife, index_day) > 0:
            print('　Index day 時體內仍有藥物殘量 ')
            On_index_day = True

        else:
            function = ask_YN('　請輸入病人肝腎功能是否異常、或是懷疑有交互作用，導致index day時仍有藥物累積在體內(Y/N): ')
            if function == 'Y':
#              體內懷疑有藥物殘留
#              * Doubtful −1 (Drug stopped at a time point prior to the index day by more than five times the elimination half-life but liver or kidney function alterations or suspected drug interactions are present)')
                Alden_score.append(-1)
            elif function == "N":
#              體內應無藥物殘留，且代謝功能正常
#              * Excluded −3 (Drug stopped at a time point prior to the index day by more than five times the elimination half-life, without liver or kidney function alterations or suspected drug interactions)')
                Alden_score.append(-3)
    if On_index_day == True:
#       * Definite 0 (Drug stopped at a time point prior to the index day by more than five times the elimination half-life but liver or kidney function alterations or suspected drug interactions are present')
        Alden_score.append(0)

#   Criterion 3: Prechallenge/ rechallenge
    used = ask_YNU('　過去是否有服用過該藥物 ("Y"es/ "N"o/ "U"nknown) ')
    if used == 'U' or used == 'N':
#       Other reaction after use of similar drug: 0 (No known previous exposure to this drug)
        Alden_score.append(0)

    elif used == 'Y':
        his = ask_YN('　過去服用類似藥物時是否有造成傷害 (Y/N) ')

        if his == 'N':
#           * Negative −2 (Exposure to this drug without any reaction (before or after reaction)
            Alden_score.append(-2)
            Naranjo_score[8] = (0, 'N')

        elif his == 'Y':
            challenge = ask_SaSiO('　是否有因服用同樣藥物／類似藥物產生SJS/TEN，或是產生了其他副作用 ("Sa"me, "Si"miliar, "O"ther) ')
            if challenge == "Sa":
#               * Positive specific for disease and drug: 4 (SJS/TEN after use of same drug)
                Alden_score.append(4)
                Naranjo_score[8] = (1, 'Y')
            elif challenge == "Si":
#               * Positive specific for disease or drug: 2 (SJS/TEN after use of similar drug or other reaction with same drug)
                Alden_score.append(2)
                Naranjo_score[8] = (1, 'Y')
            elif challenge == 'O':
#               * Positive unspecific: 1　(Other reaction after use of similar drug)
                Alden_score.append(1)
                Naranjo_score[8] = (1, 'Y')
    if Naranjo_score[8] == 0: Naranjo_score[8] = (0, 'U')

#   Criterion 4: Dechallenge'
    if rechallenge == 1:
        if resolution_day == end_day or e_to_res_day < 0 : Alden_score.append(-2)
#       * Negative -2 (Drug continued without harm)
        else: Alden_score.append(0)
#       * Neutral 0 (Drug stopped (or unknown))
    else:
        if resolution_day == reend_day or resolution_day == end_day or difference_day(resolution_day, reend_day) < 0 :
    #       緩解後仍然服用藥物
    #       * Negative -2 (Drug continued without harm)')
            Alden_score.append(-2)
        else:
    #       * Neutral 0 (Drug stopped (or unknown))
            Alden_score.append(0)

#    Criterion 5: Type of drug (notoriety)
    strongly_associated = ['TMP-SMX', 'allopurinol', 'lamotrigine', 'sulfamethoxazole','carbamazepine','phenytoin','nevirapine','sulfasalazine','sulfonamides','piroxicam','tenoxicam','phenobarbital','etoricoxib']
    associated = ['diclofenac','doxycycline','amoxicillin','ampicillin','ciprofloxacin','levofloxacin','amifostine','oxcarbazepine','rifampin','rifampicin']
    suspected = ['pantoprazole','glucocorticoids','omeprazole','tetrazepam','dipyrone','metamizole','terbinafine','levetiracetam']
    if drug in strongly_associated:
#       Strongly associated +3 (Drug of the “high-risk” list according to previous case–control studies)
        Naranjo_score[0] = (1, 'Y')
        Alden_score.append(3)
    elif drug in associated:
#       Associated +2 (Drug with definite but lower risk according to previous case–control studies)
        Naranjo_score[0] = (1, 'Y')
        Alden_score.append(2)
    elif drug in suspected:
#       Suspected +1 (Several previous reports, ambiguous epidemiology results (drug under surveillance))
        Naranjo_score[0] = (1, 'Y')
        Alden_score.append(1)

    else:
        ask = ask_YNU('　過去是否有文獻指出%s會造成SJS/TEN? ("Y"es/ "N"o/ "U"nknown) ' % drug)
        if ask == 'Y':
#           Suspected +1 (Several previous reports, ambiguous epidemiology results (drug under surveillance))
            Naranjo_score[0] = (1, 'Y')
            Alden_score.append(1)
        if ask == 'U':
#           Unknown 0 (All other drugs including newly released ones))
            Naranjo_score[0] = (0, 'U')
            Alden_score.append(0)
        elif ask == 'N':
#           Not suspected −1 (No evidence of association from previous epidemiology studyd with sufficient number of exposed controlsc)
            Naranjo_score[0] = (0, 'N')
            Alden_score.append(-1)

    return [Alden_score, Naranjo_score]

for drug_idx in range(len(Drug_list)):
    Drug_score_list.append(analysis(Drug_list[drug_idx], Drug_date_list[drug_idx]))
print('輸入完畢\n')

# In[4]:

# 計算每一個的temp score

Sum_scores_ALDEN =[]
for ALD,NAR in Drug_score_list:
    temp_sum = 0
    for score in ALD:
        temp_sum += score
    Sum_scores_ALDEN.append(temp_sum)

idx = 0
for s in Sum_scores_ALDEN:
    temp_Sum_scores = []
    temp_Sum_scores.extend(Sum_scores_ALDEN)
    del temp_Sum_scores[idx]
    POSSIBLE_DRUG = False
    for ts in temp_Sum_scores:
        if ts > 3: POSSIBLE_DRUG = True
    if POSSIBLE_DRUG == True:
        Drug_score_list[idx][0].append(-1)
        Drug_score_list[idx][1][4] = (-1,'Y')
    else:
        Drug_score_list[idx][0].append(0)
        Drug_score_list[idx][1][4] = (2, 'N')
    idx += 1
input('預估分數...\n')

# In[8]:

def read_score(input_score, drug, date_lst):
    Alden_score = input_score[0]
    Naranjo_score = input_score[1]
    Start_day = date_lst[0].split('-')[0]
    start_day = transform_time(date_lst[0].split('-')[0])
    end_day = transform_time(date_lst[0].split('-')[1])
    rechallenge = len(date_lst)
    if rechallenge > 1:
        restart_day = transform_time(date_lst[1].split('-')[0])
        reend_day = transform_time(date_lst[1].split('-')[1])
    index_day = transform_time(Index_day)
    resolution_day = transform_time(Resolution_day)
    s_to_idx_day = difference_day(index_day, start_day) # index day - start_day的天數
    e_to_res_day = difference_day(resolution_day, end_day)
    idx_to_e_day = difference_day(end_day, index_day)

    print('\n[%s] Criterion 1: Delay from initial drug component intake to onset of reaction (index day)' % Alden_score[0])
    if Alden_score[0] == 3:
        print('　* Suggestive +3 (From 5 to 28 days)\n　initial day: %s, index day: %s, 相差%s天' % (Start_day, Index_day, s_to_idx_day))
    elif Alden_score[0] == 2:
        print('　* Compatible +2 (From 29 to 56 days)\n　initial day: %s, index day: %s, 相差%s天' % (Start_day, Index_day, s_to_idx_day))
    elif Alden_score[0] == 1:
        print('　* Likely +1 (From 1 to 4 days)\n　initial day: %s, index day: %s, 相差%s天' % (Start_day, Index_day, s_to_idx_day))
    elif Alden_score[0] == -1:
        print('　* Unlikely −1 (>56 Days)\n　initial day: %s, index day: %s, 相差%s天' % (Start_day, Index_day, s_to_idx_day))
    elif Alden_score[0] == -3:
        print('　* Excluded −3 (Drug started on or after the index day)\n　initial day: %s, index day: %s, 相差%s天' % (Start_day, Index_day, s_to_idx_day))

    print('[%s] Criterion 2: Drug present in the body on index day' % Alden_score[1])
    if Alden_score[1] == 0:
        print('　* Definite 0 (Drug continued up to index day or stopped at a time point less than five times the elimination half-life before the index day)')
        print('　最後服用藥物日: %s, index day: %s' % (end_day.strftime("%Y/%m/%d"), Index_day))
    elif Alden_score[1] == -1:
        print('　* Doubtful −1 (Drug stopped at a time point prior to the index day by more than five times the elimination half-life but liver or kidney function alterations or suspected drug interactions are present)')
        print('　體內懷疑有藥物殘留(超過五個半衰期，但肝腎功能不良))')
    elif Alden_score[1] == -3:
        print('　* Excluded −3 (Drug stopped at a time point prior to the index day by more than five times the elimination half-life, without liver or kidney function alterations or suspected drug interactions)')
        print('　體內應無藥物殘留(超過五個半衰期)，且代謝功能正常')

    print('[%s] Criterion 3: Prechallenge/ rechallenge' % Alden_score[2])
    if Alden_score[2] == 4:
        print('　* Positive specific for disease and drug +4 (SJS/TEN after use of same drug)')
    elif Alden_score[2] == 2:
        print('　* Positive specific for disease or drug +2 (SJS/TEN after use of similar drug or other reaction with same drug)')
    elif Alden_score[2] == 1:
        print('　* Positive unspecific +1　(Other reaction after use of similar drug)')
    elif Alden_score[2] == 0:
        print('  * Other reaction after use of similar drug 0 (No known previous exposure to this drug)')
    elif Alden_score[2] == -2:
        print('  * Negative −2 (Exposure to this drug without any reaction (before or after reaction)')

    print('[%s] Criterion 4: Dechallenge' % Alden_score[3])
    if Alden_score[3] == -2:
        print('　* Negative -2 (Drug continued without harm)')
        print('　緩解時仍然服用藥物')
    elif Alden_score[3] == 0:
        print('　* Neutral 0 (Drug stopped (or unknown))')
    if rechallenge == 1:    print('　最後服用藥物日: %s, 症狀緩解日: %s' % (end_day.strftime("%Y/%m/%d"), Resolution_day))
    else: print('服用藥物日期: %s, 症狀緩解日: %s' % (', '.join(date_lst), Resolution_day))

    print('[%s] Criterion 5: Type of drug (notoriety)' % Alden_score[4])
    if Alden_score[4] == 3:
        print('　* Strongly associated +3 (Drug of the “high-risk” list according to previous case–control studies)')
    elif  Alden_score[4] == 2:
        print('  * Associated +2 (Drug with definite but lower risk according to previous case–control studies)')
    elif Alden_score[4] == 1:
        print('  * Suspected +1 (Several previous reports, ambiguous epidemiology results (drug under surveillance))')
    elif Alden_score[4] == 0:
        print('  * Unknown 0 (All other drugs including newly released ones))')
    elif Alden_score[4] == -1:
        print('  * Not suspected −1 (No evidence of association from previous epidemiology studyd with sufficient number of exposed controlsc)')

    print('[%s] Criterion 6: Other cause' % Alden_score[5])
    if Alden_score[5] == 0:
        print('　No other possible drug')
    elif  Alden_score[5] == -1:
        print('  * Possible −1')

    sums_A = 0
    for s in Alden_score:
        sums_A += s
    print('\n')
    if sums_A >= 6: print('Alden_score總分: %s, very probable' % sums_A)
    elif sums_A >= 4: print('Alden_score總分: %s, probable' % sums_A)
    elif sums_A >= 2: print('Alden_score總分: %s, possible' % sums_A)
    elif sums_A >= 0: print('Alden_score總分: %s, unlikely' % sums_A)
    else: print('Alden_score總分: %s, very unlikely' % sums_A)

    sums_N = 0
    print('\n[%s] Are there previous conclusive reports of this reaction? %s' % (Naranjo_score[0][0], Naranjo_score[0][1]))
    print('[%s] Did the adverse event appear after the drug was given? %s' % (Naranjo_score[1][0], Naranjo_score[1][1]))
    print('[%s] Did the adverse reaction improve when the drug was discontinued or a specific antagonist was given? %s' % (Naranjo_score[2][0], Naranjo_score[2][1]))
    print('[%s] Did the adverse reaction reappear upon readministering the drug? %s' % (Naranjo_score[3][0], Naranjo_score[3][1]))
    print('[%s] Were there other possible causes for the reaction? %s' % (Naranjo_score[4][0], Naranjo_score[4][1]))
    print('[%s] Did the adverse reaction reappear upon administration of placebo? %s' % (Naranjo_score[5][0], Naranjo_score[5][1]))
    print('[%s] Was the drug detected in the blood or other fluids in toxic concentrations? %s' % (Naranjo_score[6][0], Naranjo_score[6][1]))
    print('[%s] Was the reaction worsened upon increasing the dose? Or, was the reaction lessened upon decreasing the dose? %s' % (Naranjo_score[7][0], Naranjo_score[7][1]))
    print('[%s] Did the patient have a similar reaction to the drug or a related agent in the past? %s' % (Naranjo_score[8][0], Naranjo_score[8][1]))
    print('[%s] Was the adverse event confirmed by any other objective evidence?) %s' % (Naranjo_score[9][0], Naranjo_score[9][1]))

    for i in range(10):
          sums_N += Naranjo_score[i][0]

    if sums_N >= 9: print('Naranjo score總分: %s, Definite' % sums_N)
    elif sums_N >= 5: print('Naranjo score總分: %s, Probable' % sums_N)
    elif sums_N >= 1: print('Naranjo score總分: %s, Possible' % sums_N)
    elif sums_N <= 0: print('Naranjo score總分: %s, Doubtful' % sums_N)

    return (sums_A, sums_N)

Sum_scores = []
for s in Drug_list:
    idx = Drug_list.index(s)
    print('--------------------------------------')
    print('目前評分藥物: %s, 使用日期: %s, 不良反應發生日期: %s' % (Drug_list[idx], ', '.join(Drug_date_list[idx]), Index_day))
    Sum_scores.append(read_score(Drug_score_list[idx], Drug_list[idx], Drug_date_list[idx]))
    print('--------------------------------------')
    input('完成度(%s / %s)' % (idx+1, len(Drug_list)))

# In[29]:

import pandas as pd

df_list = []
idx = 0
for i in range(len(Drug_list)):
    temp = []
    temp.append(Drug_list[i])
    temp.append(Sum_scores[i][0])
    temp.extend(Drug_score_list[i][0])
    temp.append(Sum_scores[i][1])
    temp.extend(Drug_score_list[i][1])
    df_list.append(temp)
Score_df = pd.DataFrame(df_list, columns = ["藥物名稱", "Alden_score總分", 'Criterion 1', 'Criterion 2', 'Criterion 3','Criterion 4','Criterion 5','Criterion 6', "Naranjo score總分",
                                       'Nar_Q1', 'Nar_Q2', 'Nar_Q3', 'Nar_Q4', 'Nar_Q5', 'Nar_Q6', 'Nar_Q7', 'Nar_Q8', 'Nar_Q9', 'Nar_Q10'])
Score_df.set_index("藥物名稱", inplace=True)
Score_df.sort_values('Alden_score總分', inplace=True, ascending=False )
Score_df.to_excel('./藥物分析結果.xls')
Score_df
input('儲存藥物分析結果至./藥物分析結果.xls...')

# In[30]:

import pandas as pd
import numpy as np
def date_range_to_lst(date):
    day_lst = []
    start_day = transform_time(date[0].split('-')[0])
    end_day = transform_time(date[0].split('-')[1])
    diff_day_counts = difference_day(end_day, start_day)
    for i in range(diff_day_counts+1):
        day_lst.append((start_day + datetime.timedelta(days=i)).strftime("%Y/%m/%d"))
    return day_lst

all_date_list = []

for dates in Drug_date_list:
    if len(dates) > 1:
        for d in dates:
            RESULT = date_range_to_lst([d])
    else:
        RESULT = date_range_to_lst(dates)
    for R in RESULT:
        if R not in all_date_list: all_date_list.append(R)

all_date_list = (pd.to_datetime(all_date_list).sort_values()).tolist()
all_date_list = str(all_date_list[0]).split(' 00:00:00')[0].replace('-','/') + '-' + str(all_date_list [-1]).split(' 00:00:00')[0].replace('-','/')
all_date_list = date_range_to_lst([all_date_list])
all_date_list = (pd.to_datetime(all_date_list).sort_values())

Empty_df = [[""] * len(all_date_list)] * len(Drug_list)

Date_df = pd.DataFrame(Empty_df, columns = all_date_list)
Date_df['藥物名稱'] = Drug_list
Date_df.set_index("藥物名稱", inplace=True)

for info in Drug_info_list:
    info_index = Drug_info_list.index(info)
    date_lst = Drug_date_list[info_index]
    drug = Drug_list[info_index]
    if len(info) > 1:
        for idx in range(len(date_lst)):
            date = pd.to_datetime(date_range_to_lst([date_lst[idx]]))
            Date_df.loc[drug, date] = info[idx]
    else:
        date = pd.to_datetime(date_range_to_lst(date_lst))
        Date_df.loc[drug, date] = info

t = []
for time in Date_df.columns.tolist():
    t.append(time.strftime('%Y/%m/%d'))

Date_df.columns = t
Date_df.to_excel('./使用藥物清單.xls')
Date_df
input('儲存藥物清單結果至./使用藥物清單.xls...')
input('執行完成。')


import simpy
import random
import unittest

try:
    from unittest import mock
except ImportError:
    import mock

from cloudscope.dynamo import CharacterSequence
from cloudscope.replica import Location, Device
from cloudscope.simulation.workload import MobileWorkload
from tests.test_simulation import get_mock_simulation, get_mock_replica
from cloudscope.exceptions import WorkloadException

##########################################################################
## Workload Tests
##########################################################################

class MobileWorkloadTests(unittest.TestCase):

    def setUp(self):
        """
        Rest the workload counter
        """
        MobileWorkload.counter.reset()

    def test_name(self):
        """
        Test the workload name (as a user)
        """
        sim  = get_mock_simulation()
        work = MobileWorkload(sim, objects=['A', 'B', 'C'])

        self.assertEqual(work.name, "user 1")

    def test_locations(self):
        """
        Test the workload extracting locations from simulation
        """
        sim = get_mock_simulation()

        sim.replicas = [
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE)
        ]

        work = MobileWorkload(sim, objects=['A', 'B', 'C'])
        self.assertEqual(len(work.locations), 3)

        for loc, num in ((Location.HOME, 2), (Location.WORK, 2), (Location.MOBILE, 3)):
            self.assertEqual(len(work.locations[loc]), num)

    def test_workload(self):
        """
        Test the workload generating work in simulation
        """

        sim = get_mock_simulation()
        sim.env = simpy.Environment()

        sim.replicas = [
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE)
        ]

        work = MobileWorkloadTests(
            sim, move_prob=1.0, switch_prob=1.0, read_prob=0.5,
            access_mean=20, access_stddev=4, objects=["A", "B", "C", "D", "E"]
        )

        env.run(until=1000)

        calls = sum(replica.write.call_count for replica in sim.replicas)
        calls += sum(replica.read.call_count for replica in sim.replicas)
        self.assertGreater(calls, 25)

    @unittest.skip("Belongs in the multi-workload generator")
    def test_objects_int(self):
        """
        Ensure multi-object workload can be initialized with int
        """
        sim  = get_mock_simulation()
        work = MobileWorkload(sim, objects=20)

        self.assertEqual(len(work.objects), 20)
        self.assertEqual(work.objects, tuple([
            char for char in CharacterSequence(limit="U", upper=True)
        ]))

    def test_objects_list(self):
        """
        Ensure multi-objects workload can be initialized with a list
        """
        sim  = get_mock_simulation()
        work = MobileWorkload(sim, objects=[
            "foo", "bar", "baz", "qux", "zoo",
        ])

        self.assertEqual(len(work.objects), 5)
        self.assertEqual(work.objects, [
            "foo", "bar", "baz", "qux", "zoo",
        ])

    def test_open_multi_object(self):
        """
        Test opening an multiple objects from a blank slate
        """
        sim = get_mock_simulation()

        sim.replicas = [
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE)
        ]

        work = MobileWorkload(sim, objects=["A", "B", "C", "D", "E"])
        self.assertEqual(len(work.objects), 5)
        self.assertEqual(work.objects, ["A", "B", "C", "D", "E"])

        self.assertIsNotNone(work.location)
        self.assertIsNotNone(work.device)
        self.assertIsNotNone(work.current)

        for idx in xrange(500):
            work.update()
            self.assertIsNotNone(work.current)
            self.assertEqual(len(work.objects), 5)
            self.assertLessEqual(len(filter(None, work.objects)), 5)

    def test_workload(self):
        """
        Test the multi-object workload generating work in simulation
        """

        sim = get_mock_simulation()
        sim.env = simpy.Environment()

        sim.replicas = [
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.HOME),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.WORK),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE),
            get_mock_replica(sim, location=Location.MOBILE)
        ]

        work = MobileWorkload(
            sim, move_prob=1.0, switch_prob=1.0, read_prob=0.5,
            access_mean=20, access_stddev=4, object_prob=0.5,
            objects=["A", "B", "C", "D", "E"]
        )

        sim.env.run(until=1000)

        calls = sum(replica.write.call_count for replica in sim.replicas)
        calls += sum(replica.read.call_count for replica in sim.replicas)
        self.assertGreater(calls, 25)


from typing import List

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        i = 0
        j = len(nums) - 1
        result = [0] * len(nums)

        while i <= j:
            if abs(nums[i]) > abs(nums[j]):
                result[j - i]  = nums[i] ** 2
                i += 1
            else:
                result[j - i]  = nums[j] ** 2
                j -= 1

        return result


from django.http import HttpResponseServerError
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import status
from ..models import DealershipEmployee

class DealershipEmployeeSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = DealershipEmployee
        url = serializers.HyperlinkedIdentityField(
            view_name='dealershipemployee',
            lookup_field='id'
        )
        fields = ('id', 'dealership_id', 'dealership', 'employee_id', 'employee')
        depth = 1

class DealershipEmployees(ViewSet):

    def create(self, request):

        new_dealership_employee = DealershipEmployee()

        new_dealership_employee.dealership_id = request.data["dealershipId"]
        new_dealership_employee.employee_id = request.data["employeeId"]

        # FOR POSTMAN TESTING
        # {
        #     "dealershipId": 1,
        #     "employeeId": 1,
        # }

        new_dealership_employee.save()

        serializer = DealershipEmployeeSerializer(
            new_dealership_employee, context={'request': request})

        return Response(serializer.data)

    def retrieve(self, request, pk=None):

        try:
            dealership_employee = DealershipEmployee.objects.get(pk=pk)

            serializer = DealershipEmployeeSerializer(
                dealership_employee, context={'request': request})

            return Response(serializer.data)

        except Exception as ex:
            return HttpResponseServerError(ex)

    def put(self, request, pk=None):
        """Handle PUT requests for an individual dealership employee
        Returns:
            Response -- Empty body with 204 status code
        """
        dealership_employee = DealershipEmployee.objects.get(pk=pk)

        dealership_employee.dealership_id = request.data["dealershipId"]
        dealership_employee.employee_id = request.data["employeeId"]

        dealership_employee.save()

        return Response({}, status=status.HTTP_204_NO_CONTENT)

    def destroy(self, request, pk=None):
        """Handle DELETE requests for a single dealership employee
        Returns:
            Response -- 200, 404, or 500 status code
        """
        try:
            dealership_employee = DealershipEmployee.objects.get(pk=pk)
            dealership_employee.delete()

            return Response({}, status=status.HTTP_204_NO_CONTENT)

        except dealership_employee.DoesNotExist as ex:
            return Response({'message': ex.args[0]}, status=status.HTTP_404_NOT_FOUND)

        except Exception as ex:
            return Response({'message': ex.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def list(self, request):

        dealership_employees = DealershipEmployee.objects.all()

        limit = self.request.query_params.get('limit')

        if limit is not None:
            dealership_employees = DealershipEmployee.objects.all()[:int(limit)]

        serializer = DealershipEmployeeSerializer(
            dealership_employees, many=True, context={'request': request})

        return Response(serializer.data)


import cv2

image = cv2.imread("number.png")
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,70,255,cv2.THRESH_BINARY_INV)
thresh1 = cv2.adaptiveThreshold(gray,255,1,1,11,2)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
dilated = cv2.dilate(thresh,kernel,iterations = 1)
_,contours, hierarchy = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

cv2.imshow("image",thresh)
cv2.imshow("img",thresh1)
cv2.imshow("dilate",dilated)
cv2.waitKey(0)


from __future__ import print_function

import sys
import math
import threading
import argparse
import time

from mpi4py import MPI

import torch
from torch.autograd import Variable
from torch import nn
import torch.nn.functional as F

from nn_ops import NN_Trainer, accuracy
from data_loader_ops.my_data_loader import DataLoader

from coding import search_w
from util import *

def add_fit_args(parser):
    """
    parser : argparse.ArgumentParser
    return a parser added with args required by fit
    """
    # Training settings
    parser.add_argument('--batch-size', type=int, default=128, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=100, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--max-steps', type=int, default=10000, metavar='N',
                        help='the maximum number of iterations')
    parser.add_argument('--epochs', type=int, default=100, metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--network', type=str, default='LeNet', metavar='N',
                        help='which kind of network we are going to use, support LeNet and ResNet currently')
    parser.add_argument('--mode', type=str, default='normal', metavar='N',
                        help='determine if we use normal averaged gradients or geometric median (in normal mode)\
                         or whether we use normal/majority vote in coded mode to udpate the model')
    parser.add_argument('--dataset', type=str, default='MNIST', metavar='N',
                        help='which dataset used in training, MNIST and Cifar10 supported currently')
    parser.add_argument('--comm-type', type=str, default='Bcast', metavar='N',
                        help='which kind of method we use during the mode fetching stage')
    parser.add_argument('--err-mode', type=str, default='rev_grad', metavar='N',
                        help='which type of byzantine err we are going to simulate rev_grad/constant/random are supported')
    parser.add_argument('--approach', type=str, default='maj_vote', metavar='N',
                        help='method used to achieve byzantine tolerence, currently majority vote is supported set to normal will return to normal mode')
    parser.add_argument('--num-aggregate', type=int, default=5, metavar='N',
                        help='how many number of gradients we wish to gather at each iteration')
    parser.add_argument('--eval-freq', type=int, default=50, metavar='N',
                        help='it determines per how many step the model should be evaluated')
    parser.add_argument('--train-dir', type=str, default='output/models/', metavar='N',
                        help='directory to save the temp model during the training process for evaluation')
    parser.add_argument('--adversarial', type=int, default=1, metavar='N',
                        help='how much adversary we want to add to a certain worker')
    parser.add_argument('--worker-fail', type=int, default=2, metavar='N',
                        help='how many number of worker nodes we want to simulate byzantine error on')
    parser.add_argument('--group-size', type=int, default=5, metavar='N',
                        help='in majority vote how many worker nodes are in a certain group')
    parser.add_argument('--compress-grad', type=str, default='compress', metavar='N',
                        help='compress/none indicate if we compress the gradient matrix before communication')
    parser.add_argument('--checkpoint-step', type=int, default=0, metavar='N',
                        help='which step to proceed the training process')
    args = parser.parse_args()
    return args

if __name__ == "__main__":
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    world_size = comm.Get_size()

    args = add_fit_args(argparse.ArgumentParser(description='Draco'))

    datum, kwargs_master, kwargs_worker = prepare(args, rank, world_size)
    if args.approach == "baseline":
        train_loader, _, test_loader = datum
        if rank == 0:
            master_fc_nn = baseline_master.SyncReplicasMaster_NN(comm=comm, **kwargs_master)
            master_fc_nn.build_model()
            print("I am the master: the world size is {}, cur step: {}".format(master_fc_nn.world_size, master_fc_nn.cur_step))
            master_fc_nn.start()
            print("Done sending messages to workers!")
        else:
            worker_fc_nn = baseline_worker.DistributedWorker(comm=comm, **kwargs_worker)
            worker_fc_nn.build_model()
            print("I am worker: {} in all {} workers, next step: {}".format(worker_fc_nn.rank, worker_fc_nn.world_size-1, worker_fc_nn.next_step))
            worker_fc_nn.train(train_loader=train_loader, test_loader=test_loader)
            print("Now the next step is: {}".format(worker_fc_nn.next_step))
    # majority vote
    elif args.approach == "maj_vote":
        train_loader, _, test_loader = datum
        if rank == 0:
            coded_master = rep_master.CodedMaster(comm=comm, **kwargs_master)
            coded_master.build_model()
            print("I am the master: the world size is {}, cur step: {}".format(coded_master.world_size, coded_master.cur_step))
            coded_master.start()
            print("Done sending messages to workers!")
        else:
            coded_worker = rep_worker.CodedWorker(comm=comm, **kwargs_worker)
            coded_worker.build_model()
            print("I am worker: {} in all {} workers, next step: {}".format(coded_worker.rank, coded_worker.world_size-1, coded_worker.next_step))
            coded_worker.train(train_loader=train_loader, test_loader=test_loader)
            print("Now the next step is: {}".format(coded_worker.next_step))
    # cyclic code
    elif args.approach == "cyclic":
        W, fake_W, W_perp, S, C_1 = search_w(world_size-1, args.worker_fail)
        # for debug print
        #np.set_printoptions(precision=4,linewidth=200.0)
        _, training_set, test_loader = datum
        if rank == 0:
            cyclic_master = cyclic_master.CyclicMaster(comm=comm, **kwargs_master)
            cyclic_master.build_model()
            print("I am the master: the world size is {}, cur step: {}".format(cyclic_master.world_size, cyclic_master.cur_step))
            cyclic_master.start()
            print("Done sending messages to workers!")
        else:
            cyclic_worker = cyclic_worker.CyclicWorker(comm=comm, **kwargs_worker)
            cyclic_worker.build_model()
            print("I am worker: {} in all {} workers, next step: {}".format(cyclic_worker.rank, cyclic_worker.world_size-1, cyclic_worker.next_step))
            cyclic_worker.train(training_set=training_set, test_loader=test_loader)
            print("Now the next step is: {}".format(cyclic_worker.next_step))


from pathlib import Path
from keras.utils import data_utils

def maybe_download_vgg16_pretrained_weights(weights_file: Path):
    if not weights_file.is_file():
        print(f"Pretrained VGG16 weigths not found, downloading now to: {weights_file}")
        weights_file.parent.mkdir(parents=True, exist_ok=True)
        data_utils.get_file(
            "vgg16_weights_tf_dim_ordering_tf_kernels.h5",
            (
                "https://storage.googleapis.com/tensorflow/keras-applications/"
                "vgg16/vgg16_weights_tf_dim_ordering_tf_kernels.h5"
            ),
            cache_subdir=str(weights_file.parent.absolute()),
            file_hash="64373286793e3c8b2b4e3219cbf3544b",
        )


from django.urls import path

from api_server.apps.custom_accounts import views
from api_server.apps.custom_accounts.apps import CustomAccountsConfig

app_name = CustomAccountsConfig.name

urlpatterns = [
    path('set-csrf/', views.SetCsrf.as_view(), name='set-csrf'),
    path('hello/', views.HelloView.as_view(), name='hello'),
    path('login/', views.Login.as_view(), name='login'),
    path('logout/', views.Logout.as_view(), name='logout'),
    path('current/', views.UserViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
    }), name='current'),
]


import datetime
from movie import Movie
from projection import Projection
from reservation import Reservation
from sqlalchemy import func
import ast

class Cinema():

    def __init__(self, session):
        self.__session = session

    def movie_details(self):
        name = input("Enter the name of the movie: ")
        rating = input("Enter the rating of the movie: ")
        movie = (name, rating)
        return movie

    def add_movie(self):
        self.movie_tuple = self.movie_details()
        movie = Movie(name=self.movie_tuple[0], rating=self.movie_tuple[1])
        self.__session.add(movie)
        self.__session.commit()

    def show_movies(self):
        all_movies = self.__session.query(Movie).all()
        for movie in all_movies:
            print(movie)

    def obtain_date(self):
        isValid = False
        while not isValid:
            date = input("Enter the date of the projection (yyyy-mm-dd): ")
            try:
                d = datetime.datetime.strptime(date, "%Y-%m-%d")
                isValid = True
            except:
                print("Enter a valid date.")
            date_to_string = str(d).split()[0]
        return date_to_string

    def obtain_time(self):
        isValid = False
        while not isValid:
            time = input("Enter the time of the projection (hh:mm): ")
            try:
                t = datetime.datetime.strptime(time, "%H:%M")
                isValid = True
            except:
                print("Enter a valid time.")
        time_to_string = str(t).split()[1]
        return time_to_string

    def add_projection(self):
        movie_id = input("Type the movie_id: ")
        movie_name = self.get_movie_title_by_id(movie_id)
        print("Adding projection for " + movie_name)
        type = input("Enter the type of the projection: ")
        date = self.obtain_date()
        time = self.obtain_time()
        projection = Projection(type=type, date=date, time=time, movie_id=movie_id)
        self.__session.add(projection)
        self.__session.commit()

    def get_movie_title_by_id(self, movie_id):
        movie = self.__session.query(Movie).filter(
            Movie.id == movie_id).one()
        return movie.name

    def get_projections_for_a_movie(self, movie_id):
        projections = self.__session.query(
            Projection).filter(Projection.movie_id == movie_id).group_by(
            Projection.date).all()
        for projection in projections:
            print(projection)

    def show_projections_available_spots(self, movie_id):
        movie_name = self.get_movie_title_by_id(movie_id)
        print("Showing projections for " + movie_name)
        projections = self.__session.query(
            Projection).filter(Projection.movie_id == movie_id).all()
        for projection in projections:
            print(projection, ' - ', str(self.available_seats(projection.id)), "available seats")

    def available_seats(self, projection_id):
        seats = 100
        self.occupied_seats = self.__session.query(
            func.count(Reservation.id)).filter(
            Reservation.projection_id == projection_id).all()[0][0]
        self.free_seats = seats - self.occupied_seats
        return self.free_seats

    def print_seats(self):
        self.seats[0][0] = ' '
        for k in range(1, 11):
            self.seats[0][k] = str(k) + " "
        for k in range(1, 11):
            self.seats[k][0] = str(k) + " "
            if k == 10:
                self.seats[k][0] = str(k)
        for i in range(11):
            print(" ".join(str(x) for x in self.seats[i]))

    def check_seats_for_out_of_index(self, seats):
        seat = ast.literal_eval(seats)
        if seat[0] > 10 or seat[0] < 0 or seat[1] > 10 or seat[1] < 0:
            print("There is no such seat in our hall!")
            return False
        else:
            return True

    def show_seats(self, projection_id):
        seats = self.__session.query(
            Reservation.col, Reservation.row).filter(
            Reservation.projection_id == projection_id).all()
        self.seats = [[". " for x in range(11)] for x in range(11)]
        self.all_seats = []
        for seat in seats:
            self.seats[seat[0]][seat[1]] = 'X '
            self.free_seats -= 1
        self.print_seats()

    def check_seats_if_available(self, seats):
        place = ast.literal_eval(seats)
        if self.check_seats_for_out_of_index(seats) is True:
            if self.seats[place[0]][place[1]] == 'X ':
                print("This seat is taken!")
                return False
        else:
            return True

    def take_seats(self, seats, projection_id):
        place = ast.literal_eval(seats)
        if self.seats[place[0]][place[1]] == ". ":
            self.seats[place[0]][place[1]] = "X "
            self.free_seats -= 1
            self.all_seats.append(place)

    def make_reservation(self, username, projection_id, seats):
        seat = ast.literal_eval(seats)
        reservation = Reservation(
            username=username, row=seat[0],
            col=seat[1], projection_id=projection_id)
        self.__session.add(reservation)
        self.__session.commit()

    def cancel_reservation(self, username):
        self.__session.query(Reservation).filter(
            Reservation.username == username).delete()
        self.__session.commit()

    def print_reservation(self, movie_id, projection_id):
        print("This is your reservation: ")
        print("Movie")
        movie = self.__session.query(
            Movie).filter(
            Movie.id == movie_id).one()
        print(movie)
        print("Date and Time: ")
        projection = self.__session.query(
            Projection).filter(
            Projection.id == projection_id).one()
        print(projection)
        seats = " "
        for seat in self.all_seats:
            seats += str(seat)
        print("Seats: " + seats)


#A ideia do programa é simular um programa de arduino que seja capaz de obter dados de sensores diversos e ligar/ desligar equipamentos de uma estufa de cultivo de plantas.
# Serão analisados temperatura do ar, umidade dos vasos e luminosidade do dia
# Ventiladores serão ligados ou desligados de acordo com a temperatura
# Luzes serão ligadas ou desligadas em dias nublados (abaixo da luminosidade ideal)
#Irrigação será ligada no nível mínimo, desligada no nível máximo, e ligada novamente apenas quando atingir o mínimo para evitar que as plantas fiquem submersas (não implementado ainda da forma correta)
# prints em caps lock são para indicar comandos ao hardware (liga, desliga) já que não é possível fazê-lo pelo python sem conectar a um hardware externo com um arduino por enquanto q
# leituras do sensor por enquanto colocadas no próprio script ou via comando sys para facilitar testes
#
# biblioteca para importar hora atual e adicioná-la ao registro

#void() # simulação da primeira parte do script do arduino
from datetime import datetime
now = datetime.now() #objeto para guardar data e hora atual para o log
date = now.strftime("%m/%d/%Y, %H:%M:%S")

temp_max = 32 #max temp celsius aceitável
temp_min = 22 #min temp celsius de início dos fans

h2o_min = 45 # min teor água vaso aceitável (% Cap. Campo)
h2o_max = 90 #(capacidade de campo)

lux_min = 10000 # Luminosidade (em lux) mínima aceitável

log_dict = {} # dicionário para registro de eventos (luz baixa, temp alta e início das irrigações)
#variáveis obtidas pelo sensor

temp = 33 #temp coletada pelo sensor
h2o = 30 # % h2o coletada pelo sensor
lux = 5000 #luminosidade coletada pelo sensor

#ou

#para checar mais rápido
# import sys
# print(sys.argv)
# temp = float(sys.argv[1])
# h2o = float(sys.argv[2])
# lux = float(sys.argv[3])

def loop(): #função que roda indefinidamente dentro do programa simulado de arduino
    def temperature():
        #função de ajuste da temperatura de acordo com leitura realizada
        # aciona 1o fan a partir de 22 graus
        #aciona 2o fan a partir de 28 graus
        # aciona 3o fan a partir de 32 graus, e adiciona ao registro log a data e a temperatura observada
        if temp >= temp_min:
            print("FAN 1 LIGADO")
            if temp >= 28:
                print("FAN 2 LIGADO")
                if temp >= temp_max:
                    print("FAN 3 LIGADO. \nObservação de Alta Temperatura Adicionada ao registro.")
                    log_dict["Data Temperatura Alta"] = date
        else:
            print("Temperatura ok")
            print("FANS DESLIGADOS")

    def lum(): #falta adicionar componente para evitar que a luz fique ligada por conta de ser noite
        #garante suplementação luminosa em dias de baixa luminosidade
        #adiciona ao registro dia que ocorreu dia nublado
        if lux < lux_min:
            print("Luz muito baixa. Adicionando ao registro.\nSUPLEMENTAÇÂO LUMINOSA LIGADA")
            log_dict["Data dia Nublado"] = date
        else:
            print("Luminosidade ok")
            print("LUZES DESLIGADAS")

    def irriga():
        # a ideia é que o sistema irrigue quando chegue no nível mínimo, e continua irrigando até o nível máximo, então desliga até chegar no nível mínimo, e ligue apenas quando atingir o nível mínimo novamente, para que a planta não fique submersa o tempo inteiro.
        #registra no log quando chegou no nível mínimo
        if h2o < h2o_min:
            print("Irrigação abaixo do mínimo. Ligando irrigação e Adicionando evento ao registro")
            print("IRRIGAÇÂO LIGADA")
            log_dict["Data Irrigação"] = date
        elif h2o >= h2o_min and h2o < h2o_max:
            print("Umidade ok")
        elif h2o >= h2o_max:
            print("Umidade na capacidade máxima")
            print("IRRIGAÇÂO DESLIGADA")

    # roda as funções definidas dentro do loop
    temperature()
    lum()
    irriga()
    print("Registro:", log_dict)

#roda o loop infinitamente
loop()


import flask
import flask_uploads

def make_app() -> tuple[flask.Flask, flask.cli.FlaskGroup]:
    app = flask.Flask(__name__)
    app.config.from_object("config.AppConfig")
    configure_db(app)
    configure_uploads(app)
    register_blueprints(app)
    register_error_handlers(app)
    configure_logging(app)
    cli = flask.cli.FlaskGroup(app)  # type: ignore
    return app, cli

def configure_uploads(app: flask.Flask) -> None:
    import admin.constants

    upload_sets = [
        admin.constants.UPLOAD_PHOTO_SET,
    ]
    flask_uploads.configure_uploads(app, upload_sets)

def configure_db(app: flask.Flask) -> None:
    import store.models

    store.models.db.init_app(app)

    with app.app_context():
        if store.models.db.engine.url.drivername == "sqlite":
            store.models.migrate.init_app(
                app, store.models.db, render_as_batch=True
            )
        else:
            store.models.migrate.init_app(app, store.models.db)

def register_blueprints(app: flask.Flask) -> None:
    from admin import admin_blueprint
    from store import store_blueprint

    app.register_blueprint(admin_blueprint)
    app.register_blueprint(store_blueprint)

def register_error_handlers(app: flask.Flask) -> None:
    pass

def configure_logging(app: flask.Flask) -> None:
    pass

app, cli = make_app()

if __name__ == "__main__":
    cli()


from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget
from enum import Enum
from src import config
from src.handlers import file_handler, command_handler
from src.widgets.ConsoleLineEdit import ConsoleLineEdit

class TraverseDirType(Enum):
    UP = "up"
    DOWN = "down"

class LoggingType(Enum):
    INPUT = "input"
    RESPONSE = "response"

def logging_add(text, logging_type):
    if logging_type is LoggingType.INPUT and config.CONSOLE_LOGGING is False:
        return
    elif logging_type is LoggingType.RESPONSE and config.CONSOLE_RESPONSE_LOGGING is False:
        return

    file_handler.append_file(config.CONSOLE_LOG_FILE_PATH, text)

class ConsoleWidget(QWidget):
    command_history = []
    history_index = 0

    def __init__(self, parent=None):
        super(ConsoleWidget, self).__init__(parent)

        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.setContentsMargins(3, 3, 3, 3)
        self.layout.setSpacing(3)
        self.setLayout(self.layout)

        # Output text edit
        self.output_text_edit = QtWidgets.QTextEdit(self)
        self.output_text_edit.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.output_text_edit.setReadOnly(True)
        self.layout.addWidget(self.output_text_edit)

        # Interaction area layout
        self.interaction_layout = QtWidgets.QHBoxLayout()
        self.interaction_layout.setSpacing(3)
        self.layout.addLayout(self.interaction_layout)

        # Input line edit
        self.input_line_edit = ConsoleLineEdit(self)
        self.input_line_edit.setFrame(False)
        self.input_line_edit.returnPressed.connect(self.send_command)
        self.input_line_edit.traverseUpPressed.connect(lambda: self.history_traverse(TraverseDirType.UP))
        self.input_line_edit.traverseDownPressed.connect(lambda: self.history_traverse(TraverseDirType.DOWN))
        self.interaction_layout.addWidget(self.input_line_edit)

        # Input send button
        self.send_button = QtWidgets.QPushButton(self)
        self.send_button.setText("Send")
        self.send_button.clicked.connect(self.send_command)
        self.interaction_layout.addWidget(self.send_button)

    def send_command(self):
        input = self.input_line_edit.text()

        if not input:
            return

        self.history_add(input)
        logging_add(input, LoggingType.INPUT)

        self.input_line_edit.clear()
        self.output_text_edit.append(config.CONSOLE_PREFIX + input)

        response = command_handler.manufacture(input)

        if response != "":
            self.output_text_edit.append(response + "\n")
            logging_add(response + "\n", LoggingType.RESPONSE)

    def history_add(self, command):
        self.command_history.append(command)

        if len(self.command_history) > config.CONSOLE_HISTORY_LEN:
            self.command_history.pop(0)

        self.history_index = len(self.command_history)

        print(f'Console history: {self.command_history}')

    def history_traverse(self, traverse_dir):
        if self.command_history:
            if traverse_dir == TraverseDirType.UP and self.history_index > 0:
                self.history_index -= 1
            elif traverse_dir == TraverseDirType.DOWN and self.history_index < len(self.command_history):
                self.history_index += 1

            if self.history_index < len(self.command_history):
                self.input_line_edit.setText(self.command_history[self.history_index])
            elif self.history_index == len(self.command_history):
                self.input_line_edit.clear()


from typing import List
from uuid import UUID

from app.database import db
from app.models.transaction import Transaction, TransactionCreate, TransactionUpdate

class TransactionDAO:
    """DAO for Transaction model, this class implements the interface with firestore db"""
    collection_name = 'transactions'

    def __init__(self, parent=None):
        self.collection_ref = db.collection(self.collection_name)

    def create(self, transaction_create: TransactionCreate) -> Transaction:
        data = transaction_create.dict()
        data['id'] = str(data['id'])
        doc_ref = self.collection_ref.document(str(transaction_create.id))
        doc_ref.set(data)
        return self.get(transaction_create.id)

    def get(self, id: UUID) -> Transaction:
        doc_ref = self.collection_ref.document(str(id))
        doc = doc_ref.get()

        if doc.exists:
            return Transaction(**doc.to_dict())

        return None

    def get_by_account_id(self, account_id: str, parent: str = None) -> List[Transaction]:
        coll_ref = self.collection_ref
        if parent:
            coll_ref = db.collection(parent + '/' + self.collection_name)

        transactions = coll_ref.where('account_id', '==', account_id).stream()
        return [Transaction(**doc.to_dict()) for doc in transactions if doc.to_dict()]

    def list(self) -> List[Transaction]:
        todos_ref = self.collection_ref
        return [Transaction(**doc.get().to_dict()) for doc in todos_ref.list_documents() if doc.get().to_dict()]

    def update(self, id: UUID, transaction_update: TransactionUpdate) -> Transaction:
        data = transaction_update.dict()
        doc_ref = self.collection_ref.document(str(id))
        doc_ref.update(data)
        return self.get(id)

    def delete(self, id: UUID) -> None:
        self.collection_ref.document(str(id)).delete()