Display items from data table in random order, never repeating any item

I know I posted this yesterday but was hoping I could get some clear guidence
What I’m trying to do:
I am trying to get a random return from a data table and display it in a label but never get the same return twice and stop when list is complete.
I am using the random choice at the moment but it does return repetitive values
I tried using random shuffle but am not able to get it to work.I get an error…

TypeError: ‘NoneType’ does not support indexing at [Homeform.questionForm, line 25](javascript:void(0)) called from [Homeform.navigation, line 32](javascript:void(0)) called from [Homeform, line 44](javascript:void(0))

  my_list = list(app_tables.questions_choices.search())
    for n in range (5):
      row = random.shuffle(my_list)
      item = row['question_column']
      self.label_2.text = (item)

I have also tried

my_list = list(app_tables.questions_choices.search())
random.shuffle(my_list) 
for n in range (5):
      row=my_list[n]
      item = row['question_column']
      Mylabel=Label(text=item)
      self.add_component(Mylabel)

https://anvil.works/build#clone:XAUGQ5O35T6X46TP=H4I5PXZAFPXFR3M2JNXQWKMS

Does this solve your problem?

It is usually best to reply to the original topic with additonal details

1 Like

The problem does not lie with the label or repeating panel but with the fact that the loop does not terminate once all items in the table have been viewed.
The code returns the items but does not stop once the data table has been iterated over once.
That being said I cant tell for sure if the loop only produces each item once then starts again as it does not terminate

1 Like

In the app I sent above no repetition takes place. You can reproduce that code in your app. Otherwise, please send a clone a link so that I can help better

Sorry was somewhat confused as to what you sent me.Sorry
This is not what I am trying to accomplish.I have a ccolumn of data as you have but I dont want to return the entire column only one item at a time and once each item has been displayed one at a time by clicking a submit button the loop must not go around again as all the data would have been displayed
I can get the items to be displayed on the label one at a time,but when I try to return the items in random order and stop once all have been displayed I have a problem

I have been toying with this.Trying to create another list with the items that have already been displayed removed,then can terminate the loop

  for n in range(5):
      row = my_list[n]
      item = row['question_column']
      self.label_2.text = item
      if n == item:
        my_list.remove(n)

How about the following:

First go for

my_list = list(app_tables.questions_choices.search())
random.shuffle(my_list)

Now you can use normal python indexing.

my_list[0][column_name] 

will return the first value from our shuffled my_list. Similarly,


my_list[1][column_name]

Will return the second value

And they won’t be repeated

thanks will give it a try

@waynedavidstokes - Please provide a clone link in your next response if the suggestions haven’t quite worked.

The clone link should be a simple app that just demonstrates the problem you’re facing…
(Just like @divyeshlakhotia example app above)

Without a clone link we’ll be going in circles here since diagnosing the problem is challenging for others without more context.

Thanks for that,forgive me still very much in the learning process
https://anvil.works/build#clone:A777ZB7BAWLO3O5L=NQYIRE7GYWDJ2DMDEOHXA6U2

I hope this clears things up

Yes, I understood your problem now. Basically the reason for repetitions was that your code would search the data table every time the button was clicked and return a new list. So instead, I put that code in form_show. This will work now
https://anvil.works/build#clone:4IIGLA6DBZZ2XHLR=6DVIMH3VJCIWCYHKOASYDF3Y

If you need any further help, feel free to help.

1 Like

I had a look but if one keeps clicking the button the loop continues arround.
I am looking for the loop to go through all the items once randomly and then exit.
I can’t see where you have used the form_show function?

Oh sorry. That was a function I added on my own to make my point more clear
Here’s a fixed version

https://anvil.works/build#clone:4IIGLA6DBZZ2XHLR=6DVIMH3VJCIWCYHKOASYDF3Y

And if you’ll look at the code, you will find a function like this

  def form_show(self, **event_args):
      self.my_list = [i['question_column'] for i in app_tables.questions_choices.search()]
      random.shuffle(self.my_list)
      self.index=0

I’m so sorry.
but the label now only displays one item and doesn’y repeat at all

https://anvil.works/build#clone:4IIGLA6DBZZ2XHLR=6DVIMH3VJCIWCYHKOASYDF3Y

Deleted an extra line. Forgive me. I suppose this is what you needed.

1 Like

Perfect!!!
Thank you for your commitment.
I am very gratefull

1 Like

Here is one possible solution.

Create a form like this:
image

And use this code:

class Form1(Form1Template):
    def __init__(self, **properties):
        self.init_components(**properties)

        # this should be a server call to get the list of qustions
        # but for this test a static list works just fine
        # self.questions = anvil.server.call('get_questions')
        self.questions = [
            {'text': "what's your favorite color?"},
            {'text': "what's your favorite dish?"},
            {'text': "what's your favorite car?"},
            {'text': "what's your favorite animal?"},
            {'text': "what's your favorite sport?"},
        ]
        print('questions in orignal order:')
        print(self.questions)
        
        random.shuffle(self.questions)
        print('shuffled questions:')
        print(self.questions)
        
        self.current_question = 0
        
        self.show_current_question()

    def button_1_click(self, **event_args):
        self.answer_current_question_with('answer 1')

    def button_2_click(self, **event_args):
        self.answer_current_question_with('answer 2')

    def button_3_click(self, **event_args):
        self.answer_current_question_with('answer 3')

    def answer_current_question_with(self, answer):
        question = self.questions[self.current_question]
        question['answer'] = answer
        print('Questions so far:')
        print('Current question:', self.current_question)
        print(self.questions)
        
        self.current_question += 1
        self.show_current_question()
        
    def show_current_question(self):
        if self.current_question >= len(self.questions):
            # anvil.server.call('save_results', self.questions)
            alert('All questions have been answered and the results have been saved')
        else:
            question = self.questions[self.current_question]
            self.label_1.text = question['text']

PS: You asked about the random order of the questions many times, but you never listed the steps you expect the app to follow and the steps you get instead. So, for me to answer, I need to guess what you are trying to do and suggest answers that include a repeating panel, or an add_component or a sequence of forms, or a set of labels… Answering incomplete questions it’s a guess work.

If your question included something like this, it would have been easier for us to understand what you were trying to do:

I want the app to:

  1. read a list of questions from the database
  2. show one random question
  3. wait for the user to click a button
  4. when the button is clicked, store the answer for that question
  5. show the next random question, making sure the same question is not shown twice
1 Like

Thanks for the response Stefano.Point taken.
I will endever to be more clear and precise in the future.It wasn’t intentional,and I will get better at asking questions in a “better to understand sort of way” going forward.

You will not regret it.

Putting more effort in describing the question in English often leads you to better understanding what you are trying to do. Then all you need to do is translating that in Python.

I start asking questions on Stackoverflow, and 80% of the times I have an answer before I click Post, because the process of writing and rereading it lead me to figuring it out by myself. And when I do click Post, I have higher chances of getting a good answer if I post a good question.

1 Like