简体   繁体   中英

Is there any alternate to multiple while True loops within a function for user input?

I'm relatively new to Python and currently working on a 2nd tutorial, specifically working with SQLite.

In my attached code (specifically the function Update), I have 3 while loops and several breaks within just this simple function. I am thinking that this is not good practice and I am looking for advice to make it less vulnerable to crashing and/or more compact.

What are the side effects of having too many break statements?

def updateData():
    global cursor
    sql = 'SELECT name FROM sqlite_master WHERE type = "table" ORDER BY name'
    cursor.execute(sql)

    rows = cursor.fetchall()

    print("These are the existing tables in the system:")
    tableList = []
    for row in rows:
        print(row[0])
        tableList.append(row[0])

    while True:
        table = input("Enter table to update: ")
        if table in tableList:
            while True:
                phoneLIST = searchDB()

                if len(phoneLIST) == 0:
                    option = tryMessage()
                    if not option:
                        break
                else:

                    numID = int(input("Enter the ID number you want updated: "))

                    sql = 'PRAGMA table_info(%s)' % table
                    cursor.execute(sql)

                    rows = cursor.fetchall()

                    print("These are the existing columns in %s table:" % table)
                    colList = []
                    for row in rows:
                        print(row[1])
                        colList.append(row[1])

                    while True:
                        column = input("Enter the column name of ID: %d you want updated: " % numID)
                        column = column.upper()
                        if column in colList:
                            if column == 'BOD' or column == 'PID':
                                print("You can't change Birth of Date OR PID")
                                option = tryMessage()
                                if not option:
                                    break
                            else:
                                if column == 'PHONE':
                                    newEntry = checkPhone()
                                elif column == 'POSTAL':
                                    newEntry = checkPostal()
                                else:
                                    newEntry = input("Enter new information for column %s: " % column)

                                sql = 'UPDATE %s SET %s = "%s" WHERE PID = %d' % (table, column, newEntry, numID)
                                cursor.execute(sql)

                                displayOneEntry(numID)
                                commitMessage()
                                break
                        else:
                            print("Column not in the table")
                    break
            break
        else:
            print("Table not in the database")
            option = tryMessage()
            if not option:
                break

There's nothing wrong with while True: loops; they're the natural way of doing something over and over until an error happens or the user decides to quit.

In my opinion this function is a bit clumsy, because it's working at many different levels of detail. It might be better to reorganize it into separate functions for tables, column IDs, and values, so that each function is concerned just with its own stuff and doesn't worry about higher- or lower-level details.

I have refactored as follows, eliminating the nested while True: Thanks again @JG!

{other functions ...}

def getTable():
    global cursor
    sql = 'SELECT name FROM sqlite_master WHERE type = "table" ORDER BY name'
    cursor.execute(sql)

    rows = cursor.fetchall()

    tableList = []
    print("These are the available tables:  ")
    for row in rows:
        print(row)
        tableList.append(row[0])

    while True:
        tableName = input("Enter table to update: ")
        if tableName in tableList:
            return tableName
            break
        else:
            print("Table not in the database")
            # provide option to re-enter information
            option = tryMessage()
            if not option:
                break


def getColumn(tableName, numID):
    global cursor
    sql = 'PRAGMA table_info(%s)' % tableName
    cursor.execute(sql)

    rows = cursor.fetchall()

    print("These are the existing columns in %s table:" % tableName)
    colList = []
    for row in rows:
        print(row[1])
        colList.append(row[1])

    while True:
        colName = input("Enter the column name of ID: %d you want updated: " % numID)
        colName = colName.upper()
        if colName in colList:
            return colName
        else:
            print("Column not in the table")
            # provide option to re-enter information
            option = tryMessage()
            if not option:
                break


def getID(idList):
    while True:
        try:
            numID = int(input("Enter the ID number you want updated: "))
        except ValueError:
            print('Enter valid number')
            continue
        if numID in idList:
            return numID
        else:
            print("Wrong ID")


# admin use only
def updateData():
    global tempPassword
    passWord = input("Enter password: ")
    if passWord == tempPassword:
        global cursor
        # Displays valid tables
        tableName = getTable()

        idName = getIDName(tableName)

        while True:
            idList = searchDB()
            # provide option to re-enter information
            if len(idList) == 0:
                option = tryMessage()
                if not option:
                    break
            else:
                numID = getID(idList)
                colName = getColumn(tableName, numID)

                if colName == 'BOD' or colName == idName or colName == 'STATUS':
                    print("You can't change this field")
                    # provides option to re-enter information
                    option = tryMessage()
                    if not option:
                        break
                else:
                    if colName == 'PHONE':
                        # checks format for phone input
                        newEntry = checkPhone()
                    elif colName == 'POSTAL':
                        # checks format for postal code input
                        newEntry = checkPostal()
                    elif colName == 'POSITION_ID':
                        # checks to ensure ID is valid
                        newEntry = checkPositionID()
                    else:
                        newEntry = input("Enter new information for column %s: " % colName)

                    sql = 'UPDATE %s SET %s = "%s" WHERE %s = %d' % (tableName, colName, newEntry, idName, numID)
                    cursor.execute(sql)

                    # display the updated entry for confirmation
                    displayOneEntry(idName, numID)
                    # provide option to commit changes
                    commitMessage(idName)
                    break
    else:
        print("Access requires correct password")

{menu ...}

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