Есть ли альтернатива нескольким в то время как True циклы внутри функции для пользовательского ввода? - PullRequest
0 голосов
/ 14 января 2020

Я относительно новичок в Python и в настоящее время работаю над вторым учебным пособием, специально работающим с SQLite.

В моем прикрепленном коде (в частности, функция Update) у меня есть 3 цикла while и несколько разрывов внутри этой простой функции. Я думаю, что это не очень хорошая практика, и я ищу совет, чтобы сделать его менее уязвимым к сбоям и / или более компактным.

Каковы побочные эффекты от слишком большого количества операторов прерывания?

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

Ответы [ 2 ]

0 голосов
/ 15 января 2020

Я произвел рефакторинг следующим образом, исключив вложенное, в то время как True: еще раз спасибо @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 ...}
0 голосов
/ 14 января 2020

В циклах while True: нет ничего плохого; это естественный способ делать что-то снова и снова, пока не произойдет ошибка или пользователь не решит выйти.

На мой взгляд, эта функция немного неуклюжа, потому что она работает на разных уровнях детализации. Возможно, было бы лучше реорганизовать его в отдельные функции для таблиц, идентификаторов столбцов и значений, чтобы каждая функция занималась только своими собственными вещами и не беспокоилась о деталях более высокого или более низкого уровня.

...