mercredi 3 août 2022

Python - Problem coding random number guessing game using while loop

first time poster. I'm having a problem getting my random number guessing game in Python to work properly. I've purposely set the number to not be random (it's 50) for testing purposes. If I guess a number under 50, it will tell me that the number is higher; I can then guess higher than 50 and it will tell me lower.

For some reason though, if I guess above 50 and then try to guess under 50, the program stops.

Can someone point me in the right direction please? Here is my code:

from random import randint
randomNum = 50 #randint(0,100)
print("Let's play a guessing game.  I'm thinking of a number between 0-100. Take a guess 
what it is") 
num = int(input()) 
if(num == randomNum):
    print("Wow, what fantastic luck!  You're right!")
while (randomNum > num):
    print('Its higher than that. Guess again!')
    num = int(input())
    while (num == randomNum):
        print("You got it!")
        break

while (randomNum < num):
    print('Its lower than that! Guess again!')
    num = int(input())
    while (num == randomNum):
        print("You got it!")
        break



How Does Numpy Random Seed Changes?

So, I'm in a project that uses Monte Carlo Method and I was studying the importance of the seed for pseudo-random numbers generation.

While doing experiments with python numpy random, I was trying to understand how the change in the seed affects the randomness, but I found something peculiar, at least for me. Using numpy.random.get_state() I saw that every time I run the script the seed starts different, changes once, but then keeps the same value for the entire script, as show in this code where it compares the state from two consecutive sampling:

import numpy as np

rand_state = [0]
for i in range(5):
    rand_state_i = np.random.get_state()[1]
    # printing only 3 state numbers, but comparing all of them
    print(np.random.rand(), rand_state_i[:3], all(rand_state_i==rand_state))
    rand_state = rand_state_i

# Print:
# 0.9721364306537633 [2147483648 2240777606 2786125948] False
# 0.0470329351113805 [3868808884  608863200 2913530561] False
# 0.4471038484385019 [3868808884  608863200 2913530561] True
# 0.2690477632739811 [3868808884  608863200 2913530561] True
# 0.7279016433547768 [3868808884  608863200 2913530561] True

So, my question is: how is the seed keeping the same value but returning different random values for each sampling? Does numpy uses other or more "data" to generate random numbers other than those present in numpy.random.get_state()?




mardi 2 août 2022

Issues with random.randint

So I'm generating 4 random lists and then plugging them into a function called johnson. When I simply generate the 4 random lists everything looks fine. But if I try to plug in the result into the function johnson, the "randomness" seems to disappear. I'm not sure what's going on. Any help would be appreciated.


import random

def generate_Lt_Ut(n, delta):
    Ut1 = [random.randint(1,100) for i in range(n)]
    Ut2 = [random.randint(1,100) for i in range(n)]
    Lt1 = [random.randint(max(1,Ut1[i]-delta),Ut1[i]) for i in range(n)]
    Lt2 = [random.randint(max(1,Ut2[i]-delta),Ut2[i]) for i in range(n)]
    return Ut1, Ut2, Lt1, Lt2

def johnson(t1, t2):
    n = len(t1)
    #each time we find a minimal number, we want to cross out that job, so
    #we replace it with a number greater than all numbers in t1 and t2 combined.
    maximum1 = max(t1)
    maximum2 = max(t2)
    maxplus1 = max(maximum1, maximum2) + 1
    #seq1 is the sequence that will contain jobs from machine 1 and seq2 will
    #contain jobs from machine 2. At the end, we will reverse the sequence
    #seq2 and combine seq1 and seq2 to obtain the desired sequence.
    seq1 = []
    seq2 = []
    while len(seq1)+len(seq2)< len(t1):
        mt1 = min(t1)
        mt2 = min(t2)
        if mt1 == mt2 or mt1 < mt2:
            i = t1.index(mt1)
            seq1.append(i+1)
            t1[i] = maxplus1
            t2[i] = maxplus1
        elif mt1 > mt2:
            i = t2.index(mt2)
            seq2.append(i+1)
            t1[i] = maxplus1
            t2[i] = maxplus1
    return (seq1 + seq2[::-1])

Ut1, Ut2, Lt1, Lt2 = generate_Lt_Ut(4, 30)
u = johnson(Lt1, Lt2)
v = johnson(Ut1, Ut2)

print("Ut1: " + str(Ut1))
print("Lt1: " + str(Lt1))
print("Ut2: " + str(Ut2))
print("Lt2: " + str(Lt2))
print("u " + str(u))
print('u ' + str(v))

This is the output:

Ut1: [100, 100, 100, 100]
Lt1: [75, 75, 75, 75]
Ut2: [100, 100, 100, 100]
Lt2: [75, 75, 75, 75]
u [1, 3, 4, 2]
u [1, 4, 2, 3]

As you can see, the 4 lists Ut1, Lt1, Ut2, Lt2 don't look random at all. But if I don't plug them into johnson, then the lists do look random. This is very confusing to me...why is this happening?




Making Sure a Number Isn't "Guessed" Twice?

I have the following code that sets an initial random number, and random numbers are generated until a random number matches the initial random number - I also record how many guesses it took for this to happen (and then repeat this process many times over - each repetition is called a "game"):

all_games <- vector("list", 100)

for (i in 1:100){
    guess_i = 0
    correct_i = sample(1:100, 1)
    trial_index <- 1  
    while(guess_i != correct_i){
        guess_i = sample(1:100, 1)
        trial_index <- trial_index + 1  
    }
    
    game_results_i <- data.frame(i, trial_index, guess_i, correct_i)
    all_games[[i]] <-  game_results_i
}
  • Is it possible to modify this code to ensure that in any game, no number is guessed twice?

I thought that maybe I could ensure this by keeping track of all the numbers that were guessed in a game, and then removing them from the possible numbers that could be generated in the next turn:

all_games <- vector("list", 100)

guesses_in_a_game <- list()
all_guesses <- list()

for (i in 1:100){
    guess_i = 0
    correct_i = sample(1:100, 1)
    trial_index <- 1  
    while(guess_i != correct_i){

        guess_i = sample(1:100, 1)
         guesses_in_a_game[[i]] = guess_i
        trial_index <- trial_index + 1  
    }
    all_guesses[[i]] <- guess_i
    game_results_i <- data.frame(i, trial_index, guess_i, correct_i)
    all_games[[i]] <-  game_results_i
} 

But I am not sure how to write the code for this.

Can someone please help me with this?

Thank you!




Numpy array stuck in while loop if I enter a number greater than 0.1

What I am trying to do is :

Generating 6 random numbers which multipled for a coefficient and then added among themselves give me a value between overall - 0.5 and overall + 0.5. The program works fine with a coefficient in the last position of Gk_coeff (the sixth number of Gk_coeff[5]) which is <= 0.1, but if I enter 0.11, 0.12 (like in the code given) and so on, it stops working. There must be a reason but I really cannot think of it. I've tried using it on linux and windows and the issue persists, so it can't be related to the system.

#!/usr/bin/env python3
import random
import numpy

overall = 83

Gk_coeff = [ 0.23, 0.23, 0.23, 0.23, 0.07, 0.12 ]
Gk_values = numpy.empty(6, dtype=int)

calculated_overall = 0

while not (overall - 0.5 <= calculated_overall <= overall + 0.5) :
    calculated_overall = 0
    for i in range (len(Gk_coeff)):
        Gk_values[i] = random.randint(overall - 7, overall + 7)
        calculated_overall += (Gk_values[i] * Gk_coeff[i])

print(calculated_overall)



Split whole number into float numbers

Goal: split 100 into 5 random 2 decimal place numbers.

So far, I can simulate any number of divisions.

However, these are only integers and are "balanced", in that they are the same or close in values to each other. So, the output is always the same.

Code:

def split(x, n):
 
    if(x < n):
        print(-1)
 
    elif (x % n == 0):
        for i in range(n):
            print(x//n, end =" ")
    else:
        zp = n - (x % n)
        pp = x//n
        for i in range(n):
            if(i>= zp):
                print(pp + 1, end =" ")
            else:
                print(pp, end =" ")
       
split(100, 5)
>>> 20 20 20 20 20 

Desired Output:

  • List of numbers,
  • Floating point numbers (2 dp),
  • Non-balanced.

Example Desired Output:

[10.50, 22.98, 13.23, 40.33, 12.96]



lundi 1 août 2022

Random numbers in C++: one engine, multiple distributions -> unexpected behaviour

I am using C++14. I want to generate a random number stream using a random engine and draw random variates from different distributions from this stream. I find, however, that there appears some interaction between the distributions which leads to unexpected behaviour. This is my code

#include <random>
#include <iostream>
#include <vector>

int main()
{
    double alpha;
    std::cin >> alpha;
    std::default_random_engine generator;
    generator.seed(1);

    std::normal_distribution<> distNorm(0., 1.);
    std::gamma_distribution<> distGam(alpha, 1.);

    std::vector<double> normal;
    std::vector<double> gamma;

    for(size_t idxBatch = 0; idxBatch < 2; ++idxBatch)
    {
        for(size_t i = 0; i < 2; ++i)
            normal.push_back(distNorm(generator));

        for(size_t i = 0; i < 1; ++i)
            gamma.push_back(distGam(generator));
    }

    for(size_t i = 0; i < normal.size(); ++i)
        std::cout << normal[i] << std::endl;
    
    std::cout << std::endl;
    
    for(size_t i = 0; i < gamma.size(); ++i)
        std::cout << gamma[i] << std::endl;

    return 0;
}

Running the code with alpha = 1 produces:

-1.40287
-0.549746
0.188437
0.483496

0.490877
1.87282

Running the code with alpha = 2 produces:

-1.40287
-0.549746
-1.95939
0.257594

1.34784
2.28468

In other words, the output of the normal distribution is impacted by the parameter of the gamma distribution (3rd and 4th item in the first block)! This is unwanted. The normal distribution should be invariant against the parameterization of the gamma distribution.

Does anyone know what I am doing wrong?