Python Forum
[Tkinter] previous and next buttons
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] previous and next buttons
#1
Hi

I have a db and i got the data and put them in python lists so I can get the records places 0,1,2...
for the first record i am able to assign the right data having the index of the first element which is [0]. Now if I click the button named next, what i can do to go to next record?

    global thephoto
    global answer1
    global answer2
    global answer3
    global answer4
    global correct_answer    

    thephoto = []
    answer1 = []
    answer2 = []
    answer3 = []
    answer4 = []
    correct_answer = []

    conn2 = sqlite3.connect('emsat_data.db')
    c2 = conn2.cursor()
    c2.execute("SELECT * from math_exam")
    conn2.commit()
    records = c2.fetchall()

    for record in records:
        thephoto.append(str(record[0]))
        answer1.append(str(record[1]))
        answer2.append(str(record[2]))
        answer3.append(str(record[3]))
        answer4.append(str(record[4]))
        correct_answer.append(str(record[5]))
        #how many questions are there in db
for first records I can access calling index [0] of each list but I think this is not the right way to deal with this. Any suggestions or tutorials appreciated.
Reply
#2
You are not using "global" correctly. In this code "global" does nothing.
global thephoto
global answer1
global answer2
global answer3
global answer4
global correct_answer 
"global" tells Python to look for the variable in the global/module context. The problem is that this code is in the global/module context. It only makes sense to use the "global" keyword inside a function. You have no functions, so you should not be using "global".
a = None

def function():
    global a  # Tells Python to use global a instead of making function.a
    a = 5
But even if your database query were inside a function you still wouldn't have an need for "global".
thephoto = []
answer1 = []
answer2 = []
answer3 = []
answer4 = []
correct_answer = []

def get_quiz(database_name):
    conn = sqlite3.connect(database_name).cursor
    cursor = conn.cursor()
    cursor.execute("SELECT * from math_exam")
    conn.commit()
    
    for record in cursor.fetchall():
        thephoto.append(str(record[0]))
        answer1.append(str(record[1]))
        answer2.append(str(record[2]))
        answer3.append(str(record[3]))
        answer4.append(str(record[4]))
        correct_answer.append(str(record[5]))

get_quiz('emsat_data.db')
answer1 is not assigned inside function get_quiz(). We do not need a "global answer1" to force Python to use answer1 from the global/module scope. The function can see module variables and only modifies the list referenced by answer1. If there is no assignment (answer1 = something) there is no need to use "global".

Your code would benefit from a bit of structure. Structure can be introduced by breaking the code into functions, as I did in the example above. It can also be structured by structuring the data. In the example below I created a class to keep related data together.
class QuizQuestion:
    def __init__(self, question, answers, correct_answer):
        self.question = question
        self.answers = answers
        self.correct_answer = correct_answer

def get_quiz(database_name, quiz_name):
    quiz = []
    conn = sqlite3.connect(database_name).cursor
    cursor = conn.cursor()
    cursor.execute('SELECT * from' + quiz_name)
    conn.commit()
    
    for record in cursor.fetchall():
        quiz.append(QuizQuestion(record[0], record[1:-1], record[-1]))

quiz = get_quiz('emsat_data.db', 'math_exam')
This is much better than having a list of question and a list of possible answer_a and possible answer_b and so on. For one thing, I can now have True/False as well as multiple choice, and I can have different number of choices for each question. Being a class, QuizQuestion can do more than just store data. It can have functions. Class functions are called methods, and we could add a method that will ask a quiz question and return if the answer is correct.
class QuizQuestion:
    def __init__(self, question, answers, correct_answer):
        self.question = question
        self.answers = answers
        self.correct_answer = correct_answer

    def ask(self):
        print(self.question)
        for i, answer in enumerate(self.answers):
            print(f'{i+1:>5}: {answer}')
        return input('Answer: ') == self.correct_answer

print(QuizQuestion('What is 3 + 2?', ['1', '3', '6', '5', '11'], '4').ask())
print(QuizQuestion('What is 6 / 2?', [], '3').ask())
Now that all the question parts are all collected together, it is easy to get the related parts.
class QuizQuestion:
    """I am a question in a quiz"""
    def __init__(self, record):
        self.question = record[0]
        self.guesses = record[1:-1]
        self.answer = record[-1]

class Quiz:
    """I am a collection of quiz questions"""
    def __init__(self, name):
        conn = sqlite3.connect('emsat_data.db').cursor
        cursor = conn.cursor()
        cursor.execute("SELECT * from " + name)
        conn.commit()
        self.questions = [QuizQuestion(question) for question in cursor.fetchall()]

    def __iter__(self):
        """Return iterator to loop through the questions"""
        return self.questions  # A list has an iterator

    def __len__(self):
        """Return how many questions in the quiz"""
        return len(self.questions)

quiz = Quiz('grade6math')
for question in quiz:
    print(question.question)
    for guess in question.guesses:
        print(guess)
    print('The correct answer is', question.answer)
rwahdan likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Need code for buttons to move to previous and next documents JayCee 1 1,974 Apr-11-2020, 08:25 PM
Last Post: JayCee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020