def part1(input):
	for instruction in input[1]:
		count = int(instruction[0])
		start = int(instruction[1]) - 1
		finish = int(instruction[2]) -1
		temp = input[0][start][:count]
		input[0][start] = input[0][start][count:]
		for item in temp:
			input[0][finish].insert(0,item)
	output=''
	for stack in input[0]:
		if stack != list():
			output += stack[0]
	print(output.replace('[','').replace(']',''))

def part2(input):
	for instruction in input[1]:
		count = int(instruction[0])
		start = int(instruction[1]) - 1
		finish = int(instruction[2]) -1
		temp = input[0][start][:count]
		input[0][start] = input[0][start][count:]
		input[0][finish] = temp + input[0][finish]
	output=''
	for stack in input[0]:
		if stack != list():
			output += stack[0]
	print(output.replace('[','').replace(']',''))

def split_string(input: str) -> list[str]:
	input
	return [input[i:i + 4].strip() for i in range(0, len(input), 4)]

def parse_input(input: str) -> list[str]:
	output = input.split('\n\n')
	output[0] = list(map(split_string,output[0].split('\n')))
	columns = []
	for i in range(0,len(output[0][0])):
		columns.append([])
	for row in range(0,len(output[0])):
		for item in range(0,len(output[0][row])):
			if output[0][row][item] != '':
				columns[item].append(output[0][row][item])
	output[0] = columns
	output[1] = output[1].split('\n')
	instructions = []
	for instruction in output[1]:
		steps = []
		for step in instruction.split():
			if step.isdigit():
				steps.append(step)
		instructions.append(steps)
	output[1] = instructions
	return output

f = open("input.txt","r")

crates = parse_input(f.read())
#part1(crates)
part2(crates)


from sqlalchemy import create_engine,MetaData,Table,ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,Float,DateTime
import csv

from sqlalchemy.orm import sessionmaker
from datetime import datetime,date
from dateutil.parser import parse

engine = create_engine('sqlite:///etl.db', echo = True)
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()
year=input("Enter a year to load:")
path='../../input/'+year+'/Network.csv'

try:
    reader_file = csv.DictReader(open(path,'r',encoding='UTF-8'))# utf-8 for 2014 and 2015 and #cp 1252 for 2016
    field=reader_file.fieldnames

    tablename="Network"+"_"+year
    attr_dict = {'__tablename__': tablename}
    attr_dict["record_id"]=Column(Integer, primary_key=True, autoincrement=True)
    for i in field:
        if i =="ImportDate":
            attr_dict[i] = Column(DateTime)
        else:
            attr_dict[i] = Column(String)

    MyTableClass = type('MyTableClass', (Base,), attr_dict)
    Base.metadata.create_all(engine)

    class LogTable(Base):
        __tablename__ = 'LogTable'
        transaction_id = Column(Integer, primary_key=True,autoincrement=True)
        tablename=Column(String)
        year=Column(Integer,ForeignKey(f'Business_Rules_{year}.BusinessYear'))
        start_time=Column(DateTime)
        end_time = Column(DateTime)
        no_of_records=Column(Integer)
        transaction_status= Column(String)

    Base.metadata.create_all(engine)

    confirm=input("Do you want to transform load:{y/n)\n")
    if confirm == "y":

        start = datetime.now()

        dat_check = session.query(MyTableClass).filter_by(BusinessYear=year).first()
        if dat_check is not None:
            MyTableClass.__table__.drop(engine)
            print("Old Records Deleted")
        flag = 0
        checkpoint = 0
        total_records = 0

        try:
            for row in reader_file:
                #Cleansing ImportDate column
                #fdate=row['ImportDate'].split(" ")[0].split("-")
                #print(fdate[0],fdate[1],fdate[2])
                #dat=date(int(fdate[0]),int(fdate[1]),int(fdate[2]))
                date= parse(row['ImportDate'])
                row['ImportDate']=date
                try:
                    record = MyTableClass(**row)
                    session.add(record)
                    print(flag, "th record")
                    if flag >= 500000:
                        try:
                            session.commit()
                        except:
                            session.rollback()
                            MyTableClass.__table__.drop(engine)
                            print("Invalid Data format")
                            break
                        total_records+=flag
                        checkpoint+=1
                        print("5L records inserted: checkpoint")
                        flag = 0
                        continue
                    flag += 1
                except KeyboardInterrupt as k:
                    MyTableClass.__table__.drop(engine)
                    print("Process aborted")
                    break
                except MemoryError as e:
                    session.rollback()
                    MyTableClass.__table__.drop(engine)
                    session.add(LogTable(tablename=tablename, year=year, start_time=start, end_time=datetime.now(),
                                         no_of_records=total_records,transaction_status="Failure"))
                    session.commit()
                    print("Transaction roll back")
                    break
            else:
                total_records += flag
                session.commit()
                session.add(LogTable(tablename=tablename, year=year, start_time=start, end_time=datetime.now(),
                                     no_of_records=total_records,transaction_status="Success"))
                session.commit()
                print("All records inserted: Transaction Completed")

        except UnicodeDecodeError as e:

            MyTableClass.__table__.drop(engine)
            print("Check encoding")

except FileNotFoundError as e:
    print("Dataset for Year doesnt exist")


data = [
    {
        'name': 'Instagram',
        'followers': 346,
    },
    {
        'name': 'Cristiano Ronaldo',
        'followers': 215,
    },
    {
        'name': 'Ariana Grande',
        'followers': 183,
    },
    {
        'name': 'Dwayne Johnson',
        'followers': 181,
    },
    {
        'name': 'Selena Gomez',
        'followers': 174,
    },
    {
        'name': 'Kylie Jenner',
        'followers': 172,
    },
    {
        'name': 'Kim Kardashian',
        'followers': 167,
    },
    {
        'name': 'Lionel Messi',
        'followers': 149,
    },
    {
        'name': 'Beyoncé',
        'followers': 145,
    },
    {
        'name': 'Neymar',
        'followers': 138,
    },
    {
        'name': 'National Geographic',
        'followers': 135,
    },
    {
        'name': 'Justin Bieber',
        'followers': 133,
    },
    {
        'name': 'Taylor Swift',
        'followers': 131,
    },
    {
        'name': 'Kendall Jenner',
        'followers': 127,
    },
    {
        'name': 'Jennifer Lopez',
        'followers': 119,
    },
    {
        'name': 'Nicki Minaj',
        'followers': 113,
    },
    {
        'name': 'Nike',
        'followers': 109,
    },
    {
        'name': 'Khloé Kardashian',
        'followers': 108,
    },
    {
        'name': 'Miley Cyrus',
        'followers': 107,
    },
    {
        'name': 'Katy Perry',
        'followers': 94,
    },
    {
        'name': 'Kourtney Kardashian',
        'followers': 90,
    },
    {
        'name': 'Kevin Hart',
        'followers': 89,
    },
    {
        'name': 'Ellen DeGeneres',
        'followers': 87,
    },
    {
        'name': 'Real Madrid CF',
        'followers': 86,
    },
    {
        'name': 'FC Barcelona',
        'followers': 85,
    },
    {
        'name': 'Rihanna',
        'followers': 81,
    },
    {
        'name': 'Demi Lovato',
        'followers': 80,
    },
    {
        'name': "Victoria's Secret",
        'followers': 69,
    },
    {
        'name': 'Zendaya',
        'followers': 68,
    },
    {
        'name': 'Shakira',
        'followers': 66,
    },
    {
        'name': 'Drake',
        'followers': 65,
    },
    {
        'name': 'Chris Brown',
        'followers': 64,
    },
    {
        'name': 'LeBron James',
        'followers': 63,
    },
    {
        'name': 'Vin Diesel',
        'followers': 62,
    },
    {
        'name': 'Cardi B',
        'followers': 67,
    },
    {
        'name': 'David Beckham',
        'followers': 82,
    },
    {
        'name': 'Billie Eilish',
        'followers': 61,
    },
    {
        'name': 'Justin Timberlake',
        'followers': 59,
    },
    {
        'name': 'UEFA Champions League',
        'followers': 58,
    },
    {
        'name': 'NASA',
        'followers': 56,
    },
    {
        'name': 'Emma Watson',
        'followers': 56,
    },
    {
        'name': 'Shawn Mendes',
        'followers': 57,
    },
    {
        'name': 'Virat Kohli',
        'followers': 55,
    },
    {
        'name': 'Gigi Hadid',
        'followers': 54,
    },
    {
        'name': 'Priyanka Chopra Jonas',
        'followers': 53,
    },
    {
        'name': '9GAG',
        'followers': 52,
    },
    {
        'name': 'Ronaldinho',
        'followers': 51,
    },
    {
        'name': 'Maluma',
        'followers': 50,
    },
    {
        'name': 'Camila Cabello',
        'followers': 49,
    },
    {
        'name': 'NBA',
        'followers': 47,
    }
]


from functools import reduce
import operator

rotations = [lambda x, y, z: ( x,  y, z), lambda x, y, z: (-z,  y,  x), lambda x, y, z: (-x,  y, -z), lambda x, y, z: (z,  y, -x),    #  y is up, rotate 0, 90, 180, 270
             lambda x, y, z: (-x, -y, z), lambda x, y, z: (-z, -y, -x), lambda x, y, z: ( x, -y, -z), lambda x, y, z: (z, -y,  x),    #  y is down, rotate 0, 90, 180, 270
             lambda x, y, z: ( y,  z, x), lambda x, y, z: (-x,  z,  y), lambda x, y, z: (-y,  z, -x), lambda x, y, z: (x,  z, -y),    #  z is up, rotate 0, 90, 180, 270
             lambda x, y, z: (-y, -z, x), lambda x, y, z: (-x, -z, -y), lambda x, y, z: ( y, -z, -x), lambda x, y, z: (x, -z,  y),    #  z is down, rotate 0, 90, 180, 270
             lambda x, y, z: ( z,  x, y), lambda x, y, z: (-y,  x,  z), lambda x, y, z: (-z,  x, -y), lambda x, y, z: (y,  x, -z),    #  x is up, rotate 0, 90, 180, 270
             lambda x, y, z: (-z, -x, y), lambda x, y, z: (-y, -x, -z), lambda x, y, z: ( z, -x, -y), lambda x, y, z: (y, -x,  z)]    #  x is down, rotate 0, 90, 180, 270

def get_rotations(scanner):
    return [[r(p[0], p[1], p[2]) for p in scanner] for r in rotations]

