samedi 29 mai 2021

If-else condition returns always false when checking an object attribute

I'm trying to use the function 'set_disp_time' to change the disp_time value of every 'workshop' object from undefined to a certain number, depending on a formula. The formula can take 2 forms depending from an if statement, but the condition for entering the statement returns false even when it should return true!

This is the code: Class that calls the fuction:

from loader import Loader

loader_ = Loader(r'C:\Users\damia\OneDrive\Desktop\logistic management tool\cycles_sample.xlsx',
                 r'C:\Users\damia\OneDrive\Desktop\logistic management tool\demand_sample.xlsx',
                 r'C:\Users\damia\OneDrive\Desktop\logistic management tool\bom_sample.xlsx',
                 r'C:\Users\damia\OneDrive\Desktop\logistic management tool\workshops_sample.xlsx')


class Plant:

    def __init__(self, loader):

        self.loader = loader
        self.workshops = self.loader.get_workshops()

        for ws in self.workshops:
            print('workshop automation level: ', ws.automation)
            print('checks if the workshop automation is table: ', str(ws.automation) == 'table')

        # computes disposable times
        for workshop in self.workshops:
            workshop.set_disp_time()


plant = Plant(loader_)
class Workshop:

    def __init__(self, name, shifts, shift_dur, pauses, pause_dur, placing, type_, uptime):

        self.name = name
        self.shifts = shifts
        self. shift_dur = shift_dur
        self.pauses = pauses
        self.pause_dur = pause_dur
        self.placing = placing
        self.type_ = type_
        self.uptime = uptime

        self.parts = []
        self.automation = set()
        self.disp_time = 'undefined'

    def set_part(self, part):

        for phase in part.phases:
            if phase.placings > 0:
                self.automation.add('auto')
            elif phase.placings == 0 and phase.machining != phase.operator:
                self.automation.add('machine')
            elif phase.placings == 0 and phase.machining == phase.operator:
                self.automation.add('table')
            else:
                raise Exception('Undefined type for workshop, part, phase: ', self.name, part.name, phase.seq)

        if len(self.automation) != 1:
            raise Exception('more that 1 kind of automation')

        self.parts.append(part)

    # computes workshop disposable time
    def set_disp_time(self):

        print('inside set function')
        print(self.automation)
        print(self.automation == set('auto'))

        if self.automation == set('table'):
            self.disp_time = self.shifts * self.shift_dur * 60 * self.uptime - self.pauses * self.pause_dur
        elif self.automation == set('machine') or self.automation == set('auto'):
            self.disp_time = self.shifts * self.shift_dur * 60 * self.uptime
        else:
            raise Exception('Undefined disposable time for: ', self.name)

There's also a class that loads data from excel, but it shouldn't give any problem, since the workshop objects are created correctly:

import pandas as pd
from iteration_utilities import duplicates, unique_everseen
from workshop import Workshop


class Phase:

    def __init__(self, seq, workshop, machining, operator, placings, setup):

        self.seq = seq
        self.workshop = workshop
        self.machining = machining
        self.operator = operator
        self.placings = placings
        self.setup = setup


class Part:

    def __init__(self, name, phases, workshop):

        self.name = name
        self.phases = phases
        self.workshop = workshop
        self.demand = 'undefined'
        self.downstream_bom = 'undefined'

        # check if all seq are unique and in sequence
        if not all(x.seq < y.seq for x, y in zip(self.phases, self.phases[1:])):
            raise Exception('Unsorted phases in part: ', self.name)

    def set_demand(self, demand):
        self.demand = demand

    def set_downstream_bom(self, bom):
        self.downstream_bom = bom


