简体   繁体   中英

“None” as return from while loop

I have the following function:

def AdjustTime(f):
    if len(f) == 1:
        return '0' + f + '00'
    elif len(f) == 2:
        return f + '00'
    elif len(f) == 3:
        return '0' + f
    elif len(f) == 4:
        return f
    else:
        while True:
            if len(f) > 0 and len(f) <= 4 and int(f[:2]) <= 23 and int(f[2:]) <= 59:
                return f
                break
            else:
                clear()
                print f,'Get this date right'
                f = raw_input('')

It works until I get a correct number, which leads to a TypeError: 'NoneType' object is not subscriptable. How to fix this?

EDIT: First, thanks for the parenthesis mentions, I forgot it a few times while coding myself, now the code is the one I'm actually trying.

I want to put a string of text brought from Drafts into this function, the if/elif will convert a 1-2-3 string into the 4-digit I need and how I want it. For example, a string "1" will become "0100". But you know that. If the user screwed up somehow I'm using that while. Yes, I should reorganize it some other way, such as using the int(f[:2]) <= 23 and int(f[2:]) <= 59 before actually trying to edit the string.

Back on track, if the user screwed up, the input gives him the chance to insert a correct string, which passes through the while. The problem is, when the user puts the correct value, this is what a print f shows, considering the value as 1234:

1234
None

Now, what else can I do to help you?

EDIT2: Since everybody has been asking for the whole code, you're here to help me out, I just didn't thought it was necessary. Apologies for that (:

from urllib import quote
import time
from webbrowser import open
from console import clear

rgv = ['a path', 'This is an awesome reminder\nWith\nMultiple\nLines.\nThe last line will be the time\n23455']

a = rgv[1].split('\n')

reminder = quote('\n'.join(a[:(len(a)-1)]))

t = a[len(a)-1]

def AdjustTime(f):
    if len(f) == 1:
    return '0' + f + '00'
    elif len(f) == 2:
        return f + '00'
    elif len(f) == 3:
        return '0' + f
    elif len(f) == 4:
        return f
    else:
        while True:
            if len(f) > 0 and len(f) <= 4 and int(f[:2]) <= 23 and int(f[2:]) <= 59:
                return f
                break
            else:
                clear()
                print 'Get this date right'
                f = raw_input('')

mins = int(AdjustTime(t)[:2])*60 + int(AdjustTime(t)[2:])

local = (time.localtime().tm_hour*60+time.localtime().tm_min)

def findTime():
    if local < mins:
        return mins - local
    else: 
        return mins - local + 1440

due = 'due://x-callback-url/add?title=' + reminder + '&minslater=' + str(findTime()) + '&x-source=Drafts&x-success=drafts://'

open(due)
def AdjustTime(f):
    f = f or ""   # in case None was passed in
    while True:
        f = f.zfill(4)
        if f.isdigit() and len(f) == 4 and int(f[:2]) <= 23 and int(f[2:]) <= 59:
            return f
        clear()
        print f, 'Get this date right'
        f = raw_input('')

You need to initialize f to say, "" . In the first itereation of while True f is None , so in the if condition it's testing None[:2] and None[2:] which will obviously raise error.

EDIT: Well I wonder why don't you get

object of type 'NoneType' has no len()

error first....

At the top of your method, add this:

def AdjustTime(f):
   if not f:
      return

This will prevent the method from executing if you have passed it a "falsey" value .

In order to do this however, you'll need to change your logic to have the raw_input line in the caller of this function; because the above method will return and the prompt will never be shown:

def AdjustTime(f):
    if not f:
       return
    if len(f) == 1:
        return '0' + f + '00'
    if len(f) == 2:
        return f + '00'
    if len(f) == 3:
        return '0' + f
    if len(f) == 4:
        return f
    if 0 > len(f) <= 4 and int(f[:2]) <= 23 and int(f[2:] <= 59:
        return f

def get_input():
    f = raw_input('')
    result = AdjustTime(f)
    while not result:
        print('{} get this date right'.format(f))
        f = raw_input('')
        result = AdjustTime(f)

@gnibbler has a great suggestion in the comment:

def AdjustTime(f):
   f = f or ""

This will set the value of f to a blank string if the passed in value is falsey . The benefit of this method is that your if loops will still run (since a blank string has length), but your while loop will fail.

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