""""

"""

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

# from iso_Storages import Storage
import math

class linear_connection(object):
    """
    Description
    ===========
    Creates the flux connection [advective and diffusive] in both phases between the isotope storages.

    """

    def __init__(self,
                 storage1,  # Instance of iso-storage
                 storage2,  # Instance of iso-storage
                 ql,
                 qv,
                 Isotopologue,
                 time_steps
                 ):

        self.Isotopologue = Isotopologue
        self.q_l = ql
        self.q_v = qv
        self.storage1 = storage1
        self.storage2 = storage2
        self.__time_steps = time_steps

        self.liquid_advection = liquid_advection(self.q_l, self.storage1)
        self.liquid_diffusion = liquid_diffusion(self.storage1)
        self.vapor_advection = vapor_advection(self.q_v, self.storage1)
        self.vapor_diffusion = vapor_diffusion(self.storage1)

    def run(self):

        c1 = []  # liquid isotope concentration for storage1
        c2 = []  # liquid isotope concentration for storage2

        v1 = []
        v2 = []

        c1.append(self.storage1.get_conc_iso_liquid(self.Isotopologue))
        c2.append(self.storage2.get_conc_iso_liquid(self.Isotopologue))
        v1.append(self.storage1.get_conc_iso_vapor(self.Isotopologue))
        v2.append(self.storage2.get_conc_iso_vapor(self.Isotopologue))

        for time in range(self.__time_steps):

            self.liquid_advection = liquid_advection(self.q_l, self.storage1)
            self.liquid_diffusion = liquid_diffusion(self.storage1)
            self.vapor_advection = vapor_advection(self.q_v, self.storage1)
            self.vapor_diffusion = vapor_diffusion(self.storage1)

            # Total outgoing flux is the sum of advective flux and diffusive flux
            liquid_iso_outflux = self.liquid_advection.calc_flux_i(self.Isotopologue) + \
                                            self.liquid_diffusion.calc_flux_i(self.Isotopologue)
            # TODO: vapor advective / diffusive flux due to the concentration gradient / including equilibrium fractionation ??
            vapor_iso_outflux = self.vapor_advection.calc_flux_i(self.Isotopologue) + \
                                           self.vapor_diffusion.calc_flux_i(self.Isotopologue)

            liquid_iso_influx = liquid_iso_outflux
            vapor_iso_influx = vapor_iso_outflux

            # Calculate new concentration in the storage after the incoming or outgoing flux for each time steps
            new_liquid_conc_storage1 = (self.storage1.get_conc_iso_liquid(self.Isotopologue) * self.storage1.volume -
                                        liquid_iso_outflux * self.storage1.area) / self.storage1.volume
            new_liquid_conc_storage2 = (self.storage2.get_conc_iso_liquid(self.Isotopologue) * self.storage2.volume +
                                        liquid_iso_influx * self.storage2.area) / self.storage2.volume

            new_vapor_conc_storage1 = (self.storage1.get_conc_iso_vapor(self.Isotopologue) * self.storage1.volume -
                                       vapor_iso_outflux * self.storage1.area) / self.storage1.volume
            new_vapor_conc_storage2 = (self.storage2.get_conc_iso_vapor(self.Isotopologue) * self.storage2.volume +
                                       vapor_iso_influx * self.storage2.area) / self.storage2.volume

            # Update each storage with new liquid and vapor concentration
            self.storage1.set_conc_iso_liquid(new_liquid_conc_storage1, self.Isotopologue)
            self.storage2.set_conc_iso_liquid(new_liquid_conc_storage2, self.Isotopologue)

            # Store isotope concentration for each time steps
            c1.append(new_liquid_conc_storage1)
            c2.append(new_liquid_conc_storage2)
            v1.append(new_vapor_conc_storage1)
            v2.append(new_vapor_conc_storage2)

        return [[c1, c2], [v1,v2]]

class liquid_advection(object):
    """
    Description
    ===========
    Advective flux of isotopes [kg] between to nodes based on a given liquid flux [m/day]

    A positive flux rate [kg] is always considered to be from left node to right node a  negative from right to left.

    """

    def __init__(self,
                 q_l,  # Liquide flux in m/day positive form left to right : negative from right to left
                 storage # instance of iso_storage
                 ):
        """
        Constructor of boundary_connection

        @param q_l: Liquide flux in m3/(m2*day). Positive form left to right : negative from right to left
        @type q_l: float
        """
        # flux_connection.__init__(self ,left_node ,right_node ,flux_crosssectional_area)
        self.q_l = q_l
        self.storage = storage

    def calc_flux(self, Isotopologue):
        """
        Positive flux of the liquid flux  [m/day] left to right
        """
        flux = self.q_l

        return flux

    def calc_flux_i(self, Isotopologue):
        """
        Positive flux of the given Isotopologue [kg/m2/day] in liquid phase left to right
        """
        flux = self.calc_flux(Isotopologue)

        flux_i = self.storage.get_conc_iso_liquid(Isotopologue) * flux

        return flux_i

    def calc_flux_liquid(self, Isotopologue):
        """
        Returns the flux relative to the liquid isotope concentration.
        For vapor flux --> vapor flux * alpha(i)
        For liquid flux --> liquid flux
        """
        return self.calc_flux(Isotopologue)

class liquid_diffusion(object):
    """
    Description
    ===========
    Functions to calculate diffusive fluxes in liquids
    """

    def __init__(self, storage, q_l=None, hydrodynamic_dispersivity=0.0):

        self.storage = storage
        self.q_l = q_l
        self.hydrodynamic_dispersivity = hydrodynamic_dispersivity

    def dl_i_eff(self, dl_i, q_l=None, hydrodynamic_dispersivity=0.0):
        """
        Calculates the total (effective) liquid diffusivity for isotope i in the soil liquide phase (m**2/day)

        Description
        ===========

        Under evaporation, convective and hydrodynamic dispersion processes are negligible as compared to the diffusion ones and are frequently set to zero (Auriault and Adler, 1995)

        @param theta: liquid phase (m**3/m**3 )
        @type theta: Float

        @param tortuosity: tortuosity (m/m)
        @type tortuosity: Float

        @param q_l: liqiud water flux (m/s)
        @type q_l: Float

        @param hydrodynamic_dispersivity: per default set to 0 (m) because under evaporation, convective and hydrodynamic dispersion processes are negligible as compared to the diffusion ones
        @type hydrodynamic_dispersivity: Float
        """
        try:
            if q_l == None or hydrodynamic_dispersivity == 0.0:
                dl_i_eff = dl_i
            elif q_l != None and hydrodynamic_dispersivity != 0.0:
                dl_i_eff = dl_i + hydrodynamic_dispersivity * abs(q_l)

            return dl_i_eff

        except ValueError as err:
            print(err)
            raise NotImplementedError

    def dl_i(self, T, Isotopologue, tortuosity, theta, formulation="Cuntz", ignore_dl_i=False):
        """
        Calculates the liquid diffusivity for isotope i in the soil liquid phase (m**2/day)

        Description
        ===========

        @param T: temperature T (K) (283.15 K = 10 Celsius) <-- soil or atmosphere????
        @type T: Float

        @param Isotopologue: Identifier for the Isotopologue to be calculated (currently supported '2H' and '18O')
        @type Isotopologue: Sting

        @param theta: liquid phase (m**3/m**3 )
        @type theta: Float

        @param tortuosity: tortuosity (m/m)
        @type tortuosity: Float

        @param ignore_dl_i: If set to "True" liquid diffusivity for isotope will be set to 0 = no liquid diffusivity
        @type ignore_dl_i: Boolean

        """
        try:
            if ignore_dl_i == False:
                # SLI: cable_sli_solve.f90::L2381-2390
                dl_i = self.dl_i_self_diffusivity(T, Isotopologue, formulation="Cuntz") * theta * tortuosity
            else:
                dl_i = 0.0

            return dl_i

        except ValueError as err:
            print(err)
            raise NotImplementedError

    def dl_i_self_diffusivity(self, T, Isotopologue, formulation="Cuntz"):
        """
        Calculates the liquide self diffusivity of an given isotope in pure water (m**2/day) either after Melayah et al.  (1996) or Cuntz et al. (2007)

        Description
        ===========

        @param T: temperature T (K) of the current layer (283.15 K = 10 Celsius)
        @type T: Float

        @param Isotopologue: Identifier for the Isotopologue to be calculated (currently supported '2H' and '18O')
        @type Isotopologue: Sting

        @param formulation: Identifier for the formulation to be used to calculated dl_i_self_diffusivity (currently supported 'Melayah'and 'Cuntz')
        @type formulation: Sting

        """
        try:

            if formulation == "Melayah":
                if "18O" == Isotopologue:
                    a_i = 0.9669
                elif "2H" == Isotopologue:
                    a_i = 0.9833
                else:
                    raise NotImplementedError

                dl_i = a_i * 1.10 ** -9 * math.exp(-(535400 / T ** 2) + (1393.3 / T) + 2.1876)

            # SLI: cable_sli_solve.f90::L2381-2390
            elif formulation == "Cuntz":
                if "18O" == Isotopologue:
                    a_i = 1 / 1.026
                elif "2H" == Isotopologue:
                    a_i = 1 / 1.013
                else:
                    raise NotImplementedError

                dl_i = a_i * 1e-7 * math.exp(-577 / (T - 145))

            else:
                raise NotImplementedError

            return dl_i * 86400  # convert m2 per seconds to m2 per day

        except ValueError as err:
            print(err)
            raise NotImplementedError

    def calc_flux(self, Isotopologue, dl_i_formulation="Cuntz", ignore_dl_i=False):
        """
        Positive flux of the given Isotopologue [m/day] left to right
        Average diffusivity over the thickness
        """
        # Under evaporation, convective and hydrodynamic dispersion processes are negligible as compared to the diffusion ones and are frequently set to zero (Auriault and Adler, 1995)
        # left_node = self.left_node()
        # right_node = self.rigth_node()

        dl_i = self.dl_i(T=self.storage.T,  # TODO: where is the temperature imported from??
                         Isotopologue=Isotopologue,
                         tortuosity=self.storage.tortuosity,
                         theta=self.storage.theta,
                         formulation=dl_i_formulation,
                         ignore_dl_i=ignore_dl_i)

        dl_i_eff = self.dl_i_eff(dl_i=dl_i, q_l=self.q_l,
                                 hydrodynamic_dispersivity=self.hydrodynamic_dispersivity)

        delta_z = self.storage.thickness

        dl_mean = dl_i_eff * delta_z

        return dl_mean

    def calc_flux_i(self, Isotopologue):
        """
        Positive flux of the given Isotopologue [kg/m2/day] left to right
        """
        flux = self.calc_flux(Isotopologue)
        flux_i = self.storage.get_conc_iso_liquid(Isotopologue) * flux

        return flux_i

class vapor_advection(object):
    """
    Description
    ===========
    Advective flux of isotopes [kg] between to nodes based on a given vapor flux [m/day]

    A positive flux rate [kg] is always considered to be from left node to right node a  negative from right to left.

    """

    def __init__(self,
                 q_v, # vapor flux in m/day positive form left to right : negative from right to left. If None q_v  will be calculated based on equation A.12 Haverd&Cuntz (2005) knowing futurue Temp and matrix potential
                 storage  #  Instance of iso storage
                 ):
        """
        Constructor of boundary_connection

        @param q_v: vapor flux in (m/day). Positive form left to right : negative from right to left
        @type q_v: float
        """
        # flux_connection.__init__(self ,left_node ,right_node ,flux_crosssectional_area)
        self.q_v = q_v
        self.storage = storage

    def calc_flux(self, Isotopologue):
        """
        Positive flux of vapor  [m/day] left to right
        """
        flux = self.q_v

        return flux

    def calc_flux_i(self, Isotopologue):
        """
        Positive flux of the given Isotopologue [kg/m2/day] in vapor left to right
        """
        flux = self.calc_flux(Isotopologue)

        flux_i = self.storage.get_conc_iso_vapor(Isotopologue) * flux

        return flux_i

    def calc_flux_vapour(self, Isotopologue):
        """
        Returns the flux relative to the liquid isotope concentration.
        For vapor flux --> vapor flux * alpha(i)
        For liquid flux --> liquid flux
        """
        flux = self.calc_flux(Isotopologue)

        # TODO: Is this correct way to calculate vapour flux. (not isotope)
        flux_vapour = self.storage.alpha_i(Isotopologue) * flux

        return flux_vapour

