1

I would like to generate random numbers with a specific restriction using python. The code should do the following:

If an entered number is:

0, then generate 0 random non-recurrent numbers
<1, then generate 1 random non-recurrent numbers
<9, then generate 2 random non-recurrent numbers
<15, then generate 3 random non-recurrent numbers
<26, then generate 5 random non-recurrent numbers
<51, then generate 8 random non-recurrent numbers
<91, then generate 13 random non-recurrent numbers
<151, then generate 20 random non-recurrent numbers
<281, then generate 32 random non-recurrent numbers

The value of the random numbers should be limited by the value of the entered number. So if a 75 is entered, then the code should generate 13 random numbers with being 75 the highest value of the 13 numbers. 75 doesn't have to be the actual highest number, just in terms of max value.

My guess was to use numpy. Here is what I got until now (with an users help).

num_files=[0,1,9,...] num_nums=[0,1,2,3,5,...] for zipp in zip(num_files,num_nums) if len(docx_files)<zipp[0]: list_of_rands=np.random.choice(len(docx_files)+1, zipp[1],replace=False) 

Any ideas or more starting points?

10
  • 2
    I'm not sure I understand the series. What equation or rule determines how many random numbers you need? Commented Jan 5, 2018 at 17:43
  • It's set by me. I want to use the following rules: if the number is 0 then generate 0 random number, if its 1 then generate one, if its <9 then 2, if its <15 then 3, if <26 then 5, if <51 then 8, if <91 then 13, if <151 then 20, if <281 then 32. Commented Jan 5, 2018 at 17:47
  • Too bad, I really had hoped it was linked to the Fibonacci sequence. Commented Jan 5, 2018 at 17:48
  • Maybe use a dictionary as an adhoc switch statement to clean up multiple if clauses. How many if cases are you going to have? Commented Jan 5, 2018 at 17:50
  • 1
    How do you generate the pairs of numbers? Why (26, 5), (51, 8)? What's the function? Commented Jan 5, 2018 at 17:52

7 Answers 7

1

Here's one way of doing it. Just zip the lists of numbers and the cutoffs, and check if the number input (the variable number in the code below) is above the cutoff. Note that this doesn't handle the case of numbers larger than 281, since I'm not sure what's supposed to happen there based on your description.

import numpy as np number = 134 parameters = zip([9, 15, 26, 51, 91, 151], [3, 5, 8, 13, 20, 32]) nums = 2 for item in parameters: if number > item[0]: nums = item[1] np.random.choice(number, nums) 
Sign up to request clarification or add additional context in comments.

Comments

1

You could define a function using a dictionary with ranges as keys and number of random numbers as values:

import random def rand_nums(input_num): d = {26: 5, 51: 8, 91: 13} for k, v in d.items(): if input_num in range(k): nums = random.sample(range(k+1), v) return nums print(rand_nums(20)) print(rand_nums(50)) print(rand_nums(88)) [14, 23, 11, 9, 5] [9, 49, 23, 16, 8, 50, 47, 33] [20, 16, 28, 77, 21, 87, 85, 82, 10, 47, 43, 90, 57] >>> 

Comments

1

You can avoid a many-branched if-elif-else using np.searchsorted:

import numpy as np def generate(x): boundaries = np.array([1, 2, 9, 15, 26, 51, 91, 151, 281]) numbers = np.array([0, 1, 2, 3, 5, 8, 13, 20, 32]) return [np.random.choice(j, n, False)+1 if j else np.array([], np.int64) for j, n in np.broadcast(x, numbers[boundaries.searchsorted(x, 'right')])] # demo from pprint import pprint # single value pprint(generate(17)) # multiple values in one go pprint(generate([19, 75, 3, 1, 2, 0, 8, 9])) # interactive i = int(input('Enter number: ')) pprint(generate(i)) 

Sample output:

