简体   繁体   中英

How do I validate both a string and an integer input in python?

My goal is to print lines of text into a new document when the user enters a specific year. So far, that part works fine. However, I'm not sure how to handle the user typing "all" to signify they want to copy all data into the new file. You can see my failed attempts at trying to make sense of the trial and except blocks below:

filename = input("Enter an output file name: ")
file_write = open(filename, 'w')
file_read = open("polio.txt")
user_year = input("Enter a year: ")
while True:
    try:
        for line in file_read:
            year = int(line[68:74])
            millenium = int(line[68:69])
            century = int(line[68:70])
            decade = int(line[68:71])
            user_year == int(user_year)
            if user_year == year:
                file_write.write(line)
            if user_year == millenium:
                file_write.write(line)
            if user_year == century:
                file_write.write(line)
            if user_year == decade:
                file_write.write(line)
    except ValueError:
        if user_year == {"", "all", "ALL"}:
                file_write(line[:74])
        file_read.close

Essentially, all I need to do is find a way to compare the years the user wants to the ones in the text file while also evaluating an empty string and a string containing the phrase "ALL" or "all"

I've give you a few pieces, and hopefully they'll help you reason about the individual components so you can structure the program however you see fit.

File Access

For one, the more accepted, "Pythonic" way of doing file access is using a "context manager". Thankfully, the open statement supports that:

with open('polio.txt') as f:
    # do stuff here

This will automatically handle closing the file whenever the context is left, regardless of whether it is done with an error. This prevents you from having to keep track of file closings and potentially making a mistake. You can break out the file opening and processing into different functions to reduce extra nesting, if it bothers you.

Better to Ask Forgiveness than Acceptance

Another Python idiom is that it's better to ask forgiveness than acceptance. Rather than trying to check whether a string is a digit, as the other answerer suggested, just try to cast it as an integer and handle the case when it isn't:

try:
    user_year = int(user_year)
except ValueError:
    pass

Then you can easily check whether the value is "all" later.

Checking if an Item is in an Iterable

You are trying to see if the user has passed some variation of "all" here:

if user_year == {"", "all", "ALL"}:
    # do stuff here

This will never work, since user_year will never be a set of strings, which you are comparing to. Instead, use the in statement to test for whether the iterable contains the item:

if user_year in {"", "all", "ALL"}:
    # do stuff here

You can use str.isdigit() to check if the input is a valid integer like shown below:

filename = input("Enter an output file name: ")
file_write = open(filename, 'w')
file_read = open("polio.txt")
user_year = input("Enter a year: ")

# check for empty string after removing white spaces
# OR check if answer is all or ALL
all_option_selected = user_year.strip().lower() in {"", "all"}
# calculate year once outside the loop if input is valid integer
if user_year.strip().isdigit():
    user_year = int(user_year)
else:
    user_year = None
try:
    while True:

        for line in file_read:
            year = int(line[68:74])
            millenium = int(line[68:69])
            century = int(line[68:70])
            decade = int(line[68:71])

            if all_option_selected:
                file_write(line[:74])
                # continue with next line since user did not enter a valid year
                continue

            if user_year is None:
            # user year is not valid number and all option was not selected
            # so we break out of the loop since input is invalid
                break
            if user_year == year:
                file_write.write(line)
            if user_year == millenium:
                file_write.write(line)
            if user_year == century:
                file_write.write(line)
            if user_year == decade:
                file_write.write(line)
finally:
    file_read.close()
    file_write.close()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM