Passing a ZeroDivisionError - python

I'm trying to perform Sales Price to Cost calculations for a report. The data I'm getting is going into an Excel sheet to be passed along. The script has worked fine for weeks but recently started failing. It fails at a line that is writing data into my Excel sheet that takes two pieces of info and computes it to get my margin. The issue is my Cost isn't lower than my Sales Price (selling for a loss) and is cause my script to fail. How can I get my script to no only pass but record the equation correctly?
ws.cell(row=x, column=y, value=(s.SalePrice - s.Cost) / s.SalePrice)
I've imported pyxl and xlrd for my Excel sheets.

The error you get occurs whenever s.SalePrice is 0.
You can wrap your expression inside a try/except block to catch and handle that error appropriately:
try:
val = (s.SalePrice - s.Cost) / s.SalePrice
except ZeroDivisionError:
val = 'N/A'
ws.cell(row=x, column=y, value=val)
Replace N/A with any appropriate message you'd like to display in the event that s.SalePrice is 0.

Related

Python: calculation of italian fiscal code

I have a DataFrame where I have all the info to calculate the Italian Fiscal Code for individuals but I am facing the following problem.
I am trying to use the function below to calculate the Fiscal Code but in case of error (for example it is not able to calculate the fiscal code because of a country doesn't exist anymore), the function always write, for each line, what is in the except instead of writing the fiscal code where all the info are available and correct and what is in the except only in case a error is find.
Could you help me to find a solution?
Thanks
def check(df_PF):
try:
a=[codicefiscale.encode(surname=df_PF['cognome'][i],
name=df_PF['nome'][i],
birthdate=(df_PF['data_nascita'][i]),
sex=df_PF['tipo_sesso'][i],
birthplace=df_PF['den_comune_nascita'][i])
if (pd.notna(df_PF['cognome'][i])) &
(pd.notna(df_PF['nome'][i])) &
(pd.notna(df_PF['data_nascita'][i])) &
(pd.notna(df_PF['tipo_sesso'][i])) &
(pd.notna(df_PF['den_comune_nascita'][i]))
else None for i in range(0,len(df_PF))]
return(a)
except:
pass
return ('Not Available')

Try-Except in the For loop

I written the below Try-Except code in a For Loop for Python - PostgreSQL database input.
I have a list in .csv file to input into the PostgreSQL database.
1 of the column is primary data enabled.
Hence, if the data in the list is duplicated, the Python will throw error.
I written below code and my imagination is the code will run "try" 1st, if "try" error then only jump to the "except" line, for every rows in the list (loop).
But, when I execute my code, once the program go to "except" line, then the program would not go to "try" line again.
Ex.
If my list of data all fresh, the program run and input all rows to database correctly.
If my duplicated data is in the 1st line of the list, the program run to "except" line and the fresh data at the bottom are not input to the database.
As long as there is duplicated data on top, the program will just run into "except" line without go back to "try" line.
Any idea how to improve my code here? Thank you.
My intention is all fresh data need to capture into the database, while there is duplicated, the data row shall be skipped and continue for next line.
for data in df.iterrows():
vreceivingdate = str(data[1][0])
vreceivingtime = str(data[1][1])
vscanresult = str(data[1][2])
vinvoicenbr = str(vscanresult[0:6])
vlotnbr = str(vscanresult[6:9])
vcasenbr = str(vscanresult[9:12])
try:
rec.insertRec(vreceivingdate, vreceivingtime, vscanresult, vinvoicenbr, vlotnbr, vcasenbr)
except:
dupDataCounter += 1
Finally I found the solution for my question.
I shall not use Try-Except for this case.
To do what I want to do should use the PostgreSQL function:
"ON CONFLICT DO NOTHING".

How to handle unit conversions while interacting with FMUs?

I have a python script that filters and lists the parameters, their units and default values from a fmu using the read_model_description function from FMPy library and writes in an excel sheet (related discussion). Then using the simulate_fmu function the script simulates the fmu and writes the results with units back in the excel sheet.
In filtering the parameters and output variable, I use this line to get their units.
unit = variable.declaredType.unit if hasattr(variable.declaredType,'unit') else '-'
While interacting with the fmu, the parameter and variable values are in default SI units. I guess this is according to the FMI standard. However, in the modelDescription.xml under <UnitDefinitions> I see that there is information regarding the default SI unit to displayUnit conversion. For example:
<Unit
name="Pa">
<BaseUnit kg="1"
m="-1"
s="-2"/>
<DisplayUnit
name="bar"
factor="1E-05"/>
<DisplayUnit
name="ftH2O"
factor="0.0003345525633129686"/>
</Unit>
Is there a way to be able to get the parameter values and output variables in displayUnits if the conversion factors are already available in the modelDescription.xml?
Or is there a easier solution using python libraries like pint that can act as a wrapper around fmu to convert the units in desired unit system (i.e. SI to IP) while interacting with it?
In the FMPy source I did not find any place where unit conversion is implemented.
But all the relevant information is read in model_description.py.
The display unit information ends up in modelDescription.unitDefinitions. E.g. to convert a value val = 1.013e5 # Pa to all defined display units, the following might work:
for unit in modelDescription.unitDefinitions:
if unit.name == "Pa":
for display_unit in unit.displayUnits:
print(display_unit.name)
# not sure about the brackets here
print( (val - display_unit.offset)/display_unit.factor )
break
Take a look at the FMI Specification 2.01, chapter 2.2.2 Definition of Units (UnitDefinitions) to get the full picture.

Acess single values from Abaqus FieldValueArray with Python

I'm currently writing an post processing script for a detailed analysis of Abaqus simulations. My current problem is that I would like to Access some Abaqus Field Object data and Change values, which are below a Limit value. E.g. if the values is lower than 0 --> Change value to 0. I'm planning to do this Task with a simple if Statement. However I have some Problems to Access the data correctly. I am using Python.
My Code Looks like this:
strain_n = session.odbs[odbName].steps['Load'].frames[n].fieldOutputs['SDV2']
#SDV2 is a Scalar field, strain in y-direction from Abaqus UMAT
As far as I understood the abqus documentation correctly, I can access the FieldData with using:
data = strain_n.values
Unfortunately I do not understand how I should proceed I tried some combination with data but Nothing really did work. I am not able to access the data at one Integration Point nor am I able to Change the value.
The command len(data) tells me 2304 which corresponds well with my expectations hence I’m using 576 Elements with 4 integrations Points = 2304.
Can someone please help me ? Any tips are appreciated!
you can try to print out the data:
for v in data:
print '%d %6.4f' % (v.elementLabel, v.data)
OR you can write data into file:
with open('test.csv', 'w') as f:
for v in data:
f.write('%d %6.4f' % (v.elementLabel, v.data) + '\n')

Error swallowed

Problem
I am connecting with JayDeBeApi to SQL Server 2017 and running a script like:
SELECT ... INTO #a-temp-table
DELETE FROM a-table
INSERT INTO a-table SELECT FROM #a-temp-table
DELETE #a-temp-table
During step 3 i get the following error:
Cannot insert duplicate key row in object 'dbo.a-table' with unique index 'UQ_a-table'. The duplicate key value is (11, 0001, 3751191, T70206CAT, 0000).
Instead of ~360k records, only ~180k get inserted. So step 3 aborts.
The temp table however gets deleted. So step 4 completes.
I am able to fix the error. But with JayDeBeApi, I am not seeing the error.
It seems like everything went fine from the Python point of view.
My goal is to capture those errors to handle them appropriately.
Any idea how to achieve that?
What I've tried
My Python code looks like.
try:
localCursor = dbConnection.cursor()
x = localCursor.execute(query)
logInfo("Run script %s... done" % (scriptNameAndPath), "run script", diagnosticLog)
except Exception as e:
logError("Error running sql statement " + scriptNameAndPath + ". Skipping rest of row.",
"run script", e, diagnosticLog)
myrow = skipRowAndLogRecord(startRowTime, cursor, recordLog)
continue
x = localCursor.execute(myqrystm) completes successfully, so no exception is thrown. x is None and while inspecting localCursor, I see no sign of any error message(s)/code(s)
Step 3 should be all-or-none so the a-table should be empty following the duplicate key error unless your actual code has a WHERE clause.
Regarding the undetected exception, add SET NOCOUNT ON as the first statement in the script. That will suppress DONE_IN_PROC messages that will interfere with script execution unless your code handles multiple result sets.
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-2017
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
GO
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
END CATCH;

Categories