Repeated Random Numbers - python

I have created a bingo game where random numbers are generated and called for a list.
bingo_num = random.randint(1,100)
How would I stop a random number being generated more than once

I would suggest, random.shuffle
from random import shuffle
my_list = range(100)
shuffle(my_list)
print my_list
But if you need only specific amount of unique numbers, you can use random.sample, like this
from random import sample
my_list = range(100)
print sample(my_list, 10)

You can take a sample of a range from the random library
>>> import random
>>> nums = random.sample(range(0,200),100)
>>> nums
[143, 149, 52, 183, 161, 179, 180, 155, 163, 157, 139, 15, 154, 181, 56, 29, 31,
14, 77, 82, 165, 32, 35, 92, 109, 172, 69, 99, 54, 3, 88, 76, 11, 126, 78, 162,
198, 145, 124, 75, 114, 174, 136, 100, 190, 193, 148, 153, 167, 113, 38, 17, 16
8, 0, 196, 73, 47, 164, 184, 6, 140, 30, 58, 74, 4, 79, 147, 178, 191, 21, 112,
13, 27, 57, 199, 116, 28, 104, 111, 71, 23, 85, 170, 25, 141, 156, 91, 7, 182, 1
34, 94, 169, 175, 166, 137, 160, 129, 36, 67, 135]

Just do it the same way they do it in a real Bingo game. They do not roll dices, but put all the numbers in a big bag, shake it, and pull out numbers one at a time, until all the numbers are used up.
numbers = list(range(1, 101)) # all the numbers in the bag, from 1 to 100
random.shuffle(numbers) # shake the bag
bingo_num = numbers.pop() # pull out next number (inside your loop)

You could first create a list containing all possible numbers. Then pick a random number from that list, add that to a result list and finally remove it from the list of possible numbers.
For example if you want 5 different numbers from 0-9:
possible_numbers = range(10)
numbers = []
for i in range(5):
index = random.randint(0, len(possible_numbers) - 1)
numbers.append(possible_numbers[index])
del possible_numbers[index]

Something like this should work:
numbers = []
while len(numbers) < 100:
bingo_num = random.randint(1,100)
if not bingo_num in numbers:
numbers.append(bing_num)

You could just create a new number if already in use
advantage: easy code
disadvantage: will run long if nearly all numbers are use (there are better solutions)
Sample code:
bingo_num_list = []
# init num
bingo_num = random.randint(1,100)
# create new numbers till "find" a not used one
while bingo_num in bingo_num_list:
bingo_num = random.randint(1,100)
bingo_num_list.append(bingo_num)

Build list of all the numbers then select a random 1, remove it from the list then select the next one:
#!/usr/bin/python
import random
myNumz=[]
xIdx=1
while xIdx<101:
myNumz.insert(xIdx,xIdx)
xIdx+=1
xIdx=100
while xIdx>0:
xIdx-=1
baseNum=random.randint(0,xIdx)
print myNumz[baseNum]
myNumz.remove(myNumz[baseNum])

Related

how to take values out of a list to an array in python?