def find_overlaps(s1, s2):
    for r, rotate in enumerate(rotations):
        poss = dict()
        for i, p1 in enumerate(s1):
            for j, p2 in enumerate(s2):
                p = tuple(map(operator.sub, p1, rotate(p2[0], p2[1], p2[2])))
                if p in poss:
                    poss[p].append((r,i,j,p1,p2,p))
                else:
                    poss[p] = [(r,i,j,p1,p2,p)]

        for k,v in poss.items():
            if len(v) >= 12:
                return v
    return ()

def reorient(scanner, origin, rotation):
    return [tuple(map(operator.add, origin, rotations[rotation](p[0], p[1], p[2]))) for p in scanner]

def map_beacons(scanners):
    all_mappings = [(0, scanners[0], (0,0,0))]
    unmapped = [(i + 1, s) for i, s in enumerate(scanners[1:])]
    new_mappings = all_mappings
    while len(unmapped) > 0:
        mappings = new_mappings
        new_mappings = []
        for s1 in mappings:
            for s2 in unmapped[:]:
                overlaps = find_overlaps(s1[1], s2[1])
                if len(overlaps) > 0:
                    #print(f'overlap found: {s1[0]}, {s2[0]}')
                    # for p in overlaps:
                    #     print(p)
                    new_mappings.append((s2[0], reorient(s2[1], overlaps[0][5], overlaps[0][0]), overlaps[0][5]))
                    unmapped.remove(s2)
        all_mappings += new_mappings

    beacons = list(set(reduce(operator.add, (m[1] for m in all_mappings))))
    return beacons, tuple(m[2] for m in sorted(all_mappings))

all_beacons = []
all_scanners = []

def solve_part1(scanners):
    global all_beacons
    global all_scanners
    all_beacons, all_scanners = map_beacons(scanners)
    return len(all_beacons)

def solve_part2():
    global all_scanners
    best = 0
    for i in range(len(all_scanners)):
        for j in range(i + 1, len(all_scanners)):
            best = max(best, abs(reduce(operator.add, map(operator.sub, all_scanners[i], all_scanners[j]))))
    return best

def doit(inputfile):
    with open(inputfile,'r') as f:
        input_lines = [line.strip() for line in f.readlines() if len(line.strip()) > 0]

    scanners = []
    scanner = []
    for line in input_lines:
        if line[0:3] == '---':
            if len(scanner) > 0:
                scanners.append(scanner)
                scanner = []
        else:
            scanner.append(tuple(int(x) for x in line.split(',')))
    scanners.append(scanner)

    print(solve_part1(scanners))
    print(solve_part2())

doit('test.txt')
doit('input.txt')

"""
79
3621
483
14804
"""


"""
Write a Python program to sort the dictionary once by key.
"""

def sort_dict_by_key(data: dict):
    sorted_keys = sorted(data)
    new_dict = {}
    for i in sorted_keys:
        new_dict[i] = data[i]
    return new_dict

def test():
    print("Question 5")
    test_data = {
        2: 100000,
        1: 3,
        3: 4,
        5: 5,
        7: 1,
    }
    print(sort_dict_by_key(test_data))


import itertools as it

class LogicSystem:

    @staticmethod
    def __create_layer(connections, current_layers):
        mapped_comps = list(it.chain.from_iterable(current_layers))

        layer = []

        for comp, input_comps in connections.items():

            if comp not in layer \
                    and comp not in mapped_comps \
                    and all(input_comp in mapped_comps for input_comp in input_comps):
                layer.append(comp)

        return layer

    def organize_comps(self, connections):
        layers = [[comp for comp in connections if connections[comp] == []]]
        comp_count = len(layers[0])
        num_of_comps = len(connections)

        while comp_count != num_of_comps:
            new_layer = self.__create_layer(connections, layers)
            layers.append(new_layer)
            comp_count += len(new_layer)

        return layers

    def __init__(self, connections, sys_runs, file_name):

        self.connections = connections
        self.sys_runs = sys_runs
        self.sys_name = file_name
        self.text_file = open('{}.txt'.format(file_name), 'w+')
        self.layers = self.organize_comps(self.connections)
        self.mapped_comps = list(it.chain.from_iterable(self.layers))

    def starting_text(self):
        text = 'This text file is a simulation of the system {}\n\n' \
               'The following is the network layout for the system.'.format(self.sys_name)

        for layer in range(len(self.layers)):
            text += '\n\nLayer {}:\n\n'.format(layer+1)
            for comp in self.layers[layer]:
                text += '     {}'.format(comp)
        text += '\n\n' + '-'*65 + '\n\nInitial state for all components:\n\n\n'

        for comp in self.mapped_comps:
            text += '{} output: {} current state: {}\n\n'.format(comp.comp_name, comp.out, comp.current_state)

        self.text_file.write(text)

    def run_system(self):
        self.starting_text()
        self.text_file.write('-'*65 + '\n\nSimulation Start\n\n')
        run = 1
        while run <= self.sys_runs:

            self.text_file.write("-"*65+'\n\nRun{}:\n\n'.format(run))

            for comp in self.mapped_comps:

                input_comps = self.connections[comp]
                input_values = [in_comp.out for in_comp in input_comps]

                comp.output(*input_values)
                self.text_file.write('{} output: {} current state:{}\n\n'.format(comp.comp_name,
                                                                                comp.out,
                                                                                comp.current_state))
            run += 1

        self.text_file.close()


from urlparse import urljoin

from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import Request

from pycon_speakers.loaders import SpeakerLoader

class PyConSpider(Spider):
    name = 'confoo.ca'
    years = '2010,2011,2012,2013,2014'

    def start_requests(self):
        url = "http://confoo.ca/en/{0}/speakers"
        years = [int(x) for x in self.years.split(',')]
        for year in years:
            meta = {'year': year}
            yield Request(url.format(year), meta=meta,
                              callback=self._parse)

    def _parse(self, response):
        for section in Selector(response).xpath('//div[@class="speakers"]//div[@class="name"]'):
            il = SpeakerLoader(selector=section)
            il.add_xpath('name', '.')
            il.add_value('year', str(response.meta['year']))
            yield il.load_item()


import os
import json
import pickle
import datetime
import tkinter as tk
from tkinter import (
    ttk,
    OptionMenu,
    StringVar,
    messagebox
)

class Component(object):
    def __init__(self, serial_number=None, component_type='Winglet Strut', size_fit='A320 Series', status='Manufactured-Unfinished'):
        """Constructor"""
        self._serial_number = serial_number         # 1 to 99
        # Winglet Dtrut, Door handle, Rudder Pin
        self._component_type = component_type
        # A320 Series, A380 Series, 10x75, 12x100, 16x150
        self._size_fit = size_fit
        self._status = status                       # Polish, Paint

    # get_serial_number() function is accessible to class Batch
    def get_serial_number(self):
        return self._serial_number

    # set_serial_number is accessible outside the class
    def set_serial_number(self, serial_number):
        self._serial_number = serial_number

class Batch(Component):
    def __init__(self, batch_number, serial_number, location="Not Allocated"):
        """Constructor"""
        super(Batch, self).__init__(serial_number)
        self._date_manufacture = datetime.datetime.today().strftime('%Y%m%d')
        self._batch_create = datetime.datetime.today().strftime('%H%M')
        self._batch_number = batch_number
        self._location = location

    def create_sn_component(self, component_type, size_fit):
        sn = []
        x = 1

        sn_component = int(self.get_serial_number())
        while x <= sn_component:
            sn.append({
                "sn_component": self.create_batch_number() + '-' + self.add_zero(x),
                'type_components': component_type,
                'size_fitment_comps': size_fit,
                'status': self._status
            })
            x += 1
        return sn

    def create_batch_number(self):
        batch_num = int(self._batch_number)

        return self._date_manufacture + self.add_zero(batch_num)

    # I have used a static method because I don't need  the self to be passed as the first argument
    @staticmethod
    def add_zero(arg):
        x = 1
        batch = None
        while x <= arg:
            if x < 10:
                batch = '000' + str(x)
            elif 10 <= x < 100:
                batch = '00' + str(x)
            elif 100 <= x < 1000:
                batch = '0' + str(x)
            else:
                batch = str(x)

            x += 1

        return batch