class vapor_diffusion(object):
    """
    Description
    ===========
    Functions to caclculate diffusive fluxes
    """

    def __init__(self, storage, q_v=None, hydrodynamic_dispersivity=0.0):

        self.storage = storage
        self.q_v = q_v
        self.hydrodynamic_dispersivity = hydrodynamic_dispersivity

    @classmethod
    def dv_i(self, dv, Isotopologue, ignore_dv_i=False):
        """
        Calculates the vapour diffusivity of Isotopologue in free air (m**2/s)

        Description
        ===========

        @param dv: vapour diffusivity of water in free air (m**2/s)
        @type dv: Float

        @param Isotopologue: Identifier for the Isotopologue to be calculated (currently supported '2H' and '18O')
        @type Isotopologue: Sting

        @param ignore_dv_i:  If set to "True" vapour diffusivity of a Isotopologue in free air will be set to dv_i = dv --> the same as normal water
        @type ignore_dv_i: Boolean

        SLI: sli_init.f90 Lines: 2366 - L2367 <--checked and own implementation is okay
        """
        try:
            # SLI: cable_sli_solve.f90::L2366 - L2367
            if "18O" == Isotopologue:
                b_i = 1.0251  # H218O diffusivity in air (Merlivat 1978) // SLI: 1/b_i = alphak_vdiff
            elif "2H" == Isotopologue:
                b_i = 1.0285  # HDO diffusivity in air (Merlivat 1978) // SLI: 1/b_i = alphak_vdiff
            else:
                raise NotImplementedError

            if ignore_dv_i == True:
                return dv
            else:
                # SLI: cable_sli_solve.f90::L2373 - L2374
                dv_i = dv / b_i  # SLI: dv = Dvs ; dv_i = Divs ; 1/b_i = alphak_vdiff

                return dv_i

        except ValueError as err:
            print(err)
            raise NotImplementedError

    @classmethod
    def dv_soil_air(self, dv_free_air, theta, theta_sat, tortuosity):
        """
        Calculates the vapour diffusivity of water in soil air space (m**2/s)

        Description
        ===========

        @param dv_free_air: vapour diffusivity of water in free air (m**2/s)
        @type dv_free_air: Float

        @param theta: air pressure in the atmosphere (1bar = 1 atm = 10**5 Pa) [Pa]
        @type theta: Float

        @param theta: liquid phase (m**3/m**3 )
        @type theta: Float

        @param theta_sat: theta at saturation equal to soil porosity (m**3/m**3 )
        @type theta_sat: Float

        @param tortuosity: tortuosity (m/m)
        @type tortuosity: Float
        """
        try:
            # SLI:: cable_sli_utils.f90 L::1494: var%Dv    = Dva*parin%tortuosity*(parin%the-theta)  * ((Tsoil+Tzero)/Tzero)**1.88_r_2 ! m2 s-1
            dv_soil_air = dv_free_air * tortuosity * (theta_sat - theta)

            return dv_soil_air

        except ValueError as err:
            print(err)
            raise NotImplementedError

    @classmethod
    def dv_free_air(self, T=283.15, Pa=10 ** 5):
        """
        Calculates the vapour diffusivity of water in free air (m**2/s)

        Description
        ===========

        @param T: temperature T (K) (283.15 K = 10 Celsius) <-- soil or atmosphere????
        @type T: Float

        @param Pa: air pressure in the atmosphere (1bar = 1 atm = 10**5 Pa) [Pa]
        @type Pa: Float

        TODO: SLI uses 1 for Pa and not 100.000 why????

        """
        try:
            dva = 2.17e-5  # vapour diffusivity of water in air at 0 degC [m2/s]
            dv = dva * 1e5 / Pa * (T / 273.16) ** 1.88
            # SLI: Dva       = 2.17e-5   ! vapour diffusivity of water in air at 0 degC [m2/s]
            # SLI: Dvs  = Dva*1.e5_r_2/patm*((Ts+Tzero)/Tzero)**1.88_r_2 ! vapour diffuxivity of water in air (m2s-1)

            return dv

        except ValueError as err:
            print(err)
            raise NotImplementedError

    def calc_flux(self, Isotopologue, ignore_dv_i=False):
        """
        Positive flux of the given Isotopologue [m/day] left to right
        """
        # left_node = self.left_node()
        # right_node = self.rigth_node()

        # if isinstance(left_node, LSI_storages.iso_soil_layer) and isinstance(right_node, LSI_storages.iso_soil_layer):

        dv_free_air = self.dv_free_air(T=self.storage.T,
                                       Pa=1e5)  # TODO: Change to actual atmospheric preassure)

        dv_soil_air = self.dv_soil_air(dv_free_air=dv_free_air,
                                       theta=self.storage.theta,
                                       theta_sat=self.storage.theta_sat,
                                       tortuosity=self.storage.tortuosity)

        dv_i = self.dv_i(dv=dv_soil_air,
                         Isotopologue=Isotopologue,
                         ignore_dv_i=ignore_dv_i)

        delta_z = self.storage.thickness  # sqrt of area in m

        dv_i_mean = dv_i * delta_z * 86400

        return dv_i_mean

    def calc_flux_i(self, Isotopologue):
        """
        Positive flux of the given Isotopologue [kg/m2/day] left to right
        """
        flux = self.calc_flux(Isotopologue)
        flux_i = self.storage.get_conc_iso_vapor(Isotopologue) * flux

        return flux_i

    def calc_flux_liquid(self, Isotopologue):
        """
        Returns the flux relative to the liquid isotope concentration.
        For vapor flux --> vapor flux * alpha(i)
        For liquid flux --> liquid flux
        """
        flux = self.calc_flux(Isotopologue)
        flux_vapour_liquid = self.storage.alpha_i(Isotopologue) * flux

        return flux_vapour_liquid


from django.contrib import admin
from .models import CustomerOrder, OrderItem

class OrderItemAdmin(admin.TabularInline):
    model = OrderItem
    readonly_fields = ('line_total',)

class OrderAdmin(admin.ModelAdmin):
    inlines = (OrderItemAdmin,)

    readonly_fields = ('order_number', 'date',
                       'delivery_cost', 'order_total',
                       'grand_total', 'original_bag',
                       'stripe_pid',)

    fields = ('order_number', 'date', 'full_name',
              'email', 'telephone', 'address1',
              'address2', 'postcode',
              'county', 'country', 'delivery_cost',
              'order_total', 'grand_total', 'original_bag',
              'stripe_pid',)

    list_display = ('order_number', 'date', 'full_name',
                    'order_total', 'delivery_cost',
                    'grand_total',)

    ordering = ('-date',)

admin.site.register(CustomerOrder, OrderAdmin)


#!/usr/bin/python3
""" function that saves JSON to text file
"""

import json

def save_to_json_file(my_obj, filename):
    """ input: JSON object
        filename: the file to write
    """
    with open(filename, 'w', encoding='utf-8') as f:
        jsonStr = json.dumps(my_obj)
        f.write(jsonStr)


import os
import openpyxl

# 识别结果文件夹
RESULT_DIRS = 'C:/Users/a7825/Desktop/工作空间/跑代码/mac0001/out'
# 正解文件夹
CORRECT_DIRS = 'C:/Users/a7825/Desktop/工作空间/跑代码/mac0001/zhengjie'
# 特征值文件夹
EIGENVALUE_DIRS = 'C:/Users/a7825/Desktop/工作空间/跑代码/mac0001/tezheng'

# 特征值合并后的文件
MERGE_CSV = 'C:/Users/a7825/Desktop/工作空间/跑代码/mac0001/mac0001.csv'

class HandelInfo(object):

    def __init__(self):
        # 当前操作正解的excel文件中的工作表
        self.correct_file_wb_sheet = None

        # 操作的数据集
        self.result_set = ' '  # a
        # 当前操作的识别结果文件
        self.result_file_name = ''  # a01
        self.merge_file = open(MERGE_CSV, 'a+')

    # 解析识别结果
    def parse_out(self):
        # 遍历识别结果中的所有文件
        for file_name in os.listdir(RESULT_DIRS):
            # result_file_name 表示当前处理的识别结果文件 a01.out
            self.result_file_name = file_name.split('.')[0]
            # 从文件名中获取a01,a02,a03,a04
            # result_set 表示当前处理的类集
            if self.result_set != file_name[0]:
                self.result_set = file_name[0]
                # correct_file_wb_sheet 表示打开当前类集对应的正解的excel
                self.correct_file_wb_sheet = openpyxl.load_workbook(
                    os.path.join(CORRECT_DIRS, '%s' % self.result_set + '.xlsx')).active
            # 读取识别结果文件
            with open(os.path.join(RESULT_DIRS, file_name), 'rb') as file:
                # 识别出来的日文
                data = file.readlines(1)[0].decode('utf-8').split(':')[1].strip()
                self.comparison(data)

    # 用识别出来的结果取正解的excel文件中做对比
    def comparison(self, data):
        # csv_file： 识别结果对应的特征值文件
        csv_file = os.path.join(EIGENVALUE_DIRS, '%s' % self.result_file_name + '.wav.csv')
        # sheet最大行数
        for row in range(1, self.correct_file_wb_sheet.max_row + 1):
            value = self.correct_file_wb_sheet.cell(row=row, column=1).value
            if value:
                #if self.strQ2B(value) == self.result_file_name.upper():改了之后就不怕空格了
                if self.strQ2B(value).strip() == self.result_file_name.upper().strip():
                    z = ''.join(self.correct_file_wb_sheet.cell(row=row, column=2).value.split())
                    o = ''.join(data.split()).replace('、', '')
                    if z == o:
                        # 识别出来正确的结果
                        print('识别结果正确: %s--->%s' % (o, z))
                        self.handel_csv(csv_file, True)
                    else:
                        print('识别结果错误: %s--->%s' % (o, z))

                        self.handel_csv(csv_file, False)

    def handel_csv(self, csv, v):
        # 正确打1 错误打0
        with open(csv, 'r') as f:
            if v:
                data = f.read().replace("'unknown'", '1')
                print(data)
                self.merge_file.write(data)
            else:
                data = f.read().replace("'unknown'", '0')
                print(data)

                self.merge_file.write(data)

    def strQ2B(self, ustring):
        """把字符串全角转半角"""
        rstring = ""
        for uchar in ustring:
            inside_code = ord(uchar)
            if inside_code == 0x3000:
                inside_code = 0x0020
            else:
                inside_code -= 0xfee0
            if inside_code < 0x0020 or inside_code > 0x7e:  # 转完之后不是半角字符返回原来的字符
                rstring += uchar
            rstring += chr(inside_code)
        return rstring

if __name__ == '__main__':
    a = HandelInfo()
    a.parse_out()


from threading import Thread
import time; import os;

def function(sec):
    print("Enter: threaded function")
    time.sleep(sec)
    print("Exit : threaded function")

