Sign in to follow this  
Sacred

Python, random

Recommended Posts

Hey! I got this exercise from Michale D.'s book for Python Newbies like me. In an old chapter, I was asked to make it possible to print something randomly but with no repeats. I skipped it, but now I want to know how... And I can't figure it out! I'm yet crappy at Python programming and I can't seem to figure out, how to make all words in 'WORDS' print without any repeats - and it should be in random order. Heres the code: --- # Chapter 5, exercise 1 # Place words in random order with no repeats import random WORDS = ("ARRRR", "Work", "God", "Dammit") tester = [] loop = 0 while loop != 4: word = random.choice(WORDS) if word not in tester: print word loop += 1 raw_input("\nPress enter to exit.") --- Can someone please explain to me, how to do this? :) Best regards, Sacred

Share this post


Link to post
Share on other sites
You use tester as a list to keep 'used' words in.

But then you never add words to tester, so it never remembers the words you've used. Doh!


Once you've fixed that, you can attempt a better approach without using such a list, or a counter. The only hint I'll give you is that there's another function in the random module that is well suited to this particular problem.

Share this post


Link to post
Share on other sites
Whops, forgot to post the new code. And I'll look into the other function :D

But if I say something like:
---
# Chapter 5, exercise 1
# Place words in random order with no repeats
import random

WORDS = ("ARRRR", "Work", "God", "Dammit")
tester = []

loop = 0

while loop != 4:
word = random.choice(WORDS)
if word not in tester:
tester.append(word) # New line
print word
loop += 1

raw_input("\nPress enter to exit.")

---

It'll just freeze and sees no error. Neither do I, but I guess it has to be something with my code adding the word to the list 'tester'?

EDIT: I guess you mean the .shuffle() function? :) That one looks cool to me.

Share this post


Link to post
Share on other sites
A couple things.

First, you force the loop to run exactly four times. Each time through the loop, you ask for a random choice out of the four available words. What if you get one of the words twice, or, bizarrely, three times? You'll only get a fraction of the available words.

Your code works. I tested it. It's just not robust.

random.shuffle shuffles a list in place. You can then iterate over a list and print each element. However, I presume the exercise wants you to perform the shuffle by yourself. I'll give you two hints:
>>> l = [1, 2, 3, 4]
>>> for i in l: print i
...
1
2
3
4

and
>>> l = [1, 2, 3, 4]
>>> print l
[1, 2, 3, 4]
>>> l.remove(3)
>>> print l
[1, 2, 4]

Those should give you an idea of how to perform a manual random selection in robust fashion.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sacred

while loop != 4:
word = random.choice(WORDS)
if word not in tester:
tester.append(word) # New line
print word
loop += 1

raw_input("\nPress enter to exit.")



You could hit a bad patch of random numbers and keep getting the same word or three forever. why not limit random's choices instead of filtering?

Share this post


Link to post
Share on other sites
Yeah, sorry, I'm really new to this Python code yet :P First of all, I wanted it to make sure they were printed randomly and also make sure, that they wouldn't get printed more than once. But I can't figure the way to make a for loop print a string instead of the number of the element. But it's really helpful - I'll try read on :) If you didn't mention the other functions I don't think I would've seen them before I opened up another more advanced book and realized, that my current only taught me the basics. And the for loop seems very clear for such thing. I never though loops would be so much apreciated before the bigger programs. And I'm really just talking about those premade source codes, that I'm rewriting - which is small pieces of junk ;p I wouldn't dare think of a real program...

Thanks!


Best regards,

Sacred :)

Share this post


Link to post
Share on other sites
In Python and many other languages, for statements iterate over sequences. What this means is that instead of using the contrived syntax:
for(index = start; index < end; index += step) {
manipulate(sequence[index]);

to manipulate the elements of a sequence (like an array/list or tuple or dictionary or string), you can simply do:
for item in sequence:
manipulate(item)

This is one of the many ways that having a richer object and type system leads to more compact, expressive code (albeit at the potential penalty of performance decrease).

Your entire program is simple:
import random

words = ['a', 'boy', 'came', 'down', 'expecting', 'fly', 'girls', 'here']
random.shuffle(words)
for word in words:
print word
words.remove(word) # this ensures each word only occurs once

That's it. Study that and figure out what it does and the implications, and congratulations on picking a sensible language! [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
Your entire program is simple:
import random

words = ['a', 'boy', 'came', 'down', 'expecting', 'fly', 'girls', 'here']
random.shuffle(words)
for word in words:
print word
words.remove(word) # this ensures each word only occurs once



This is incorrect. If you remove from the same list you are iterating over it will skip the next element. How about this:
import random

words = ['a', 'boy', 'came', 'down', 'expecting', 'fly', 'girls', 'here']
random.shuffle(words)
while words:
print words.pop()


The pop() method both removes and returns the last element. Since I'm using a while loop there are no skips.

Share this post


Link to post
Share on other sites
Thanks! I was wondering what the .pop() really did, but I didn't dare figure it out :P Seems like I made it kinda too big - and you could just do it like this? And yes, I love this language. C++ took so much of my time so I wanted to try out something like this - and I really wanna go further with Python :)


Best regards,

Sacred

Share this post


Link to post
Share on other sites

Upon further reflection you don't even need to remove anything. random.shuffle() take care of it...if you do a regular for loop there's no chance it will accidentally "back up" and repeat the same word. As usual, there are myriad different ways of doing the same thing.

Most of my Python self-education has been done by reading the docs (they are online at python.org but also bundled in a help .chm file in my Windows install) and then testing things out in the command-line interpreter. Based on something I read in the manual, I make a prediction about what a line of code should do. I then type it into the interpreter and see if I was right or wrong. I repeat with varying values, types, etc. to see if I fully understand.

Share this post


Link to post
Share on other sites
Yeah, that would be an example of confusing two approaches to fixing the problem.

When you random.shuffle() the list, it's already shuffled. You can just go through and print each thing, and there will be one of each, in a random order. That's what shuffle() does.

If you want to shuffle by yourself, the idea is to, each time, randomly select one of the remaining things, and then remove it from the list. As it happens, we have a direct way to select something from a list: random.choice(). We don't need to generate an index and then index into the list.


hat = ['a', 'boy', 'came', 'down', 'expecting', 'fly', 'girls', 'here']

while hat: # This implicitly means "while the list is not empty".
word = random.choice(hat) # Randomly pull a word out of the hat,
print word # display it,
hat.remove(word) # and actually *pull it out* of the hat. ;)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this