0

I'm using Colab to run the following code:

import numpy as np
import pandas as pd


MAP_locs = ["LOAD POINT 1","LOAD POINT 2","DELIVERY POINT"] 

MAP_SIZE = len(MAP_locs)

LOAD_POINT_1 = []
LOAD_POINT_2 = []
DELIVERY_POINT = []

for i in range(10):
    LOAD_POINT_1.append(0.5)
    LOAD_POINT_2.append(0.5)
    DELIVERY_POINT.append(-1)

d = {'LOAD POINT 1': LOAD_POINT_1,
     'LOAD POINT 2': LOAD_POINT_2,
     'DELIVERY POINT': DELIVERY_POINT}

df = pd.DataFrame(data=d)


VESSEL_Y = 6 
VESSEL_X = [1,0,0] 
VESSEL_X_to_df = MAP_locs[VESSEL_X.index(1)] 


class VESSEL():
    def __init__(self, x , y, cargo_capacity, cargo_on_board):
        self.y = VESSEL_Y
        self.x = VESSEL_X.index(1)
        self.cargo_capacity = 1
        self.cargo_on_board = 0

    def load(self):

        print("Loading")

        cargo_to_load = 0
        max_quantity_2load =  self.cargo_capacity - self.cargo_on_board
        cargo_on_location = df.at[VESSEL_Y,VESSEL_X_to_df]
        if cargo_on_location <= 0 or max_quantity_2load == 0:
            False
            print("Load = False")
        else:
            True
            print("Load = TRUE")
            if cargo_on_location > max_quantity_2load:
                cargo_to_load = max_quantity_2load
            if cargo_on_location <= max_quantity_2load:
                cargo_to_load = cargo_on_location
            print("Max quantity 2 load: ",max_quantity_2load,'\n', "Cargo on loc: ",cargo_on_location,'\n', "Cargo on board: ",self.cargo_on_board,'\n', "Cargo to load: ",cargo_to_load)
            df.at[VESSEL_Y,VESSEL_X_to_df] = df.at[VESSEL_Y,VESSEL_X_to_df] - cargo_to_load 
            self.cargo_on_board = self.cargo_on_board + cargo_to_load 
            cargo_on_location = df.at[VESSEL_Y,VESSEL_X_to_df] 
            cargo_to_load = 0 
            max_quantity_2load =  self.cargo_capacity - self.cargo_on_board 
            print("Loaded")
            print("Max quantity 2 load: ",max_quantity_2load,'\n', "Cargo on loc: ",cargo_on_location,'\n', "Cargo on board: ",self.cargo_on_board,'\n', "Cargo to load: ",cargo_to_load)
            print('\n','\n')

    def discharge(self):
        print("cargo on board: ",self.cargo_on_board)
        CT_capacity = df.at[VESSEL_Y,VESSEL_X_to_df] 
        if CT_capacity >= 0 or self.cargo_on_board == 0: 
            False
            print("Discharge = False")
        else:
            True
            print("Discharge = TRUE")
            if -CT_capacity > self.cargo_on_board:
                cargo_to_discharge = self.cargo_on_board
            if -CT_capacity <= self.cargo_on_board:
                cargo_to_discharge = -CT_capacity
            print("cargo_to_discharge 2: ",cargo_to_discharge)
            print("PD value1:",df.at[VESSEL_Y,VESSEL_X_to_df])
            CT_remaining_capacity = df.at[VESSEL_Y,VESSEL_X_to_df]+cargo_to_discharge
            print("CT remaining capacity",CT_remaining_capacity)
            df.at[VESSEL_Y,VESSEL_X_to_df] = CT_remaining_capacity 
            print("here is a problem. it should be -0.5 dunno why is zero:",df.at[VESSEL_Y,VESSEL_X_to_df])
            self.cargo_on_board = self.cargo_on_board - cargo_to_discharge 
            CT_capacity = df.at[VESSEL_Y,VESSEL_X_to_df] 
            if -CT_capacity > self.cargo_on_board:
                cargo_to_discharge = self.cargo_on_board
            if -CT_capacity <= self.cargo_on_board:
                cargo_to_discharge = -CT_capacity
            print("Discharged")
            print("CT_capacity: ",CT_capacity,'\n', "cargo_to_discharge: ",cargo_to_discharge,'\n', "Cargo on board: ",self.cargo_on_board, '\n', "PD value:",df.at[VESSEL_Y,VESSEL_X_to_df])
            print('\n','\n')


print("Vessel gonna act")
print("Vessel loc: ", VESSEL_X_to_df)
VESSEL_1 = VESSEL(x=VESSEL_X,y=VESSEL_Y,cargo_capacity=1, cargo_on_board=0)
VESSEL_1.load()

VESSEL_X = [0,0,1] 
VESSEL_X_to_df = MAP_locs[VESSEL_X.index(1)] 
print("Vessel loc: ", VESSEL_X_to_df)
VESSEL_1.discharge()

The idea is to have a vessel loading and discharging on some locations. The amount to load and discharge is limited by the vessel capacity and storage (load ranges from 0 to 1 and discharge from 0 to 2).

I think the loading is working well, but when using discharge and I try to update DF info (df.at[VESSEL_Y,VESSEL_X_to_df]), the value turns to zero and I was expecting -0.5, i.e., I was expecting to get PD Value2 of -0.5 and not 0.00.

For some reason, df.at is not working here and I have been unable to find out why. I have considered changed to loc or similar, but wanted to find out why this is not working.

Thank you for your help.

Joao
  • 13
  • 4

1 Answers1

0

The issue is that .at tries to conserve the datatype, which in this case is integer. See this answer. When you alter your datatype, it works as intended. I added a period to the line:

DELIVERY_POINT.append(-1.)

which makes it a float. Now your code runs as intended. My understanding from the linked discussion is that .loc won't have this issue. It also is possible that .loc runs a hair slower, but likely this difference is negligible.

amquack
  • 837
  • 10
  • 24