class Loader:

    def __init__(self, cycles_file, demand_file, bom_file, workshops_file):

        self.cycles_file = cycles_file
        self.demand_file = demand_file
        self.bom_file = bom_file
        self.workshops_file = workshops_file
        self.workshops = []

        cycles = pd.read_excel(self.cycles_file, sheet_name=None)
        # checks if all part names are unique
        cycles_names = []
        for sheet in cycles:
            cycles_names.append(sheet)
        if list(duplicates(cycles_names)):
            raise Exception('Multiple parts names in cycles file: ', list(duplicates(cycles_names)))
        # list of parts sheets
        sheets = []
        for sheet in cycles:
            sheets.append(cycles[sheet])
        # fillna
        sheets = [sheets[i].fillna(0) for i in range(len(sheets))]
        # drops useless 2nd row
        sheets = [sheets[i].drop([0]) for i in range(len(sheets))]
        # drops useless columns
        sheets = [sheets[i].drop(['Unnamed: 1', 'T mac (min/pz)', 'Unnamed: 4', 'Unnamed: 5'], axis=1) for i in range(len(sheets))]
        # list of parts names
        parts = []
        for sheet in sheets:
            part_name = sheet.columns[0]
            workshops_set = set()
            phases_list = []
            for i in range(len(sheet.index)):
                seq = sheet.iloc[i][0]
                workshop = sheet.iloc[i][1]
                workshops_set.add(workshop)
                machining = sheet.iloc[i][2]
                operator = sheet.iloc[i][3]
                placings = sheet.iloc[i][4]
                setup = sheet.iloc[i][5]
                # checks placings coherence
                if (placings > 0 and setup > 0) or (placings > 0 and operator > 0):
                    raise Exception('Placing coherence error in part, phase: ', self.name, seq)
                phase = Phase(seq, workshop, machining, operator, placings, setup)
                phases_list.append(phase)
            for workshop in workshops_set:
                same_workshop_phases = []
                for phase in phases_list:
                    if workshop == phase.workshop:
                        same_workshop_phases.append(phase)
                part = Part(part_name, same_workshop_phases, workshop)
                parts.append(part)

        demand_data = pd.read_excel(self.demand_file)
        # checks for multiple products
        if list(duplicates(demand_data)):
            raise Exception('Multiple parts in demand file: ', list(duplicates(demand_data)))
        # demand assignment
        for part in parts:
            for col in demand_data.columns:
                if part.name == col:
                    part.set_demand(demand_data[col])

        bom_data = pd.read_excel(self.bom_file)
        bom_data = bom_data.fillna(0)
        # changes index name from numbers to parts
        new_indexes = []
        for item in bom_data['Unnamed: 0']:
            new_indexes.append(item)
        bom_data.index = new_indexes
        # deletes parts names column
        bom_data = bom_data.drop(['Unnamed: 0'], axis=1)
        # checks for multiple parts in rows and columns
        if list(duplicates(bom_data.columns)):
            raise Exception('Multiple parts in BoM columns: ', list(duplicates(bom_data.columns)))
        if list(duplicates(bom_data.index)):
            raise Exception('Multiple parts in BoM rows: ', list(duplicates(bom_data.index)))
        # checks if there are reciprocal dependencies
        coordinates = []
        for column in bom_data.columns:
            for row in bom_data.index:
                if row != column and bom_data.at[row, column] > 0:
                    coordinates.append({row, column})
        duplicates_list = list(duplicates(coordinates))
        if duplicates_list:
            raise Exception('Reciprocal dependencies in the BoM: ', duplicates_list)
        # sets downstream BoM
        for part in parts:
            part.set_downstream_bom(bom_data.loc[part.name])
        # checks coherence of parts data
        if len(list(unique_everseen(list(bom_data.columns) + list(bom_data.index)))) != len(sheets):
            raise Exception('Incoherent data about parts names in the BoM')

        workshops_data = pd.read_excel(self.workshops_file, sheet_name=None)
        # checks if there are turns and turn durations
        for workshop in workshops_data:
            if int(workshops_data[workshop]['Shifts']) == 0:
                raise Exception('Missing shifts in workshop: ', workshop)
            if float(workshops_data[workshop]['Shift duration (h)']) == 0:
                raise Exception('Missing Shift duration in workshop: ', workshop)
        # checks for multiple names
        if list(duplicates(workshops_data)):
            raise Exception('Duplicate names in workshops data: ', list(duplicates(workshops_data)))
        # checks if all the workshops in the parts are present in the workshop file
        for part in parts:
            for phase in part.phases:
                if phase.workshop not in workshops_data:
                    raise Exception('workshop in cycles not found in workshops file: ', phase.workshop)
        # creates workshop obj
        for workshop in workshops_data:
            name = workshop
            shifts = int(workshops_data[workshop]['Shifts'])
            shift_dur = float(workshops_data[workshop]['Shift duration (h)'])
            pauses = int(workshops_data[workshop]['Pauses/shift'])
            pause_dur = float(workshops_data[workshop]['Pause duration (min)'])
            placing = float(workshops_data[workshop]['Placing duration (min)'])
            type_ = str(workshops_data[workshop]['Type'])
            uptime = float(workshops_data[workshop]['uptime'])
            workshop = Workshop(name, shifts, shift_dur, pauses, pause_dur, placing, type_, uptime)
            self.workshops.append(workshop)

        # setting parts for workshops
        for part in parts:
            for workshop in self.workshops:
                if workshop.name == part.workshop:
                    workshop.set_part(part)

    def get_workshops(self):
        return self.workshops

This is the result I get:

workshop automation level: {'auto'}

checks if the workshop automation is table: False

workshop automation level: {'machine'}

checks if the workshop automation is table: False

workshop automation level: {'machine'}

checks if the workshop automation is table: False

workshop automation level: {'table'}

checks if the workshop automation is table: False

workshop automation level: {'table'}

checks if the workshop automation is table: False

workshop automation level: {'table'}

checks if the workshop automation is table: False

workshop automation level: {'table'}

checks if the workshop automation is table: False

workshop automation level: {'table'}

checks if the workshop automation is table: False

inside set function {'auto'} False

Traceback (most recent call last): File "C:\Users\damia\PycharmProjects\logistic_management_tool\plant.py", line 25, in plant = Plant(loader_)

File "C:\Users\damia\PycharmProjects\logistic_management_tool\plant.py", line 22, in init workshop.set_disp_time()

File "C:\Users\damia\PycharmProjects\logistic_management_tool\workshop.py", line 48, in set_disp_time raise Exception('Undefined disposable time for: ', self.name)

Exception: ('Undefined disposable time for: ', 'clav acciaio')

Aucun commentaire:

Enregistrer un commentaire