0
votes

I know this question is similar to one I have already asked, but it is an extension and so justified its own space :-)

I am a Python newbie writing a code which takes input from a user and then stores that user input in an array (to do more stuff with later), provided two criteria are met:

1) The total inputs add up to one

2) There is no input itself greater than one.

I have already had some help with this question, but had to modify it a bit since my code inputs can't easily be written with the inputs being classified by some index "n" (the questions prompting input can't really be formatted as "input (n), where n runs from 1 to A")

Here is my attempt so far:

num_array = list()
input_number = 1
while True:

     a1  = raw_input('Enter concentration of hydrogen (in decimal form): ')
     a2 = raw_input('Enter concentration of chlorine (in decimal form): ')
     a3 = raw_input('Enter concentration of calcium (in decimal form): ')



     li = [a1, a2, a3]

     for s in li:
        num_array.append(float(s))
        total = sum([float(s)])

     if float(s-1)  > 1.0:     
         num_array.remove(float(s-1))
         print('The input is larger than one.')

     continue


     if total > 1.0:    # Total larger than one, remove last input and print reason
         num_array.remove(float(s-1))
         print('The sum of the percentages is larger than one.')

     continue

     if total == 1.0:    # if the sum equals one: exit the loop
          break

input_number += 1

I am rather glad it compiles, but Python doesn't like the line

if float(s-1)  > 1.0: 

for which it throws the error:

TypeError: unsupported operand type(s) for -: 'str' and 'int'

I know this is because the "s" is a string, not an integer, but I can't think of an easy way around the problem, or for how to implement a loop over user inputs in this case in general.

How to improve this program to only write user input to the array if the criteria are met?

Thanks for your time and help!

3
Try changing to float(s)-1asongtoruin
Not sure what you mean by being "rather glad it compiles": Python is an interpreted languagebrianpck
@brianpck Well, you can still get SyntaxError which is kinda close - it happens before the actual interpretation step. The python docs liken the generation of bytecode to compilation.MisterMiyagi
What brings you to assume "can't easily be written with the inputs being classified by some index "n""? It's perfectly fine to do an for element in ('hydrogen', 'chlorine', 'calcium'): and would prevent problems such as s being checked only for the last element.MisterMiyagi
It looks like your continue statements should be indented one more level, to fall within the prior if statements.Jeff

3 Answers

2
votes

You'll simply need to cast to float before you do subtraction:

if float(s) - 1  > 1.0:

This way, you can subtract 1 from the float value of s

EDIT: I would also make the following changes to your code in order to function more correctly.

num_array = list()
input_number = 1
while True:
    a1  = raw_input('Enter concentration of hydrogen (in decimal form): ')
    a2 = raw_input('Enter concentration of chlorine (in decimal form): ')
    a3 = raw_input('Enter concentration of calcium (in decimal form): ')

    try:   # try to cast everythiong as float.  If Exception, start loop over.
        li = [float(a1), float(a2), float(a3)]
    except ValueError:
        continue

    total = 0  # reset total to 0 each iteration
    for s in li:
        num_array.append(s)
        total += s  # use += to keep running toatal

        if s > 1.0:     
            num_array.remove(s)
            print('The input is larger than one.')
            break  # break rather than continue to break out of for loop and start while loop over


        if total > 1.0:
            num_array.remove(s)
            print('The sum of the percentages is larger than one.')
            break   # break again

    if total == 1.0:
        break

I think this is what you were going for.

2
votes

One way you can assure the input type is with a try/except condition to exit a loop:

while True:
    a1  = raw_input('Enter concentration of hydrogen (in decimal form): ')
    a2 = raw_input('Enter concentration of chlorine (in decimal form): ')
    a3 = raw_input('Enter concentration of calcium (in decimal form): ')
    try:
        a1 = float(a1)
        a2 = float(a2)
        a3 = float(a3)
        break
    except ValueError:
        print('All inputs must be numerals')

And then it will just stay in the loop if they didn't enter something Python could convert to a float.

1
votes

Your code is a bit confused. I'm sure that someone could pick holes in the following but give it a whirl and see if it helps.

Initially putting the questions into a list, allows you to ask and validate the input one at a time within a single loop, exiting the loop only when all of the questions have been asked, validated and stored.

First define the questions, next process each question within a loop and within that loop, use the while statement to stay on the same question, until a valid answer has been supplied.

input_number = 1
questions = []
answers = []
questions.append('Enter concentration of hydrogen (in decimal form): ')
questions.append('Enter concentration of chlorine (in decimal form): ')
questions.append('Enter concentration of calcium (in decimal form): ')
for i in questions:
    while True:
        try:
            ans  = float(raw_input(i)) #Accept the answer to each question
        except ValueError:
            print('Please input in decimal form')
            continue # Invalid input, try again
        if ans > 1.0:
            print('The input is larger than one.')            
            continue # Invalid input, try again
        if sum(answers,ans) > 1.0:
            print('The sum of the answers is larger than one.')
            print(answers)
            continue # Invalid input, try again
        answers.append(ans)
        break # The answer to this question has been validated, add it to the list
print ("Your validated input is ",answers)
input_number += 1