My Data This picture shows my data. See this: [1, 0,list([32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110,....], I want this data to be like : [1,0,32,64,117,115......]. I want data out of the list and become a member of the array. How can I do this easily and quickly? I have tried a long method but there are many errors. The method I have tried: Take data out of the list one by one and append in the particular row then move to the next data row and do the same thing there for the list.
you can try something like this :
`for i in range(len(data)) :
data[i][2].insert(0,data[i][1])
data[i][2].insert(0,data[i][0])
data[i].pop(1)
data[i].pop(0)`
You could do something like below.
We iterate through the given list, checking each type. If an element is a type list we will iterate through that and append each of those elements to a list called new. If an element we have iterated through in the given list is a type != list then we can directly append the element to new.
x = [1, 0,list([32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110])]
new = []
for num in x:
if type(num) == list:
for num2 in num:new.append(num2)
else:new.append(num)
You can flatten this jagged nested array with numpy.hstack() as follows:
import numpy as np
original = [1, 0,list([32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110])]
f = np.hstack(np.array(original, dtype=object)).tolist()
print(f)
#[1, 0, 32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110]
Let first consider this example
# lets take this example value for data
data = [1, 0,list([32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110])]
print("data before modification:", data)
print()
extract_items = data.pop(2) # Since in the picture, the inner list is always the third element we can use the index 2
for item in extract_items: # loop through the inner list and append items to outer
data.append(item)
print("extract_items", extract_items)
print("data", data)
**output for example case: **
data before modification: [1, 0, [32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110]]
extract_items: [32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110]
data: [1, 0, 32, 64, 117, 115, 101, 114, 32, 119, 104, 101, 110]
Which is what we would like.
Thus, the Final Solution:
for element in data:
extract_items = element.pop(2)
for item in extract_items:
element.append(item)

Reverse-engineering conditional output for a function definition

I have defined a function to generate a list of prime numbers less than or equal to a given input which you can specify, based on the sieve of eratosthenes.
def eratosthenes(max_num):
primes = list(range(2,max_num+1))
for i in primes:
j=2
while i*j<= primes[-1]:
if i*j in primes:
primes.remove(i*j)
j=j+1
return primes
Now, if I wanted to find out which prime would be the 50th in the list, such that
len(primes) = 50
How would I go about this? Is it possible to reverse-engineer a defined function in this way?
You will get the 50th value from the list just with eratosthenes(300)[49]:
def eratosthenes(max_num):
primes = list(range(2,max_num+1))
for i in primes:
j=2
while i*j<= primes[-1]:
if i*j in primes:
primes.remove(i*j)
j=j+1
return primes
print(eratosthenes(300))
print(eratosthenes(300)[49])
which will yield
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293]
229
The counting of indices starts from zero, therefore 50th value can be extracted with list index value 49.
Then if you would like to limit then length of the list to 50, you may reverse-engineer by calling the function many times until the condition is met:
i = 2
while True:
primes = eratosthenes(i)
if len(primes) >= 50:
break
i = i + 1
print(i)
print(len(primes))
print(primes[49])
which yields
229
50
229
Why don't you call the function in a loop with increasingly large max numbers until the length of the output is 50, then print out the last item in the output?

How to get a list of combinations in z3py?

I have a list in python of integers like this:
myList = [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
I want to get Z3 to output various sets or lists of numbers which are all members of myList... Essentially, I want to use Z3 to get additional lists of numbers which all exist in myList but are in various different orders. Put differently, I want to get various outputs from Z3 which contain numbers in the set myList above.
I am having trouble doing this with Z3py because I do not know how to have z3 return a list or a set as the model when I call s.model(), assuming s = Solver().
from z3 import *
myList = [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
s = Solver ()
pick = []
for (i, v) in enumerate(myList):
b = Bool ('pick_%d' % i)
s.add(b == b)
pick += [(b, v)]
while (s.check() == sat):
m = s.model()
chosen = []
block = []
for (p, v) in pick:
if m.eval(p, model_completion=True):
chosen += [v]
block.append(Not(p))
else:
block.append(p)
print chosen
s.add(Or(block))
Note that this will print 2^n solutions where n is the number of elements in your list; so it'll take a while to finish if n is large!

How to check index if the N'th index should be greater than previous

I want to run a loop from 0 to 1000 i want to print numbers which is lower than previous digit "ex:123 3 is greater than 2 and 2 is greater than 1 so print 123" i tried from 1 to 100 and how to check for 1000 or greater numbers
i tried to convert int input to list and checking with 2 digits
no=int(input())
lis=[]
num_lis=[]
le=0
for i in range(10,no):
lis=str(i)
num_lis=[int (x)for x in lis]
le=len(num_lis)-1
if num_lis[le]>num_lis[le-1]:
print(i)
From 1 to 100 no problem i want to check three digits to like 1<2<3 if correct print i
my code only check last two digit how do i check for three and four digits
Printing all numbers that are lower then the one after:
You can simply remember one digit and print it if the next one is bigger:
number = None
while number is None:
number = int(input("Input a number: "))
number = str(number)
last_digit = int(number[0])
for s in number[1:]:
this_digit = int(s)
if this_digit > last_digit:
print(last_digit, end="")
last_digit = this_digit
print(last_digit)
Output for 12354:
1235
This prints all numbers that are lower then the next one.
Checking if numbers are "in ascending order":
To zimply check you can use zip(). Characters '0123456789' compare in this order: '0'<'1'<'2'<'3'<'4'<'5'<'6'<'7'<'8'<'9' - no need to convert it to an integer, simply compare the characters "as is":
def IsIncreasing(number):
n = str(number)
return all(a<b for a,b in zip(n,n[1:]))
How does this work?
It makes tuples from the number and number shifted by 1:
"123456789"
"23456789"
==> ('1','2'),('2','3'),...,('7','8'),('8','9') as generator of tuples
and ensures all first elements are smaller then the second element using all()
Example:
for k in [1234,1,123456798]:
print(k,IsIncreasing(k))
Output (reformatted):
1234 True
1 True
123456798 False
There is no need to compare via sorting which takes more computation.
Test all numbers from 1 to 1000:
You can create a list of all "increasing" numbers from 1 to 1000 using the IsIncreasing() function:
get_all_up_to_1000 = [k for k in range(1,1001) if IsIncreasing(k)]
print( *(f"{k:>3}," for k in get_all_up_to_1000))
Output:
1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15,
16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 34, 35,
36, 37, 38, 39, 45, 46, 47, 48, 49, 56, 57, 58, 59,
67, 68, 69, 78, 79, 89, 123, 124, 125, 126, 127, 128, 129,
134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157,
158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238,
239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269,
278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367,
368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478,
479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789,
You could create a function that verifies if the digits of the number are sorted:
def int_sorted(i):
s = str(i)
return s == ''.join(sorted(s, key=int))
print(int_sorted(123))
print(int_sorted(1234))
print(int_sorted(4234))
Output
True
True
False
Note that sorted(s, key=int) sorts s (the string of digits) according to int value of each of the digits, by using the key parameter of sorted. This function works independent of the number of digits.
In case it must be greater than strict you could do:
def int_sorted(i):
s = str(i)
sorted_s = sorted(s, key=int)
return s == ''.join(sorted_s) and all(int(c) < int(n) for c, n in zip(sorted_s, sorted_s[1:]))
print(int_sorted(123))
print(int_sorted(1234))
print(int_sorted(4234))
print(int_sorted(99))
Output
True
True
False
False

How do I generate a list of random integers without consecutive numbers?

After I sort a randomly generated list, I have consecutive numbers, e.g.
[7, 9, 13, 47, 64, 76, 83, 94, 95, 114, 115, 116, 120, 121, 123, 124, 127, 136, 152, 154, 167, 184, 189, 205, 212, 222, 226, 229, 231, 238]
Here consecutive numbers are (94, 95), (120, 121) and (123, 124).
How do I remove them?
My code is:
while len(set(l)) != 30:
a = random.randint(1, 240)
l.append(a)
l = list(set(l))
l = sorted(l)
f.write(str(l))
I do not want to use randrange or choice from random module.
Create a random number a and check if a and a±1 are not in the set:
import random
l = set()
while len(l) != 30:
a = random.randint(1, 240)
if not {a-1,a,a+1} & l: # set intersection: empty == False == no common numbers
l.add(a)
l = sorted(l) # sorted creates a sorted list from any iterable
print(l)
Output:
[5, 12, 40, 47, 55, 59, 62, 73, 76, 82, 84, 89, 93, 95, 109,
125, 127, 141, 165, 168, 184, 187, 196, 202, 204, 210, 215,
218, 229, 231]
Directly using a set makes the check if the number (±1) is already part of your random numbers very fast.
Doku:
set.intersection (or &)
And as function:
import random
def get_random_numbers_no_neighboring_elems(min_num, max_num, amount):
"""Generates amount random numbers in [min_num,..,max_num] that do not
include neighboring numbers."""
# this is far from exact - it is best to have about 5+ times the amount
# of numbers to choose from - if the margin is too small you might take
# very long to get all your "fitting numbers" as only about 1/4 of the range
# is a viable candidate (worst case):
# [1 2 3 4 5 6 7 8 9 10]: draw 2 then 5 then 8 and no more are possible
if (max_num-min_num) // 5 < amount:
raise ValueError(f"Range too small - increase given range.")
l = set()
while len(l) != amount:
a = random.randint(min_num, max_num)
if not {a-1,a,a+1} & l: # set intersection: empty == False == no commons
l.add(a)
return sorted(l)
print(get_random_numbers_no_neighboring_elems(1,240,80))
I add a solution where edges can be selected with same probability than others, but they need to be mutually exclusive :
def rand2(k,n,edge=False):
forbid=set()
l=set()
while len(l)<k:
x=random.randint(1,n)
if x not in forbid :
l.add(x)
forbid.update({x,x-1,x+1})
if edge and x in {1,n} : forbid.add(n+1-x)
return l
from collections import Counter
print(Counter([tuple(rand2(2,5)) for i in range(10000)]))
#Counter({(2, 4):1943, (1, 4):1720, (3, 5):1711, (2, 5):1652, (1, 3):1637, (1, 5):1337})
print(Counter([tuple(rand2(2,5,edge=True)) for i in range(100000)]))
#Counter({(2, 5): 2060, (3, 5): 2026, (1, 4): 1981, (1, 3): 1975, (2, 4): 1958})

Categories