My code is supposed to calculate and print the average pH for every fluid given the file variable name.
This is what I have so far, trying to separate the txt file into parts using
result = 0
line = file_variable.readline()
found = False
while line != "" and not found:
list = line.strip().split(",")
result += list
if line != "":
avg = result / 3
if not found:
result = None
file_name = str(input("Enter a file name: "))
file_variable = open(file_name, "r", encoding="utf-8")
Baking soda (1 Tbsp) in Water (1 cup),8.4,8.3,8.7
Boy, where to start?
list = line.strip().split(",") if list.isnum:
list is the name of a built-in type in Python, and while you can overshadow that by using it as a variable name, for the sake of not confusing yourself and everybody else, you really shouldn't:
lst = line.strip().split(",") if lst.isnum:
OK, that's better.
lst is an instance of the class that can now still be referred to as
list. Now, your
if lst.isnum: appears to be an attempt to test the output of a method of that instance. But in Python you can't call methods without typing the parentheses. Without parentheses, currently, your
if statement is asking whether the pointer to the method itself is non-zero which, for methods that exist, is always going to be true...
lst = line.strip().split(",") if lst.isnum():
OK, that's better. Except note that I said, "...for methods that exist".
isnum is not a method of the
list class so the code will just raise an exception here. You presumably mean the string method
lst = line.strip().split(",") if lst.isnumeric():
But of course this is still wrong. You want to test whether items in the list are numeric. Therefore, you need to call some function or method of each item, not of the list itself. Although strings have an
isnumeric method, the
list class (to which our
lst variable belongs) does not. One elegant way around this is to use a "list comprehension":
lst = line.strip().split(",") lst = [item for item in lst if item.isnumeric()]
But of course that doesn't actually convert the items from strings to numbers. Did you really think you could just add up a bunch of strings and divide by 3?
lst = line.strip().split(",") lst = [float(item) for item in lst if item.isnumeric()]
OK, now we have a list of actual floating-point numbers that can be manipulated numerically. But we've thrown away the information about which substance we're measuring.
lst = line.strip().split(",") substance = lst.pop(0) # remove and store the first item in the list lst = [float(item) for item in lst if item.isnumeric()]
I would then suggest that you somehow associate each pH value-list/average with its respective substance—otherwise that associative info is going to get lost/corrupted. There are neat ways of doing that with a
dict, although currently you have a variable called
found that is unused—suggesting that you may be intending to do something like:
if substance == the_particular_substance_we_are_currently_interested_in: found = True avg = ...
(Note: if you do this, do it inside the loop—you want to check each line to see if it's the target, after all.)
Now, as for your
result += lst... Well, you initialized
0 so it's an integer, and
lst as we know is a
list. You can't add a
list to an integer—it doesn't make sense. What you presumably want to do is
sum the values in the list (and you won't even need
avg = sum(lst) / len(lst)
Note that I'm dividing by whatever the length of
lst is, rather than hard-coding the number 3 in there. Hardcoding assumptions like that is a really effective way to set hard-to-find traps for your future self, so let's avoid it.