class App(tk.Frame):
    # Initialize Method
    def __init__(self, master):
        """Constructor"""
        tk.Frame.__init__(self, master)
        # Set the Font and color of Nee Batch Frame
        s = ttk.Style()
        s.configure('Blue.TLabelframe.Label', font=('courier', 13, 'bold'))
        s.configure('Blue.TLabelframe.Label', foreground='#374e9b')
        s.configure('Red.TLabelframe.Label', font=('courier', 13, 'bold'), foreground='#990000')
        # get screen width and height
        self.master.geometry('800x820')
        # Add a tittle on window
        self.master.title("PPEC - Inventory System")

        # Create instance for menu frame, this is the Menu Frame in the Main Window
        self._menu_frame = ttk.LabelFrame(
            self.master, text=' Menu ', style="Blue.TLabelframe")
        # Create instance frames from menu choice, this is the New Frames in the Main Window
        self._create_batch_frame = ttk.LabelFrame(
            self.master, text=' Create New Batch ', style="Red.TLabelframe")
        self._list_batch_frame = ttk.LabelFrame(
            self.master, text=' List All Batches ', style="Red.TLabelframe")
        self._detail_batch_frame = ttk.LabelFrame(
            self.master, text=' View Details Batch ', style="Red.TLabelframe")
        self._detail_comp_frame = ttk.LabelFrame(
            self.master, text=' View Details Component ', style="Red.TLabelframe")
        self._show_details_frame = ttk.LabelFrame(
            self.master, text=' Batch Details', style="Red.TLabelframe")
        self._comp_allocation_frame = ttk.LabelFrame(
            self.master, text=' Allocation Stock ', style="Red.TLabelframe")
        self._search_product_type_frame = ttk.LabelFrame(
            self.master, text=' Search By product Type ', style="Red.TLabelframe")
        self._finish_comp_frame = ttk.LabelFrame(
            self.master, text=' Finish a Component ', style="Red.TLabelframe")
        # the below tkinter LabelFrame is used to display the scrollbar
        self.scroll_comp_finished_frame = ttk.LabelFrame(
            self.master, text='Finished Products')
        self.scroll_comp_unfinished_frame = ttk.LabelFrame(
            self.master, text='Unfinished Products')

        # Initialize path and filename of json file
        self.path = '../Data'
        self.filename = 'BatchIndex'
        self.file_path_name_w = './' + self.path + '/' + self.filename + '.json'

        # Dictionary for dropdown components type
        self.choices_comp = {'Door handle': ['A320 Series', 'A380 Series'],
                             'Rudder Pin': ['A320 Series', 'A380 Series','10x75', '12x100', '16x150'],
                             'Winglet Strut': ['A320 Series', 'A380 Series']
                            }

        # Place Dropdown into the container element create a new status
        self.choices_status = {'Paint': ['AJ74','AB76', 'BT98', 'DF56', 'BE43'],
                                'Polished': ['Matte', 'Gloss']
                            }

        # Create a Tkinter variable for dropdown
        self.tk_var = StringVar(self)
        self.entry_type_comp = StringVar(self)
        self.entry_size_fitment = StringVar(self)
        self.entry_choose_location = StringVar(self)
        self.entry_choose_status = StringVar(self)
        self.entry_choose_paint = StringVar(self)
        self.entry_code_paint = StringVar(self)
        # Create a Tkinter variable for input
        self.entry_batch_no = StringVar(self)
        self.entry_components = StringVar(self)

        # Call methods
        self.create_menu()
        self._inventory = self.create_json_file()
        self.create_batch_pkl_file()
        self.create_comp_pkl_file()

    # Create json file and save all batch created
    def create_json_file(self):
        # Input the try except in a while loop, because try to see if file exist if not exist give an error that is catch by except,
        # the exception take the data and save into file and create, and start the loop again, this time check that file exist so open the file
        while True:
            try:
                fh = open(self.file_path_name_w, 'rb+')
                data_file = json.load(fh)
                return data_file
                break
            except FileNotFoundError:
                data = {'Batch': []}
                self.save_data(data)
                continue

    def save_data(self, datafile):
        # Write Data
        with open(self.file_path_name_w, 'w+') as fp:
            fp.write(json.dumps(datafile, indent=2, sort_keys=False))
        fp.close()

    # Create batch pickle file from json file
    def create_batch_pkl_file(self):
        # list to collect data from json file  and save into pickle file
        with open('../Data/BatchIndex.json') as json_file:
            # load the json file to check data saved inside
            data = json.load(json_file)

            # Check json file inside the Batch List all Ojects and save each object in a single pickle file with value of key:number
            for batch_obj in data['Batch']:
                number = batch_obj['number']
                qty_comp = batch_obj['quantity_comp']
                manufacture_date = batch_obj['manufacture_date']
                location = batch_obj['location']
                component = batch_obj['component']

                i = 0
                comps = []

                while i < len(component):
                    sn_component = component[i]['sn_component']
                    type_components = component[i]['type_components']
                    size_fitment_comps = component[i]['size_fitment_comps']
                    status = component[i]['status']
                    comps.append([sn_component,type_components,size_fitment_comps,status])

                    i += 1

                self.file_path_name_pkl_w = './' + self.path + '/' + batch_obj['number'] + '.pkl'

                batch = [number, qty_comp, manufacture_date, location, comps]
                batch_dict = { batch[0]: batch }
                self.save_batch_pkl_data(batch_dict)

    def save_batch_pkl_data(self, pkl_batch_file):
        # Write Data
        with open(self.file_path_name_pkl_w, 'wb') as fhp:
            pickle.dump(pkl_batch_file, fhp)
        fhp.close()

    # Create components pickle file from json file
    def create_comp_pkl_file(self):
         # list to collect data from json file  and save into pickle file
        with open('../Data/BatchIndex.json') as json_file:
            # load the json file to check data saved inside
            data = json.load(json_file)

            # Check json file inside the Batch List all Ojects and save each object in a single pickle file with value of key:number
            for batch_obj in data['Batch']:

                for comp_obj in batch_obj['component']:
                    sn_component = comp_obj['sn_component']
                    type_components = comp_obj['type_components']
                    size_fitment_comps = comp_obj['size_fitment_comps']
                    manufacture_date = batch_obj['manufacture_date']
                    status = comp_obj['status']
                    number = batch_obj['number']
                    location = batch_obj['location']

                    self.file_path_name_comp_pkl_w = './' + self.path + '/' + comp_obj['sn_component'] + '.pkl'

                    # batch = [sn_component, type_components, size_fitment_comps, manufacture_date, status, number]
                    # data[batch_obj['sn_component'][comp_obj]] = batch
                    comp = [sn_component, type_components, size_fitment_comps, manufacture_date, status, location, number]
                    comp_dict = { comp[0]: comp }
                    self.save_comp_pkl_data(comp_dict)

    def save_comp_pkl_data(self, pkl_comp_file):
        # Write Data
        with open(self.file_path_name_comp_pkl_w, 'wb') as fhcp:
            pickle.dump(pkl_comp_file, fhcp)
        fhcp.close()

    """ this method manage the choice you make on the dropdown options menu,
        display in the frame below the menu the choice you made"""
    def change_dropdown(self, *args):
        option = self.tk_var.get()
        # set a dictionary with coice for menu
        choice_dict = {
            '1': self.create_new_batch,
            '2': self.list_all_batches,
            '3': self.view_details_batch,
            '4': self.view_details_comp,
            '5': self.show_frame_allocation,
            '6': self.search_product_type,
            '7': self.finish_component,
            '8': self.close_app
        }
        # call the methods that user choose from the dropdown menu
        choice_dict.get(option, self.create_menu)()

    """ this method manage the choice you do for the component, for one type component you choose,
        display the size/fit for the this specific component """
    def search_product_options(self, *args):
        comp_types = self.choices_comp[self.entry_type_comp.get()]
        self.entry_size_fitment.set(comp_types[0])

        menu = self.optionmenu_size_fitment['menu']
        menu.delete(0, 'end')

        for comp_type in comp_types:
            menu.add_command(label=comp_type, command=lambda c_type=comp_type: self.entry_size_fitment.set(c_type))

    """ this method manage the choice you do for the status, for the painted finished you choose the code in the select,
        and polished no have code """
    def update_status_options(self, *args):
        comp_statuses = self.choices_status[self.entry_choose_status.get()]
        self.entry_code_paint.set(comp_statuses[0])

        menu = self.optionmenu_code_paint['menu']
        menu.delete(0, 'end')

        for comp_status in comp_statuses:
            menu.add_command(label=comp_status, command=lambda c_status=comp_status: self.entry_code_paint.set(c_status))

    # Check if number of batch exist
    def check_batch_number_exist(self):
        entry_batch_no = self.entry_batch_no.get()
        # Check if the bacth insert is a number
        if self.isNumber(entry_batch_no):
            new_batch = Batch(entry_batch_no, None)
            batch_num = new_batch.create_batch_number()

            try:
                data = self.create_json_file()
                temp_list = []
                # Access data
                for dict_obj in data['Batch']:
                    temp_list.append(dict_obj['number'])

                if batch_num in temp_list:
                    messagebox.showinfo('Oooops!!', 'The batch number ' + batch_num + ' already exist')
                else:
                    self.show_msg_before_save()
            except (ValueError, KeyError, TypeError):
                messagebox.showerror('Comp Json Error', 'Is not a number, enter a valid number.')
        else:
            messagebox.showerror('Warning', 'Is not a number, enter a valid number.')

    # Check the input is a number
    def isNumber(self, value):
        try:
            val = int(value) # check if the parameter passed is numeric
            return True # if so return True
        except (TypeError, ValueError): # if the params is not numeric the exception is a TypeError or ValueError
            return False # return False

    # This method create a menu with a dropdown to choice options
    def create_menu(self):
        # Create a container to hold all label for menu
        self._menu_frame.grid(column=0, row=9, padx=10, pady=10, ipadx=40, sticky=tk.W)

        # Dictionary with options
        choices = {'1', '2', '3', '4', '5', '6', '7', '8'}
        # set the default label in the dropdown option
        self.tk_var.set('Options')

        # Create the Dropdown Menu Option
        OptionMenu(self._menu_frame, self.tk_var, *sorted(choices)).grid(column=1, row=8, ipadx=5)

        # Place labels into the container element menu_frame
        ttk.Label(self._menu_frame, text="1. Create a New Batch").grid(
            column=0, row=0, sticky=tk.W)
        ttk.Label(self._menu_frame, text="2. List All Batches").grid(
            column=0, row=1, sticky=tk.W)
        ttk.Label(self._menu_frame, text="3. View details of a Batch").grid(
            column=0, row=2, sticky=tk.W)
        ttk.Label(self._menu_frame, text="4. View Details of Components").grid(
            column=0, row=3, sticky=tk.W)
        ttk.Label(self._menu_frame, text="5. Allocate Manufactured Stock").grid(
            column=0, row=4, sticky=tk.W)
        ttk.Label(self._menu_frame, text="6. Search By Product Type").grid(
            column=0, row=5, sticky=tk.W)
        ttk.Label(self._menu_frame, text="7. Finish a Component").grid(
            column=0, row=6, sticky=tk.W)
        ttk.Label(self._menu_frame, text="8. Quit").grid(
            column=0, row=7, sticky=tk.W)
        ttk.Label(self._menu_frame, text="Choose the option:").grid(
            column=0, row=8, ipady=10, sticky=tk.W)

        # link function to change dropdown and pass the choice as an argument
        self.tk_var.trace('w', self.change_dropdown)

        for child in self._menu_frame.winfo_children():
            child.grid_configure(padx=10, pady=4)

    # This method create a frame with all input to create a new batch
    def create_new_batch(self):
        self._show_details_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Create a new Object from Batch class
        new_batch = Batch(batch_number='0', serial_number='0')
        # remove the button for exit to application
        self._show_details_frame.grid_remove()
        # Create a container to hold all label for menu
        self._create_batch_frame.grid(
            column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._create_batch_frame, text="Batch number:").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._create_batch_frame, text="{}".format(new_batch._date_manufacture)).grid(
            column=1, row=0, padx=0, pady=10, sticky=tk.W)
        ttk.Label(self._create_batch_frame, text="How many components\n in this Batch (1 to 9999):").grid(
            column=0, row=1, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._create_batch_frame, text="Select component type:").grid(
            column=0, row=2, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._create_batch_frame, text="Select Size/Fitment type:").grid(
            column=0, row=3, padx=10, pady=10, sticky=tk.W)
        # Place Entry into the container element create new batch
        ttk.Entry(self._create_batch_frame, textvariable=self.entry_batch_no).grid(
            column=1, row=0, padx=52, pady=10)
        ttk.Entry(self._create_batch_frame, textvariable=self.entry_components).grid(
            column=1, row=1)
        # Place Dropdown into the container element create a new batch
        self.entry_type_comp.trace('w', self.search_product_options)

        self.optionmenu_type_comp = OptionMenu(self._create_batch_frame, self.entry_type_comp, *sorted(self.choices_comp.keys()))
        self.optionmenu_size_fitment = OptionMenu(self._create_batch_frame, self.entry_size_fitment, '')

        self.entry_type_comp.set('Door handle')

        self.optionmenu_type_comp.grid(column=1, row=2, padx=20, pady=10, ipadx=5)
        self.optionmenu_size_fitment.grid(column=1, row=3, padx=20, pady=10, ipadx=5)

        # Place Buttons into the container element create new batch and call the methods check_batch_number_exist
        ttk.Button(self._create_batch_frame, text="Create Batch", command=self.check_batch_number_exist).grid(
            column=0, row=4, padx=10, pady=10, sticky=tk.W)

    # Show the message on separated windows of the batch created.
    def show_msg_before_save(self):
        entry_batch_no = self.entry_batch_no.get()
        entry_no_comps = self.entry_components.get()
        entry_type_comps = self.entry_type_comp.get()
        entry_size_fit = self.entry_size_fitment.get()
        # Call Date Class
        new_batch = Batch(entry_batch_no, entry_no_comps)
        sn_comps = new_batch.create_sn_component(entry_type_comps, entry_size_fit)
        batch_num = new_batch.create_batch_number()
        # Save in a variable the value return from Batch Object
        date_manufacture = new_batch._date_manufacture
        # Setting up the message box
        show_msg_saving = messagebox.askyesno(
            'Warning!',
            'This batch No {}\ncreated at {}\ncontains {} {} {}\n\n\tis this correct!'.format(
                batch_num, date_manufacture, len(sn_comps), entry_size_fit, entry_type_comps, _icon='warning')
        )
        # If click "yes" the details insert is saved on BatchIndex.json file
        if show_msg_saving:
            # Setting up the messagebox for show batch detail
            show_msg_details = messagebox.askyesno(
                'Batch Created',
                'Batch and Component records created at {} on {}\n\nShow Batch details?'.format(
                    new_batch._batch_create, date_manufacture, _icon='info')
            )
            # If click "Yes" The batch details are displayed
            if show_msg_details:
                self.show_details_batch()
            # Call the method that Save the detail on json file
            self.save_batch_to_json_file(self._inventory)
            self.create_batch_pkl_file()
            self.create_comp_pkl_file()

    """ The method save_batch_to_json_file() is called when you click "yes" on the message box that appear
        when click "Create batch" button and save all data in BatchIndex.json file.
    """
    def save_batch_to_json_file(self, inventory):
        entry_batch_no = self.entry_batch_no.get()
        entry_no_comps = self.entry_components.get()
        entry_type_comps = self.entry_type_comp.get()
        entry_size_fit = self.entry_size_fitment.get()
        # Call Date Class
        new_batch = Batch(entry_batch_no, entry_no_comps)
        sn_comps = new_batch.create_sn_component(entry_type_comps,entry_size_fit)
        batch_num = new_batch.create_batch_number()
        manufacture_date = new_batch._date_manufacture
        # Dictionary to collect data and save into json file
        a_dict = {}
        #data = self.create_json_file()
        temp_list = []
        for dic_obj in inventory["Batch"]:
            temp_list.append(dic_obj)
        qty_comp = entry_no_comps
        temp_list.append(
            {'number': batch_num,
            'quantity_comp': qty_comp,
            'location': new_batch._location,
            'manufacture_date': manufacture_date,
            'component': sn_comps
            })
        inventory["Batch"] = temp_list
        a_dict["Batch"] = inventory["Batch"]
        self.save_data(a_dict)
        # Clear the entry one the file is created to set with empty string
        self.entry_batch_no.set('')
        self.entry_components.set('')

    # Show the details of the batch created
    def show_details_batch(self):
        print('New Batch Details Method Called')
        entry_batch_no = self.entry_batch_no.get()
        entry_no_comps = self.entry_components.get()
        entry_type_comps = self.entry_type_comp.get()
        entry_size_fit = self.entry_size_fitment.get()
        # Call Date Class
        new_batch = Batch(entry_batch_no, entry_no_comps)
        sn_comps = new_batch.create_sn_component(entry_type_comps,entry_size_fit)
        batch_num = new_batch.create_batch_number()
        comp_location = new_batch._location

        sn = []
        comps = []
        for item in sn_comps:
            sn.append(item['sn_component'] )
            comps.append(item['sn_component'] + ' ' + item['status'])

        comps = "\n\t".join(comps)

        # Save in a variable the value return from Batch Object
        date_manufacture = new_batch._date_manufacture
        # remove the button for exit to application
        self._create_batch_frame.grid_remove()
        # Create a container to hold all label for menu
        self._show_details_frame.grid(column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._show_details_frame, text="Batch number:\t{}".format(batch_num)).grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="Manufacture Date:\t{}".format(date_manufacture)).grid(
            column=0, row=1, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="Component type:\t{}".format(entry_type_comps)).grid(
            column=0, row=2, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="Component Size/Fitment type: {}".format(entry_size_fit)).grid(
            column=0, row=3, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="SerialNumbers: {}".format(sn)).grid(
            column=0, row=4, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="Component Status: [\n\t{}\n\t]".format(comps)).grid(
            column=0, row=5, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._show_details_frame, text="Component Location: {}".format(comp_location)).grid(
            column=0, row=6, padx=10, pady=10, sticky=tk.W)

    # This method show all batches
    def list_all_batches(self):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Open file json for retrieving all batch saved
        fh = open(self.file_path_name_w, 'r')
        data_file = json.load(fh)
        fh.close()

        # Loop for display all list Batches
        r = 1
        for list_batch in data_file['Batch']:
            batch_number = list_batch['number']
            quantity_comp = list_batch['quantity_comp']
            allocated_location = list_batch['location']
            for comp in list_batch['component']:
                type_components = comp['type_components']
                size_fitment_comps = comp['size_fitment_comps']

            # Place labels into the container element create row for each batch
            ttk.Label(self._list_batch_frame, text=batch_number).grid(column=0, row=r, padx=10, pady=10, sticky=tk.W)
            ttk.Label(self._list_batch_frame, text=type_components).grid(column=1, row=r, padx=10, pady=10, sticky=tk.W)
            ttk.Label(self._list_batch_frame, text=size_fitment_comps).grid(column=2, row=r, padx=10, pady=10, sticky=tk.W)
            ttk.Label(self._list_batch_frame, text=quantity_comp).grid(column=3, row=r, padx=10, pady=10, sticky=tk.W)
            ttk.Label(self._list_batch_frame, text=allocated_location).grid(column=4, row=r, padx=10, pady=10, sticky=tk.W)

            r += 1

        # Create a container to hold all label for menu
        self._list_batch_frame.grid(column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._list_batch_frame, text="Batch number").grid(column=0, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._list_batch_frame, text="Type").grid(column=1, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._list_batch_frame, text="Size/Fitment").grid(column=2, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._list_batch_frame, text="Quantity Made").grid(column=3, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._list_batch_frame, text="Location").grid(column=4, row=0, padx=10, pady=10, sticky=tk.W)

    # Show detail of the batch
    def view_details_batch(self):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._list_batch_frame.grid_remove()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Create a container to hold all label for menu
        self._detail_batch_frame.grid(
            column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._detail_batch_frame, text="Batch number:").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        # Place Entry into the container element create new batch
        ttk.Entry(self._detail_batch_frame, textvariable=self.entry_batch_no).grid(
            column=1, row=0, padx=52, pady=10)
        # Place Buttons into the container element create new batch
        ttk.Button(self._detail_batch_frame, text="Show Details", command=lambda : self.check_batch_exist(self.entry_batch_no.get())).grid(
            column=0, row=9, padx=10, pady=10, sticky=tk.W)

    # Check if batch exist, receive parameter from view_details_batch()
    def check_batch_exist(self, code):
        # Check if the bacth insert is a number
        if self.isNumber(code):

            if os.path.exists('../Data/' + code + '.pkl'):
                fhb = open('../Data/' + code + '.pkl', 'rb+')
                data = pickle.load(fhb)
                comps = []
                compStatus = []

                if code in data.keys():
                    # if the code is correct and exist execute the statement
                    batchDetail = data[code]  # pass to variable the element value to collect the right elements from the same list
                    ttk.Label(self._detail_batch_frame, text="Batch Number:\t{}".format(batchDetail[0])).grid(column=0, row=1, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Location:\t{}".format(batchDetail[3])).grid(column=0, row=2, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Manufacture date:\t{}".format(batchDetail[2])).grid(column=0, row=3, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Type:\t{}".format(batchDetail[4][0][1])).grid(column=0, row=4, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Size/Fit:\t{}".format(batchDetail[4][0][2])).grid(column=0, row=5, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Number Components in Batch:\t{}".format(batchDetail[1])).grid(column=0, row=6, padx=10, pady=10, sticky=tk.W)
                    n_comps = int(batchDetail[1])
                    i = 0
                    for i in range(n_comps):
                        comps.append(batchDetail[4][i][0])
                        compStatus.append(batchDetail[4][i][0] + ' ' + batchDetail[4][i][3])

                    ttk.Label(self._detail_batch_frame, text="SN Component:\t{}".format(comps)).grid(column=0, row=7, padx=10, pady=10, sticky=tk.W)
                    ttk.Label(self._detail_batch_frame, text="Component Status: [\n\t{}\n\t]".format("\n\t".join(compStatus))).grid(column=0, row=8, padx=10, pady=10, sticky=tk.W)

                return True

            else:
                messagebox.showwarning('Warning','Batch not found')
                return False
        else:
            messagebox.showerror('Warning', 'Is not a number, enter a valid number.')

    # Show detail of components
    def view_details_comp(self):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._list_batch_frame.grid_remove()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Create a container to hold all label for menu
        self._detail_comp_frame.grid(
            column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._detail_comp_frame, text="Component SN:").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        # Place Entry into the container element create new batch
        ttk.Entry(self._detail_comp_frame, textvariable=self.entry_components).grid(
            column=1, row=0, padx=52, pady=10)
        # Place Buttons into the container element create new batch
        ttk.Button(self._detail_comp_frame, text="Show Details", command=lambda : self.check_comp_exist(self.entry_components.get())).grid(
            column=0, row=7, padx=10, pady=10, sticky=tk.W)

    # Check if component exist by receiving parameter from view_details_comp()
    def check_comp_exist(self, code):
        # Check if the bacth insert is a number
        #if self.isNumber(code):

        if os.path.exists('../Data/' + code + '.pkl'):
            fhb = open('../Data/' + code + '.pkl', 'rb+')
            data = pickle.load(fhb)

            if code in data.keys():
                # if the code is correct and exist execute the statement
                compDetail = data[code]  # pass to variable the element value to collect the right elements from the same list
                ttk.Label(self._detail_comp_frame, text="Component Detail for:\t{}".format(compDetail[0])).grid(column=0, row=1, padx=10, pady=10, sticky=tk.W)
                ttk.Label(self._detail_comp_frame, text="Type:\t{}".format(compDetail[1])).grid(column=0, row=2, padx=10, pady=10, sticky=tk.W)
                ttk.Label(self._detail_comp_frame, text="Size/Fit:\t{}".format(compDetail[2])).grid(column=0, row=3, padx=10, pady=10, sticky=tk.W)
                ttk.Label(self._detail_comp_frame, text="Date of Manufacture:\t{}".format(compDetail[3])).grid(column=0, row=4, padx=10, pady=10, sticky=tk.W)
                ttk.Label(self._detail_comp_frame, text="Current Status:\t{}".format(compDetail[4])).grid(column=0, row=5, padx=10, pady=10, sticky=tk.W)
                ttk.Label(self._detail_comp_frame, text="Part of Batch:\t{}".format(compDetail[6])).grid(column=0, row=6, padx=10, pady=10, sticky=tk.W)

            return True

        else:
            messagebox.showwarning('Warning','Component not found')
            return False
        #else:
            #messagebox.showerror('Warning', 'Is not a number, enter a valid number.')

    # This method allocate a batch
    def show_frame_allocation (self):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Dictionary for dropdown location
        choices_location = {'Dubai','Paisley'}
        # set the default label in the dropdown option
        self.entry_choose_location.set('Paisley')

        # Create a container to hold all label for menu
        self._comp_allocation_frame.grid(
            column=0, row=10, padx=10, pady=10, ipadx=40, sticky=(tk.N, tk.W, tk.E, tk.S))
        # Place labels into the container element create new batch
        ttk.Label(self._comp_allocation_frame, text="Enter Batch Number:").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._comp_allocation_frame, text="Choose Location:").grid(
            column=0, row=1, padx=10, pady=10, sticky=tk.W)
        # Place Entry into the container element create new batch
        ttk.Entry(self._comp_allocation_frame, textvariable=self.entry_batch_no).grid(
            column=1, row=0, padx=52, pady=10)

        # Place Dropdown into the container element create a new batch
        OptionMenu(self._comp_allocation_frame, self.entry_choose_location, *
                   sorted(choices_location)).grid(column=1, row=1, padx=20, pady=10, ipadx=5)

        # Place Buttons into the container element create new batch
        ttk.Button(self._comp_allocation_frame, text="Allocate", command=lambda : self.check_allocation(self.entry_choose_location.get(), self.entry_batch_no.get())).grid(
            column=0, row=7, padx=10, pady=10, sticky=tk.W)

    def check_allocation(self, loc, code):
        # Check if the bacth insert is a number
        if self.isNumber(code):

            if os.path.exists('../Data/' + code + '.pkl'):
                fhb = open('../Data/' + code + '.pkl', 'rb+')
                data = pickle.load(fhb)
                fhb.close()

                if code in data.keys():
                    # if the code is correct and exist execute the statement
                    batchDetail = data[code]  # pass to variable the element value to collect the right elements from the same list
                    if (batchDetail[3] != 'Not Allocated'):
                        messagebox.showwarning('warning', 'Batch Already Allocated')
                    else:
                        yes_allocate_comp = messagebox.askyesno('Allocation', 'Batch Not Allocated, do you like to allocate batch num: {}?'.format(batchDetail[0]))
                        if yes_allocate_comp:
                            self.update_allocation_batch(loc, code)
            else:
                messagebox.showwarning('Warning','Batch not found')
        else:
            messagebox.showerror('Warning', 'Is not a number, enter a valid number.')

    def update_allocation_batch(self, loc, batchN):
        with open(self.file_path_name_w, 'r+') as f:
            data = json.load(f)
            for list_batch in data['Batch']:
                if (list_batch['number'] == batchN):
                    list_batch['location'] = loc

            f.seek(0)        # should reset file position to the beginning.
            json.dump(data, f, indent=2)
            f.truncate()     # remove remaining part
            f.close()
            # update also pickle file
            self.create_batch_pkl_file()
            self.create_comp_pkl_file()

            messagebox.showinfo('Allocate', 'This Batch is now allocated and will be shipped to the {} location'.format(loc))

    # method for search by product
    def search_product_type(self):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()
        # This statement destroy the old scrollbar when you call a new searching
        for child in self.scroll_comp_finished_frame.winfo_children(): child.destroy()
        for child in self.scroll_comp_unfinished_frame.winfo_children(): child.destroy()

        self._search_product_type_frame.grid(column=0, row=10, padx=10, pady=10, ipadx=40, sticky=tk.W)

        # Place labels into the container element search_product_type_frame
        ttk.Label(self._search_product_type_frame, text="Select component type:").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)
        ttk.Label(self._search_product_type_frame, text="Select Size/Fitment type:").grid(
            column=0, row=1, padx=10, pady=10, sticky=tk.W)

        # Dictionary for dropdown components type
        self.entry_type_comp.trace('w', self.search_product_options)

        self.optionmenu_type_comp = OptionMenu(self._search_product_type_frame, self.entry_type_comp, *sorted(self.choices_comp.keys()))
        self.optionmenu_size_fitment = OptionMenu(self._search_product_type_frame, self.entry_size_fitment, '')

        self.entry_type_comp.set('Door handle')

        self.optionmenu_type_comp.grid(column=1, row=0, padx=20, pady=10, ipadx=5)
        self.optionmenu_size_fitment.grid(column=1, row=1, padx=20, pady=10, ipadx=5)

        # Place Buttons into the container element create new batch
        ttk.Button(self._search_product_type_frame, text="Search", command=lambda: self.search_product(self.entry_type_comp.get(), self.entry_size_fitment.get())).grid(
            column=0, row=10, padx=10, pady=10, sticky=tk.W)

    def search_product(self, ctype, fit):
        # Open file json for retrieving all batch saved
        fh = open(self.file_path_name_w, 'r')
        data = json.load(fh)
        fh.close()

        unfinish_product = []
        finish_product = []

        # Loop and append in a new list all Batches founded
        msg_search = messagebox.askyesno('Info Component', 'You Selected {} {} is this Correct?'.format(fit, ctype))

        if msg_search:
            # this loop the json file and collect some data that I need for display in my scrollbar
            for list_product in data['Batch']:
                location = list_product['location']
                manufacture_date = list_product['manufacture_date']

                # this loop the json file and collect some data that I need for display in my scrollbar and check in a condition if finished or not
                for list_comp in list_product['component']:
                    serial_number = list_comp['sn_component']
                    status = list_comp['status']
                    # check if the component found are finished if so append in finish product list
                    if list_comp['type_components'] == ctype and list_comp['size_fitment_comps'] == fit and list_comp['status'] != 'Manufactured-Unfinished':
                        all_finished = [ctype,fit,serial_number,location,status,manufacture_date]
                        finish_product.append(all_finished)
                    # if not finished append into unfinish product list
                    elif list_comp['type_components'] == ctype and list_comp['size_fitment_comps'] == fit and list_comp['status'] == 'Manufactured-Unfinished':
                        all_unfinished = [ctype,fit,serial_number,location,status,manufacture_date]
                        unfinish_product.append(all_unfinished)

            # Check if the both list are empty, if so show a message and return False
            if len(unfinish_product) == 0 and len(finish_product) == 0:
                    messagebox.showwarning('Warning', 'No Stock Available!')
                    show_product = False
            # if not empty return True
            else:
                show_product = True

        # if show product is True call a function to display in a scrollbar all component founded
        if show_product:
            self.create_finished_scroll(finish_product, unfinish_product)

    """
        Start Methods to create 2 Scrolbars
        This methods create 2 scrollbar for finish and unfinished product
    """
    def create_finished_scroll(self, finished, unfinished):
        self.scroll_comp_finished_frame.grid(row=11, column=0, padx=10, pady=10, sticky=tk.W)
        self.create_frame_finished_scroll(self.scroll_comp_finished_frame, finished)

        self.scroll_comp_unfinished_frame.grid(row=12, column=0, padx=10, pady=10, sticky=tk.W)
        self.create_frame_unfinished_scroll(self.scroll_comp_unfinished_frame, unfinished)

    def create_frame_finished_scroll(self, box, finished):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()

        canvas = tk.Canvas(box, borderwidth=0)
        self.finished_comp_frame = tk.Frame(canvas)
        vsb = tk.Scrollbar(box, orient="vertical", command=canvas.yview)
        canvas.configure(yscrollcommand=vsb.set, width=750, heigh=80)

        vsb.pack(side="right", fill="y")
        canvas.pack(side="left", fill="both", expand=True)
        canvas.create_window((4,4), window=self.finished_comp_frame, anchor="w", tags="frame")

        # be sure that we call OnFrameConfigure on the right canvas
        self.finished_comp_frame.bind("<Configure>", lambda event, canvas=canvas: self.on_scroll_frame_configure(canvas))

        self.fill_finished_window(self.finished_comp_frame, finished)

    def fill_finished_window(self, frame, finished):
        sn_components = ttk.Label(self.finished_comp_frame, text="Component Serial Number", font=('courier', 11, 'bold'))
        sn_components.grid(row=0, column=0, padx=10, sticky=tk.W)
        location_comp = ttk.Label(self.finished_comp_frame, text="Location", font=('courier', 11, 'bold'))
        location_comp.grid(row=0, column=1, padx=10, sticky=tk.W)
        finish = ttk.Label(self.finished_comp_frame, text="Finish", font=('courier', 11, 'bold'))
        finish.grid(row=0, column=2, padx=10, sticky=tk.W)
        manufacture_date = ttk.Label(self.finished_comp_frame, text="Manufacture Date", font=('courier', 11, 'bold'))
        manufacture_date.grid(row=0, column=3, padx=10, sticky=tk.W)

        for i in range(len(finished)):
            sn_components_w1 = ttk.Label(self.finished_comp_frame, text=str(finished[i][2:3]))
            sn_components_w1.grid(row=i+1, column=0, padx=10, sticky=tk.W)
            location_comp_w1 = ttk.Label(self.finished_comp_frame, text=str(finished[i][3:4]))
            location_comp_w1.grid(row=i+1, column=1, padx=10, sticky=tk.W)
            finish_w1 = ttk.Label(self.finished_comp_frame, text=str(finished[i][4:5]))
            finish_w1.grid(row=i+1, column=2, padx=10, sticky=tk.W)
            manufacture_date_w1 = ttk.Label(self.finished_comp_frame, text=str(finished[i][5:]))
            manufacture_date_w1.grid(row=i+1, column=3, padx=10, sticky=tk.W)

    def create_frame_unfinished_scroll(self, box, unfinished):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._finish_comp_frame.grid_forget()
        self._search_product_type_frame.grid_forget()

        canvas = tk.Canvas(box, borderwidth=0)
        self.unfinished_comp_frame = tk.Frame(canvas)
        vsb = tk.Scrollbar(box, orient="vertical", command=canvas.yview)
        canvas.configure(yscrollcommand=vsb.set, width=750, heigh=80)

        vsb.pack(side="right", fill="y")
        canvas.pack(side="left", fill="both", expand=True)
        canvas.create_window((4,4), window=self.unfinished_comp_frame, anchor="w", tags="frame")

        # be sure that we call OnFrameConfigure on the right canvas
        self.unfinished_comp_frame.bind("<Configure>", lambda event, canvas=canvas: self.on_scroll_frame_configure(canvas))

        self.fill_unfinished_window(self.unfinished_comp_frame, unfinished)

    def fill_unfinished_window(self, frame, unfinished):
        sn_components = ttk.Label(self.unfinished_comp_frame, text="Component Serial Number", font=('courier', 11, 'bold'))
        sn_components.grid(row=0, column=0, padx=10, sticky=tk.W)
        location_comp = ttk.Label(self.unfinished_comp_frame, text="Location", font=('courier', 11, 'bold'))
        location_comp.grid(row=0, column=1, padx=10, sticky=tk.W)
        unfinish = ttk.Label(self.unfinished_comp_frame, text="Finish", font=('courier', 11, 'bold'))
        unfinish.grid(row=0, column=2, padx=10, sticky=tk.W)
        manufacture_date = ttk.Label(self.unfinished_comp_frame, text="Manufacture Date", font=('courier', 11, 'bold'))
        manufacture_date.grid(row=0, column=3, padx=10, sticky=tk.W)

        for i in range(len(unfinished)):
            # split the fifth element from unfinished list and take the first element to show on scrollbar
            split_unfinish = unfinished[i][4:5]
            split_result = [i.split('-', 1)[1] for i in split_unfinish]

            sn_components_w1 = ttk.Label(self.unfinished_comp_frame, text=str(unfinished[i][2:3]))
            sn_components_w1.grid(row=i+1, column=0, padx=10, sticky=tk.W)
            location_comp_w1 = ttk.Label(self.unfinished_comp_frame, text=str(unfinished[i][3:4]))
            location_comp_w1.grid(row=i+1, column=1, padx=10, sticky=tk.W)
            unfinish_w1 = ttk.Label(self.unfinished_comp_frame, text=str(split_result))
            unfinish_w1.grid(row=i+1, column=2, padx=10, sticky=tk.W)
            manufacture_date_w1 = ttk.Label(self.unfinished_comp_frame, text=str(unfinished[i][5:]))
            manufacture_date_w1.grid(row=i+1, column=3, padx=10, sticky=tk.W)

    def on_scroll_frame_configure(self, canvas):
        canvas.configure(scrollregion=canvas.bbox("all"))

    """
        =============== END Scrollbar Methods =========================

    """

    # Method that finish component
    def finish_component(self, fcomp='No'):
        self._show_details_frame.grid_forget()
        self._create_batch_frame.grid_forget()
        self._detail_batch_frame.grid_forget()
        self._list_batch_frame.grid_forget()
        self._detail_comp_frame.grid_forget()
        self._comp_allocation_frame.grid_forget()
        self._search_product_type_frame.grid_forget()
        self.scroll_comp_finished_frame.grid_forget()
        self.scroll_comp_unfinished_frame.grid_forget()

        # Create a container to hold all label for finish component
        self._finish_comp_frame.grid(column=0, row=10, padx=10,
            pady=10, ipadx=40, sticky=tk.W)

        # Place labels into the container element finish_comp_frame
        ttk.Label(self._finish_comp_frame, text="Enter SN of the Component to Finish").grid(
            column=0, row=0, padx=10, pady=10, sticky=tk.W)

        # Place Entry into the container element create new batch
        ttk.Entry(self._finish_comp_frame, textvariable=self.entry_components).grid(
            column=1, row=0, padx=52, pady=10)

        # Place Buttons into the container element create new batch
        if (fcomp == 'Yes'):
            ttk.Label(self._finish_comp_frame, text="Select Type Finish").grid(
                column=0, row=1, padx=10, pady=10, sticky=tk.W)
            ttk.Label(self._finish_comp_frame, text="Select Paint Code").grid(
                column=0, row=2, padx=10, pady=10, sticky=tk.W)

            self.entry_choose_status.trace('w', self.update_status_options)

            self.optionmenu_type_status = OptionMenu(self._finish_comp_frame, self.entry_choose_status, *sorted(self.choices_status.keys()))
            self.optionmenu_code_paint = OptionMenu(self._finish_comp_frame, self.entry_code_paint, '')

            self.entry_choose_status.set('Polished')

            self.optionmenu_type_status.grid(column=1, row=1, padx=20, pady=10, ipadx=5)
            self.optionmenu_code_paint.grid(column=1, row=2, padx=20, pady=10, ipadx=5)

            ttk.Button(self._finish_comp_frame, text="Save Status", command=lambda: self.update_finished_comp(
                self.entry_components.get(),self.entry_choose_status.get(),self.entry_code_paint.get())).grid(column=0, row=4, padx=11, pady=10, sticky=tk.W)
        else:
            ttk.Button(self._finish_comp_frame, text="Check Status", command=lambda: self.check_sn_comp_finished(self.entry_components.get())).grid(
                column=0, row=4, padx=10, pady=10, sticky=tk.W)

    def update_finished_comp(self, sn, stat, code):
        # Open json file and read and load data in a variable
        with open(self.file_path_name_w, 'r+') as f:
            data = json.load(f)
            i = 0
            for list_batch in data['Batch']:
                for i in list_batch['component']:
                    if (i['sn_component'] == sn):
                        i['status'] = stat + ': ' + code

            f.seek(0)        # <--- should reset file position to the beginning.
            json.dump(data, f, indent=2)
            f.truncate()     # remove remaining part
            f.close()
            # update also pickle file
            self.create_batch_pkl_file()
            self.create_comp_pkl_file()

            messagebox.showinfo('Finished', 'Component Number {} will be finished using {}: {}'.format(sn,stat,code))

    def check_sn_comp_finished(self, sncomp):
        # Check if file exist, if so open and read
        if os.path.exists('../Data/' + sncomp + '.pkl'):
            fhc = open('../Data/' + sncomp + '.pkl', 'rb+')
            data = pickle.load(fhc)

            if sncomp in data.keys():
                compDetails = data[sncomp]  # pass to variable the element value to collect the right elements from the same list
                if (compDetails[4] == 'Manufactured-Unfinished' and compDetails[5] != 'Not Allocated'):
                    yes_correct_comp = messagebox.askyesno('Info', 'You selected {} {} {} is this correct?'.format(compDetails[2], compDetails[1], compDetails[5]))
                    if yes_correct_comp:
                        self.finish_component('Yes')
                elif (compDetails[4] == 'Manufactured-Unfinished' and compDetails[5] == 'Not Allocated'):
                    yes_allocate_comp = messagebox.askyesno('Allocation', 'Batch Not Allocated, do you like to allocate batch num: {}?'.format(compDetails[6]))
                    if yes_allocate_comp:
                        self.show_frame_allocation()
                else:
                    messagebox.showwarning('Warning', 'This comp is already finished!')
        else:
            messagebox.showerror('Error', 'Component not found')

    # Method that close Application
    def close_app(self):
        # Below line is just for testing if everything work
        msgbox_exit = messagebox.askyesno(
            'Exit Program', 'Are you sure want to EXIT!', icon='warning')
        if msgbox_exit:
            # Below line is just for testing if everything work
            print('Close App method Called')
            self.quit()
        else:
            # Below line is just for testing if everything work
            print('Return to menu')

