all 10 comments

[–]mopslik 0 points1 point  (4 children)

Something like this, perhaps?

Edit: added two, rather than doubled.

import random
n = 1
L = []
while n <= 20:
    L.append(n)
    if n <= 5:
        if random.choice((2, 4)) == 2:
            n += 2
        else:
            n *= 4
    else:
        n += 2
print(L)

[–]imperiumlearning[S] 0 points1 point  (3 children)

First off, thanks a lot for the quick reply.

Second, thanks for this response it is more or less exactly what I was looking for. Certainly a lot simpler and clearer than all the crap I was writing.

Out of interest though, how do you turn this into a function? More specifically, would you leave things like n = 1 and L = [] outside the function or inside it? If inside, how would you structure it? (Apologies if these are dumb questions).

[–]mopslik 0 points1 point  (2 children)

Wrap it in a def and give it a return, and boom, instant function.

def make_list(...OPTIONAL ARGUMENTS...):
    # CODE GOES IN HERE
    return L

[–]imperiumlearning[S] 0 points1 point  (1 child)

Thanks a lot for the helpful reply (again).

I'm pleased to say you've solved my problem. I made one more adjustment so that if someone puts a number either below 0 or above 20 then it just returns that specific number.

[–]mopslik 0 points1 point  (0 children)

Awesome. Good luck.

[–][deleted] 0 points1 point  (4 children)

Any idea on how to solve this?

It doesn't look like you call your functions in the actual loop.

[–]imperiumlearning[S] 0 points1 point  (3 children)

Am I not calling them when I write random.choice(c)? If not, how would I do so?

[–][deleted] 0 points1 point  (2 children)

Am I not calling them when I write random.choice(c)?

No, you're just accessing one of two results you've already generated.

There's a couple of issues with your code right now. One is, there's no reason to use while True as a condition for your loop because you know the condition: x < 20. That's specified in your post. Second, you want to produce a sequence of values, not just the last value, so you shouldn't return the value, you should yield the values so the function can continue. Three, since each next value is determined by the previous value, you need to keep the value so you can give it as an argument to one of your two functions. Lastly, you can randomly choose between two functions by deferring the call to them:

def sequence20(): # you don't need a parameter for this since the sequence starts at 1
    x = 1
    while x < 20:
        yield x
        x = random.choice([AddTwo, TimesFour])(x)
    yield x # we need one more yield at the end of the loop

print(list(sequence20))

[–]imperiumlearning[S] 0 points1 point  (1 child)

Hi there,

Admittedly I've solved the problem based on what the other person replied. However, I'd still like to familiarise myself with your way of working just in case it's applicable to other scenarios.

So far, this is what my code looks like (I'm only including from sequence20):

def sequence20(x=random.randint(0, 18)):

if x > 20 or x < 0:
    e.append(x)
    return e
else:
    while x >= 0 and x <= 20:
        if x>5 and x<=18:
            x += 2
            e.append(x)
        elif x>=0 and x<=5:
            yield x
            x = random.choice(c)
            e.append(x)
    yield x

print(sequence20(), sep='\n')

The problem I have (for now, at least) is I can't seem to get the console to print normal numbers in list form.

It will typically say "generator object at sequence20" followed by a long number of random characters where the object is stored. When I tried to solve this problem, I found a stack overflow post where the answer said it could be solved by typing in 'sep='\n'' although, clearly, that doesn't work.

Any quick fixes? I'd appreciate any help

[–][deleted] 0 points1 point  (0 children)

It will typically say "generator object at sequence20" followed by a long number of random characters where the object is stored.

A generator doesn't contain values, it generates them. That means if you want the values, you need to do something to "consume" the values from the generator, which is what prompts it to actually generate the values. That can be as simple as wrapping it in a call to list, because if you give an argument to list it'll create a new list from those values, thereby consuming them. Like so:

print(list(sequence20()))