if __name__ == "__main__":
    start = time.perf_counter()

    threads   = [Thread(target = function, args = [1]) for _ in range(100)]
    starts    = [process.start() for process in threads]
    joins     = [process.join() for process in threads]

    finish = time.perf_counter()

    print(f"\n\tFinished in {finish - start} seconds;")


import yaml
from appium import webdriver
from appium.webdriver.webdriver import WebDriver

def get_driver(config_path) -> WebDriver:
    caps = dict()
    caps['platformName'] = 'Android'
    caps['appPackage'] = 'com.xueqiu.android'
    caps['appActivity'] = '.view.WelcomeActivityAlias'
    caps['autoGrantPermissions'] = True
    with open(config_path, 'r', encoding='utf-8') as data:
        caps.update(yaml.load(data))
    print(caps)
    driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=caps)
    driver.implicitly_wait(5)
    return driver


class Solution:
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        pos = 0

        for i in range(len(nums)):
            # first moves through all the values
            el = nums[i]
            if el != 0:
                # this pointer keeps on incrementing when value is correctly placed
                nums[pos], nums[i] = nums[i], nums[pos]
                pos += 1


from sklearn.preprocessing import OneHotEncoder, LabelEncoder
import pandas as pd

from sklearn.externals import joblib

def extract_features(train_file, test_file, feat_train_file, feat_test_file):
    df = pd.read_csv(train_file, header=None, names=['country','sku_id','title','category_lvl_1','category_lvl_2','category_lvl_3','short_description','price','product_type'])
    df1 = pd.read_csv(test_file, header=None, names=['country','sku_id','title','category_lvl_1','category_lvl_2','category_lvl_3','short_description','price','product_type'])

    num_trains = df.shape[0]

    df = pd.concat((df,df1))

    df = df.fillna('')
    df = df[['category_lvl_1','category_lvl_2','category_lvl_3','short_description','product_type']]
    for c in df.columns:
        df[c] = LabelEncoder().fit_transform(df[c])

    X = OneHotEncoder().fit_transform(df.values)

    X_train = X[:num_trains,:]
    X_val = X[num_trains:,:]

    print('saving %s' % feat_train_file)
    joblib.dump(X_train, feat_train_file)

    print('saving %s' % feat_test_file)
    joblib.dump(X_val, feat_test_file)

if __name__ == "__main__":
    # Data loading

    train_file = '../data/data_train.csv'
    test_file = '../data/data_valid.csv'

    feat_train_file = '../features/sp_feat.trn'
    feat_test_file = '../features/sp_feat.tst'
    extract_features(train_file, test_file, feat_train_file, feat_test_file)


import sys

lst = []
for k in range(10):
    n = int(input())
    lst.append(n)

per = {}
for x in lst:
    if x not in per:
        per[x] = 1
    else:
        per[x] += 1

max_key = max(per, key=per.get)

avg = int(sum(lst) / len(lst))
print(avg)
print(max_key)


import csv
import time
import gurobipy as gp
import matplotlib.pyplot as plt
import networkx as nx
import pandas as pd
import numpy as np
from gurobipy import GRB
from matplotlib.lines import Line2D
from matplotlib.patches import Patch
import constants
from itertools import chain

# -------------------------------------------- Give input to the model ----------------------------------------------

# Files
shipment_file = constants.shipment_file_time_windows
time_diff_matrix_file = constants.time_diff_matrix_file
depots_file = constants.depots_file

# Parameters

# The maximum waiting time in between shipments
max_waiting_time = constants.max_waiting_time

# Max and min duration
max_duration = constants.max_duration
min_duration = constants.min_duration
max_driving_time = constants.max_driving_time

# The weights in the cost function that determines the operational cost for executing one shipment after another
weight_waiting_time = constants.weight_waiting_time
weight_empty_driving_time = constants.weight_empty_driving_time

# The fixed cost for adding a new truck to the planning
fixed_cost_new_truck = constants.fixed_cost_new_truck

# The amount of time spend on not driving within one shipment block
loading_time = constants.loading_time

# Length of time discretizaiton interval
time_window_interval_in_minutes = constants.time_window_interval_in_minutes
max_number_shipment_multiplication = constants.max_number_shipment_multiplication

gap_percentage = constants.gap_percentage

# ------------------------------------------------ Import Input Data -----------------------------------------------

# Format function for dictionary
def format_dict(d, indent=0):
    for key, value in d.items():
        print('\t' * indent + str(key))
        if isinstance(value, dict):
            format_dict(value, indent + 1)
        else:
            print('\t' * (indent + 1) + str(value))

# Import Shipments from csv to dataframe
# Shipments is a list of all shipments that have to be executed, with their Shipment ID, start time, end time,
# start location and end location
pd.set_option("display.max_rows", 30, "display.max_columns", 7)
shipments_data_df = pd.read_csv(shipment_file)
print('OVERVIEW SHIPMENTS: ')
print(shipments_data_df)

# Import Shipments from csv to dictionary
with open(shipment_file, newline='') as csv_file:
    reader = csv.DictReader(csv_file)
    base_shipments_data = {row['shipment_id'] : {'earliest_start_time': float(row['earliest_start_time']),
                                                'latest_start_time': float(row['latest_start_time']),
                                                'earliest_end_time': float(row['earliest_end_time']),
                                                'latest_end_time': float(row['latest_end_time']),
                                                'start_location': row['start_location'],
                                                'end_location': row['end_location']}
                           for row in reader}

shipments_data_s = {}
shipments_data_e = {}
base_to_windowed_map = {}
interval = int(time_window_interval_in_minutes * 1/.6)
for ship_id, ship_data in base_shipments_data.items():
    length = int((ship_data['latest_start_time'] - ship_data['earliest_start_time']) * 100)
    i = 1
    base_to_windowed_map[ship_id] = []
    if np.ceil(length/interval) + 1 <= max_number_shipment_multiplication:
        pass
    else:
        interval = int(length / (max_number_shipment_multiplication - 2))
    #interval = max(interval, min(30, int(length / (max_number_shipment_multiplication - 2))))
    for minutes in list(range(0, length, interval)) + [length]:
        key = ship_id + '.' + str(i)
        key_s = key + '_s'
        key_e = key + '_e'
        shipments_data_s[key_s] = {
            'start_time': ship_data['earliest_start_time'] + minutes * 0.01,
            'end_time': ship_data['earliest_end_time'] + minutes * 0.01,
            'start_location': ship_data['start_location'],
            'end_location': ship_data['end_location']
        }
        shipments_data_e[key_e] = {
            'start_time': ship_data['earliest_start_time'] + minutes * 0.01,
            'end_time': ship_data['earliest_end_time'] + minutes * 0.01,
            'start_location': ship_data['start_location'],
            'end_location': ship_data['end_location']
        }
        base_to_windowed_map[ship_id].append(key)
        i += 1

shipments_data = {**shipments_data_s, **shipments_data_e}

# Import Depots from csv to dictionary
with open(depots_file, newline='') as csv_file:
    reader = csv.DictReader(csv_file)
    depots_data = {row['Depot']: int(row['Trucks']) for row in reader}

format_dict(depots_data)
M = len(depots_data)

# Import time difference matrix from csv to dataframe.
# The time difference matrix gives the driving time between all different locations.
time_diff_matrix = pd.read_csv(time_diff_matrix_file)
time_diff_matrix.set_index('Location', drop=True, inplace=True)

print(time_diff_matrix.head())

N = len(base_shipments_data)
print('number of shipments input: ', N)
print('time discretization distance: ', time_window_interval_in_minutes)
print('max number of shipment multiplications: ', max_number_shipment_multiplication)

print('number of shipments after time discretization: ', len(shipments_data_s))
for ship, lst in base_to_windowed_map.items():
    print(ship, len(lst))

for ship_id, ship_data in shipments_data.items():
    print(ship_id)
for ship_id, ship_data in shipments_data.items():
    print(ship_data['start_time'])
for ship_id, ship_data in shipments_data.items():
    print(ship_data['end_time'])

# -------------------------------------Translate data to the Network Flow Graph--------------------------------------

# Create list of depots
depot_list = list(depots_data.keys())

# Determine startup costs: take the average cost of driving from Ermelo to the start location
total_fixed_cost = 0
for depot in depot_list:
    fixed_cost = weight_empty_driving_time * 2 * time_diff_matrix.at['Ermelo', depot]
    total_fixed_cost += fixed_cost
fixed_cost_new_truck = total_fixed_cost / M
fixed_cost_new_truck = constants.fixed_cost_new_truck

print('fixed cost new truck: ', fixed_cost_new_truck)

shipment_per_depot = []
for depot in depot_list:
    nodes = [depot + "_" + ship_id for (ship_id, _) in shipments_data.items()]
    nodes_no_time_windows = list({depot + "_" + ship_id[:ship_id.rfind('.')] for (ship_id, _) in shipments_data.items()})
    shipment_per_depot.append(nodes)

depot_nodes_start = [depot + '_s' for depot in depot_list]
depot_nodes_end = [depot + '_t' for depot in depot_list]

locations = set.union({value['start_location'] for (_, value) in shipments_data_s.items()},
                      {value['end_location'] for (_, value) in shipments_data_e.items()})

# Construct compatibility arcs with flow upper bound and cost

# The compatibility arcs are the arcs that connect shipment 1 to shipment 2 iff it is feasible to execute shipment 1,
# drive to the start location of shipment 2, and start shipment 2.
# Initiate the arcs and give them flow upper bound 1

comp_arcs = {}
for (end_ship_id, end_ship_data) in shipments_data_e.items():
    for (start_ship_id, start_ship_data) in shipments_data_s.items():
        waiting_time = start_ship_data['start_time'] - end_ship_data['end_time'] - \
                       time_diff_matrix.at[end_ship_data['end_location'], start_ship_data['start_location']]
        if 0 <= waiting_time:
            comp_arcs[(end_ship_id, start_ship_id)] = 1

arcs_dict = {}
print('number of locations: ' + str(len(locations)))
print('number of connection based arcs: ' + str(len(comp_arcs)))
first_matches = []
for location in locations:
    for end_ship_id, end_ship_data in filter(lambda item: item[1]['end_location'] == location,
                                             shipments_data_e.items()):
        for next_location in locations:
            earliest_start_id = ''
            earliest_start_time = 0
            for start_ship_id, start_ship_data in filter(lambda item: item[1]['start_location'] == next_location,
                                                         shipments_data_s.items()):
                if (end_ship_id, start_ship_id) in comp_arcs and (
                        earliest_start_id == '' or start_ship_data['start_time'] < earliest_start_time):
                    earliest_start_id = start_ship_id
                    earliest_start_time = start_ship_data['start_time']
            if earliest_start_id != '':
                first_match = (end_ship_id, earliest_start_id)
                first_matches.append(first_match)

print('number of first matches arcs: ', len(first_matches))

# Construct latest first matches

latest_first_matches = []
relevant_locations = {shipments_data_s[earliest_start_id]['start_location'] for (_, earliest_start_id) in first_matches}
relevant_start_shipments = {earliest_start_id for (_, earliest_start_id) in first_matches}
for start_ship_id in relevant_start_shipments:
    for previous_location in locations:
        latest_end_shipment_id = ''
        latest_end_time = 0
        for (end_ship_id, earliest_start_id) in filter(
                lambda item: shipments_data_e[item[0]]['end_location'] == previous_location,
                first_matches):
            if (end_ship_id, start_ship_id) in first_matches and (latest_end_shipment_id == '' or shipments_data_e[end_ship_id]['end_time'] > latest_end_time):
                latest_end_shipment_id = end_ship_id
                latest_end_time = shipments_data_e[end_ship_id]['end_time']
        if latest_end_shipment_id != '':
            latest_first_match = (latest_end_shipment_id, start_ship_id)
            latest_first_matches.append(latest_first_match)
            for depot in depot_list:
                arcs_dict[(depot + "_" + latest_end_shipment_id, depot + "_" + start_ship_id)] = N

