[Python]rand # generator - over complicated?

Started by
9 comments, last by kevtimc 17 years, 6 months ago
Before I begin, let me assure you this example is not homework of any kind, it comes from the "How to Think Like a Computer Scientist: Learning with Python" book by Allen B. Downey, Jeffrey Elkner and Chris Meyers. First of all, here's the exercise, Generate a random number between low and high. This particular chapter (#9) was about tuples, but I think he got off track with random number explainations [lol]. Anyways, my program works correctly, and has some error checking in it (checks if low == high, or if low > high [and switches the values with tuples]). Here is the code:
import random 
   
def randgen(low, high):
    if low > high:
        low, high = high, low
    if low == high: # if they are equal...
        print high # there is only one choice
        return
    x = random.random() # declare x 
    while (x * high) < low or (x * high) > high: # if its less than low or more than high...
        # re-declare it
        x = random.random() * high
    print x * high # if the while loop exits, we knows it between low and high
    return
        
randgen(2, 1)
randgen(1, 2)


I'm actually a bit proud of myself for making this without any outside help (I usually have trouble with problem-solving [grin]). My question is, plain n' simple, is my program over-complicated? Thanks to those willing to help.
Advertisement
Quote:Original post by kevtimc
My question is, plain n' simple, is my program over-complicated?

Yeah. Its a good first attempt, though, so you can continue to be happy [grin]

A hint for how to remove the loop: You've already figured out that random()*high will give you a number between 0 and high. What range does random()*high + 10 result in?

CM
Quote:Original post by Conner McCloud
A hint for how to remove the loop: You've already figured out that random()*high will give you a number between 0 and high. What range does random()*high + 10 result in?

CM


A random number between 0 and high plus 10? [wink] Let me think on this some more.

Quote:Original post by kevtimc
Quote:Original post by Conner McCloud
A hint for how to remove the loop: You've already figured out that random()*high will give you a number between 0 and high. What range does random()*high + 10 result in?

CM


A random number between 0 and high plus 10? [wink] Let me think on this some more.

Hold that thought. Unless Python has some crazy operator precedence rules that I'm unaware of, you may want to take another look at that formula. Note the difference between
random()*high + 10
and
random() * (high + 10)

Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Quote:Original post by TheAdmiral
Quote:Original post by kevtimc
Quote:Original post by Conner McCloud
A hint for how to remove the loop: You've already figured out that random()*high will give you a number between 0 and high. What range does random()*high + 10 result in?

CM


A random number between 0 and high plus 10? [wink] Let me think on this some more.

Hold that thought. Unless Python has some crazy operator precedence rules that I'm unaware of, you may want to take another look at that formula. Note the difference between
random()*high + 10
and
random() * (high + 10)

Regards
Admiral


I understand this, and have tried many different times, still trying to come up with a solution.
Typically rather than trying to correct the inputs to a function like this it is better to specify preconditions and assert that they are correct. High really should be greater than low, and its the callers responsibility to make that true, but we should check it (but we shouldn't have to fix it).

For the rest, you might want to think about this problem on a number line. What operations do you need to do to the *range* to shift it into the correct position
Here, let me take a shot at explaining.

1. I have an opaque container of water which can hold up to 1L. It contains some amount of water from none at all up to 1L. (We'll say for the sake of argument that it's weighted in such a way that I can't tell how much there is until I open the container, which I'm not doing yet.) Now you give me another container with a known .5L quantity of water.

Between the two containers, what is the smallest amount of water I could possibly have? The largest amount?

2. There is a shelf with several containers on it similar to the one from (1): each contains some quantity of water from 0 up to 1L, each completely random and independant of each other. There is also a tap from which I may pour out a known, measured quantity of water (let's say that some computer-controlled apparatus lets me pour out an exact amount according to my specification.) I want to repay you in kind by giving you a quantity of water that is somewhere between .5L and 1.5L, but such that neither of us knows exactly how much (immediately).

How can I do this? Having done it, how do you find out how much water you ended up with?

3. The same, except now I want to give you between N and N+1 litres of water, for whatever reason.

4. The same as (3), except now instead of a shelf, there is a clerk who I can ask for a water-container that holds X litres, and he'll give me a bottle that could hold up to X litres, and indeed contains somewhere from 0 up to XL of water, but noone knows exactly how much until the container is opened.

Between the clerk and the tap, how can I give you between N and N+X litres of water?

5. Only slightly different: how can I give you between A and B litres of water, knowing that? (I.e., solve for N and X in terms of A and B, then apply the previous method.)

6. A container is like the random function. Opening the container is like calling the function. A quantity of water is like a value returned by the function.
Thanks for the help all, I got the answer, low + (low * x). My explaination: say we have 2 low and 4 high. Low * 0.00001 will equal a bit more than 0, + 2 will bring the number in range. If x = 0.999, (low * x) will be a little less than 2, plus the 2 will keep it in range and close to 4, huzzah! [cool]

EDIT: Nvm, it's wrong =(
Zahlman:
1.) .5 - 1.5 L
2.) This kinda seems like the problem I'm trying to solve now, which I haven't found an answer to yet =P
3 - 6 I can't do without knowing number 2
Quote:Original post by kevtimc
2.) This kinda seems like the problem I'm trying to solve now, which I haven't found an answer to yet =P


It is, and it's key to understanding. I can't just answer this for you because you won't really understand unless you work it out for yourself.

Look very carefully at questions 1 and 2 next to each other and note similarities.

This topic is closed to new replies.

Advertisement