1

I wrote a simple program to read some floats from a file:

line2 = f1.readline()
if "Totals" in line2:
    cline = line2.strip()
    csline= cline.split("  ")
    zforcet = float(csline[7])
    torquet = float(csline[8])

line2 in question is :

Totals             7.911647E+03  -1.191758E+03   7.532665E+03   4.137034E+00

My code works, but my question is this there a more obvious way to code this ?

I mean it is not at all obvious to me that the second real number on the line is csline[7] and i could do this only after trail and error and printing out the contents of csline. I am looking for a way to "read the second float" on a line directly.

Byte Commander
  • 6,506
  • 6
  • 44
  • 71
user85392
  • 33
  • 3

3 Answers3

2

Just use split() It will split on every whitespace and you ll get a list like this:

["Totals", "7.911647E+03", "-1.191758E+03", "7.532665E+03", "4.137034E+00"]

So the first element of the list will be "7.911647E+03"

Also note, that it will be a string by default, you ll have to make it a float, using the float function. (eg float("7.911647E+03"))

EDIT: As highlighted in the comment if you are really looking for a way to "read the second float" on a line directly Than i would iterate over the splitted line, and check the types of the elements, and grab the second float type.

splitted_line = ["Totals", "7.911647E+03", "-1.191758E+03", "7.532665E+03", "4.137034E+00"]

counter = 1
for i in splitted_line:
    try:
        float(i)
        counter += 1
        if counter== 2:
            print(i)
    except ValueError:
        pass

This will print out 7.911647E+03

Gábor Erdős
  • 3,599
  • 4
  • 24
  • 56
  • That is not what OP is asking, `looking for a way to "read the second float" on a line directly`, he is asking for filtering all the float values after splitting, without prior knowing their type, and then selecting the second element – ZdaR Apr 20 '16 at 12:06
  • Its not very clear from the question, but i ll add en edit to my answer. – Gábor Erdős Apr 20 '16 at 12:07
  • 1
    Actually, Gabor your first answer is just what I was looking for. Thanks! It turns out, in my case the second field is always a float. Sorry I didnt make this clear. – user85392 Apr 20 '16 at 20:45
  • No problem, glad i could help. Please mark the answer as solved if it indeed solved your problem! Thanks – Gábor Erdős Apr 21 '16 at 10:29
0

I would go for automated trial and error in case we can not be sure that the second number in a line (which you want) is always the third word (space-separated characters/digits):

line2 = f1.readline()
if "Totals" in line2:
    numbers = []
    for word in line2.split():
        try:
            number.append(float(word))
        except ValueError:
            pass

    zforcet = numbers[2] if len(numbers) > 2 else 0
    torquet = numbers[3] if len(numbers) > 3 else 0

We split the line into words and try to convert each word to a float number. If it succeeds, we append the number to our list, if not we don't care.

Then after having parsed the line, we can simply pick the n-th number from out numbers list - or a default value (0) if we could not parse enough numbers.

Byte Commander
  • 6,506
  • 6
  • 44
  • 71
0

You want to:

  1. Make a list with all the float values out of line2
  2. Do something with the second element of that list

For that you'll have to:

  1. Make a helper function to check if something is a float
  2. Split line2 and pass each element to your helper function
  3. Keep only the actual floats

Once you have a list of actual floats in line2, it's just a matter of knowing which item you want to pick (in this case, the second one, so floats[1].

--

def is_float(e):
    try:
        float(e)
    except ValueError:
        return False
    return True

def get_floats(line):
    return [float(item) for item in line.rstrip().split() if is_float(item)]

After which your code becomes:

line2 = f1.readline()
if "Totals" in line2:
    floats = get_floats(line2)
    zforcet = floats[1] # -1191.758
    torquet = floats[2] # 7532.665

Which is not so much shorter but somewhat clearer and easier to debug.

If you plan to reuse the above code, you could also abstract the indexes of items you want to pick:

ZFORCET = 1
TORQUET = 2

And then:

line2 = f1.readline()
if "Totals" in line2:
    floats = get_floats(line2)
    zforcet = floats[ZFORCET]
    torquet = floats[TORQUET]
Jivan
  • 21,522
  • 15
  • 80
  • 131