Creating a Class from a SplitTxn
Dear All,
This is another newbie question. I’m self-taught with python/jython (mainly using Google) and I’m probably overlooking something which is simple to many, but not to me.
I’m trying to create a simple python class from a SplitTxn, but I've encountered a (not obvious to me) issue.
When I print out:
print s.getParentTxn().getAccount(), type(s.getParentTxn().getAccount()).name
I get (correctly):
Real property Investments:Estuary Account
but when I create my class as:
class Split:
def init(self, s):
self.parent = s.getParentTxn().getAccount()
and I do within def init(self, s)::
print self.parent, type(self.parent).name
I get:
(Real property Investments:Estuary,) tuple
I would expect this output to be identical to the first output created previously.What’s going on, and why is self.parent a tuple?
David
Comments are currently closed for this discussion. You can start a new one.
Keyboard shortcuts
Generic
? | Show this help |
---|---|
ESC | Blurs the current field |
Comment Form
r | Focus the comment reply box |
---|---|
^ + ↩ | Submit the comment |
You can use Command ⌘
instead of Control ^
on Mac
Support Staff 1 Posted by Sean Reilly on 24 Aug, 2021 09:15 AM
Hi David,
I'm not sure why those two situations would be different either, but I don't see why the call to type() is in there at all. Can you omit that and the
.name
part? To get the full name of any Account object you can call .getFullAccountName().Thanks,
Sean
--
Sean Reilly
Developer, The Infinite Kind
https://infinitekind.com
2 Posted by davidcullen on 24 Aug, 2021 09:23 AM
Sean, thanks for the quick reply. Yes, I know about getFullAccountName. I used type() to get the class names (there may be a more correct way).
Sent from my iPad
3 Posted by Stuart Beesley ... on 24 Aug, 2021 09:34 AM
You may be bumping into the fact that when you
print
an object that is a class instance, then the class' internal str and repr methods get called. This is similar to repr() in Python. So on an Account object, for example, MD defines the repr as .getFullAccountName() (which includes the parent). Whereas .getAccountName() is just the name of that account.You don't need type().name; just type().
NOTE: You don't seem to be setting up your class correctly. The format is:
(i.e.
__init__
)I suspect your tuple 'issue' is something to do with the exact format of your print command - i.e if I do something like this, I get something like you are seeing:
4 Posted by davidcullen on 24 Aug, 2021 09:55 AM
Thanks. This makes good sense (to me) and I will explore more tomorrow.
I didn’t explain fully before, but the **s** parameter passed to my class was actually a SplitTxn.
Thanks for your insight.
David
Sent from my iPad
5 Posted by Stuart Beesley ... on 24 Aug, 2021 01:39 PM
Ps... In Java the str and repr methods are called 'toString()'. So for the class Account it's:
6 Posted by davidcullen on 25 Aug, 2021 07:43 AM
This may be of use to anyone following my problem.
After much googling, by trial & error I finally solved things (there may be a simpler way, but this works for me).
I get the correct output, as in:In essence, my problem was that I have a simple class which is initiated with a SplitTxn, s. The class, Split, has many variables (eg Split.amount and Split.parent, and several more) which came from SplitTxn.
The issue I faced was that when I print either amount or parent directly, as:
but when I similarly print the instance variables, as:
I get tuples as output, such as:
My “solution” was to create a specific def str(self) function (and also a special amt() functon as I wanted to format the Split.amount — I couldn’t seem to do this directly.
Here are the relevant parts of my code for anyone interested:
The (simplified) Class:
and my function:
I still don’t fully understand what is going on, but things are working correctly now.
David
Support Staff 7 Posted by Sean Reilly on 25 Aug, 2021 07:50 AM
Hi David,
You'll definitely want to use the currency object's formatter to get a string for any amounts. For your split I'd recommend:
s.getAccount().getCurrencyType().format(s.geValue(), '.')
and for the parent amount of the split (in the currency of the container/parent account, which might be different than the category's currency):
s.getParentTxn().getAccount().getCurrencyType().format(s.getAmount(), '.')
The integer/long value of any amount in moneydance is always specified in the smallest units of whatever currency the value is in. So while most currencies will be the amount in cents/pennies/etc there are some which will have zero or 4, or 5 decimal places.
Thanks,
Sean
--
Sean Reilly
Developer, The Infinite Kind
https://infinitekind.com
8 Posted by Stuart Beesley ... on 25 Aug, 2021 08:16 AM
It is a steep learning curve and as Sean says, the .getCurrencyType() methods to convert the long values are what you need. You should not need to access the object’s instance variables at all, just use the api methods. I would also point you to .formatSemiFancy() and the other similar fancy methods.
By no means a model of excellence, but take a look at extract_data.py from line number
7497 where it says ‘for txn in txns:’ for an example of navigating txns, splits, and the data. Get the code from here:
https://github.com/yogi1967/MoneydancePythonScripts/raw/master/extr...
9 Posted by davidcullen on 25 Aug, 2021 08:29 AM
Sean/Stuart,
Thanks both for your prompt feedback!
I'll certainly follow things through as both you have indicated -- I still have a lot to learn!
10 Posted by davidcullen on 25 Aug, 2021 09:01 AM
formatSemiFancy(long amt, char decimalChar) is just what I need!
11 Posted by Stuart Beesley ... on 25 Aug, 2021 09:10 AM
👍
12 Posted by davidcullen on 25 Aug, 2021 09:23 AM
I’m working my way through things:
but then when I try:This all works (no errors):
I get
Any ideas on what is going wrong (and how to fix things)?
Support Staff 13 Posted by Sean Reilly on 25 Aug, 2021 09:36 AM
It sounds like the '.' in python is a string whereas in java it is expecting a
char
. My understanding is that a jython string with one character should be translated to a java character, so I'm not sure why that isn't working. Maybe try a double-quoted string?--
Sean Reilly
Developer, The Infinite Kind
https://infinitekind.com
14 Posted by Stuart Beesley ... on 25 Aug, 2021 10:07 AM
Your quote marks are wrong. Look closely. You need plain text version of quotes.
15 Posted by davidcullen on 25 Aug, 2021 10:20 AM
Stuart: good spotting! I’m not sure how that slipped through!
16 Posted by Stuart Beesley ... on 25 Aug, 2021 10:58 AM
Even better. Rather than passing “.” pass this instead..:
17 Posted by davidcullen on 26 Aug, 2021 04:10 AM
I tried to follow your advice, but still no luck.
executes successfully (as expected), but when I try to do:This code:
I still get:
Googling seems to indicate that this is because of a jython.2.7 known bug?
This google find Stackover suggests that using:
(modified) can solve the problem but I think this is java which I do not know well and I cannot get this to work in jython/python.
If I cannot fix things, I’ll just use my earlier workaround.
18 Posted by Stuart Beesley ... on 26 Aug, 2021 04:23 AM
You need this as lines 1 and 2 in your script:
and then also, add these lines too next:
I think this will eliminate a lot of your string / utf-8 errors.
19 Posted by Stuart Beesley ... on 26 Aug, 2021 04:41 AM
PS - your code works for me OK. However, when I copy and paste your code from above, I get this see screenshot.. See the extra (hidden) square symbol! I have seen this before when copying from the moneydance api web site myself..
What Os and Editor are you using? I have a suspicion that you are using a normal 'text editor' of some sort and not a coders editor. It's critical your file is plain text (not anything else) - like rtf.... For example on a Mac, Brackets is simple...
??
20 Posted by davidcullen on 26 Aug, 2021 08:40 AM
Stuart,
Fantastic!
I do not know what has happened and when I look at my code, I no NOT see the square symbol in between format and (.
However, when I fully retype the "bad" code line verbatim, it works!
I can only think that because I used "cut & paste" for the code originally, that somehow an invisible square symbol crept into things?
Anyway, everything seems to be working fine now.
Thanks for your perseverance. No need to reply to the private email sent to you earlier.
David
21 Posted by Stuart Beesley ... on 26 Aug, 2021 09:02 AM
My recommendation to you is to switch to a (free, simple) coders tool for writing your scripts... It will stop errors to do with formatting and plain text etc.....
22 Posted by Stuart Beesley ... on 26 Aug, 2021 09:08 AM
PS - Oddly your email didn't arrive? Can you resend? Happy to be in direct contact in the future if you like...
23 Posted by davidcullen on 27 Aug, 2021 02:07 AM
Stuart,
Thanks for all your help - I am learning a lot!
Not sure why the emails did not get through - I didn't receive any delivery failure messages on my side. Anyway, things are now working so no need to trouble you further. My code is very incomplete at this stage and I'm still working on it.
I had been using your shebangs, but not the dirty hacks which I am now using).
I am using Nova 7.3 which I find very useful. I take your point re other editors but at this stage I will stick with it. My main errors were self-inflicted - the trailing ',' causing the tuple issue and the square which I think was caused by using "cut and paste" on the code (but works when I fully type the code).
24 Posted by Stuart Beesley ... on 27 Aug, 2021 04:58 AM
👍
25 Posted by Stuart Beesley ... on 29 Aug, 2021 06:14 AM
Tip. Assuming you are using
sys.setdefaultencoding('utf8')
, then this is a good replacement for str() where you might get utf8 issues…def safeStr(_theText): return ("%s" %(_theText))
davidcullen closed this discussion on 26 Sep, 2021 09:57 AM.