# ====================
# Start GUI
# ====================
if __name__ == "__main__":
    _frame = tk.Tk()
    app = App(_frame)
    app.mainloop()


import os
in_dir = r"D:\Data\speech\Buckeye\original"

for f in os.listdir(in_dir):
    if not f.endswith('.words'):
        continue
    file_path = os.path.join(in_dir, f)
    lines = []
    print(file_path)
    with open(file_path, 'r', encoding='utf8') as f:
        for line in f:
            line = line.rstrip()
            if not line:
                continue
            print(repr(line))
            if line.count(';') == 3:
                line = ';'.join(line.split(';')[:-1])
                line = line.rstrip()
            lines.append(line)
    #error
    with open(file_path, 'w', encoding='utf8', newline='') as f:
        for line in lines:
            f.write(f"{line}\n")


from models.base_model import BaseModel
import tensorflow as tf

class LinearRegressionModel(BaseModel):
    """Class containing the model of the optimizee - in this case a simple linear regressor with a single output,
    classifying the inputs into either 0 or 1.

    Arguments:
        config {dict} -- Configuration for model.
    """

    def __init__(self, config):
        super(LinearRegressionModel, self).__init__(config)

        self.build_model()
        self.init_saver()

    def build_model(self):
        # here you build the tensorflow graph of any model you want and also define the loss.
        # tf.set_random_seed(0)

        self.x = tf.placeholder(
            tf.float32, shape=[None, self.config["dim"]], name="input")
        self.y = tf.placeholder(tf.float32, shape=[None, 1], name="label")

        self.losses = []
        self.accuracy = None

    def init_saver(self):
        self.saver = tf.train.Saver(max_to_keep=self.config["max_to_keep"])

    def create_problem(self, optimizer_name="rnn"):
        """Creates initial instance of the optimizee and returns the weights.

        Keyword Arguments:
            optimizer_name {str} -- Name that defines the optimizer, used to group the variables. (default: {"rnn"})

        Returns:
            weights {list} -- Returns weights in the initial problem.
        """

        with tf.variable_scope(optimizer_name):
            W = tf.get_variable(
                shape=[self.config["dim"], 1], initializer=tf.glorot_uniform_initializer(), name="kernel")
            b = tf.get_variable(
                shape=[1], initializer=tf.glorot_uniform_initializer(), name="bias")

            pred = tf.add(tf.matmul(self.x, W), b)

        self.losses.append(tf.reduce_mean(
            tf.nn.sigmoid_cross_entropy_with_logits(labels=self.y, logits=pred)))

        return [W, b]

    def rollout(self, updates, weights, iteration):
        """Does one step of the rollout - creates new instance of the problem
        where the weights are created by applying updates calculated by the optimizer.

        Arguments:
            updates {list} -- List of updates to be applied to the parameters.
            weights {list} -- List of parameters of the last layer of the rollout.

        Returns:
            weights {list} -- Returns ops to calculate the new weights.
        """

        weights = [var + update for update, var in zip(updates, weights)]
        pred = tf.add(tf.matmul(self.x, weights[0]), weights[1])

        self.losses.append(tf.reduce_mean(
            tf.nn.sigmoid_cross_entropy_with_logits(labels=self.y, logits=pred)))

        if iteration == self.config["rollout_length"]:
            self.prediction = tf.round(tf.sigmoid(pred))
            correct_prediction = tf.equal(self.prediction, self.y)
            self.accuracy = tf.reduce_mean(
                tf.cast(correct_prediction, tf.float32))

        return weights