[array([ 9, 1, 14, 4, 12])] [array([ 8, 12, 6, 17, 4]), array([17, 29, 2, 20, 16, 37, 36, 13, 34, 58, 49, 72, 41]), array([1, 3]), array([1]), array([2, 1]), array([], dtype=int64), array([1, 8]), array([3, 2, 6])] Enter number: 280 [array([184, 73, 80, 280, 254, 164, 192, 145, 176, 29, 58, 251, 37, 107, 5, 51, 7, 128, 142, 125, 135, 87, 259, 83, 260, 10, 108, 210, 8, 36, 181, 64])] 

1 Comment

That works fine! How could I exclude the output 0? For instance, if the input is "2", then it gives me "0, 2". I want to use only numbers ranging from 1-9. And how could I add an input option, so that I can enter in the shell a number and then the code generates the random numbers?
0

How about:

def gen_rand_array(n): mapping = np.array([[1,1], [26,5], [51,8], [91,13]]) k = mapping[np.max(np.where(n > mapping[:,0])),1] return np.random.choice(n+1,k) 

Example:

>>> gen_rand_array(27) array([ 0, 21, 26, 25, 23]) >>> gen_rand_array(27) array([21, 5, 10, 3, 13]) >>> gen_rand_array(57) array([30, 26, 50, 31, 44, 51, 39, 13]) >>> gen_rand_array(57) array([21, 18, 35, 8, 13, 13, 20, 3]) 

Here's a screen shot putting it all together:

enter image description here

Explanation:

The line k = mapping[np.max(np.where(n > mapping[:,0])),1] is just finding the number of random values needed from the array mapping. n > mapping[:,0] return a boolean array whose values will be True for all the numbers smaller then n, False otherwise. np.where(...) will return the indexes of the elements of the array that are true. Since the values in the first column of mapping (i.e. mapping[:,0]) are ascending, we can find the index of the largest one that is less than n be calling np.max(...). Finally we want the corresponding value from the second column which is why we pass the result of that as an index to mapping again i.e. mapping[...,1] where the 1 is for the second column.

4 Comments

Sorry so far, I am absolutely newbie in programming and Python (just started 2 weeks ago). So I am not sure to understand your code completely. But I think this is the most promising way. I am just struggling with applying this code to get the results you have shown in example. I now I need to add "import numpy as np" and I need to add "print(...)", but I am not sure what do add in the brackets. And I also need an input option, or?
ok I tried to add "gen_rand_array(27)", but it doesn't produce an output.
Sorry, yes you'll need to import numpy as np then run the code with the function definition i.e. my first code block about. Then you can try print(gen_rand_array(27)). It should produce an output...
@Thegreatlord I've added an explanation as well
0

I don't know how to implement it in your code but with this code you then you get the randoms:

import random x = 51 if x < 26: ar_Random = [None]*5 for i in range(0, 6): ar_Random[i] = random.randint(startNumOfRandom, stopNumOfRandom) elif x < 51: ar_Random = [None]*8 for i in range (0,9): ar_Random[i] = random.randint(startNumOfRandom, stopNumOfRandom) ... 

Comments

0

I'm not sure how you're mapping the length to the input but this is how you generate N random numbers with a maximum using Numpy.

import numpy as np //set entered_num and desired_length to whatever you want random_nums = np.random.randint(entered_num, size = desired_length) 

Comments

0
import random Starting_Number = int(input()) if Starting_Number < 26: print(random.sample(range(1, 26), 5)) elif Starting_Number < 51: print(random.sample(range(1, 51), 8)) elif Starting_Number < 91: print(random.sample(range(1, 91), 13)) 

Here you go!!!

random.sample is the module you are looking for.

Have a good one!

1 Comment

That's pretty good! The only problem is that it generates beyond the max value. My aim was: (1) If the starting number is e.g. 44, then 8 random numbers should be generated, because my rule says "if the number is <51, then generate 8 random numbers. But the highest value of these 8 numbers is determined by the starting number, and thus when using 44, the random numbers should be like: 2, 14, 13, 28, 34, 38, 9, 43 (with being the highest number 43; all numbers above the starting number are not allowed).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.