Python Forum
How to print multiple elements from multiple lists in a FOR loop?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to print multiple elements from multiple lists in a FOR loop?
#1
Question 
This is a followup post to my previous one - I decided to re-write the code and now i'm facing a new problem.

I'm working on a dynamic, text based (for now), Test Maker program. The user gets to write the question, choose how many answers it will have, what score to give for it, choose the right question and print the results in a table form.

How can I write a for loop (not one-liner) so I can go through the lists and print the output according to the table?

here's the function where I want to place it:

def finish(lines):

    print("\n\n==============RESULTS==============\n")
    print("#\t Question\t Answer\t\t Score")
    number_of_questions = len(question_list)
here's the result table template I wish to present:

[Image: DlKT8vw.png]

and here's the full code:

def get_questions():

    question = input("Enter your question: ")
    if len(question) == 0:
        print("No Empty Questions.")
        get_questions()

    question_list.append(question)

    return question


def get_question_score(s):

    try:
        s = int(input("Enter Question Score: "))

    except ValueError:
        print("[!]Error! Use numbers.")

    return s


def check_sum(s):

    scores_local.clear()

    try:
        if sum(scores) + s > 100:
            print("Score sum is higher than 100")
            print(f"{100 - sum(scores)} left")
            score = 0
            if len(scores) != 0:
                scores.pop()
            return False

    except ValueError:
        print("Use Numbers.")

    scores_local.append(s)
    scores.append(s)

    return True


def get_number_of_answers(n_o_a):

    try:
        n_o_a = int(input("Number of answers (Max 4)? "))

    except ValueError:
        print("Please select [2-4]")

    number_of_answers.append(n_o_a)

    return n_o_a


def big_small(n_o_a):

    if n_o_a < 2 or n_o_a > 4:
        print("Please select [2-4]")
        answers.clear()
        answers_local.clear()
        big_small(n_o_a=number_of_answers[0])
        return False

    elif 2 > number_of_answers[0] > 4:
        print("Error! Please select [2-4]")
        return False

    else:
        print(n_o_a)
        return True


def get_answers(num_of_answers, answer):

    answers_local.clear()
    answers.clear()

    for ans in range(number_of_answers[0]):
        answer = input(f"Answer #{ans+1}: ")    # Start indexing from 1
        if len(answer) == 0:
            print("Error! No Input!")
            get_answers(num_of_answers, answer="")

        answers_local.append(answer)
        answers.append(answer)

    return answer


def get_right_answer_number(num):

    try:
        num = int(input("Type the Right Answer Number: "))

    except ValueError:
        print("Error! Please type numbers only.")

    return num


def check_right_answer_number(num):

    if 0 < num <= number_of_answers[0]:
        return True

    else:
        return False


def ask_if_sure(ans):   # Returns True

    ask_sure = input("Are you sure? [Y/n]: ")
    if ask_sure.lower() == "n":
        number_of_answers.clear()
        check_right_answer_number(num=number_of_answers[0])

    elif ask_sure.lower() == "y":
        return True

    else:
        print("Error! Please type [Y/n]")
        ask_if_sure(ans="")


def ask_continue():

    a_continue = input("Do you wish to add more questions? [Y/n]: ")
    if a_continue.lower() == "y":
        return True

    elif a_continue.lower() == "n":
        return False

    else:
        print("Error! Please choose [Y/N]")
        ask_continue()


def restart():

    answers_local.clear()
    number_of_answers.clear()
    right_answer_number.clear()
    main()


def finish(lines):

    print("\n\n==============RESULTS==============\n")
    print("#\t Question\t Answer\t\t Score")
    number_of_questions = len(question_list)


def main():

    questions = get_questions()
    question_score = get_question_score(s=0)
    score_sum = check_sum(question_score)   # Returns True/False
    num_of_answers = get_number_of_answers(n_o_a=0)
    is_bigger = big_small(num_of_answers)   # Returns True/False

    if not is_bigger:
        print(f"Question score: {question_score}, Valid: {score_sum}")
        if sum(scores) != 0:
            scores.pop()
            question_score = get_question_score(s=0)

    while is_bigger:

        question = questions[-1]
        multiple_answers = get_answers(num_of_answers, answer="")
        print(answers_local)
        right_answer_number_var = get_right_answer_number(num=0)
        print(right_answer_number_var)
        is_right = check_right_answer_number(right_answer_number_var)

        if not is_right:
            print(f"Error! Please select [1={number_of_answers[0]}")
            right_answer_number_var = get_right_answer_number(num=0)

        while is_right:
            sure = ask_if_sure(ans="")

            while sure:
                if number_of_answers[0] < len(questions):
                    lines = len(questions)
                else:
                    lines = number_of_answers[0]

                answers.append(right_answer_number_var)
                ask_if_continue = ask_continue()
                if not ask_if_continue:
                    finish(lines)

                while ask_if_continue:
                    restart()
                    break
                break
            break
        break


if __name__ == "__main__":

    question_list = []
    scores = []
    scores_local = []
    number_of_answers = []
    answers = []
    answers_local = []
    right_answer_number = []

    main()
Thanks for your time!
Reply
#2
You don't handle empty questions correctly. Be careful about using recursion
question_list = []

def get_questions():
    question = input("Enter your question: ")
    if len(question) == 0:
        print("No Empty Questions.")
        get_questions()
    question_list.append(question)
    return question

for _ in range(3):
    get_questions()