print('number of latest first matches: ', len(latest_first_matches))
print(latest_first_matches)

# Determine the cost for the compatibility arcs
# Determine the empty driving time between the execution of shipment 1 and shipment 2
def empty_driving_time(ship_1_data, ship_2_data):
    return time_diff_matrix.at[ship_1_data['end_location'], ship_2_data['start_location']]

# Determine the waiting time between the execution of shipment 1 and shipment 2
def waiting_time(ship_1_data, ship_2_data):
    return ship_2_data['start_time'] - ship_1_data['end_time'] - empty_driving_time(ship_1_data, ship_2_data)

# The cost of compatibility arc (ship 1, ship 2) is the operational cost of executing shipment 2 after shipment 1
# The operational cost is weighted sum of the empty driving time and the waiting time

def cost(end_ship_id, start_ship_id):
    end_ship_data = shipments_data_e[end_ship_id[end_ship_id.index('_') + 1:]]
    start_ship_data = shipments_data_s[start_ship_id[start_ship_id.index('_') + 1:]]
    operational_cost = weight_waiting_time * waiting_time(end_ship_data, start_ship_data) + \
                       weight_empty_driving_time * empty_driving_time(end_ship_data, start_ship_data)
    return operational_cost

# Assign the costs to the compatibility arcs
cost = {
    arc: cost(arc[0], arc[1]) for (arc, _) in arcs_dict.items()
}

# Construct waiting arcs between start shipments
count_waiting_arcs = 0
for location in locations:
    starting_shipments = []
    for start_ship_id, start_ship_data in filter(lambda item: item[1]['start_location'] == location,
                                                 shipments_data_s.items()):
        starting_shipments.append((start_ship_id, start_ship_data['start_time']))
    starting_shipments.sort(key=lambda tup: tup[1])
    for i in range(len(starting_shipments) - 1):
        this_ship_id, this_start_time = starting_shipments[i]
        next_ship_id, next_start_time = starting_shipments[i + 1]
        waiting_arc = (this_ship_id, next_ship_id)
        for depot in depot_list:
            arcs_dict[(depot + "_" + this_ship_id, depot + "_" + next_ship_id)] = len(starting_shipments)
        cost[waiting_arc] = weight_waiting_time * (next_start_time - this_start_time)
        count_waiting_arcs += 1

# Construct waiting arcs between end shipments
for location in locations:
    ending_shipments = []
    for end_ship_id, end_ship_data in filter(lambda item: item[1]['end_location'] == location,
                                             shipments_data_e.items()):
        ending_shipments.append((end_ship_id, end_ship_data['end_time']))
    ending_shipments.sort(key=lambda tup: tup[1])
    for i in range(len(ending_shipments) - 1):
        this_ship_id, this_end_time = ending_shipments[i]
        next_ship_id, next_end_time = ending_shipments[i + 1]
        waiting_arc = (this_ship_id, next_ship_id)
        for depot in depot_list:
            arcs_dict[(depot + "_" + this_ship_id, depot + "_" + next_ship_id)] = len(ending_shipments)
        cost[waiting_arc] = weight_waiting_time * (next_end_time - this_end_time)
        count_waiting_arcs += 1

print('number of waiting arcs: ', count_waiting_arcs)
print('number of time space based arcs: ', int(len(arcs_dict)/M))

# Construct shipment arcs

for (start_ship_id, start_ship_data) in shipments_data_s.items():
    for (end_ship_id, end_ship_data) in shipments_data_e.items():
        if start_ship_id != end_ship_id and start_ship_data == end_ship_data:
            shipment_arc = (start_ship_id, end_ship_id)
            for depot in depot_list:
                arcs_dict[(depot + "_" + start_ship_id, depot + "_" + end_ship_id)] = 1
            cost[shipment_arc] = 0

print('number of time space based arcs with shipments arcs: ', int(len(arcs_dict)/M))

# Construct pull out / pull in arcs with flow upper bound and cost
# The cost of the pull out arcs is a fixed cost for adding a new truck to the planning plus the operational costs

# pull out arcs
for depot in depot_list:
    for (ship_id, ship_data) in shipments_data_s.items():
        cost_from_depot = weight_empty_driving_time * time_diff_matrix.at[depot, ship_data['start_location']]
        pull_out_arc = (depot + "_s", depot + "_" + ship_id)
        arcs_dict[pull_out_arc] = 1
        cost[pull_out_arc] = fixed_cost_new_truck + cost_from_depot

# pull in arcs
for depot in depot_list:
    for (ship_id, ship_data) in shipments_data_e.items():
        cost_to_depot = weight_empty_driving_time * time_diff_matrix.at[ship_data['end_location'], depot]
        pull_in_arc = (depot + "_" + ship_id, depot + "_t")
        arcs_dict[pull_in_arc] = 1
        cost[pull_in_arc] = cost_to_depot

# Construct circulation arcs with flow upper bound and cost
for depot in depot_list:
    circulation_arc = (depot + "_t", depot + "_s")
    arcs_dict[circulation_arc] = N
    cost[circulation_arc] = 0

arcs, flow_upper = gp.multidict(arcs_dict)
format_dict(cost)
# -------------------------------------- Optimization model -----------------------------------------------------------

# Model
model = gp.Model('min-cost-flow')

# Decision variables
# flow = model.addVars(arcs, obj=cost, name="flow")
flow = model.addVars(arcs, obj=cost, vtype=GRB.INTEGER, name="flow")

# Constraints
# Flow upper bound for every arc: For every arc the flow is bounded by an upperbound.
model.addConstrs((flow[i, j] <= flow_upper[i, j] for i, j in arcs), "upper")

# Flow conservation for every node: For every node the incoming flow is exactly the same as the outgoing flow.
flat_nodes = [node for nodes in shipment_per_depot for node in nodes]
model.addConstrs(
    (flow.sum(node, '*') == flow.sum('*', node)
     for node in flat_nodes), "c")
model.addConstrs(
    (flow.sum(start_node, '*') == flow.sum('*', start_node)
     for start_node in depot_nodes_start), "conservation_s")
model.addConstrs(
    (flow.sum(end_node, '*') == flow.sum('*', end_node)
     for end_node in depot_nodes_end), "conservation_e")

# Flow requirement in every shipment node: every shipment node has an inflow of exactly one in total in all layers.
# Only visit one of the nodes for the same time window.
for i in range(len(shipment_per_depot[0])):
    acc = 0
    nodes = []
    for j in range(len(shipment_per_depot)):
        key = shipment_per_depot[j][i]
        key_core = key[(key.find('_') + 1):key.rfind('.')]
        print(key)
        print(key_core)
        time_window_nodes = base_to_windowed_map[key_core]
        for k in range(len(time_window_nodes)):
            key_depot = key[:(key.find('_') + 1)]
            nodes.append(key_depot + time_window_nodes[k])
            acc += flow[(key_depot + time_window_nodes[k] + '_s', key_depot + time_window_nodes[k] + '_e')]
    print('nodes: ', nodes)
    print(shipment_per_depot[0][i])
    model.addConstr(acc == 1, "exactly_one_" + shipment_per_depot[0][i])

# for ship_id in base_shipments_data:
#     acc = 0
#     nodes = []
#     time_window_nodes = base_to_windowed_map[ship_id]
#     for time_window_node in time_window_nodes:
#         for depot in depot_list:
#             nodes.append(depot + '_' + time_window_node)
#             acc += flow[(depot + '_' + time_window_node + '_s', depot + '_' + time_window_node + '_e')]
#     model.addConstr(acc == 1, "exactly_one_" + ship_id)

# Capacity cap depots: every layer has a maximum flow equal to the maximum depot capacity.
for i in range(len(depot_nodes_start)):
    model.addConstrs(
        (flow.sum(start_node, '*') <= depots_data[start_node[:-2]]
         for start_node in depot_nodes_start), "depot_cap"
    )

# Optimize the model
model.Params.MIPGap = gap_percentage/100
model.Params.MIPFocus = 1
tic = time.time()
model.optimize()
toc = time.time()
time = toc - tic
print('running time: ', time)

# ---------------------------------------- Print the solution ----------------------------------------------------------

solution_arcs = []
if model.status == GRB.OPTIMAL:
    solution = model.getAttr('x', flow)
    for i, j in arcs:
        if solution[i, j] > 0:
            print('%s -> %s: %g' % (i, j, solution[i, j]))
            solution_arcs += [(i, j)]
    #         total_trucks = 0
    #         for depot_t in end_depot_nodes:
    #             for i,_ in solution_arcs:
    #                 if i == depot_t:
    #                     total_trucks += solution[i, j]
    # print('The total number of trucks needed is: ' + total_trucks)

# ---------------------------------------- Visualize solution as graph ------------------------------------------------

# # Graph Flow Model
# plt.figure(figsize=(20, 10))
# h = nx.Graph(arcs)
# pos = nx.random_layout(h)
# nx.draw(h, pos, with_labels=True, font_size=20)
# plt.savefig('Network Flow Model Graph.png')
#
# # Graph Flow Model
# plt.figure(figsize=(20, 10))
# k = nx.Graph(solution_arcs)
# pos = nx.spring_layout(h)
# nx.draw(k, pos, with_labels=True, font_size=20)
# plt.savefig('Network Flow Solution Graph.png')
#
# # Graph showing different cycles
# plt.figure(figsize=(20, 10))
# f = nx.Graph(solution_arcs)
# pos = nx.spring_layout(f)
# nx.draw(f, pos, with_labels=True, font_size=16)
# plt.savefig('Network Cycle Solution Graph.png')

# Graph showing different cycles
plt.figure(figsize=(20, 10))
f = nx.Graph(solution_arcs)
#fixed_positions = {'Ermelo_s':(0,0), 'Ermelo_t': (0.0), 'FC1_s': (0,0), 'FC2_s': (0,0), 'FC1_t': (0,0), 'FC2_t': (0,0)}
#fixed_nodes = fixed_positions.keys()
pos = nx.spring_layout(f)
nx.draw(f, pos, with_labels=True, font_size=16)
plt.savefig('Depot Solution Graph.png')

# Directed graph generating different truck trips from cycles in the graph
g = nx.DiGraph(solution_arcs)

# Making sure that every cycle goes from 's', to the shipments, to 't'
cycles_s_to_t = []
real_cycles = []
for cycle in nx.simple_cycles(g):
    number = 1
    cycle_s_to_t = []
    for node in cycle:
        if node in depot_nodes_start:
            for i in range(len(cycle)):
                cycle_s_to_t.append(cycle[(cycle.index(node) + i) % len(cycle)])
    print('cycle s to t: ', cycle_s_to_t)
    cycles_s_to_t.append(cycle_s_to_t)
    real_cycle = [cycle_s_to_t[0]]
    for i in range(len(cycle_s_to_t)-1):
        if cycle_s_to_t[i][:-2] == cycle_s_to_t[i+1][:-2]:
            real_cycle.append(cycle_s_to_t[i])
    real_cycle += [cycle_s_to_t[-1]]
    real_cycles.append(real_cycle)
    #print('real: ', real_cycle)

cycles = []
visited = set()
for cycle in real_cycles:
    should_continue = False
    for ship in cycle:
        if ship not in depot_nodes_start and ship not in depot_nodes_end and ship in visited:
            should_continue = True
    if should_continue:
        continue
    cycles.append(cycle)
    for ship in cycle:
        visited.add(ship)

# Print the different truck trips
number = 1
for cycle in cycles:
    print('truck trip ' + str(number) + ': ' + str(cycle))
    number += 1

