Lost in a Loop with Lists

Guys,

Been using here for quite a while and thanks for everyone who are helping out the Newbie’s like me. Thank you.

But finally had to make an account to get something clarified and which I couldn’t find an answer for.

This is what I am trying to do,

I am randomly trying to select an item from a list.
ex :
token = [A, B, C, D, E, F, G, H, I]

Because this function will be happening along side a different loop, let’s say ( every ten vouchers I need a token ).

What I would need is as every 10 vouchers pass, ( ex : if count % 10 == 0 : )
I need a token. I wouldn’t mind the tokens to be repeated but not immediately.

How I would need it is,

every 10 numbers,
A,

next 10,
B,

so on …
C, D, E, F, G, H, I, A, B, C, D, E, F, G, H, I, A, B, C, D, E, F, G, H, I, A, B, C, D, E, F, G, H, I…

So the above should get selected one at a time every 10 vouchers. I wouldn’t mind the 9 characters in token getting shuffled or randomized as far as the same tokens don’t appear before all are done for once.

Thank you.

What have you tried so far? Approach with (if count % 10 == 0) looks like something that would solve part of the problem. What else it would need? What do you suspect might work?

What I tried so far.

Every 10 vouchers I am using this, >> if count % 10 == 0

And tried to “random.choice” the Tokens.
Unfortunately this returns a Token sometimes like >> B, C, C, D, E, I, E, E, E etc.

Then I tried,
01.
to assign a variable to “random.choice” and
either “token.remove” or
02.
“new_token.append” to add them later after as the list is finished.

due to my poor knowledge in coding all of these attempts fell apart. :sweat:

to add further,

How I see it working is to,

  1. Remove the selected “random.choice” everytime it get’s selected from the Main List and write them to a New List,

  2. If the Main List = 0 Items, we pull the items from the New List and do the same thing again and again until the vouchers run out. :tired_face:

That does seem reasonable. What’s your code so far?

Hi,

I deleted the mess I coded,

A sample would be a great favor if possible so that I can configure it to my List and codes. :slight_smile:

I can help you with making it work, I won’t write it for you.

Try from the fresh then, knowing what doesn’t work is also an advantage.

The issue is I watched 02 youtube videos and realized we can use the append to new list and remove the choices.
But I do not understand how to put them together in a running loop :sweat:

Hi,

I somehow managed to go through some posts online and write this piece of Code.

Function :

def tokenFeed_without_repetition(tokenList):

    i = 0

    while True:

        i = (i + random.randrange(1, len(tokenList))) % len(tokenList)

        yield tokenList[i]

Usage :

    # Token List below
    tokenList = ["10 $","13 $","17 $"]

    for token_of_choice in tokenFeed_without_repetition(tokenList):
           Some Functions here with if's and elifs...

Notes : ( for anyone interested on the solution I found so far )

01. I used "break" to stop the "for loop" in usage as one gets picked.
02. This "doesn't solve the issue, but helps to stop the repetition of the same element. The below example issue is avoided by the above method.
ex : B, C, C, D, E, I, E, E, E etc.

I think you’re on the right track of thinking with your current function.
I would like to point out one thing regarding this comment.

It would seem that your main loop of concern is actually in regard to vouchers and not tokens. Your function tokenFeed_without_repetition uses the yield syntax and would be considered a generator function. You can use them in for loops to yield some value each iteration, alternatively you can use the next() syntax to yield the next value from the generator without having to stick the function in a for loop at all. This would allow you to simplify things to only one for loop (the loop over vouchers).

For example:

import tokenFeed_without_repetition
from random import sample   # only needed for the example vouchers 

# I don't know what form your 'vouchers' will take and won't
# assume they're inherently ordered integers.
# As an example we'll construct a list of 100 'vouchers'
# where each voucher is a string of 4 random letters ('fgyr', 'hsyt')
# that we can later iterate over with enumerate()
vouchers = ["".join(sample('abcdefghijklmnopqrstuvwxyz', 4)) for _ in range(100)]

token_list = ["10 $", "13 $", "17 $"]

# this initializes the generator function, without using it in a for loop,
# as the variable token_feed. Every time we need to retrieve the
# next value in the generator we can use next(token_feed) to get it.
token_feed = tokenFeed_without_repetition(token_list)

for index, voucher in enumerate(vouchers):
    if index % 10 == 0:
        token = next(token_feed)
        print(f"The current voucher is: {voucher}, with the token: {token}")

# prints something like this:
# The current voucher is: flwe, with the token: 13 $
# The current voucher is: afsk, with the token: 17 $
# ...

Hi,

First and Foremost Thank you very much for your feedback.

But somehow I am lost trying to understand your reply.

My issue is as follows.

Let’s assume a scenario.

  1. I do not need to generate Voucher Numbers. We already have them from the system which we have given to the Customers.

Voucher numbers get’s fed through a list.

Ex : V/2021/JAN/0000001 etc.

But for each Vouchers we give Tokens to our customers.

So we need the Token Value for every 10 Vouchers.

Voucher List = [V/2021/JAN/0000001,V/2021/JAN/0000002,V/2021/JAN/0000003,V/2021/JAN/0000004,V/2021/JAN/0000005,V/2021/JAN/0000006,V/2021/JAN/0000007,V/2021/JAN/0000008,V/2021/JAN/0000009,V/2021/JAN/0000010,V/2021/JAN/0000011,V/2021/JAN/0000012,V/2021/JAN/0000013,V/2021/JAN/0000014,V/2021/JAN/0000015,V/2021/JAN/0000016,V/2021/JAN/0000017] …so on,

Every 10 Vouchers I need a Token. Tokens range from 5 USD - 1000 USD. Over 500 Tokens. Imagine 2, 3 gets generated every now and then on a value of 1000 USD? It’s a problem right.

So we want them to work in a sequence we can control it.

So Let’s assume our token List is of 05 for this example.

Token List = [5,10,15,20,25]

So,
every time a voucher goes through count becomes,

Count = Count + 1

and,

if count % 10 == 0 ( which means every 10 Vouchers )

I need a Token.

All I need is to tokens to generate within the given 5, one token at a time instead of two occurrences of 25 USD, But after the 5 tokens had got printed randomly, this has to occur again.

So the final result would be like,

V/2021/JAN/0000001
V/2021/JAN/0000002
V/2021/JAN/0000003
V/2021/JAN/0000004
V/2021/JAN/0000005
V/2021/JAN/0000006
V/2021/JAN/0000007
V/2021/JAN/0000008
V/2021/JAN/0000009
V/2021/JAN/0000010

Now the if count % 10 == 0 kicks in to spit a token ( ONE TOKEN ) out of the 5, I want the 5 to be random but not to have the same one again until 50 Vouchers have gone through,

V/2021/JAN/0000011
V/2021/JAN/0000012
V/2021/JAN/0000013
V/2021/JAN/0000014
V/2021/JAN/0000015
V/2021/JAN/0000016
V/2021/JAN/0000017
V/2021/JAN/0000018
V/2021/JAN/0000019
V/2021/JAN/0000020

Now the if count % 10 == 0 kicks in >>> AGAIN <<< to spit a token ( ONE TOKEN ) out of the 5, But this time I want to avoid the last one for sure.

after Voucher 30, I want to avoid last 02 random occurrence’s.

When the list is empty and nothing is left to generate, I want the List to fill in with all tokens again, which would happen at the Voucher No. 60.

Hope this helps.

Sorry for all the typing.

Thank you again. :slight_smile:

Unfortunately, this doesn’t work for me, or whatever I assumed it to be. Still this generates same token again and again immediately.

Just to cement the requirement,

from how I see a solution to this would be to create a function to run every 10 counts of vouchers.