print(question_list)
Output:
Enter your question: 1 Enter your question: No Empty Questions. Enter your question: 2 Enter your question: No Empty Questions. Enter your question: 3 ['1', '2', '', '3', ''] <-- Two blank questions
Personally I think a blank question is a great way to indicate you are done entering questions, but if you want to keep asking until a question is answered you should use something like this:
def get_questions():
    while True:
        question = input("Enter your question: ")
        if len(question) == 0:
            print("No Empty Questions.")
        else:
            question_list.append(question)
            return question
Reply
#3
Ways to print nice looking tables were recently discussed here:

https://python-forum.io/Thread-Formatting-lists
Reply
#4
(Dec-01-2020, 11:17 PM)deanhystad Wrote: You don't handle empty questions correctly. Be careful about using recursion
question_list = []

def get_questions():
    question = input("Enter your question: ")
    if len(question) == 0:
        print("No Empty Questions.")
        get_questions()
    question_list.append(question)
    return question

for _ in range(3):
    get_questions()
print(question_list)
Output:
Enter your question: 1 Enter your question: No Empty Questions. Enter your question: 2 Enter your question: No Empty Questions. Enter your question: 3 ['1', '2', '', '3', ''] <-- Two blank questions
Personally I think a blank question is a great way to indicate you are done entering questions, but if you want to keep asking until a question is answered you should use something like this:
def get_questions():
    while True:
        question = input("Enter your question: ")
        if len(question) == 0:
            print("No Empty Questions.")
        else:
            question_list.append(question)
            return question

That's a cool solution! it doesn't fit the current build because I want the user to type the answers immidietely rather than stack them and then type the answers for them.
I will definetely use this solution in other stuff though!
thanks for your time!
Reply
#5
(Dec-01-2020, 11:19 PM)deanhystad Wrote: Ways to print nice looking tables were recently discussed here:

https://python-forum.io/Thread-Formatting-lists

Thank you!
There are some good ideas there i'll check them out and update if anything worked.

Thanks for your time!
Reply
#6
You would get a lot of benefit from writing some classes to manage your test and questions. Something like this (but much better):
import random

class Question:
    def __init__(self, question=''):
        self.question = question
        self.answers = []
        self.correct_answer = 0

    def ask(self):
        while True:
            print(f'\nQuestion: {self.question}')
            for i, answer in enumerate(self.answers):
                print(f'{i+1}: {answer}')
            try:
                answer = int(input('Enter answer: '))
                if not answer in range(1, len(self.answers)+1):
                    raise ValueError
                return answer
            except ValueError:
                print('Please enter the number of your answer')

    def print(self):
        print(f'\nQuestion: {self.question}')
        for i, answer in enumerate(self.answers):
            print(f'{i+1}: {answer}')
        print(f'Correct answer : {self.correct_answer}')

def make_quiz():
    quiz = []
    while True:
        text = input('Enter question: ')
        if len(text) == 0:
            return quiz
        q = Question(text)

        while len(q.answers) < 4:
            text = input(f'Enter answer {len(q.answers)+1}: ')
            if len(text) > 0:
                q.answers.append(text)
            elif len(q.answers) < 2:
                print('There must be at least two answers')
            else:
                break; # done entering answers

        q.correct_answer = q.ask()

        q.print()
        if input('Add this question to the quiz? (y/n): ')[0] in ('Yy'):
            quiz.append(q)

def take_quiz(quiz):
    questions = random.sample(quiz, k=len(quiz))
    score = 0
    for q in questions:
        answer = q.ask()
        if answer == q.correct_answer:
            score += 1
        else:
            print(f'The correct answer is {q.correct_answer}: {q.answers[q.correct_answer-1]}')
        print('\n\n')
    print(f'Your score is {score} out of {len(questions)}')

print('Enter questions for the quiz')
quiz = make_quiz()
print('\n\nTake the quiz')
take_quiz(quiz)
You would want a way to store a quiz in a file and load a quiz from a file. You might want a way to edit a quiz, though it may be easier to just edit the quiz file. Unless the file is encrypted.
bowlofred likes this post
Reply
#7
I'll start by thanking you for that answer!

This is what I planned to do but in stages. I guess you're right and I should add the classes now.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Lightbulb Multiple inputs on the same line (beginner) dementshuk 9 341 Sep-03-2021, 02:21 PM
Last Post: dementshuk
  How to combine multiple rows of strings into one using pandas? shantanu97 1 176 Aug-22-2021, 05:26 AM
Last Post: klllmmm
  Generate Multiple sql Files With csv inputs vkomarag 13 616 Aug-20-2021, 07:03 PM
Last Post: vkomarag
  Generate a string of words for multiple lists of words in txt files in order. AnicraftPlayz 2 321 Aug-11-2021, 03:45 PM
Last Post: jamesaarr
  Replace String in multiple text-files [SOLVED] AlphaInc 5 545 Aug-08-2021, 04:59 PM
Last Post: Axel_Erfurt
  Display table field on multiple lines, 'wordwrap' 3python 0 165 Aug-06-2021, 08:17 PM
Last Post: 3python
  Apply fillna to multiple columns in dataframe rraillon 2 279 Aug-05-2021, 01:11 PM
Last Post: rraillon
  Open and read multiple text files and match words kozaizsvemira 3 4,127 Jul-07-2021, 11:27 AM
Last Post: Larz60+
  Plotting Multiple files ! Helen_145 1 409 Jun-26-2021, 03:28 PM
Last Post: snippsat
  Create Dict from multiple Lists with duplicate Keys rhat398 10 815 Jun-26-2021, 11:12 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

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