Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there an option for not converting numbers to numeric types when reading idfs? #438

Open
airallergy opened this issue Feb 28, 2024 · 10 comments

Comments

@airallergy
Copy link
Contributor

Hi, is there a way to tell eppy to treat all fields as string when reading idfs (perhaps internally)?

I needed to do a lot of object-wise comparisons between different idfs, float numbers always have a precision issue in such case, hence not reassuring.

@santoshphilip
Copy link
Owner

off the top of my head, I am not seeing a way to have all fields be strings.

My recollection is that eppy looks at the IDD file and does the conversion as soon as it read the IDF file.
This is hard-coded. It will need a code change make it behave differently.

I understand your problem. The floating points make the comparison unstable. There is a use case here that may be worth pursuing.
How badly do you want this? You could make a fork of eppy and implement it. When you make comparison, you could use this fork. The chance that the code change may be easy.
Then it is worth looking at how to change the API so that all eppy users have this functionality.

Do you have some pseudo-code on how you want to do the comparison ?
I may get some ideas if I look at it.

@airallergy
Copy link
Contributor Author

Thanks for the reply, nothing urgent really, I was more to check if I have missed anything.

I was just doing something like `if this_obj == that_obj' through a loop, the context, if interested, was to find the common objects from several idfs with different ventilation settings to automatically make macro parameters.

I will probably read the idfs as plain text to do the comparison for now. Speaking of which, does eppy store the raw object as a string attribute before parsing? That is something like "OBJECT_NAME,FIELD1,FIELD2,...,FIELDN;", which may be easier to implement if not exist already.

@airallergy
Copy link
Contributor Author

Actually, I just had a closer look and found that there is an internal argument conv in the idfreader1 function to determine whether the the data types should be converted.

def idfreader1(fname, iddfile, theidf, conv=True, commdct=None, block=None):

All needed here is to expose this argument to IDF, openidf etc. That being said, I am not sure what to think of that users may read things in string and find a lot of useful functions (e.g. calculating u values) not working?

@santoshphilip
Copy link
Owner

ha! i tried something else:

import eppy
fname = "/Applications/EnergyPlus-22-1-0/ExampleFiles/HVACTemplate-5ZonePTAC.idf"
idf = eppy.openidf(fname)
idf.outputtype = "compressed"
idf.saveas(f"compressed.idf")
comp = "compressed.idf"
s = open(comp, 'r').read()
su = s.upper()
objs = [ob.strip() for ob in su.split(';')]
print(objs[10])
spaces = [ob for ob in objs if ob.startswith('ZONE,')]
print()
for space in spaces:
    print(space)

prints out

RUNPERIOD, RUN PERIOD 2, 1, 14, , 1, 14, , TUESDAY, YES, YES, NO, YES, YES

ZONE, PLENUM-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 0.609600067, 283.2
ZONE, SPACE1-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 2.438400269, 239.247360229
ZONE, SPACE2-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 2.438400269, 103.311355591
ZONE, SPACE3-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 2.438400269, 239.247360229
ZONE, SPACE4-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 2.438400269, 103.311355591
ZONE, SPACE5-1, 0.0, 0.0, 0.0, 0.0, 1, 1, 2.438400269, 447.682556152

Does this give you options?
Can you do your comparison with something like this.

PS: I have not read you previous comment in detail. Our comments crossed each other :-)

@santoshphilip
Copy link
Owner

responding to your comment on setting conv=False in idfreader1

Yes that will break a lot of things.
But you may still want to use that option to meet your needs. Taking the python philosophy - we are all adults here https://mail.python.org/pipermail/tutor/2003-October/025932.html

the question is - how to expose that functionality in an intuitive way.
It is a rather obscure use-case. Needs some thought.

@airallergy
Copy link
Contributor Author

Re the first reply, I had a script to remove comments and convert multi-line objects into single lines, which achieved similar outputs to yours. I was not aware of the outputtype option, could be useful in some other cases in the future. Thanks!

Re the second, we could simply add **kwargs to all the functions/classes in the chain: openidf() - easyopen() - IDF - IDF.read(), so that we can pass conv=False to idfreader1 without changing the default behaviour.

@santoshphilip
Copy link
Owner

on outputtype see function documentation at https://eppy.readthedocs.io/en/latest/eppy.html#module-eppy.modeleditor. There are couple of options there.

I see how **kwargs can do the trick.

For both outputtype and conv=False we are getting more and more obscure functionality that is ot obvious. I had almost forgotten about outputtype

Most of eppy is very intuitive. Then we have these hidden functionality :-(

Lets hold off on this for some time. It is not mission critical yet. Close the issue if you want to.

@airallergy
Copy link
Contributor Author

Don't mind keeping this open.

@airallergy
Copy link
Contributor Author

Btw, I was curious why the number conversion was embedded in the first place?

I understand it may be just a design decision that can be traced back to long ago, but it seems that there is a good side to remain string for everything by default (e.g. consistency before and after eppy processing), and only do the conversion in those calculation functions ad hoc.

@santoshphilip
Copy link
Owner

This is very old code - possibly coming from before it became eppy. I don't have a clear recollection of why it was done that way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants