0

I am trying to use the following function:

random.randint()

to generate a series of numbers that should equal the input() integer. The only problem here is, that I tried doing it through a "while if" loop. wherein the loop keeps generating numbers till the random combination equals n = int(input()). However, this method is very consuming and sometimes it takes up to an entire minute for the pycharm to find a correct combination. Are there already made functions to solve this problem?

Edit

I will add the code as requested but yeah the code is huge because of the variables. The reason the range is from (1, a) is because a range of (0, a) causes error from random module.

I tried the same block of codes but with other variables to generate something different like an income statement with a range (0, a) and it worked totally fine, I don't know why the range (0, a) sometimes work and sometimes not.


# Cash
ca = 0
# Marketable securities
ms = 0
# Accounts receivable
ar = 0
# Inventories
i = 0
# Total current assets
tca = 0
# Land and buildings
lab = 0
# Machinery and equipment
mae = 0
# Furniture and fixtures
faf = 0
# Vehicles
v = 0
# Other (includes financial leases)
ot = 0
# Total gross fixed assets
tgfa = 0
# Less: Accumulated depreciation
ad = 0
# Net fixed assets
nfa = 0
# Total assets
ta = 0

# Accounts payable
ap = 0
# Notes payable
npp = 0
# Accruals
acc = 0
# Total current liabilities
tcl = 0
# Long-term debt (includes financial leases)
ltd = 0
# Total liabilities
tl = 0
# Preferred stock
ps = 0
# Common stock
cs = 0
# Paid-in capital in excess of par on common stock
pic = 0
# Retained earnings
re = 0
# Total stockholders’ equity
tse = 0
# Total liabilities and stockholders’ equity
tlase = 0

while ta <= 0 and 0 >= tlase:
    ca += random.randint(1,a)
    ms += secrets.randbelow(ca)
    ar += secrets.randbelow(ca)
    i += secrets.randbelow(ca)
    lab += random.randint(1,a)
    mae += random.randint(1,a)
    faf += secrets.randbelow(ca)
    v += secrets.randbelow(ca)
    ot += secrets.randbelow(ca)
    ad += secrets.randbelow(ca)
    ap += secrets.randbelow(ca)
    npp += secrets.randbelow(ca)
    acc += secrets.randbelow(ca)
    ltd += random.randint(1,a)
    ps += secrets.randbelow(ca)
    cs += secrets.randbelow(ca)
    pic += secrets.randbelow(ca)
    re += random.randint(1,a)
    tca += ca + ms + ar + i
    tgfa += lab + mae + faf + v + ot
    nfa += tgfa - ad
    ta += tgfa - (ad + ca + ms + ar + i)
    tcl += ap + npp + acc
    tl += tcl + ltd
    tse += ps + cs + pic + re
    tlase += ps + cs + pic + re + tcl + ltd

    if 0 >= ta and tlase <= 0:
        ca *= 0
        ms *= 0
        ar *= 0
        i *= 0
        lab *= 0
        mae *= 0
        faf *= 0
        v *= 0
        ot *= 0
        ad *= 0
        ap *= 0
        npp *= 0
        acc *= 0
        ltd *= 0
        ps *= 0
        cs *= 0
        pic *= 0
        re *= 0
        tca *= 0
        tgfa *= 0
        nfa *= 0
        ta *= 0
        tcl *= 0
        tl *= 0
        tse *= 0
        tlase *= 0

    elif ta != tlase:
        ca *= 0
        ms *= 0
        ar *= 0
        i *= 0
        lab *= 0
        mae *= 0
        faf *= 0
        v *= 0
        ot *= 0
        ad *= 0
        ap *= 0
        npp *= 0
        acc *= 0
        ltd *= 0
        ps *= 0
        cs *= 0
        pic *= 0
        re *= 0
        tca *= 0
        tgfa *= 0
        nfa *= 0
        ta *= 0
        tcl *= 0
        tl *= 0
        tse *= 0
        tlase *= 0
    else:
        print("true")