import requests
import json

utl = 'http://test-user.ekeguan.com/sem/addSemUser'
url = 'http://test-shijuan.ekeguan.com'
data = {
    "businessId": 2,
    "mobilestyle": 'pc',
    "sourceType": '42',
    "graduateTime": '202207',
    "degree": '本科',
    'phone': 18500352554,
    'smsCode': 8272
       }
header = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'projectId': '1',
    'appFlag': '1',
    'deviceType': 'HUAWEI_EML-AL00_29',
    'deviceId': 'e77f7bcd-97ad-87f3-c79b-fbe7ffbffbaa',
    'platformVersion': 'Andriod:4.1+',
    'platform': 'android-Android',
    'EagleEye-TraceId': 'd26865ea-b22b-441d-d26865ea-b22b-441d',
    'timestamp': '1603198276',
    'appVersion': 'v4.1.7',
    'source': '1100'
}
data1 = {
    "businessId": 2,
    "phone": '18500352554'
}
# response = requests.post(url=url, headers=header, data=data1)
# print(response.json())
response = requests.post(url=utl, headers=header, data=data)
print(response.json())


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

# # 1. Data set
#
# PyTorch 의 TorchVision, TorchText, TorchAudio 등의 라이브러리에서는 다양한 데이터셋 샘플을 제공합니다.
#
# 각 라이브러리에 대해 학습 데이터와 테스트 데이터를 사용하는 방법과 더불어 dataset을 커스텀하여 사용하는 방법에 대해 소개하겠습니다.
#
# ---

