Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » Python

elementtree and rounding questions

 
Jump to:  
 
Guest
PostPosted: Wed Jul 30, 2008 1:56 am    Post subject: elementtree and rounding questions
       
Hi,

Hoping that some of you won't mind taking a peek at my code and sharing your
thoughts. I just started using the elementtree module yesterday to work
with xml files. Here's an example of some xml code I might be parsing:

============================================================
<data>
<fonts>
<fontData embed="true" name="Times" />
<fontData embed="true" name="Arial" />
</fonts>
<color>
</color>
<template>
<fonts>
<fontData>
<fontData embed="true" name="Courier">text</fontData>
</fontData>
<fontData embed="true" name="Helvetica" />
</fonts>
<width>
</width>
</template>
</data>
============================================================

What I'd like to do is get the attribute 'name' from the 2nd set 'fontData' tags. So what I'd end up with is ['Courier', 'Helvetica']. Here's the first lines of code I tested:

============================================================
from xml.etree import ElementTree as ET

tree = ET.parse('/Users/jay/Desktop/test.txt')

root = tree.getroot()

fntList = []
f = root.getiterator('fonts')
n = f[-1].getiterator('fontData')
for i in n:
i = i.get('name')
if i != None: fntList.append(i)

print fntList
============================================================

This gives me ['Courier', 'Helvetica'] which is what I'm wanting. If I'm understanding this correctly, it seems getiterator('fonts') will get both of the 2 sections of <fonts> tags. Since I only want the second section, which is the last, I look at f[-1] and use the getiterator('fontData') in order to search through all the appropriate tags. Looks like getiterator also finds all nested tags as seen above when it grabbed both font names I was wanting.

So I continued to experiment a bit and came up with this next:

============================================================
from xml.etree import ElementTree as ET

tree = ET.parse('/Users/jay/Desktop/test.txt')

root = tree.getroot()

fntList = []
f = root.getiterator('fonts')
n = f[-1].find('fontData')
for i in n:
fntList.append(i.get('name'))

print fntList
============================================================

This code just gave me ['Courier']. Now if I change 'find' to 'findall' then I'll get [None, 'Helvetica']. Not exactly sure what exactly that's doing. Seems the 'findall' searches through the tags that aren't nested, but then just using 'find' found the first nested 'name'.

Anyway, I'm hoping someone might tell me if the first example of code above is a decent way to parse xml files. I'm still new to Python and am looking for good code structure as well as accurate examples.

--

One other question I had was about rounding floats. I was first looking at this syntax to round out to 6 decimal places if needed:

Quote:
f = '508.5'
x = '%.6f' % (float(f)/72)
x
'7.062500'


However, in this instance I don't want the last 2 zeroes. So would it be better to do something like this:

Quote:
f = '508.5'
x = round(float(f)/72, 6)
x
7.0625


I've been reading a bit about some rounding bugs, but am really not that knowledgeable about the subject. Does anyone have a preference of how they like to round as well as the result they see?

Thanks for looking at my questions.

Jay
 

 
Gabriel Genellina
PostPosted: Wed Jul 30, 2008 3:23 am    Post subject: Re: elementtree and rounding questions
       
En Wed, 30 Jul 2008 00:56:55 -0300, <jyoung79@kc.rr.com> escribi�:

Quote:
One other question I had was about rounding floats. I was first looking
at this syntax to round out to 6 decimal places if needed:

f = '508.5'
x = '%.6f' % (float(f)/72)
x
'7.062500'

However, in this instance I don't want the last 2 zeroes. So would it
be better to do something like this:

f = '508.5'
x = round(float(f)/72, 6)
x
7.0625

I've been reading a bit about some rounding bugs, but am really not that
knowledgeable about the subject. Does anyone have a preference of how
they like to round as well as the result they see?

If all you need is to *display* the value - use formatting expressions
like %f, the locale variants, the Template class, or whatever.

If you want to *compute* something using the rounded value, use the
round/ceil/floor functions, or perhaps consider using the Decimal class
depending on your needs.

From the above, looks like you want to display the value using up to six
decimal places, avoiding right zeroes. So you just want to strip '0'
characters from the right side:

py> f = '508.5'
py> x = '%.6f' % (float(f)/72)
py> x
'7.062500'
py> x.rstrip('0')
'7.0625'

--
Gabriel Genellina
 

 
Stefan Behnel
PostPosted: Wed Jul 30, 2008 4:25 am    Post subject: Re: elementtree and rounding questions
       
jyoung79@kc.rr.com wrote:
Quote:
============================================================
data
<fonts
<fontData embed="true" name="Times" /
<fontData embed="true" name="Arial" /
</fonts
<color
</color
<template
<fonts
<fontData
<fontData embed="true" name="Courier">text</fontData
</fontData
<fontData embed="true" name="Helvetica" /
</fonts
<width
</width
</template
/data
============================================================

You can exploit the structure: the Elements you are looking for do not have
children, but they do have a "name" attribute.

declarations = [ fontData for fontData in root.getiterator('fontData')
if fontData.get("name") ]

This gives you a list of all "fontData" Elements that declare a font name. The
one you want is the last one, i.e. declarations[-1].

You can also do

font_names = [ fontData.get("name")
for fontData in root.getiterator('fontData')
if fontData.get("name") ]

or something like that. And if you only want the fontData Elements that appear
in the template Elements, try findall instead of getiterator:

tree.findall("//template//fontData")

("//" means: descend into the subtree, while "/" would mean: look only at the
direct children).


Quote:
f = root.getiterator('fonts')
n = f[-1].getiterator('fontData')

You should not rely on ET returning a list from ".getiterator()", so avoid
using f[-1] here.


Quote:
fntList = []
f = root.getiterator('fonts')
n = f[-1].find('fontData')
for i in n:
fntList.append(i.get('name'))

print fntList
============================================================

This code just gave me ['Courier']. Now if I change 'find' to 'findall' then I'll get [None, 'Helvetica']. Not exactly sure what exactly that's doing.

The first value (None) comes from the "fontData" Element that does not have a
"name" attibute. The path expression "fontData" means: find all children that
are named "fontData". As above, what you want is ".//fontData".

Stefan
 

 
Guest
PostPosted: Wed Jul 30, 2008 11:10 am    Post subject: Re: elementtree and rounding questions
       
Thank you very much Gabriel and Stefan for your help! I really appreciate the excellent examples you've shared which is helping me understand how all this works. Again, thank you for taking the time to help me with this.

Jay
 

Page 1 of 1 .:.

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

Krynicki Ryszard wiersze forum bmw pozycjonowanie dessous Teka