Home > Mobile >  Customize def __str__(self): method when creating a class in Python
Customize def __str__(self): method when creating a class in Python

Time:10-17

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'
>>>      
  • Related