# How to round values in Pyomo

I have a variable in Pyomo called model.variable_objectiveCosts and I would like to print this value to a file. Basically it works. But when I would like to divide the value by 100 and then round to 2 decimal digits, I get an error when using the following code  "%.2f" % model.variable_objectiveCosts/100

The error message is

"TypeError: Implicit conversion of Pyomo NumericValue type variable_objectiveCosts' to a float is
disabled. This error is often the result of using Pyomo components as
arguments to one of the Python built-in math module functions when
defining expressions. Avoid this error by using Pyomo-provided math
functions."


Now it tells me to use the Pyomo-provided math functions. However, I could not find a round function in Pyomo. Do you know how I can still round the result to 2 digits?

Here is a part of my code:

# Imports
import pyomo.environ as pyo
import pandas as pd
from pyomo.util.infeasible import log_infeasible_constraints
from pyomo.opt import SolverStatus, TerminationCondition
import sys

#Check if the problem is solved or infeasible
if (solution.solver.status == SolverStatus.ok) and (solution.solver.termination_condition == TerminationCondition.optimal):
# Do something when the solution in optimal and feasible
print("Result Status: Optimal")
#Create pandas dataframe for displaying the results
outputVariables_list = [model.variable_heatGenerationCoefficient_SpaceHeating, model.variable_heatGenerationCoefficient_DHW, model.variable_help_OnlyOneStorage, model.variable_temperatureBufferStorage, model.variable_usableVolumeDHWTank, model.variable_surplusPowerTotal, model.variable_surplusPowerPositivePart, model.variable_surplusPowerNegativePart, model.variable_help_isSurplusPowerPositive, model.variable_electricalPowerTotal, model.variable_RESGenerationTotal, model.variable_pvGeneration, model.variable_costsPerTimeSlotPositivePart, model.variable_revenuePerTimeSlotPositivePart, model.variable_currentChargingPowerEV, model.variable_energyLevelEV, model.variable_SOC_EV, model.param_heatDemand_In_W, model.param_DHWDemand_In_W, model.param_electricalDemand_In_W, model.param_pvGenerationNominal, model.param_outSideTemperature_In_C, model.param_windAssignedNominal, model.param_electricityPrice_In_Cents, model.param_availabilityPerTimeSlotOfEV, model.param_energyConsumptionEV, model.param_COPHeatPump_SpaceHeating, model.param_COPHeatPump_DHW, model.param_BigM_Surplus_Positive, model.param_BigM_Surplus_Negative, model.param_BigM_Costs_Positive, model.param_BigM_Costs_Negative, model.variable_objectiveMaximumLoad, model.variable_objectiveSurplusEnergy ,model.variable_objectiveCosts, model.objective_combined_general, model.set_timeslots]
optimal_values_list = [[pyo.value(model_item[key]) for key in model_item] for model_item in outputVariables_list]
results = pd.DataFrame(optimal_values_list)
results= results.T
results = results.rename(columns = {0:'variable_heatGenerationCoefficient_SpaceHeating', 1:'variable_heatGenerationCoefficient_DHW', 2:'variable_help_OnlyOneStorage', 3:'variable_temperatureBufferStorage', 4:'variable_usableVolumeDHWTank', 5:'variable_surplusPowerTotal', 6:'variable_surplusPowerPositivePart', 7:'variable_surplusPowerNegativePart', 8:'variable_help_isSurplusPowerPositive', 9:'variable_electricalPowerTotal', 10:'variable_RESGenerationTotal', 11:'variable_pvGeneration', 12:'variable_costsPerTimeSlot', 13:'variable_revenuePerTimeSlot', 14:'variable_currentChargingPowerEV', 15:'variable_energyLevelEV', 16:'variable_SOC_EV', 17:'param_heatDemand_In_W', 18:'param_DHWDemand_In_W', 19:'param_electricalDemand_In_W', 20:'param_pvGenerationNominal', 21:'param_outSideTemperature_In_C', 22:'param_windAssignedNominal', 23:'param_electricityPrice_In_Cents', 24:'param_availabilityPerTimeSlotOfEV', 25:'param_energyConsumptionEV', 26:'param_COPHeatPump_SpaceHeating', 27:'param_COPHeatPump_DHW', 28:'param_BigM_Surplus_Positive', 29:'param_BigM_Surplus_Negative', 30:'param_BigM_Costs_Positive', 31:'param_BigM_Costs_Negative', 32:'variable_objectiveMaximumLoad_kW', 33:'variable_objectiveSurplusEnergy_kWH', 34:'variable_objectiveCosts_Euro', 35:'objective_combined_general', 36:'set_timeslots'})
cols = ['set_timeslots']
results[cols]= results [cols].round(0).astype(int)
results.set_index('set_timeslots', inplace=True)
results.to_csv("C:/Users/wi9632/Desktop/Result_BT1.csv", index=True,  sep =";")
elif (solution.solver.termination_condition == TerminationCondition.infeasible):
# Do something when model in infeasible
print ("Result Status: Infeasible")
else:
# Something else is wrong
print("Solver Status: ", solution.solver.status)

• If you have a line like this in your imports from pyomo.environ import * , then you should have the math functions you need for rounding. So, make sure you don't use round function from other packages (like math or numpy) or have those imports to override what pyomo is importing.
– EhsanK
Aug 16 at 12:58
• Thanks EhasnK for your comment. How can I use the math functions to round those values in Pyomo? What command do I have to use? Aug 16 at 13:06
• If you have the from pyomo.environ import *, then I believe the round function is already there. What I meant is to test it like that and make sure you're not rounding with np.round or math.round. This seems to be a common issue. If you do a quick search on the web, you'll see some similar questions with the same error.
– EhsanK
Aug 17 at 14:11
• Thanks EhsanK for your answer. Unfortunately np.round(model.variable_objectiveCosts/100, 2) leads to the following error message "TypeError: loop of ufunc does not support argument 0 of type MonomialTermExpression which has no callable rint method". When just using np.round(model.variable_objectiveCosts, 2) I get a error "TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'" Aug 18 at 8:52
• There is a lot of documentation on rounding values on the whole dataframe or just a column (series) or a single value in case you want to treat a given value differently. I'm sure you can find the appropriate command by a simple search :)
– EhsanK
Aug 18 at 13:26

• Thanks for your answer Optimizaiton team. When I use your suggested approach in my example by using the code round(pyo.value(model.variable_objectiveCosts/100) ,2) I get the error "TypeError: 'float' object is not iterable". I also tried to just adjust the values in a dataframe (because at the end of the day this is what I want) by using  df['variable_objectiveCosts'] = df['variable_objectiveCosts'/100].round(2) but here I get also an error message telling "TypeError: unsupported operand type(s) for /: 'str' and 'int'". Any idea how I can fix these errors? Aug 16 at 12:01
• Thanks optimization team for your comment. I added a part of my code (my full code is quite complex and has 2000 lines) after the solve statement. You have to scroll to almost the very right for the variable model.variable_objectiveCosts. What I want is to print this to a file (via a pandas dataframe together with all other variables) and there it should be devided by 100 and rounded to 2 decimal values. Aug 16 at 12:38
• @PeterBe in this piece you shared in the comment, df['variable_objectiveCosts'] = df['variable_objectiveCosts'/100].round(2) you're dividing by 100 in the brackets. that's why it gave you the TypeError. You need to bring it out df['variable_objectiveCosts']/100`