# ## 1.1 TorchVision
#
# `TorchVision` 는 컴퓨터비전 라이브러리로 datasets, transforms(argument) 등의 다양한 기능을 제공하고 있습니다.
#
# 이번 단계에서는 `TorchVision` 에서 제공하는 Datasets 을 활용하는 방법에 대해서 알아보겠습니다. `TorchVision` 에 대한 자세한 설명은 관련 파트(링크) 에서 자세히 다루도록 하겠습니다.

# 우선 torchvision 을 설치합니다. 환경에 따라 아래 명령어로 설치할 수 있습니다.
#
# 1. Anaconda
#
#    `
#    conda install torchvision -c pytorch
#    `
#
# 2. pip
#
#    `
#    !pip install torchvision
#    `
#
#

# 이후 torchvision 에서 여러 vision dataset 을 다운받을 수 있습니다. 대표적인 vision dataset 인 CIFAR 를 예시로 살펴보겠습니다.

# In[4]:

from torchvision import datasets

# CIFAR
CIFAR_train = datasets.CIFAR10(
    root="CIFAR",	# (str), 데이터셋이 저장될 경로, True 인 경우 루트 디렉토리에 생성
    train=True,		# (bool), True 인 경우, train set 에서 데이터 생성
    download=True	# (bool), True 인 경우, root 디렉토리에 데이터 다운로드
)
CIFAR_test = datasets.CIFAR10(
    root="CIFAR",
    train=False,	# (bool), Flase 인 경우, test set 에서 데이터 생성
    download=True
)