number_of_vehicles = len(cycles)
# print('cycles: ', cycles)

# ----------------------------------------- Evaluate Solution ---------------------------------------------------------

# Analyze input data

# Sum over the duration of the shipments to generate the total number of hours that have to be planned
total_hours_input = 0
for ship_id, ship_data in base_shipments_data.items():
    ship_duration = ship_data['earliest_end_time'] - ship_data['earliest_start_time']
    total_hours_input += ship_duration

# Analyze the solution

# Determine different variables of the solution that could be insightful
total_waiting_time = 0
total_empty_driving_time = 0
total_pull_out_time = 0
total_pull_in_time = 0
total_shipment_time_check = 0
total_hours_planned = 0
truck_trip_durations = []
truck_trip_driving_time = []

# Define functions to make the code better readable
def start_loc_ith_trip_in_cycle(j):
    shipment = cycle[j][cycle[j].index('_') + 1:]
    return shipments_data[shipment]['start_location']

def end_loc_ith_trip_in_cycle(j):
    shipment = cycle[j][cycle[j].index('_') + 1:]
    return shipments_data[shipment]['end_location']

def driving_time_from_ith_trip_to_next_trip(j):
    return time_diff_matrix.at[end_loc_ith_trip_in_cycle(j), start_loc_ith_trip_in_cycle(j + 1)]

def start_time_ith_trip_in_cycle(j):
    shipment = cycle[j][cycle[j].index('_') + 1:]
    return shipments_data[shipment]['start_time']

def end_time_ith_trip_in_cycle(j):
    shipment = cycle[j][cycle[j].index('_') + 1:]
    return shipments_data[shipment]['end_time']

def duration_ith_trip_in_cycle(j):
    return end_time_ith_trip_in_cycle(j) - start_time_ith_trip_in_cycle(j)

def get_depot_from_cycle(cycle):
    depot = cycle[0][:cycle[0].index('_')]
    return depot

def get_duration_from_cycle(cycle):
    first_ship_id = cycle[1][cycle[1].index('_') + 1:]
    last_ship_id = cycle[-2][cycle[-2].index('_') + 1:]
    duration = time_diff_matrix.at[get_depot_from_cycle(cycle), shipments_data[first_ship_id]['start_location']] + \
               (shipments_data[last_ship_id]['end_time'] - shipments_data[first_ship_id]['start_time']) + \
               time_diff_matrix.at[shipments_data[last_ship_id]['end_location'], get_depot_from_cycle(cycle)]
    return duration

for cycle in cycles:
    depot = get_depot_from_cycle(cycle)
    # Pull out trips
    pull_out_time = time_diff_matrix.at[depot, start_loc_ith_trip_in_cycle(1)]
    total_pull_out_time += pull_out_time
    # Shipment trips
    shipment_time = 0
    for i in range(len(cycle) - 2):
        one_shipment_time = end_time_ith_trip_in_cycle(i + 1) - start_time_ith_trip_in_cycle(i + 1)
        shipment_time += one_shipment_time
    total_shipment_time_check += shipment_time
    # Driving empty in between shipments
    empty_driving_time = 0
    for i in range(len(cycle) - 3):
        one_empty_driving_time = time_diff_matrix.at[
            end_loc_ith_trip_in_cycle(i + 1), start_loc_ith_trip_in_cycle(i + 2)]
        empty_driving_time += one_empty_driving_time
    total_empty_driving_time += empty_driving_time
    # Waiting time in between shipments
    waiting_time = 0
    for i in range(len(cycle) - 3):
        one_waiting_time = start_time_ith_trip_in_cycle(i + 2) - end_time_ith_trip_in_cycle(i + 1) - \
                           time_diff_matrix.at[end_loc_ith_trip_in_cycle(i + 1), start_loc_ith_trip_in_cycle(i + 2)]
        waiting_time += one_waiting_time
    total_waiting_time += waiting_time
    # Pull in trips
    pull_in_time = time_diff_matrix.at[end_loc_ith_trip_in_cycle(len(cycle) - 2), depot]
    total_pull_in_time += pull_in_time
    # Durations
    truck_trip_durations.append(round(get_duration_from_cycle(cycle), 2))
    driving_time = round(
        pull_out_time - (len(cycle) - 2) * loading_time + shipment_time + empty_driving_time + pull_in_time, 2)
    truck_trip_driving_time.append(driving_time)

number_too_long_duration = 0
for h in truck_trip_durations:
    if h > max_duration:
        number_too_long_duration += 1

number_too_long_driving_time = 0
for h in truck_trip_durations:
    if h > max_driving_time:
        number_too_long_driving_time += 1

for h in truck_trip_durations:
    total_hours_planned += h

inefficiency_percentage = (total_hours_planned - total_hours_input) / total_hours_planned
inefficiency_percentage_no_pull_arcs = (total_hours_planned - total_hours_input - total_pull_out_time -
                                        total_pull_in_time) / total_hours_planned

# Print the different variables
print('The total waiting time is: ', str(round(total_waiting_time, 2)), ' hours')
print('The total empty driving time is: ', str(total_empty_driving_time), ' hours')
print('The total pull out time is: ', str(total_pull_out_time), ' hours')
print('The total pull in time is: ', str(total_pull_in_time), ' hours')
print('The durations of the truck trips are: ', str(truck_trip_durations))
print('Of which ', number_too_long_duration, ' are too long')
print('The total number of hours driving is: ', str(truck_trip_driving_time))
print('Of which ', number_too_long_driving_time, ' are too long')
print('The total hours of input is: ', str(round(total_hours_input, 2)), ' hours')
print('The total hours planned is: ', str(round(total_hours_planned, 2)), ' hours')
print('The inefficiency percentage (i.e. percentage of hours in planning that is devoted to something else than '
      'executing shipments) is: ', str(round(100 * inefficiency_percentage, 2)), '%')
print('The inefficiency percentage without pull out/in is: ', str(round(100 * inefficiency_percentage_no_pull_arcs, 2)),
      '%')

def get_driving_time_from_cycle(cycle):
    cycle_index = cycles.index(cycle)
    driving_time = truck_trip_driving_time[cycle_index]
    return driving_time

# Find reliefpoints
relief_dict = {}
for cycle in cycles:
    cycle_key = tuple(cycle)
    depot = get_depot_from_cycle(cycle)
    relief_dict[cycle_key] = []
    for i in range(len(cycle) - 2):
        if start_loc_ith_trip_in_cycle(i + 1) == depot:
            relief_dict[cycle_key].append(start_time_ith_trip_in_cycle(i + 1))
        if end_loc_ith_trip_in_cycle(i + 1) == depot:
            relief_dict[cycle_key].append(end_time_ith_trip_in_cycle(i + 1))

# ------------------------------------- Visualize solution as Gantt Chart -------------------------------------------

# figure parameters
bar_height = 3
space_between_bars = 3
space_below_lowest_bar = 3
space_above_highest_bar = 3

# Constructing the figure
fig, gnt = plt.subplots(figsize=(20, 10))
fig = plt.subplots_adjust(right=0.58)

plt.title('Visualization optimal solution of MDVSPTW')
gnt.grid(False)

# Constructing the axes
# x axis
gnt.set_xlim(-1, 23)
gnt.set_xlabel('Time')
gnt.set_xticks([i for i in range(23)])
gnt.set_xticklabels(['04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00',
                     '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00', '00:00', '01:00', '02:00'],
                    fontsize=6, rotation=30)

# y axis
gnt.set_ylabel('Truck Trips')
gnt.set_ylim(0, number_of_vehicles * (bar_height + space_between_bars) + space_above_highest_bar)
gnt.set_yticks([space_below_lowest_bar + 0.5 * bar_height + (bar_height + space_between_bars) * i for i in
                range(number_of_vehicles)])
gnt.set_yticklabels((i + 1 for i in range(number_of_vehicles)), fontsize=8)

# Constructing bars for different type of activities in a truck trip
y = space_below_lowest_bar

for cycle in cycles:
    depot = get_depot_from_cycle(cycle)
    # Pull out trips
    if depot == 'DC1':
        gnt.broken_barh([(start_time_ith_trip_in_cycle(1) - time_diff_matrix.at[depot, start_loc_ith_trip_in_cycle(1)],
                          time_diff_matrix.at[start_loc_ith_trip_in_cycle(1), depot])],
                        (y, bar_height), facecolors='tab:cyan', edgecolor='black')
    elif depot == 'Ermelo':
        gnt.broken_barh([(start_time_ith_trip_in_cycle(1) - time_diff_matrix.at[depot, start_loc_ith_trip_in_cycle(1)],
                          time_diff_matrix.at[start_loc_ith_trip_in_cycle(1), depot])],
                        (y, bar_height), facecolors='tab:green', edgecolor='black')
    else:
        gnt.broken_barh([(start_time_ith_trip_in_cycle(1) - time_diff_matrix.at[depot, start_loc_ith_trip_in_cycle(1)],
                          time_diff_matrix.at[start_loc_ith_trip_in_cycle(1), depot])],
                        (y, bar_height), facecolors='tab:purple', edgecolor='black')
    # Shipment trips
    for i in range(len(cycle) - 2):
        gnt.broken_barh([(start_time_ith_trip_in_cycle(i + 1),
                          duration_ith_trip_in_cycle(i + 1))],
                        (y, bar_height), facecolors='tab:orange', edgecolor='black')
    # Driving empty in between shipments
    for i in range(len(cycle) - 3):
        gnt.broken_barh([(end_time_ith_trip_in_cycle(i + 1),
                          driving_time_from_ith_trip_to_next_trip(i + 1))],
                        (y, bar_height), facecolors='tab:blue', edgecolor='black')
    # Waiting time in between shipments
    for i in range(len(cycle) - 3):
        gnt.broken_barh([(end_time_ith_trip_in_cycle(i + 1) + driving_time_from_ith_trip_to_next_trip(i + 1),
                          start_time_ith_trip_in_cycle(i + 2) - end_time_ith_trip_in_cycle(i + 1) -
                          driving_time_from_ith_trip_to_next_trip(i + 1))],
                        (y, bar_height), facecolors='tab:grey', edgecolor='black')
    # Pull in trips
    if depot == 'DC1':
        gnt.broken_barh([(end_time_ith_trip_in_cycle(len(cycle) - 2),
                          time_diff_matrix.at[end_loc_ith_trip_in_cycle(len(cycle) - 2), depot])], (y, bar_height),
                        facecolors='tab:cyan', edgecolor='black', label=str(cycle[len(cycle) - 2]))
    elif depot == 'Ermelo':
        gnt.broken_barh([(end_time_ith_trip_in_cycle(len(cycle) - 2),
                          time_diff_matrix.at[end_loc_ith_trip_in_cycle(len(cycle) - 2), depot])], (y, bar_height),
                        facecolors='tab:green', edgecolor='black', label=str(cycle[len(cycle) - 2]))
    else:
        gnt.broken_barh([(end_time_ith_trip_in_cycle(len(cycle) - 2),
                          time_diff_matrix.at[end_loc_ith_trip_in_cycle(len(cycle) - 2), depot])], (y, bar_height),
                        facecolors='tab:purple', edgecolor='black', label=str(cycle[len(cycle) - 2]))
    # Reliefpoints
    cycle_key = tuple(cycle)
    if get_duration_from_cycle(cycle) <= max_duration and get_driving_time_from_cycle(cycle) <= max_driving_time:
        for relief_time in relief_dict[cycle_key]:
            gnt.annotate('', (relief_time, y + bar_height),
                         xytext=(relief_time, y + bar_height + 2),
                         arrowprops=dict(width=1.5, headwidth=3, headlength=2, facecolor='pink', edgecolor='pink',
                                         shrink=0.05), fontsize=6, horizontalalignment='right', verticalalignment='top')
    if get_duration_from_cycle(cycle) <= max_duration and get_driving_time_from_cycle(cycle) > max_driving_time:
        for relief_time in relief_dict[cycle_key]:
            gnt.annotate('', (relief_time, y + bar_height),
                         xytext=(relief_time, y + bar_height + 2),
                         arrowprops=dict(width=1.5, headwidth=3, headlength=2, facecolor='maroon', edgecolor='maroon',
                                         shrink=0.05), fontsize=6, horizontalalignment='right', verticalalignment='top')
    if get_duration_from_cycle(cycle) > max_duration:
        for relief_time in relief_dict[cycle_key]:
            gnt.annotate('', (relief_time, y + bar_height),
                         xytext=(relief_time, y + bar_height + 2),
                         arrowprops=dict(width=1.5, headwidth=3, headlength=2, facecolor='r', edgecolor='r',
                                         shrink=0.05), fontsize=6, horizontalalignment='right', verticalalignment='top')

    # Step up in y direction
    y += bar_height + space_between_bars

