I am creating a MultipleChoice class in Python3, where the first parameter is supposed to be a question, the second parameter a list with alternatives (each entry a string, not numbered), and the third parameter is the number of the correct answer. The list with alternatives could be of varying length.
I have created the class, and I am trying to create a _str_ method that returns the question and all the alternatives underneath the question, but this time numbered. An outline of what I want to achieve looks like this:
question1 = MultipleChoice('What´s best?', ['Mac', 'PC'], 1)
question2 = MultipleChoice('Biggest city in England?' , ['Manchester','Liverpool', 'London'], 3)
print(question1)
print(question2)
INTENDED OUTPUT:
What´s best? 1 - Mac , 2 - PC
Biggest city in England? 1 - Manchester , 2 - Liverpool , 3 - London
I have tried inserting methods into the brackets in the f-string in the _str_ method, unsuccessfully. I did this because I assume I have to loop through the list with alternatives and assign each entry a number similar to the index number, and thought more complex tasks like this would be better to do in a separate method (instead of trying to do this inside the brackets in the f-string.
It´s also a school assignment, so I have to achieve this using the _str_ method.
Any help would be greatly appreciated. Below is my code so far:
class MultipleChoice:
#Constructor
def __init__(self, question, alternatives, correct_answer):
self.question = question
self.alternatives = alternatives
self.correct_answer = correct_answer
def __str__(self):
return f'{self.question}? \n{self.alternatives}.'
if __name__ == '__main__':
question1 = MultipleChoice('What´s best?', ['Mac', 'PC'], 1)
question2 = MultipleChoice('Biggest city in England?' , ['Manchester','Liverpool', 'London'], 3)
print(question1)
print(question2)
CodePudding user response:
You can try with __str__
as shown below (update the f-string with dashes and/or whitespaces instead of newlines to meet your needs):
>>> class MultipleChoice:
... #Constructor
... def __init__(self, question, alternatives, correct_answer):
... self.question = question
... self.alternatives = alternatives
... self.correct_answer = correct_answer
... def __str__(self):
... return f'{self.question}\n' '\n'.join(f'{i} {a}' for i, a in enumerate(self.alternatives,1))
...
>>> question1 = MultipleChoice('What´s best?', ['Mac', 'PC'], 1)
>>> question2 = MultipleChoice('Biggest city in England?' , ['Manchester','Liverpool', 'London'], 3)
>>>
>>> print(question1)
What´s best?
1 Mac
2 PC
>>> print(question2)
Biggest city in England?
1 Manchester
2 Liverpool
3 London
CodePudding user response:
For this we can use enumerate to easily get the index number of a given element in a list, and with its second argument we can shift it to start from 1, we can use this to get
>>> question = 'Biggest city in England?'
>>> alternatives = ['Manchester', 'Liverpool', 'London']
>>> for i,v in enumerate(alternatives,1):
print(f'{i} - {v}')
1 - Manchester
2 - Liverpool
3 - London
>>>
Now lets change the previous loop into an appropriate list comprehension
>>> [f'{i} - {v}' for i,v in enumerate(alternatives,1)]
['1 - Manchester', '2 - Liverpool', '3 - London']
>>>
Now we use str.join to, well, join them together and remove the [] to make it into a generator expression while we are at it
>>> temp=', '.join(f'{i} - {v}' for i,v in enumerate(alternatives,1))
>>> temp
'1 - Manchester, 2 - Liverpool, 3 - London'
>>>
now we got the 80% of it, lets go for the final touch
>>> f"{question} {temp}"
'Biggest city in England? 1 - Manchester, 2 - Liverpool, 3 - London'
>>>
And we're done.
Also f-string can take almost any python expression, so we can make this into a one liner
>>> f"{question} { ', '.join(f'{i} - {v}' for i,v in enumerate(alternatives,1)) }"
'Biggest city in England? 1 - Manchester, 2 - Liverpool, 3 - London'
>>>