# `datasets` 에서 사용하는 매개변수는 아래와 같습니다.
#
# 1. root
# 2. train
# 3. download
# 4. transform
# 5. target_transform
#
# *추가 예정*

# 이때, `torchvision.transforms` 클래스를 사용하면 데이터 타입을 tesor 로 변환하거나 이미지에 변형을 줄 수 있습니다. 관련하여 자세한 내용은 Data Argument 파트(링크)에서 자세히 다루며, 여기에서는 가볍게 살펴보도록 하겠습니다.

# In[6]:

from torchvision import datasets
from torchvision.transforms import ToTensor, RandomCrop, RandomVerticalFlip

# ToTensor, 데이터 타입을 tensor 로 변경
cifar_test_ToTensor = datasets.CIFAR10(
    root="CIFAR_ToTensor",
    train=False,
    download=True,
    transform=ToTensor(),	# data 타입을 Tesor 로 변경
)

# RandomCrop, 데이터를 랜덤으로 crop 하여 size 크기로 출력
cifar_test_RandomCrop = datasets.CIFAR10(
    root="CIFAR_RandomCrop",
    train=False,
    download=True,
    transform=RandomCrop(25),	# data 를 랜덤으로 crop 하여 25*25 사이즈로 출력
)

# RandomVerticalFlip, 이미지 뒤집기
cifar_test_RandomVerticalFlip = datasets.CIFAR10(
    root="CIFAR_RandomVerticalFlip",
    train=False,
    download=True,
    transform=RandomVerticalFlip(p=0.5),	# data 를 수직으로 뒤집기
)

# transforms 중 RandomCrop 의 결과를 살펴보겠습니다. 원래 Cifar 데이터의 크기는 32 * 32 이지만, RandomCrop(25) 으로 25 * 25 크기로 잘려 변형되었습니다.
#
# matplotlib 라이브러리로 시각화하여 결과를 살펴보겠습니다.

# In[27]:

import torch
import matplotlib.pyplot as plt

# 노란 배경의 흰 말 사진(idx :808) 데이터로 확인
crop_image, l1 = cifar_test_RandomCrop[808] #transform 거친 데이터
image, l2 = test[808] # 원본 데이터

fig = plt.figure(figsize=(7, 7)) # 출력할 이미지 사이즈 조정

ax1 = fig.add_subplot(1, 2, 1)
ax1.imshow(crop_image)
ax1.set_xlabel("crop, label:"+ str(l1))
ax1.set_xticks([]), ax1.set_yticks([])

ax2 = fig.add_subplot(1, 2, 2)
ax2.imshow(image)
ax2.set_xlabel("origin, label:"+ str(l2))
ax2.set_xticks([]), ax2.set_yticks([])

plt.show()

# 위 출력 결과에서 crop 된 이미지가 사이즈에 맞춰 변형된 것을 확인할 수 있습니다. 참고로 cifar 10 데이터 셋에서 말 사진은 label 7로 분류됩니다. 또한, dataset으로 불러온 데이터들이 feature(데이터셋의 특징, cifar 데이터에서는 이미지 픽셀값)과 label 로 구성되어 있다는 것을 알 수 있습니다.
#
#
#
# 불러온 데이터 셋을 `DataLoader` 클래스로 묶어서 객체로 활용할 수 있습니다. 관련 내용은 이하 `DataLoader` 클래스 파트(링크)에서 자세히 다루도록 하겠습니다.
#
# CIFAR 와 MNIST 외의 다양한 vision 데이터가 있습니다. 관련하여 공식문서 ([링크](https://pytorch.org/vision/stable/datasets.html)) 를 참조바랍니다.
#
# ---
#
#

# ## 1.2 TorchText
#
# `TorchText` 는 자연어처리 라이브러리로 Tokenization 을 비롯한 다양한 기능을 제공하고 있습니다. 이번 단계에서는 `TorchText` 에서 제공하는 Datasets 을 활용하는 방법에 대해서 알아보겠습니다. `TorchText` 에 대한 자세한 설명은 관련 파트(링크) 에서 자세히 다루도록 하겠습니다.
#
# *(추가예정)*
#
#
#
# ---
#
#

#
#
# ## 1.3 TorchAudio
#
# `TorchAudio` 는 오디오 라이브러리로 ??? 을 비롯한 다양한 기능을 제공하고 있습니다. 이번 단계에서는 `TorchAudio` 에서 제공하는 Datasets 을 활용하는 방법에 대해서 알아보겠습니다. `TorchAudio` 에 대한 자세한 설명은 관련 파트(링크) 에서 자세히 다루도록 하겠습니다.
#
# *(추가예정)*
#
#
#
# ---
#
#

# ### 1.4 Custom Dataset
#
# 사용자가 직접 Dataset을 정의하여 사용할 수도 있습니다.
#
# *(추가예정)*
#
# - https://tutorials.pytorch.kr/beginner/basics/tensorqs_tutorial.html
#
# - https://sanghyu.tistory.com/90
# - https://pytorch.org/docs/stable/data.html#dataloader-collate-fn
# - https://tutorials.pytorch.kr/beginner/basics/data_tutorial.html#id9
#
#
#
# ---
#


#!/usr/bin/python3

import multiprocessing
import subprocess
import ipaddress
import argparse
import sys
import os

# Nice comment
def sweeper( job_q , results_q, interface):
    DEVNULL = open(os.devnull,'w')
    while True :
        ip = job_q.get()
        if ip is None :
            break ;

        try :
            subprocess.check_call(['ping' , '-c1' , ip , '-I' , interface],stdout=DEVNULL)

            results_q.put(ip)

        except:
            pass

if __name__ == '__main__' :

    arg_parser = argparse.ArgumentParser(description='Performs quick ping sweep on a given network')
    arg_parser.add_argument('ip_network' , type=str , help='IP network to scan. Example:10.1.1.0/24')
    arg_parser.add_argument('iface' , type=str , nargs="?" , default="eth0", help='Interface to use. Default is eth0')
    args = arg_parser.parse_args();

    ip_network = ipaddress.IPv4Network(args.ip_network)
    print("Sweeping %s on interface : %s"%(args.ip_network,args.iface))
    interface = args.iface
    jobq = multiprocessing.Queue()
    resultq = multiprocessing.Queue()

    for ipaddr in list(ip_network.hosts()):
        jobq.put(str(ipaddr))

    ProcessQueue = [multiprocessing.Process(target=sweeper , args=(jobq,resultq,interface)) for ipaddr in list(ip_network.hosts())]

    for p in ProcessQueue :
        p.start();

    for p in ProcessQueue:
        jobq.put(None);

    for p in ProcessQueue:
        p.join()

    while not resultq.empty():
        ip = resultq.get();

        print('%s\thost is up'%(ip))


import numpy as np
import pandas as pd
import streamlit as st

st.set_option('deprecation.showPyplotGlobalUse', False)

img_url = 'https://encrypted-tbn0.gstatic.com/images?q=tbn' \
          ':ANd9GcS2j3GxJqj8vYW9Tei7I51uYgiWkQa90LSWTQ&usqp=CAU '
st.set_page_config(
    layout="wide", initial_sidebar_state="auto",
    page_title="Gross to Net", page_icon=img_url)