# Constructing the legend
legend_elements = [Patch(edgecolor='black', facecolor='tab:orange', linewidth=0.5, label='Shipment'),
                   Patch(edgecolor='black', facecolor='tab:cyan', linewidth=0.5, label='Stem trips DC'),
                   Patch(edgecolor='black', facecolor='tab:purple', linewidth=0.5, label='Stem trips FC'),
                   Patch(edgecolor='black', facecolor='tab:green', linewidth=0.5, label='Stem trips Ermelo'),
                   Patch(edgecolor='black', facecolor='tab:blue', linewidth=0.5, label='Empty Driving'),
                   Patch(edgecolor='black', facecolor='tab:grey', linewidth=0.5, label='Waiting'),
                   Line2D([], [], color='r', marker='$\downarrow$', markersize=8,
                          label='Reliefpoint on trip with too long duration', lw=0),
                   Line2D([], [], color='maroon', marker='$\downarrow$', markersize=8,
                          label='Reliefpoint on trip with too long driving time', lw=0),
                   Line2D([], [], color='pink', marker='$\downarrow$', markersize=8,
                          label='Reliefpoint on feasible trip', lw=0)]
gnt.legend(handles=legend_elements, bbox_to_anchor=(1.05, 1), loc='upper left')

# Printing analytics in the gantt chart
txt = \
    'Total waiting time is: ' + str(round(total_waiting_time, 2)) + ' hours \n' + 'Total empty driving time ' \
                                                                                'and stem time is: ' + str(
        total_empty_driving_time + total_pull_in_time + total_pull_out_time) + ' hours \n' + \
    'Total number of hours planned is: ' + str(round(total_hours_planned, 2)) + ' hours \n' + \
    'Total hours of input was: ' + str(round(total_hours_input, 2)) + ' hours \n' + 'The inefficiency is: {0}%'.format(
        str(round(100 * inefficiency_percentage, 2))) + '\n' + \
    'The inefficiency without stem trips is: ' + str(round(100 * inefficiency_percentage_no_pull_arcs, 2)) + '%'

plt.text(1.05, 0.3, txt, horizontalalignment='left',
         verticalalignment='center', transform=gnt.transAxes)

# Save the figure
plt.savefig("figures/gantt chart MDVSPTW TSN.png")


import pandas as pd

def write_styling_excel_file(path: str, df: pd.DataFrame, sheet_name: str, index=False):
    "Функция записывает файл, атоматически расширяя столбцы до 45"

    with pd.ExcelWriter(path) as writer:
        df.to_excel(writer, sheet_name=sheet_name, index=index, na_rep='NaN')

        # автонастройка ширины колонок
        # решил что больше ничего и не нужно
        for column in df:
            width = max(df[column].astype(str).map(len).max(), len(column))
            width += 5
            if width > 45:
                width = 45

            col_idx = df.columns.get_loc(column)
            writer.sheets[sheet_name].set_column(col_idx, col_idx, width)

        if index:
            for _ in df.index.names:
                col_idx = df.index.names.index(_)
                width = 35
                writer.sheets[sheet_name].set_column(col_idx, col_idx, width)

        writer.save()


import matplotlib.pyplot as plt
import numpy as np

class Environment():

    # constructor function

    def __init__(self, water, air):

        self.water = water    # water temperature
        self.air = air        # air temperature

        self.dt = water - air  #temperature difference between water and air

class Plant():

    # set up constants for use in chloroplast activity

    A = 0.004547
    B = 0.9901
    C = 4.064

    # set up constants for temperature based activity

    TEMP_MAX = 37.1  #max temp
    TEMP_OPT = 24.6  #optimum temp

    RATE_MAX = 0.19  #greatest rate

    Instances = []

    # constructor function - define parameters for specific object

    def __init__(self, light, temp, surface_area, environment):

        Plant.Instances.append(self)

        self.light = light
        self.temp = temp
        self.surface_area = surface_area
        self.environment = environment     # literal environment object

        self.growth_light = self.calculate_light()
        self.growth_temp = self.calculate_temp()
        self.loss_rate = self.calculate_loss()

    # returns energy gained via light

    def calculate_light(self):

        light = self.light
        growth = light / ((Plant.A * (light ** 2)) + (Plant.B * light) + Plant.C)

        return growth

    # returns energy gained via temperature

    def calculate_temp(self):

        temp = self.temp
        #multiplied by 4 to ensure that light and heat had equal importance
        growth = (Plant.RATE_MAX * ((Plant.TEMP_MAX - temp)/(Plant.TEMP_MAX - Plant.TEMP_OPT)) * (temp / Plant.TEMP_OPT)) * 4

        return growth

    # return energy lost via convection

    def calculate_loss(self):

        environment = self.environment
        loss = self.surface_area * 3000 * environment.dt

        return loss

    # simple function - prints all calculations made for debugging

    def debug_calculation(self):

        print('\n\nplant gains: ', self.growth_light, ' via light')
        print('plant gains: ', self.growth_temp, ' via temperature')
        print('plant loses: ', self.loss_rate, ' via convection')

        print('\nplant overall gains/loses: ', self.growth_light + self.growth_temp)
        print('\The temperature dropped by: ', self.loss_rate)

Garden = Environment(30, 29.5)

#range of surrounding stimuli
temps = [0, 37.1 ,0.1]
lights = [0,801,1]

surface_area = 0.5

#list for heat map
Energy_Levels = []

#this loop creates the rows of the heat map

