7beggars_nnnnm
7beggars_nnnnm

Reputation: 757

Find the line with the min and max value and your line number from text file (Get Value Error Float Type)

I have a file 1.txt containing words and symbols on some lines while on other lines I have only numbers, and never no numbers are on the same line where words and symbols are.

FOO >
1.0
BAR <
0.004
FOO FOO <
0.000004
BAR BAR <

What I need is to analyze only the lines that have numbers, and then compare the numbers found and print the maximum value and minimum value.

In addition it is important that I know the line number (instead index) of the minimum value and the maximum value.

I tried to solve this looking at some questions like

Find Min and Max from Text File - Python e How to Find Minimum value from *.txt file

But, for example, when I run the code

import csv
rows = []
with open('1.txt', mode='r') as infile:
    reader = csv.reader(infile, delimiter=" ")
    for row in reader:  # each row is a list
        rows.append(row)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)

I have bumped into the following error

ValueError: could not convert string to float: 'FOO'

How could I escape the lines that have symbols and words and just analyze the lines that have numbers, also obtaining the indicator of the lines with the minimum and maximum value?

I could extract all the rows that contains only numbers to a new file (for example using regex), but I would need to know the previous/after line to the line that the minimum value was found, then any line extraction would increase the number of steps of the analysis in which I am involved because I would have to return to analyze the original 1.txt file.

Note: I am inexperienced in Python compared to a frequent user of this language, but I think it is something simple for stackoverflow Questions list, and I suspect that perhaps this issue has already been answered. But as I already looked for some satisfactory question and I did not find it so I'm doing my own question.

Upvotes: 2

Views: 2085

Answers (4)

Abhi_J
Abhi_J

Reputation: 2129

One possible approach without the need for any extra modules

Code:

def is_float(x):
  try:
    float(x)
    return True
  except:
    return False

with open('url1.txt', 'r') as myfile:
  lines = myfile.readlines()
  
nums = [x for x in lines if is_float(x)]
my_min = min(nums)
my_max = max(nums)

print('Max: ', my_max, 'line number: ', lines.index(my_max)+1)
print()
print('Min: ', my_min, 'line number: ', lines.index(my_min)+1)

Input:

FOO >
1.0
BAR <
0.004
FOO FOO <
0.000004
BAR BAR <

Output:

Max:  1.0
 line number:  2

Min:  0.000004
 line number:  6

Explanation:

  1. write a function to check if a string can be converted to float, this can be done by using try statement and float()
  2. filter floats from lines read from file
  3. find the min and max values
  4. find indices of min and max in list of lines using list.index(<value>)
  5. Add 1 to indices to get line number as indices starts from zero

Upvotes: 2

Ajay
Ajay

Reputation: 5347

import csv
rows = []
with open('1.txt', mode='r') as infile:
    reader = csv.reader(infile, delimiter=" ")
    for row in reader:
        if not row[0].isalpha():
            rows.append(row[0])
    print(rows)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)

Incorporate an if statement to check if the row[0] is not an alpha

str.isalpha() Return True if all characters in the string are alphabetic and there is at least one character, False otherwise

Upvotes: 0

Axiomel
Axiomel

Reputation: 215

I suggest a simple solution by collecting all numbers and their indices using a try except statement. After the number and indices are collected in two lists you can find the min and max by for instance making use of the numpy package.

import numpy as np

numbers, indices = [],[]
with open("1.txt") as my_text_file:
    for i, line in enumerate( my_text_file.readlines() ):
        try:
            numbers.append( float(line) )
            indices.append( i )
        except:
            pass

maxvalue = np.max( numbers )
minvalue = np.min( numbers )
maxindx  = indices[ np.argmax( numbers ) ]
minindx  = indices[ np.argmin( numbers ) ]

print("The maximum value is found at line "+str(maxindx)+" with the value "+str(maxvalue))
print("The minimum value is found at line "+str(minindx)+" with the value "+str(minvalue))

For the provided 1.txt file thisproduces theprint out

The maximum value is found at line 1 with the value 1.0                                                                 
The minimum value is found at line 5 with the value 4e-06 

Cheers

Upvotes: 0

CATboardBETA
CATboardBETA

Reputation: 530

This might be overkill, but what immediately came to my mind is RegEx (Regular Expressions), using the re library.

Here's the RegEx you would use for a float: ^[1-9]\d*(\.\d+)?$. So we can implement this code:

import csv
import re

rows = []
with open('1.txt', mode='r') as infile:
    reader = csv.reader(infile, delimiter=" ")
    for row in reader:  # each row is a list
        if bool(re.match(r'^[1-9]\d*(\.\d+)?$', row): rows.append(row)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)

What I changed:
I added if bool(re.match..., resulting in rows only getting appended to under the circumstance that row is only a float (or integer).

Upvotes: 1

Related Questions