jeudi 2 novembre 2023

Program to read a file and generate a random number

Let me explain the problem first. The below shows the generation of a random number from a text file having a book.

* **Seed Initialization**: The PRNG (Pseudorandom Number Generator) is initialized with a given seed. This dictates the starting position within the text. For instance, with a seed of 1,000, the process would start from the 1,000th character in the text.

 

* **Pair Formation**:

  * To generate pairs of letters, start at the initial seed position and move forward by a predetermined step (e.g., 100 characters). This ensures the letters in each pair are independent of one another.

  * After picking the first letter, skip the step interval to select the second letter, forming your first pair.

* If both letters in a pair are same , the pair is discarded and not used in the process.

  * Continue this process to create subsequent pairs. For our purpose, this is done 64 times, resulting in 32 letter pairs.

 

* **Binary Representation**:

  * For each of the 32 pairs, determine the relationship between the letters based on their ASCII values.

  * If the first letter has a greater ASCII value than the second, assign a "1" to a new column for that pair. Otherwise, assign a "0". This assignment is based on the premise that there's a 50% chance for either scenario.

 

* **Probability Assignment**:

  * Each pair is then given a decreasing probability value. The first pair gets a probability of 1/2, the second pair 1/4, the third pair 1/8, and so on. This pattern continues for all pairs.

 

* **Random Number Generation**:

  * Utilize the assigned probabilities and the binary representation (1 or 0) from the earlier step to compute a pseudorandom number. This can be achieved using the formula:

 



 

This method effectively utilizes the text to produce pseudorandom numbers based on the initialized seed and predetermined step value.

To assist with understanding and visualization, these two attached pictures can help complement this description.

Here's my code for the same. My main issue is when char2 is an empty string, the seed resets to 1000 which may cause the random number to be repeated. I tried using continue but it becomes an infinite loop. I was hoping to get some help in that part. I get a type error if I don't that if statement.

from statistics import mean


class WarAndPeacePseudoRandomNumberGenerator:
    def __init__(self,seed=1000,step = 100):

        self.seed = seed
        self.step = step
        self.fileName = "war-and-peace.txt"
        self.file = open(self.fileName, 'r')    # open a file for reading
        self.file.seek(0)                       # start from 0
        
    def readCharacters(self,seed,step):
        #print(self.seed)
        self.file.seek(self.seed)
        char1 = self.file.read(1)
        self.file.seek(self.seed+self.step)
        char2 = self.file.read(1)
        return char1, char2

    def generateList(self):
        binarylist = []
        pairs_generated = 0
        while pairs_generated < 32:
            char1, char2 = self.readCharacters(self.seed, self.step)
            if not char2:
                # If char2 is empty (end of file), reset the seed and step to start over
                self.seed = 1000
                self.step += 100
                continue
            if char1 == char2:
                self.step += 100  # Increase the step by 100 places
                self.file.seek(self.seed + self.step)
                char2 = self.file.read(1)  # Read char2 again with the updated step
                continue
            if ord(char1) > ord(char2):
                binarylist.append(1)
            else:
                binarylist.append(0)

            pairs_generated += 1
            self.step += 100
            self.seed = self.seed + self.step
        return binarylist
    
    def closeFile(self):
        if self.file is not None:
            self.file.close()
    
    def random(self):
        randomNumber = 0.0
        probDenom= 2
        binaryList = self.generateList()
        for i in range (len(binaryList)):
            randomNumber = randomNumber + binaryList[i] * (1/probDenom)
            probDenom = probDenom * 2
        return randomNumber

def main():
    randomNumberList = []
    prng2 = WarAndPeacePseudoRandomNumberGenerator(12345)   # With seed
    r1 = prng2.random()                                     # Random number 1
    r2 = prng2.random()                                     # Random number 2
    prng2.closeFile()                                       # Closing the file

    prng = WarAndPeacePseudoRandomNumberGenerator()         # Without seed value
    for i in range(10):                                  # Generating 10000 random numbers
        r = prng.random()                                   # 
        randomNumberList.append(r)                          # Appending the random number obtained to the list
    prng.closeFile()                                        # Closing the file

    median = mean(randomNumberList)
    minimum = min(randomNumberList)
    maximum = max(randomNumberList)

    print("Random numbers generated with seed 12345: {} {}".format(r1, r2))
    print("\nAfter generating 10000 random numbers")
    print("\nMedian: {} ".format(median))
    print("\nMinimum: {} ".format(minimum))
    print("\nMaximum: {} ".format(maximum))
    print("random num: {}".format(randomNumberList[1:5])) # testing

if __name__ == '__main__':
    main()




Aucun commentaire:

Enregistrer un commentaire