halfer
  • 19,824
  • 17
  • 99
  • 186
  • Is there a fixed number of numbers that you need to generate? Is there a fixed range for each number? Perhaps a useful speed-up would be to generate *all but one* of the numbers randomly, and then compute what the final number would have to be (the input number, minus the total so far). – jasonharper Sep 12 '22 at 20:14
  • @jasonharper Yes, am trying to make it look like this: a = input b = generated randomly c = generated randomly d = generated randomly b + c + d = a, otherwise the loop gonna keep generating till they coincidentally match or equal. I know it is not the optimal way but there is no other alternative so far... – Ismail Alhabil Sep 12 '22 at 20:22
  • 2
    @IsmailAlhabil You need to supply your current code in the question itself. It's unclear to what you mean when you say "generate a series of numbers that should equal the input() integer." Do you mean their sum should equal the value entered by the user? Filter out values which aren't equal to the input value? The quantity should be equal to the input value? Please clarify. – pjs Sep 12 '22 at 20:25
  • Is there a fixed number of "random" numbers that should fit in the whole number? – Damiaan Sep 12 '22 at 20:29
  • Please provide enough code so others can better understand or reproduce the problem. – Community Sep 12 '22 at 20:47
  • @Mechanic pic, yes, thanks a lot, I made few edits on the code and it worked super great with me. The code provided by NoDakker is also great, but it generates values in the same method as my code which takes really really long time especially if the roof or max possible value is relatively high. – Ismail Alhabil Sep 13 '22 at 13:54

2 Answers2

0

If I understand the narrative and comments, your program would prompt for an integer value and the try to find a fixed number of integers that when added together would equal the entered number. With that, here is one possible code snippet that may spur you on.

import random

while True:

    response = input("Enter a number or enter 'Q' to quit: ")
    
    if response.upper() == "Q":
       break
       
    num     = int(input("Enter the number of integers that need to add up to your value: "))
    summary = int(response)
    tries   = 0
    
    while True:
        work = 0
        x    = []
        y    = 0
        for i in range (0, num):
            y = random.randint(1, summary)
            x.append(y)
            work  += y
            tries += 1
        if (work == summary):
            break
        
    print ("The selected random values are:", x, "after", tries, "tries")

I tossed in a counter as to how many times the program attempted to come up with a combination of integers to sum up to the entered value.

Following was a test run on my terminal.

@Una:~/Python_Programs/RandomSum$ python3 RandomSum.py 
Enter a number or enter 'Q' to quit: 442
Enter the number of integers that need to add up to your value: 4
The selected random values are: [38, 119, 124, 161] after 6476 tries
Enter a number or enter 'Q' to quit: 100
Enter the number of integers that need to add up to your value: 3
The selected random values are: [10, 46, 44] after 1392 tries
Enter a number or enter 'Q' to quit: 442
Enter the number of integers that need to add up to your value: 6
The selected random values are: [39, 236, 8, 30, 65, 64] after 49632 tries
Enter a number or enter 'Q' to quit: Q

Give that a try.

NoDakker
  • 3,390
  • 1
  • 10
  • 11
0
import random

def constrained_sum_sample_pos(n, total):
    """Return a randomly chosen list of n positive integers summing to total.
    Each such list is equally likely to occur."""

    dividers = sorted(random.sample(range(1, total), n - 1))
    return [a - b for a, b in zip(dividers + [total], [0] + dividers)]

this code worked fine for me, it is not exactly what I really want but it does the job. The only difference is in this code, you input the max value, and the generated numbers sum is equal to that max value that you input. However, for my code, am trying to make the code itself generate a random max value from the range and the other generated numbers' sum should still equal it. So, the only difference is that I wish to make the max value also randomly generated along with its variables in order to make the resulting output totally random despite making the same input every time.

for those who still didn't get what I mean: the provided code does this: A: you enter this value B + C + D (are randomly generated) = A

for my code: your input = input() A: python picks a random number from the range (1, your input) B + C + D (are also randomly generated) = A even if you use the same input, every time the sum of the randomly generated numbers will equal the randomly generated input from the range

I hope I didn't overexplain it