What I think the function might do;

  1. Check if the “New List items” are ZERO to pull in Tokens from “Main List”.
  2. Check If Items are Not ZERO, or ZERO ( As the 1st instance would be ZERO items in “New List”, the function will write all Items to the “New List” from “Main List”)
  3. It will generate a random Token from Token List
  4. Save it in a Variable ( then I will Print it from there :slight_smile: )
  5. Remove that Random Token from the existing List
  6. Write the Rest of the token items to a New List to Preserve the Main List.

then the count goes again printing us the voucher numbers from the list, once another 10 goes through.

The above 6 Steps happen again. :slight_smile:

These 02 Videos below made me understand this could be the answer.

But the function is too complex to write by myself for the little knowledge I have.

Video 01 .

Video 02.

Hope this helps if someone wishes to give me a hand.

Many thanks again to all of you.

Bro,

any advise would be highly appreciated. :slight_smile:

These tutorials would appear to provide you with what you need for your task (at least from what I understand anyway). The only real difference between what is demonstrated in these videos and the function you wrote earlier is that your earlier function is a special kind of function in Python known as a generator.

I’ll write a generator function using the shuffle method from the random library. Try rewriting it using the random index method from that first video (using randint to produce a random list index instead of shuffling a copy of the master list).

from random import shuffle

def token_generator(master_token_list):
    """
    Every time the next() function is called on
    the generator object do these things:
        1. Check if the current token list is empty
        2. If the current token list is empty, make a copy of the
           master token list and shuffle it
        3. Remove the last token from the current token list and return it
    """
    current_tokens = []
    while True:
        if len(current_tokens) == 0:
            current_tokens = master_token_list.copy()
            shuffle(current_tokens)
        yield current_tokens.pop()

Usage

vouchers =  # Use your voucher list
tokens = # Use your token list
token_feed = token_generator(tokens)

for count, voucher in enumerate(vouchers):
    if count % 10 == 0:
        token = next(token_feed)
        # Do whatever you need to do with the voucher and token

This method (and the videos you posted) are using a form of selection often referred to as “random selection without replacement”. There are a multitude of ways to implement it in code and I would highly recommend looking the term up to see other implementations and how it differs from methods “with replacement”. While I think this is what you’re going for, I will note that it isn’t perfect. Most of the time, you won’t have any tokens directly repeating one another so long as your tokens are all unique. However, there’s always a random chance the last item from the shuffled list and the first item from the newly copied and shuffled list are the same. The probability of directly repeating tokens is inversely proportional to the length of the token list. The more tokens in the master list, the less likely you are to have direct repeats.
Next, I would ask yourself how the generator function could be altered to handle this edge case and remove any possibility of directly repeating tokens.

1 Like

Thanks a lot brother.
I am very new to python and I am still studying the basics.

I will carefully read through everything you’ve mentioned in detail and see the test results. Thanks a lot again for helping me in.

Have a blessed day mate. :muscle:

:heart_eyes: :heart_eyes: :heart_eyes: :heart_eyes: :heart_eyes:

Buddy Good Day to you from where ever you may be,

Thanks a lot Buddy I just tested this today and it worked.
I understood your explanation and thanks again for teaching me how it worked.

Sorry for my late reply because I didn’t have the time to test this leisurely.
Today I managed and succeeded.

Thank you very much again for your support.

May Guidance be upon you at all time as well.

Do Tc.

Unfortunately couldn’t find a method to tackle the edge case, nevertheless it does meet my requirement, that is the number of tokens we have shouldn’t repeat within one set of Batch of vouchers.

We can do something like .

  • While generated token first time for 10 voucher, keep that token in user defined param.
  • Next time (Second slot) , check if param contains next random picked token. If yes ==> pick again next token and store in param. If no ==> replace param value with token received,
  • Next iteration do same …

Explained what i understand with Question. Sorry if I missed something.

Might help some of following article for looping

docs

for loop two param

here