#runs throught each possible temperature
#changes the floats into integers
for temp in range(int((temps[1]-temps[0])//temps[2])):

    #each temperature has its own row
    row = []

    #changes the floats into integers
    for light in range(int((lights[1]-lights[0])//lights[2])):

        #returns original value
        plant_temp = temp * temps[2] + temps[0]
        plant_light = light * lights[2] + lights[0]

        #enters detail into classes to create an object
        a = Plant(plant_light, plant_temp, surface_area, Garden)

        #calculates total growth from light and temperature function
        row.append(a.growth_light + a.growth_temp)

    Energy_Levels.append(row)

#this makes the graph neater
fig, ax = plt.subplots()

#this creates a heat map, the brighter the area, the greater the rate of growth in that situation
plt.imshow(Energy_Levels, cmap='hot', interpolation='nearest')
#this flips the y axis
plt.gca().invert_yaxis()
#labels
plt.xlabel('Light Intensity (W/m^2)')
plt.ylabel('Temperature (°C)')
plt.title('Growth rate depending on light and temperature')

#this was to make sure that temperature was between 0 and 37 rather than measuring the instances
fig.canvas.draw()
labels = [item.get_text() for item in ax.get_yticklabels()]
labels = list(map(int, labels[1:]))
print(labels)

newlabels = [0]
for i in labels:
    i = i/10
    newlabels.append(i)

#replaces the tick labels
ax.set_yticklabels(newlabels)
plt.show()

#---------------------------------------------------------
# JASAMRIT RAHALA copyright 07799000145 (Helped us in writing the code)
#----------------------------------------------------------


from datetime import datetime

import feature_2

def main():
    start = datetime.now()
    feature_2.main()
    end = datetime.now()
    processing_time = (end-start).total_seconds() * 1000
    print(f"Start time: {start}.")
    print(f"End time: {end}.")
    print(f"Processing time: {processing_time} milliseconds.")

if __name__ == "__main__" :
    main()


import math
import numpy as np

with open("Tag-5/input.txt", "rt") as myfile:
    contents = myfile.read()

seats = contents.splitlines()

# part 1

seatIDs = np.zeros(len(seats))
for n, seatcode in enumerate(seats):

    row_string = seatcode[0:8]
    max = 127
    min = 0
    for c in row_string:
        if c == "F":
            max = math.floor(max - (max - min) / 2)
        if c == "B":
            min = math.ceil(min + (max - min) / 2)
    row = max

    column_string = seatcode[7:]
    max = 7
    min = 0
    for c in column_string:
        if c == "L":
            max = math.floor(max - (max - min) / 2)
        if c == "R":
            min = math.ceil(min + (max - min) / 2)
    column = max

    seatIDs[n] = row * 8 + column

np_seatIDs = np.array(seatIDs)
print(np.max(np_seatIDs))

# part 2

sorted_seatIDs = np.sort(np_seatIDs)

first_seat = sorted_seatIDs[0]
offset = 0

for n, seat in enumerate(sorted_seatIDs):
    if not (seat == (n + offset + first_seat)):
        print(seat - 1)
        offset += 1


# 4. Faça um Programa que verifique se o e-mail digitado faz
# parte dos e-mails de spam.

mail_spam= 'gmail.com'

mail= input('Digite o e-mail para verificar se é spam: ')
separador = mail.split(sep=	'@')

if separador[1] == mail_spam:
    print(f'O email digitado está dentro da relação de spam {mail_spam}')


from __future__ import annotations
from typing import Optional, TYPE_CHECKING
from PyQt5.QtWidgets import QMainWindow

from src.machine.rfid import RFIDReader
from src.dialog_handler import UI_LANGUAGE
from src.display_controller import DP_CONTROLLER
from src.ui.setup_keyboard_widget import KeyboardWidget
from src.ui_elements.rfidwriter import Ui_RFIDWriterWindow

if TYPE_CHECKING:
    from src.ui_elements import Ui_MainWindow

class RFIDWriterWindow(QMainWindow, Ui_RFIDWriterWindow):
    """ Class for the Option selection window. """

    def __init__(self, mainscreen: Ui_MainWindow):
        super().__init__()
        self.setupUi(self)
        DP_CONTROLLER.initialize_window_object(self)
        self.mainscreen = mainscreen

        self.button_back.clicked.connect(self._close_window)
        self.button_write.clicked.connect(self._write_rfid)
        self.input_text.clicked.connect(lambda: self._open_keyboard(self.input_text))

        self.keyboard_window: Optional[KeyboardWidget] = None
        self.rfid = RFIDReader()

        UI_LANGUAGE.adjust_rfid_reader_window(self)
        self.showFullScreen()
        DP_CONTROLLER.set_display_settings(self)

    def _write_rfid(self):
        """Try to write the label to the RFID"""
        text = self.input_text.text()
        if len(text) < 3:
            self.label_information.setText(UI_LANGUAGE.get_rfid_information_display("error"))
            return
        self.label_information.setText(UI_LANGUAGE.get_rfid_information_display("prompt"))
        self.button_write.setDisabled(True)
        self.rfid.write_rfid(text, self._display_success)

    def _close_window(self):
        self.rfid.cancel_reading()
        self.close()

    def __del__(self):
        self.rfid.cancel_reading()

    def _display_success(self, _: str):
        self.label_information.setText(UI_LANGUAGE.get_rfid_information_display("success"))
        self.button_write.setDisabled(False)

    def _open_keyboard(self, le_to_write, max_char_len=30):
        """ Opens up the keyboard connected to the lineedit """
        self.keyboard_window = KeyboardWidget(self.mainscreen, le_to_write=le_to_write, max_char_len=max_char_len)


# 导入需要的库
import numpy as np
import torch
import torch.nn as nn
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import warnings
from scipy.stats import norm, skew

# 导入封装好的模型算法
from sklearn.linear_model import LogisticRegression
from sklearn import tree
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier

# 定义evaluate函数用来评价在test集上的表现
def evaluate_on_train(predictions, y_train):
    acc = 0
    for i in range(len(y_train)):
        if predictions[i] == y_train[i]:
            acc += 1
    return acc / len(y_train)

# 定义忽略警告函数
def ignore_warn(*args, **kwargs):
    pass

warnings.warn = ignore_warn

# 限制floats类型的数据输出为小数点后3位
pd.set_option('display.float_format', lambda x: '{:.3f}'.format(x))

# 导入数据
train = pd.read_csv("./data/train.csv")
test = pd.read_csv("./data/test.csv")

# 观察数据
# print("[INFO] train dataset: {}".format(train.head(5)))
# print("[INFO] test_code dataset: {}".format(test_code.head(5)))

# 得到训练数据和测试数据的总数
# print("[INFO] train size is : {}".format(train.shape[0]))
# print("[INFO] test_code size is : {}".format(test_code.shape[0]))

# [INFO] train size is : 8693
# [INFO] test_code size is : 4277

# 根据上述结果展示可以看到训练数据集占比为2/3，测试数据集占比为1/3

# 保存train和test中的Id列
train_Id = train["PassengerId"]
test_Id = test["PassengerId"]

# 由于Id对训练数据没有影响，因此去除掉Id列
train.drop("PassengerId", axis=1, inplace=True)
test.drop("PassengerId", axis=1, inplace=True)

# -----------------------------数据预处理------------------------------------
# 得到train和test数据集的长度
ntrain = train.shape[0]
ntest = test.shape[0]

# 得到train中的标签
y_train = train["Transported"]
y_train = y_train.astype(int)  # 将bool转换为int类型，从而实现false/true到0/1的转换

# 合并train和test数据集
all_data = pd.concat((train, test)).reset_index(drop=True)
all_data.drop("Transported", axis=1, inplace=True)

# 查看数据的丢失率
# all_data_na = (all_data.isnull().sum() / len(all_data)) * 100
# # 得到前30个数据丢失率对应的属性
# all_data_na = all_data_na.drop(all_data_na[all_data_na == 0].index).sort_values(ascending=False)
#
# # 得到丢失数据情况字典，便于后续展示
# missing_data = pd.DataFrame({'Missing Ratio': all_data_na})
#
# print(missing_data)

# 查看所有属性对label的影响
# 展示所有的属性对Transported的影响

# corrmat = train.corr()
# plt.subplots(figsize=(12, 9))
# sns.heatmap(corrmat, vmax=0.9, square=True)
# plt.show()

# ----------------------对all_data中需要作为features使用的数据进行填充---------------------
# 1.对字符类型和Bool类型的使用None进行填充，对数字类型使用0进行填充
# all_data["ShoppingMall"] = all_data["ShoppingMall"].fillna(0)
# all_data["VIP"] = all_data["VIP"].fillna("None")
# all_data["HomePlanet"] = all_data["HomePlanet"].fillna("None")
# all_data["CryoSleep"] = all_data["CryoSleep"].fillna("None")
# all_data["VRDeck"] = all_data["VRDeck"].fillna(0)
# all_data["FoodCourt"] = all_data["FoodCourt"].fillna(0)
# all_data["RoomService"] = all_data["RoomService"].fillna(0)
# all_data["Age"] = all_data["Age"].fillna(0)

# 参考链接：https://www.kaggle.com/code/viktortaran/space-titanic-0-80336-from-neophyte
# 2.使用上述参考链接填充模式代码
all_data["CryoSleep"] = all_data["CryoSleep"].fillna("Unknown")

# 增加相加的属性
all_data1 = all_data
all_data1["Expenses"] = all_data1.iloc[:, 7: 12].sum(axis=1)

# 设置CroySleep属性为新属性和老属性的综合结果
def CroySleep_fill(x, y):
    if x == "Unknown" and y == 0:
        return True
    elif x == "Unknown" and y != 0:
        return False
    else:
        return x

# 给CryoSleep属性重新设置属性值
all_data1["CryoSleep"] = all_data1[["CryoSleep", "Expenses"]].apply(lambda row: CroySleep_fill(row["CryoSleep"],
                                                                                row["Expenses"]), axis=1)

# 重新设置CryoSleep属性，设置为False
all_data["CryoSleep"] = all_data["CryoSleep"].astype('bool')

# print(all_data["CryoSleep"].describe())

# 对新生成的属性Expense的处理
# 得到生成新属性的原始属性的Mean值
RoomService_mean = all_data.loc[all_data.CryoSleep == 0].RoomService.mean()
FoodCourt_mean = all_data.loc[all_data.CryoSleep == 0].FoodCourt.mean()
ShoppingMall_mean = all_data.loc[all_data.CryoSleep == 0].ShoppingMall.mean()
Spa_mean = all_data.loc[all_data.CryoSleep == 0].Spa.mean()
VRDeck_mean = all_data.loc[all_data.CryoSleep == 0].VRDeck.mean()

# 对7-12列的属性，进行空缺值填充
all_data.iloc[:, 7: 12] = all_data.iloc[:, 7: 12].fillna("Unknown")

# print("before, null values is :\n{}".format(all_data.isnull().sum()))

# 设置填充的函数
def fill_in(x, y, mean):
    if x == True and y == "Unknown":
        return 0
    elif x == False and y == "Unknown":
        return mean
    else:
        return y

# all_data['RoomService'] = all_data[['CryoSleep', 'RoomService']].apply(
#     lambda row: fill_in(row['CryoSleep'], row['RoomService'], RoomService_mean), axis=1)

# 使用mean中值填充
all_data['RoomService'] = all_data['RoomService'].fillna(RoomService_mean)

# print("RoomService null values size is : {}".format(all_data['RoomService'].isnull().sum()))

all_data['FoodCourt'] = all_data[['CryoSleep', 'FoodCourt']].apply(
    lambda row: fill_in(row['CryoSleep'], row['FoodCourt'], FoodCourt_mean), axis=1)
all_data['ShoppingMall'] = all_data[['CryoSleep', 'ShoppingMall']].apply(
    lambda row: fill_in(row['CryoSleep'], row['ShoppingMall'], ShoppingMall_mean), axis=1)
all_data['Spa'] = all_data[['CryoSleep', 'Spa']].apply(
    lambda row: fill_in(row['CryoSleep'], row['Spa'], Spa_mean), axis=1)
all_data['VRDeck'] = all_data[['CryoSleep', 'VRDeck']].apply(
    lambda row: fill_in(row['CryoSleep'], row['VRDeck'], VRDeck_mean), axis=1)

# 使用“Unknown Unknown”对Name属性进行填充
all_data.Name = all_data.CryoSleep.fillna("Unknown Unknown")

# 填充HomePlanet和Destination
from sklearn.preprocessing import OrdinalEncoder

ordinal_encoder = OrdinalEncoder()
object_cols = ['HomePlanet', 'Destination']
all_data.HomePlanet = all_data.HomePlanet.fillna('Earth')
all_data.Destination = all_data.Destination.fillna('PSO J318.5-22')
all_data[object_cols] = ordinal_encoder.fit_transform(all_data[object_cols])

# 填充Age属性
Age_mean_adult = all_data.loc[all_data.Expenses > 0].Age.mean()
Age_mean_kids = all_data.loc[all_data.Expenses == 0].Age.mean()
Age_mean_all = all_data.Age.mean()

# 定义填充年龄的函数
def fill_in_age(x):
    if x > 0:
        return Age_mean_adult
    elif x == 0:
        return Age_mean_kids
    else:
        return

# 直接使用age_mean_adult数值进行填充
all_data["Age"] = all_data["Age"].fillna(Age_mean_adult)

# 填充VIP
all_data["VIP"] = all_data["VIP"].fillna(0)

# 填充Cabin属性
all_data.Cabin.str.split("/", expand=True)

# 得到两个新属性
all_data['Cabin_Deck'] = all_data.Cabin.str.split("/", expand=True)[0]
all_data['Cabin_Side'] = all_data.Cabin.str.split("/", expand=True)[2]

# 填充得到的关于Cabin属性值
all_data['Cabin_Deck'] = all_data['Cabin_Deck'].fillna("F")
all_data['Cabin_Side'] = all_data['Cabin_Side'].fillna("P")

object_cols_1 = ['Cabin_Side', 'Cabin_Deck']
all_data[object_cols_1] = ordinal_encoder.fit_transform(all_data[object_cols_1])

# print("after, null values is :\n{}".format(all_data.isnull().sum()))

# --------------------------进行更多的特征工程-----------------------------
# -----------Skewed features，倾斜特征-----------
# numeric_feats = all_data.dtypes[all_data.dtypes != "object"].index
# skewed_feats = all_data[numeric_feats].apply(lambda x: skew(x.dropna())).sort_values(ascending=False)
# # print("\nSkew in numerical features: \n")
# skewness = pd.DataFrame({'Skew': skewed_feats})
# # skewness.head(10)
# # （高度）偏斜特征的 Box Cox 变换
# skewness = skewness[abs(skewness) > 0.75]
# # print("There are {} skewed numerical features to Box Cox transform".format(skewness.shape[0]))
#
# from scipy.special import boxcox1p
# skewed_features = skewness.index
# lam = 0.15
# for feat in skewed_features:
#     # all_data[feat] += 1
#     all_data[feat] = boxcox1p(all_data[feat], lam)

# --------------------------得到需要的特征-------------------------
# 选择其中对Transported标签影响较大的属性
features = ['HomePlanet','CryoSleep', 'Destination',
            'Age','VIP','RoomService',
            'FoodCourt','ShoppingMall',
            'Spa','VRDeck','Expenses',
            'Cabin_Deck','Cabin_Side']

# 原来使用的属性：["HomePlanet", "CryoSleep", "Age", "VRDeck", "VIP", "ShoppingMall", "FoodCourt", "RoomService"]

# 得到独热编码
all_data = pd.get_dummies(all_data[features])

# 得到训练集和测试集
# 得到新的训练集和测试集
new_X_train = all_data[:ntrain]
new_X_test = all_data[ntrain:]
# print("[INFO] train features shape is: {}, test_code features shape is: {}".format(new_X_train.shape, new_X_test.shape))

# ---------------------------初始化模型算法-------------------------

# ----------------------使用随机森林来实现分类-------------------
rfc = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)
# rfc.fit(new_X_train, y_train)
# predictions = rfc.predict(new_X_test)

# --------------------------使用LR算法--------------------
lr = LogisticRegression(max_iter=2000)
# lr.fit(new_X_train, y_train)
# predictions = lr.predict(new_X_test)

# # -----------------使用kNN最近邻算法--------------------
knn = KNeighborsClassifier()
# knn.fit(new_X_train, y_train)
# predictions = knn.predict(new_X_test)

# -----------------使用决策树算法---------------
dt = tree.DecisionTreeClassifier(random_state=1)
# dt.fit(new_X_train, y_train)
# predictions = dt.predict(new_X_test)

# ---------------使用SVC算法-----------
svc = SVC(probability=True)
svc.fit(new_X_train, y_train)
predictions = svc.predict(new_X_test)

# 使用XGBClassifier算法
xgb = XGBClassifier(random_state=1)
# xgb拟合数据，在train上训练
# xgb.fit(new_X_train, y_train)
# predictions = xgb.predict(new_X_train)
# 使用xgb算法在test数据集上进行测试
# predictions = xgb.predict(new_X_test)

# 使用投票策略集成模型
voting_classifier = \
    VotingClassifier(estimators=[('lr', lr), ('knn', knn), ('rfc', rfc), ('svc', svc), ('xgb', xgb)], voting='soft')
# 模型拟合训练样本
# voting_classifier.fit(new_X_train, y_train)
# 查看在train dataset上的train_acc
# predictions = voting_classifier.predict(X_train)
# 得到在test数据集上的结果
# predictions = voting_classifier.predict(new_X_test)

# 得到train_acc
# train_acc = evaluate_on_train(predictions, y_train)
# print("[INFO] train_acc is {}".format(train_acc))

new_predictions = []
# 将predictions转换为true或false
for i, label in enumerate(predictions):
    if label == 1:
        new_predictions.append(True)
    else:
        new_predictions.append(False)

# print("[INFO] After transfer, predictions is : {}".format(new_predictions))

# 处理结果
output = pd.DataFrame({'PassengerId': test_Id, 'Transported': new_predictions})
output.to_csv("./submission/202208011904_SVC_classifier_submit.csv", index=False)
print("[INFO] Submission was successfully saved!")


import unittest
from solution import concat_files
from subprocess import call

class ConcatTest(unittest.TestCase):
    """docstring for ConcatTest"""
    def setUp(self):
        call('echo \'File1\' > file1', shell=True)
        call('echo \'File2\' > file2', shell=True)

    def test_concat(self):
        expected_output = 'File1\n\nFile2\n\n'
        call('py solution.py file1 file2', shell=True)
        target_file = open('MEGATRON', 'r')
        output = target_file.read()
        target_file.close()
        self.assertEqual(expected_output, output)

    def tearDown(self):
        call('rm file1 file2 MEGATRON', shell=True)

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


import calculables, samples, steps, supy, ROOT as r

class isoLook(supy.analysis) :
    def parameters(self) :
        GeV=1000.
        objects =  {'jet'  : ('jet_AntiKt4LCTopo_',''),
                    'met'  : ('MET_RefFinal_STVF_',''),
                    'muon' : ('mu_staco_',''),
                    'ele'  : ('el_','')
                    }
        lepton = self.vary()
        fieldsLepton =    ['name', 'ptMin', 'etaMax',   'isoVar', 'isoType']
        muonParameters =  ['muon',  20*GeV,      2.4, 'ptcone30', 'relative']
        eleParameters  =  ['ele',   20*GeV,      2.4, '',         '']
        lepton['mujets'] = dict(zip(fieldsLepton, muonParameters))
        lepton['mujets']['isoVars'] = ['etcone20', 'ptcone30']
        lepton['ejets'] = dict(zip(fieldsLepton, eleParameters))
        lepton['ejets']['isoVars'] = ['Etcone20', 'Etcone20_pt_corrected', 'ptcone30']
        #leptons['eljets'] = dict(zip(fieldsLepton, ['electron',  10,      2.4, '??',       'relative']))

        return {'objects'  : objects, 'lepton'   : lepton,
                'muon':  dict(zip(fieldsLepton, muonParameters)),
                'ele' :  dict(zip(fieldsLepton, eleParameters)),
                'minJetPt' : 10.0*GeV,
            }
    def listOfSteps(self,config) :
        ss = supy.steps
        shv = ss.histos.value
        shpt, shmass = ss.histos.pt, ss.histos.mass
        shaeta, sheta = ss.histos.absEta, ss.histos.eta
        pi = r.TMath.Pi()
        MeV2GeV = 1.0e+3
        objects = config['objects']
        isoVars = config['lepton']['isoVars']
        leptonObj = objects[config['lepton']['name']]
        lsteps = []
        lsteps += [ss.printer.progressPrinter()]
        #lsteps += [ss.printer.printstuff(['Indices'.join(objects['muon'])])]
        lsteps += [ss.filters.multiplicity('Indices'.join(leptonObj), min=1),]
        lsteps += [ss.histos.multiplicity('Indices'.join(leptonObj), 10),]
        lsteps += [shv(iv.join(leptonObj), 25, -4.*MeV2GeV, 26.*MeV2GeV, 'Indices'.join(leptonObj))
                   for iv in isoVars]

        return lsteps

    def listOfCalculables(self,config) :
        cg, cm = calculables.gen, calculables.muon
        objects = config['objects']
        muon = config['muon']
        ele = config['ele']
        lcals =  supy.calculables.zeroArgs(supy.calculables)
        lcals += [cm.Indices(objects['muon'], muon['ptMin'], muon['etaMax'])]
        lcals += supy.calculables.fromCollections(calculables.muon, [objects['muon'],])
        lcals += [cm.Indices(objects['ele'], ele['ptMin'], ele['etaMax'])]
        lcals += supy.calculables.fromCollections(calculables.electron, [objects['ele'],])

        return lcals

    def listOfSampleDictionaries(self) :
        return [samples.localTmp]

    def listOfSamples(self,config) :
        test = False #True
        nEventsMax= 1000 if test else None
        samples = ['tt-af',  'tt-fs',
                   'tHu-af', 'tHu-fs',
                   'tHb-af', 'tHb-fs',]
        return (
            supy.samples.specify(names ='tt-fs', nEventsMax=nEventsMax, color = r.kBlack, markerStyle = 20)
            +supy.samples.specify(names ='tt-af', nEventsMax=nEventsMax, color = r.kRed)
            +supy.samples.specify(names ='tHu-af', nEventsMax=nEventsMax, color = r.kBlue)
            +supy.samples.specify(names ='tHu-fs', nEventsMax=nEventsMax, color = r.kCyan)

            )

    def conclude(self,pars) :
        #make a pdf file with plots from the histograms created above
        org = self.organizer(pars)
        org.scale(lumiToUseInAbsenceOfData=1.0e-3) # /pb
        supy.plotter(org,
                     pdfFileName = self.pdfFileName(org.tag),
                     doLog=False,
                     blackList = ['lumiHisto','xsHisto','nJobsHisto',],
                     samplesForRatios=('tt-fs',['tt-af','tHu-af','tHu-fs']),
                     ).plotAll()


from csv import  reader
from os import walk
import pygame

map = {}

def import_csv_layout(path):
    terrain_map = []
    with open(path) as level_map:
        layout = reader(level_map, delimiter = ',')
        for row in layout:
            terrain_map.append(list(row))
        return terrain_map

def import_folder(path):
    surface_list = {}

    for _,__,img_files in walk(path):
        for image in img_files:
            full_path = path + '/' + image

            img_num = image.split("_")[-1].split(".")[0]
            image_surf = pygame.image.load(full_path).convert_alpha()
            surface_list[img_num] = image_surf
    return surface_list

# def convert(path):
#     import_folder(path)
#     img_numlist =[]
#     for _, __, image_files in walk(path):
#         for image in image_files:
#             for full_path in image:
#                 img = image.split('_')
#                 img_two = img[2].split('.')
#             # print(img_two)
#             # append the img num to the list
#             img_num = int(img_two[0])
#             img_numlist.append(img_num)
#         num_sorted = sorted(img_numlist)
#         # print(num_sorted)
#     return img_numlist

# convert('images/tree')


import json
import os
import subprocess
from django.http import HttpResponse
from . import cv
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile

@csrf_exempt
def process_img(request):  # post /api/process
    if request.method != 'POST':
        data = {'res': 'Only POST requests allowed!'}
        res = HttpResponse(content=json.dumps(
            data), content_type='application/json')
        return res
    file = request.FILES['image']
    if 'darknet' not in os.getcwd():
        os.chdir('./darknet')
    default_storage.save('data/' + file.name, ContentFile(file.read()))
    command = './darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights /data/' + \
        file.name + '-i 0 -dont_show'
    subprocess.run([command])
    newPath = cv.saveImg('predictions.jpg')
    file = None
    with open(newPath, "r") as f:
        file = f.read()
    data = {'res', file}
    res = HttpResponse(content=json.dumps(
        data), content_type='application/json')
    os.chdir('./data')
    os.remove(file.name)
    os.chdir('../')
    return res


import os
from io import StringIO

import numpy as np
from Bio.Blast import NCBIXML
from Bio.Blast.Applications import NcbiblastpCommandline
from config.config import DBConfig
from model_processor.data_processor import ModelProcessor
from search.search_processor import SearchProcessor

class SearchBlast(object):
    def __init__(self, model):
        self.config = DBConfig()
        self.pdb_dir = self.config.pdb_dir
        assert os.path.exists(self.pdb_dir)
        self.processor = ModelProcessor(model)
        self.db_data = {}
        self.db_idx = 0
        self.e_value_trash = self.config.e_value_trash

    def set_e_value_trash(self, value):
        self.e_value_trash = value

    def set_hierarchy_mode(self):
        self.processor.is_upload = True

    def search_blast_hits(self, pdb_file, chain):
        assert os.path.exists(pdb_file)
        result = self.processor.process_file(pdb_file, chain)
        try:
            saml = result['alphabet']
            embedding = result['embedding']
            sequence = result['sequence']
            source_coo = result['source_coo']
            source_stride = result['stride']
        except KeyError as e:
            raise e
        if self.e_value_trash == 'auto':
            scale = np.round(np.sqrt(len(embedding) / 10)) - 1
            self.e_value_trash = 1.0 * 10 ** -scale
        result = self.process_blast(saml_string=saml)
        source_record = dict({'saml': saml,
                              'file': pdb_file,
                              'chain': chain,
                              'sequence': sequence,
                              'embedding': embedding,
                              'source_coo': source_coo,
                              'source_stride': source_stride
                              })
        result.update({'source': source_record})
        return result

    @staticmethod
    def out_result(result_data):
        for key in result_data:
            record = result_data[key]
            e_value = record['e_value']
            print(f'{key} E-value: {e_value}')

    def clear_task_ws(self):
        self.processor.clear_task_ws()

    def process_blast(self, saml_string):
        blast_db = self.config.get_blast_db_name()
        blast_cmd = NcbiblastpCommandline(db=str(blast_db), outfmt=5, max_target_seqs=7000)
        out, err = blast_cmd(stdin=saml_string)
        query_result = {}
        for record in NCBIXML.parse(StringIO(out)):
            for align in record.alignments:
                for hsp in align.hsps:
                    e_value = hsp.expect
                    if e_value <= self.e_value_trash:
                        keys = align.hit_id.split('|')
                        key = f'{keys[1]}:{keys[2]}'
                        record = {'query': hsp.query,
                                  'match': hsp.match,
                                  'e_value': e_value,
                                  'sbj': hsp.sbjct}
                        query_result.update({key: record})
        return query_result

    def inference_results(self, results_record):
        inference_data = self.processor.inference(results_record)
        return inference_data

TEST_FILE1 = "/home/dp/Data/SAML/test/pdb/sample10/1hxd.pdb"
TEST_FILE2 = "/home/dp/Data/SAML/test/pdb/sample2/3qvo.pdb"
TEST_FILE3 = "/home/dp/Data/SAML/test/pdb/sample3/6x9z.pdb"
TEST_FILE4 = "/home/dp/Data/SAML/test/pdb/sample4/1A1B.pdb"

if __name__ == "__main__":
    search = SearchBlast()
    b_result = search.search_blast_hits(TEST_FILE1, 'A')
    search.inference_results(b_result)

    # vis.plot_blast_out(b_result)