efka_options = {
    'Ειδική': 1632,
    '1η': 2640,
    '2η': 3144,
    '3η': 3744,
    '4η': 4476,
    '5η': 5340,
    '6η': 6912,
}

st.title('ΜΕΙΚΤΑ ΣΕ ΚΑΘΑΡΑ')
st.subheader('υπολογισμός κρατήσεων επιχείρησης παροχής υπηρεσιών')

def convert(number):
    currency_string = "€ {:,.2f}".format(number)
    return currency_string

def calculate_income():
    st.markdown('### Έσοδα (τζίρος)')
    me_fpa = st.number_input('Ετήσιες αποδοχές που έχουν ΦΠΑ', min_value=0)
    xwris_fpa = st.number_input('Ετήσιες αποδοχές που δεν έχουν ΦΠΑ',
                                min_value=0)

    without_fpa = me_fpa / 1.24

    total_income = without_fpa + xwris_fpa

    return total_income

def calculate_expenses():
    st.markdown('### ΕΞΟΔΑ')
    logistika = st.number_input('Ετήσια λογιστικά έξοδα', min_value=0)
    enoikia = st.number_input('Ενοίκια', min_value=0)
    revma = st.number_input('Ρεύμα', min_value=0)
    nero = st.number_input('Νερό', min_value=0)
    internet = st.number_input('Τηλέφωνα-Internet', min_value=0)
    special = st.number_input('Ειδική', min_value=0)
    other_expenses = st.number_input('Aναλώσιμα/Λοιπά έξοδα', min_value=0)

    total = logistika
    total += enoikia
    total += revma
    total += nero
    total += internet
    total += special
    total += other_expenses

    efka_help = 'Από 01/01/2020 δημιουργούνται επτά (7) ασφαλιστικές ' \
                'κατηγορίες για ελεύθερους επαγγελματίες και ' \
                'αυτοαπασχολούμενους, εκ των οποίων μία θεωρείται ειδική ' \
                'ασφαλιστική κατηγορία και απευθύνεται σε νέους ' \
                'επαγγελματίες (πρώτα πέντε έτη ασφάλισης). '

    st.markdown('### ΕΦΚΑ')
    efka = st.selectbox('Ασφ. Κατηγορία', options=efka_options,
                        help=efka_help, )
    st.markdown(f'Ποσό: **{convert(efka_options[efka])}**')

    total += efka_options[efka]
    return total

def compute_tax_on_atomic(amount_to_be_taxed):

    st.markdown('### Ανάλυση Φορολογίας Ατομικής Επιχείρησης')

    x = amount_to_be_taxed
    tax_prc_values = [0.09, 0.22, 0.28, 0.36, 0.44]
    step = 10_000
    tax_values = []
    for f in tax_prc_values[:-1]:
        if x > 0:
            x -= step
            tax_values.append(f * step)
        else:
            break

    if x > 0:
        tax_values.append(tax_prc_values[-1] * x)

    total_tax = sum(tax_values)

    tax_coeff = ["{:.0%}".format(i) for i in tax_prc_values[:len(tax_values)]]
    tax_coeff.append('Σύνολο')
    tax_values.append(total_tax)
    tax_values = [convert(i) for i in tax_values]

    tax_df = pd.DataFrame({'Συντελεστής': tax_coeff,
                           'Ποσό': tax_values})

    st.dataframe(tax_df)

    st.markdown(f'**Συνολικός Κύριος Φόρος Ατομικής '
                f'Επιχείρησης: {convert(total_tax)}**')

    net_value = amount_to_be_taxed - total_tax
    return total_tax, net_value

def compute_tax_for_oe_and_ee(amount_to_be_taxed):
    st.markdown('### Ανάλυση Φορολογίας ΟΕ-ΕΕ Επιχείρησης')
    tax_prc = 0.22

    total_tax = tax_prc * amount_to_be_taxed
    extra_tax = 1000  # telos epitideuvatos

    total_tax += extra_tax
    column1 = [
        'Συντελεστής 22%',
        'Τέλος Επιτηδεύματος',
        'Σύνολο'
    ]
    column2 = [
        convert(tax_prc * amount_to_be_taxed),
        convert(extra_tax),
        convert(total_tax)
    ]
    data = pd.DataFrame({'Ανάλυση': column1, 'Ποσό': column2})
    st.dataframe(data)

    st.markdown(f'**Συνολικός Κύριος Φόρος OE-EE '
                f'Επιχείρησης: {convert(total_tax)}**')

    net_value = amount_to_be_taxed - total_tax
    return total_tax, net_value

def analyse_per_month(value):
    twelve = round(value / 12, 2)
    fourteen = round(value / 14, 2)

    labels = [
        'Συνολικό καθαρό εισόδημα',
        'Καθαρό εισόδημα ανά μήνα για 12 μήνες',
        'Καθαρό εισόδημα ανά μήνα για 14 μήνες',
    ]
    values = [
        convert(value),
        convert(twelve),
        convert(fourteen)
    ]

    data = pd.DataFrame({'Καθαρά Κέρδη': labels,
                         'Ποσό': values})

    st.dataframe(data)

col1, col2 = st.columns(2)
with col1:
    total_in = calculate_income()
with col2:
    expenses = calculate_expenses()

run = st.button('Υπολογισμός Κρατήσεων')
if run and total_in > 0:
    to_be_taxed = total_in - expenses
    labels = ['Συνολικά έσοδα (χωρίς ΦΠΑ)',
              'Συνολικά έξοδα & ΕΦΚΑ',
              'Ποσό προς φορολόγηση (καθαρά κέρδη)']

    numbers = [convert(total_in),
               convert(expenses),
               convert(to_be_taxed)]

    df = pd.DataFrame({'Αποτελέσματα': labels, 'Ποσό': numbers})

    st.dataframe(df)

    col1, col2 = st.columns(2)

    st.markdown('### Η προκαταβολή φόρου δεν λαμβάνεται υπόψιν στους '
                'υπολογισμούς')

    with col1:
        atomic_tax, atomic_net = compute_tax_on_atomic(to_be_taxed)
        analyse_per_month(atomic_net)
    with col2:
        ee_tax, ee_net = compute_tax_for_oe_and_ee(to_be_taxed)
        analyse_per_month(ee_net)


import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.ticker import FormatStrFormatter

from .datasets import sets, sets_smt

NUM_RUNS = 20

def plot_fft_runtime(*args):

    smt  = len(args) > 0 and args[0] == "smt"
    sets_selected = sets_smt if smt else sets

    theme = "ggplot" if smt else "./custom-ggplot.mplstyle"
    plt.style.use([theme, "./matplotlibrc"])

    for name, title, roundtrip, data in sets_selected:

        labels = []
        axes = None

        for data_per_lib in data:

            for label, filename, marker, line in data_per_lib:

                data = pd.read_csv(filename, comment=";")

                if not data["success"].isin(["Warmup", "Success"]).all():
                    raise ValueError(f"Error processing file {file}:\n"
                                     f"Not all runs were Warmup/Success.")

                def max_unary(x): return max(1, x)

                data = data[data["success"] == "Success"]
                data["n"] = data["nx"] \
                        * data["ny"].apply(max_unary) \
                        * data["nz"].apply(max_unary)

                if roundtrip:
                    data["Time_FFT [ms]"] = data["Time_FFT [ms]"].add(data["Time_iFFT [ms]"])

                data = data[["dim", "n", "Time_FFT [ms]"]]
                data_grouped = data.groupby(["dim", "n"])

                def lower(x): return np.quantile(x, 0.25)
                def upper(x): return np.quantile(x, 0.75)
                measures = [lower, np.median, upper]
                data_agg = data_grouped.agg({"Time_FFT [ms]": measures})
                data_agg.columns = ["lower", "median", "upper"]
                data_agg.reset_index(level=1, inplace=True)

                data_agg["upper"] = data_agg["upper"].sub(data_agg["median"])
                data_agg["lower"] = data_agg["median"].sub(data_agg["lower"])
                data_agg.sort_index(inplace=True)

                medians = data_agg[["n", "median"]].set_index("n")
                errors = data_agg[["lower", "upper"]].to_numpy().transpose().reshape(1, 2, -1)

                axes = medians.plot(kind="line", yerr=errors, ax=axes, marker=marker, linestyle=line)

                labels += [label]

        axes.set_xscale('log', base=2)
        axes.set_yscale('log', base=10)
        axes.set_xticks(data_agg["n"])

        if not "case1" in name:
            axes.get_xaxis().set_major_formatter(FormatStrFormatter('%d'))

        xmin, xmax = plt.xlim()
        xminNew = 2**(np.log2(xmin)-0.05*np.log2(xmax/xmin))
        xmaxNew = 2**(np.log2(xmax)+0.05*np.log2(xmax/xmin))
        plt.xlim((xminNew, xmaxNew))

        axes.legend(labels)

        plt.title(title)
        plt.xlabel("problem size (# samples)")
        plt.ylabel("runtime [ms]")

        plt.savefig(f"plots/fft-runtime-{name}.pdf")

        plt.close()


from odoo import models, fields, api,_
from datetime import datetime
from odoo.exceptions import UserError, AccessError ,ValidationError
from dateutil import relativedelta

class IsAssetWizard(models.Model):
    _name='is.asset.wizard'

    start_date=fields.Date('Start Date',required=True)
    category_id=fields.Many2one('account.asset.category','Category',required=True)
    end_date=fields.Date('End Date', required=True,
                          default=str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10],
                          )

    target_move = fields.Selection([('posted', 'All Posted Entries'),
                                    ('all', 'All Entries'),
                                    ], string='Target Moves', required=True, default='posted')

    @api.multi
    def print_report(self):
        data = {}
        production = []
        if self.start_date and self.end_date:
            records = self.env['account.asset.asset'].search(
                [('date', '>=', self.start_date), ('date', '<=', self.end_date),('category_id', '=', self.category_id.id)
                 ])

            data['records'] = records.ids
            data['start_date'] = self.start_date
            data['end_date'] = self.end_date
            data['category_id'] = self.category_id.name
            data['target_move'] = self.target_move
            return self.env['report'].get_action(self, 'is_account_asset_10.is_asset_template', data=data)

class is_account_asset_wazirds(models.AbstractModel):
    _name = 'report.is_account_asset_10.is_asset_template'

    @api.model
    def render_html(self, docids,data):
        # data['00000000'] = self.env['account.analytic.line'].browse(data['records'])
        data['records']=self.env['account.asset.asset'].browse(data['records'])
        docs=data['records']
        docargs = {

            'data': data,
            'docs': docs,
        }
        return self.env['report'].render('is_account_asset_10.is_asset_template', docargs)