PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label random. Show all posts
Showing posts with label random. Show all posts

Wednesday, November 9, 2022

[FIXED] How to get a line break for text pulled randomly from a javascript array const

 November 09, 2022     css, html, javascript, line-breaks, random     No comments   

Issue

I'm creating a simple webpage tool for language education that randomly selects a question from a javascript array const, but the longer questions are cut off, especially for mobile. How can I get a line break for these longer text questions? I've tried adding breaks inside the array, and I've tried adding css line breaks for the input and divs, but nothing works.

    <style>
    .button {
      background-color: #094997;
      border-radius: 12px;
      border: none;
      color: white;
      padding: 12px 20px;
      text-align: center;
      text-decoration: none;
      font-size: 24px;
      width: 200px;
    }
    input
    {
        font-size:22px;
        padding: 50px 50px;
        text-align: center;
        width: 200px;
        height: 250px;
    }
    .questionsdiv {
        text-align: center; 
    }

    </style>


    <div class="questionsdiv">
    <input type="text" "randomquestion"="" id="randomquestion">
    <br><br>
      <button class="button" onclick="findquestion();" type="randomquestion">Random Question</button>
    </div>


    <script>

    const question = ["How old are you?","Where do you go on Saturdays?","Do you have any brothers or sisters?","How many books do you own?","Who is your favorite music artist lately?","Do you like Jazz music?","Have you ever traveled outside of Japan?","Do you want to live in the countryside or in the city when you are older and have a family?",];

    function findquestion() {
      let randomIndex = Math.floor(Math.random() * question.length);
      document.getElementById("randomquestion").setAttribute("value", question[randomIndex]);
    }

    </script>

Solution

In this code, the input tag is used to display the text, and the input tag in html does not support multi-line texts. You have to replace input with textarea And use innerHTML instead of setAttribute

  <style>
    .button {
      background-color: #094997;
      border-radius: 12px;
      border: none;
      color: white;
      padding: 12px 20px;
      text-align: center;
      text-decoration: none;
      font-size: 24px;
      width: 200px;
    }
    textarea
    {
        font-family:arial;
        font-size:22px;
        padding: 50px 50px;
        text-align: center;
        width: 200px;
        height: 250px;
    }
    .questionsdiv {
        text-align: center; 
    }

    </style>


    <div class="questionsdiv">
    <textarea type="text" randomquestion="" id="randomquestion"></textarea>
    <br><br>
      <button class="button" onclick="findquestion();" type="randomquestion">Random Question</button>
    </div>


    <script>

    const question = ["How old are you?","Where do you go on Saturdays?","Do you have any brothers or sisters?","How many books do you own?","Who is your favorite music artist lately?","Do you like Jazz music?","Have you ever traveled outside of Japan?","Do you want to live in the countryside or in the city when you are older and have a family?",];

    function findquestion() {
      let randomIndex = Math.floor(Math.random() * question.length);
      document.getElementById("randomquestion").innerHTML  = question[randomIndex];
    }

    </script>

NOTE: textarea by default use monospace font-family property you can replace it with any font you want



Answered By - dante velli
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, November 5, 2022

[FIXED] Why can't python access the special linux RANDOM environment variable?

 November 05, 2022     environment-variables, python, random     No comments   

Issue

I've been refactoring a bash script that uses the special RANDOM linux environment variable. This variable provides random integers when accessed.

From another SO question:

RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated. The sequence of random numbers may be initialized by assigning a value to RANDOM. If RANDOM is unset, it loses its special properties, even if it is subsequently reset.

Here's an example of the expected output, working correctly:

ubuntu:~$ echo ${RANDOM}
19227
ubuntu:~$ echo ${RANDOM}
31030

However, when I try to replicate its usage in python I was surprised to find that it does not seem to work.

>>> import os
>>> os.environ.get('RANDOM')
(No output)
>>> os.environ.get('RANDOM')==None
True

This is quite unexpected. Obviously I can just replicate the random integer behavior I want using

random.randint(0, 32767)

But other scripts may be relying on the environment variables specific value (You can seed RANDOM by writing to it), so why can I not simply read this variable in python as expected?


Solution

RANDOM is a shell variable, not an environment variable. You need to export it to get it into the environment:

imac:barmar $ export RANDOM
imac:barmar $ python
Python 3.9.2 (v3.9.2:1a79785e3e, Feb 19 2021, 09:06:10) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['RANDOM']
'15299'

However, this just puts the most recent value of RANDOM in the environment, it won't change each time you use os.environ['RANDOM'] the way $RANDOM does when you use it in the shell.



Answered By - Barmar
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, October 31, 2022

[FIXED] When does MySQL ORDER BY RAND() function order?

 October 31, 2022     mysql, performance, random     No comments   

Issue

I've read about the ORDER BY RAND() and its performance problems -- do these only apply to queries that return large datasets? For example, if I have a table with 100,000 rows and return a dataset with 10 records using a WHERE clause and then use ORDER BY RAND() LIMIT 1, will this ORDER BY RAND() be applied AFTER my table has been filtered down to records matching the WHERE clause, and thus have negligible performance issues?


Solution

You're right, it will apply the ORDER BY after reducing the number of rows with WHERE, GROUP BY, and HAVING. But it will apply ORDER BY before LIMIT.

So if you filter the number of rows down sufficiently, then yes, the ORDER BY RAND() may achieve what you want without a great performance impact. There's a legitimate benefit to code that is simple and easily readable.

The trouble comes when you think your query should reduce the rows to something small, but over time as your data grows, the number of rows it needs to sort becomes large again. Since your query then does LIMIT 10 on the sorted result hides the fact that you're performing ORDER BY RAND() on 500k rows. You just see performance mysteriously getting worse.

I have written about alternative methods for picking a random row in my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming, or in other answers here on Stack Overflow:

  • Selecting random rows with MySQL
  • randomizing large dataset
  • quick selection of a random row from a large table in mysql


Answered By - Bill Karwin
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, October 10, 2022

[FIXED] Why rand() isn't really random?

 October 10, 2022     gd, php, random     No comments   

Issue

I wanted to put random points on an image (stars in space for some little fun side project)

I have this simple script.

<?php
$gd = imagecreatetruecolor(1000, 1000);
$white = imagecolorallocate($gd, 255, 255, 255);

for ($i = 0; $i < 100000; $i++) 
{
    $x = rand(1,1000);
    $y = rand(1,1000);

    imagesetpixel($gd, round($x),round($y), $white);
}

header('Content-Type: image/png');
imagepng($gd);
?>

Keep in mind this is just for testing, that is why I put 100000 in for loop so it shows the pattern I noticed emerging. We have 1 million pixel to use, still random X and Y creates this pattern instead: enter image description here

So it is far from random. I know rand is not real random, that is why it isn't good for cryptography. But I find no information about how it works and what should I do to avoid patterns like this.


Solution

Linear congruential random number generators (which is what PHP rand uses) will always display autocorrelation effects on an x-y plot.

You will have better results with mt_rand. This is a Mersenne Twister generator.



Answered By - Bathsheba
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 7, 2022

[FIXED] How can I filter a dataframe based on (randomly selected) unique values of a column?

 October 07, 2022     dataframe, dplyr, r, random, statistics     No comments   

Issue

I read some articles here on how to filter based on specific values in a given column. However, what I am interested in is whether I can filter randomly selected unique values of a column. To better understand my question, please consider the following sample dataframe:

MeasurementPoint <- c(1,2,1,2,3,3,4,4,6,7,6,7)
subject <- c(1,1,1,1,2,2,3,3,4,4,4,4)
MeasurementMethod <- c("A","A", "B", "B", "A","B", "A","B","A","A", "B","B")
value <- c(-0.06, 0.11,-0.11,-0.01.-0.13, 0.02, -0.08, 0.09, 0.05, 0.04, -0.03, -0.02)
df1 <- data.frame(MeasurementPoint, subject,MeasurementMethod, value)
df1
 MeasurementPoint subject MeasurementMethod value
         1            1            A        -0.06
         2            1            A         0.11
         1            1            B        -0.11
         2            1            B        -0.01
         3            2            A        -0.13
         3            2            B         0.02
         4            3            A        -0.08
         4            3            B         0.09
         6            4            A         0.05
         7            4            A         0.04
         6            4            B        -0.03
         7            4            B        -0.02

Some values are measured on different subjects with two different MeasurementMethod and on different MeasurementPoints, e.g. multiple spots on their body.

Some subjects have more than one MeasurementPoints like subject #1 and #4. The rest have only one MeasurementPoint on their bodies, and only the MeasurementMethod varies for them (subject #2 and #3).

I would like to filter only one MeasurementPoint per subject and leave the rest. This selection should be "randomly" done. And as an example the follwoing dataframe would be an outcome of interest:

  MeasurementPoint subject MeasurementMethod value
                2       1                 A  0.11
                2       1                 B -0.01
                3       2                 A -0.13
                3       2                 B  0.02
                4       3                 A -0.08
                4       3                 B  0.09
                6       4                 A  0.05
                6       4                 B -0.03

Please note that the selection of MeasurementPoint = 2 for the first subject and MeasurementPoint = 6 for the last subject should happen randomly.


Solution

We can group_by the subject column, and filter rows that match the random MeasurementPoint value generated by sample.

library(dplyr)

df1 %>% 
  group_by(subject) %>% 
  filter(MeasurementPoint == sample(MeasurementPoint, 1))

# A tibble: 8 × 4
# Groups:   subject [4]
  MeasurementPoint subject MeasurementMethod value
             <dbl>   <dbl> <chr>             <dbl>
1                1       1 A                 -0.06
2                1       1 B                 -0.11
3                3       2 A                 -0.13
4                3       2 B                  0.02
5                4       3 A                 -0.08
6                4       3 B                  0.09
7                6       4 A                  0.05
8                6       4 B                 -0.03


Answered By - benson23
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, October 6, 2022

[FIXED] How to sample data points for two variables that has highest (close to +1) or lowest (close to zero) correlation coefficient?

 October 06, 2022     matlab, python, r, random, statistics     No comments   

Issue

Let's assume that we have N (N=212 in this case) number of datapoints for both variables A and B. I have to sample n (n=50 in this case) number of data points for A and B such that A and B should have the highest possible positive correlation coefficient or lowest correlation coefficient (close to zero) for that sample set. Is there any easy way to do this (Please note that the sampling should be index-based i.e., if we select a ith datapoint then both A and B should be taken corresponding to that ith index)? Below is the sample dataframe (Coded in R but I am OK with any programming language):

df <- structure(list(A = c(1.37, 1.44, 1.51, 1.59, 1.67, 1.75, 1.82,1.9, 1.97, 2.05, 2.12, 2.19, 2.26, 2.33, 2.4, 2.47, 2.53, 2.6,  2.66, 2.72, 2.78, 2.84, 2.9, 2.95, 3.01, 3.05, 3.09, 3.13, 3.16,  3.18, 3.2, 3.21, 3.22, 3.22, 3.23, 3.23, 3.23, 3.22, 3.21, 3.2,  3.18, 3.15, 3.13, 3.1, 3.06, 3.03, 3, 2.98, 2.95, 2.92, 2.89,  2.86, 2.84, 2.81, 2.79, 2.76, 2.74, 2.71, 2.69, 2.67, 2.65, 2.62,  2.6, 2.58, 2.56, 2.55, 2.54, 2.53, 2.53, 2.53, 2.54, 2.55, 2.56, 2.58, 2.59, 2.61, 2.62, 2.64, 2.66, 2.68, 2.7, 2.72, 2.74, 2.76, 2.79, 2.82, 2.84, 2.88, 2.91, 2.94, 2.98, 3.02, 3.06, 3.1, 3.14, 3.19, 3.24, 3.29, 3.34, 3.39, 3.45, 3.5, 3.56, 3.61, 3.66, 3.71, 3.77, 3.82, 3.87, 3.91, 3.96, 4.01, 4.06, 4.11, 4.15, 4.2, 4.24, 4.28, 4.32, 4.35, 4.39, 4.42, 4.44, 4.47, 4.49, 4.51, 4.53, 4.54, 4.56, 4.57, 4.58, 4.59, 4.6, 4.61, 4.62, 4.63, 4.64, 4.65, 4.65, 4.66, 4.66, 4.66, 4.66, 4.65, 4.64, 4.63, 4.62, 4.61, 4.6, 4.58, 4.56, 4.54, 4.52, 4.5, 4.48, 4.45, 4.42, 4.39, 4.36, 4.32, 4.28, 4.23, 4.19, 4.14, 4.08, 4.03, 3.97, 3.91, 3.84, 3.78, 3.71, 3.64, 3.57, 3.5, 3.43, 3.36, 3.29, 3.22, 3.15, 3.08, 3, 2.93, 2.86, 2.78, 2.7, 2.63, 2.55, 2.47, 2.4, 2.32, 2.24, 2.16, 2.08, 2, 1.93, 1.85, 1.76, 1.68, 1.6, 1.53, 1.45, 1.38, 1.31, 1.24, 1.18, 1.11, 1.05, 0.99, 0.93, 0.88, 0.83, 0.78), B = c(1.44, 0.76, 0.43, 0.26, 0.69, 0.46, 0.07, 0.22, 0.38, 0.44, 0.37, 0.31, 0.48, 0.45, 0.86, 1.15, 1.13, 0.5, 0.39, 0.64, 0.71, 0.86, 0.45, 0.6, 0.29, 0.58, 0.24, 0.64, 0.61, 0.49, 0.53, 0.27, 0.03, 0.18, 0.25, 0.24, 0.2, 0.23, 0.3, 0.39, 0.32, 0.22, 0.18, 0.24, 0.2, 0.61, 0.12, 0.16, 0.29, 0.51, 0.48, 0.27, 0.28, 0.41, 0.48, 0.76, 0.45, 0.59, 0.55, 0.69, 0.46, 0.42, 0.42, 0.22, 0.34, 0.19, 0.11, 0.18, 0.33, 0.48, 0.91, 1.1, 0.32, 0.18, 0.09, NaN, 0.27, 0.31, 0.3, 0.27, 0.79, 0.43, 0.32, 0.48, 0.77, 0.32, 0.28, 0.4, 0.46, 0.69, 0.93, 0.71, 0.41, 0.3, 0.34, 0.44, 0.3, 1.03, 0.97, 0.35, 0.51, 1.21, 1.58, 0.67, 0.37, 0.04, 0.57, 0.67, 0.7, 0.47, 0.48, 0.38, 0.61, 0.8, 1.1, 0.39, 0.38, 0.48, 0.58, 0.55, 0.7, 0.7, 0.86, 0.61, 0.18, 0.9, 0.83, 0.9, 0.83, 0.61, 0.23, 0.22, 0.44, 0.41, 0.52, 0.71, 0.59, 0.9, 1.23, 1.56, 0.73, 0.69, 1.23, 1.28, 0.43, 0.97, 0.58, 0.44, 0.23, 0.46, 0.48, 0.22, 0.21, 0.66, 0.26, 0.55, 0.69, 0.84, 1.04, 0.83, 0.85, 0.63, 0.63, 0.17, 0.58, 0.66, 0.44, 0.53, 0.81, 0.63, 0.51, 0.15, 0.42, 0.77, 0.73, 0.87, 0.34, 0.51, 0.63, 0.05, 0.23, 0.87, 0.84, 0.39, 0.61, 0.89, 1.06, 1.08, 1.01, 1.05, 0.27, 0.79, 0.88, 1.34, 1.26, 1.42, 0.81, 1.46, 0.84, 0.54, 0.95, 1.42, 0.44, 0.73, 1.31, 1.75, 2.1, 2.36, 1.94, 2.31, 2.17, 2.35)), class = "data.frame", row.names = c(NA, -212L))

Solution

Perhaps there is a better way, but it seems to me that this is something that could be solved with a genetic algorithm. The following approach will return the correlation value (i.e. fitness) only if n genes/variables are "turned on"; otherwise, zero is returned.

I had to initialize the population with individuals with exactly 50 genes turned on to start the evolutionary process. The result is pretty high (r = 0.97) after 1142 generations, and no improvement is made over the last 50 generations.

# required libraries
library(GA)
library(memoise)

# original data
df <- structure(list(A = c(1.37, 1.44, 1.51, 1.59, 1.67, 1.75, 1.82,1.9, 1.97, 2.05, 2.12, 2.19, 2.26, 2.33, 2.4, 2.47, 2.53, 2.6,  2.66, 2.72, 2.78, 2.84, 2.9, 2.95, 3.01, 3.05, 3.09, 3.13, 3.16,  3.18, 3.2, 3.21, 3.22, 3.22, 3.23, 3.23, 3.23, 3.22, 3.21, 3.2,  3.18, 3.15, 3.13, 3.1, 3.06, 3.03, 3, 2.98, 2.95, 2.92, 2.89,  2.86, 2.84, 2.81, 2.79, 2.76, 2.74, 2.71, 2.69, 2.67, 2.65, 2.62,  2.6, 2.58, 2.56, 2.55, 2.54, 2.53, 2.53, 2.53, 2.54, 2.55, 2.56, 2.58, 2.59, 2.61, 2.62, 2.64, 2.66, 2.68, 2.7, 2.72, 2.74, 2.76, 2.79, 2.82, 2.84, 2.88, 2.91, 2.94, 2.98, 3.02, 3.06, 3.1, 3.14, 3.19, 3.24, 3.29, 3.34, 3.39, 3.45, 3.5, 3.56, 3.61, 3.66, 3.71, 3.77, 3.82, 3.87, 3.91, 3.96, 4.01, 4.06, 4.11, 4.15, 4.2, 4.24, 4.28, 4.32, 4.35, 4.39, 4.42, 4.44, 4.47, 4.49, 4.51, 4.53, 4.54, 4.56, 4.57, 4.58, 4.59, 4.6, 4.61, 4.62, 4.63, 4.64, 4.65, 4.65, 4.66, 4.66, 4.66, 4.66, 4.65, 4.64, 4.63, 4.62, 4.61, 4.6, 4.58, 4.56, 4.54, 4.52, 4.5, 4.48, 4.45, 4.42, 4.39, 4.36, 4.32, 4.28, 4.23, 4.19, 4.14, 4.08, 4.03, 3.97, 3.91, 3.84, 3.78, 3.71, 3.64, 3.57, 3.5, 3.43, 3.36, 3.29, 3.22, 3.15, 3.08, 3, 2.93, 2.86, 2.78, 2.7, 2.63, 2.55, 2.47, 2.4, 2.32, 2.24, 2.16, 2.08, 2, 1.93, 1.85, 1.76, 1.68, 1.6, 1.53, 1.45, 1.38, 1.31, 1.24, 1.18, 1.11, 1.05, 0.99, 0.93, 0.88, 0.83, 0.78), B = c(1.44, 0.76, 0.43, 0.26, 0.69, 0.46, 0.07, 0.22, 0.38, 0.44, 0.37, 0.31, 0.48, 0.45, 0.86, 1.15, 1.13, 0.5, 0.39, 0.64, 0.71, 0.86, 0.45, 0.6, 0.29, 0.58, 0.24, 0.64, 0.61, 0.49, 0.53, 0.27, 0.03, 0.18, 0.25, 0.24, 0.2, 0.23, 0.3, 0.39, 0.32, 0.22, 0.18, 0.24, 0.2, 0.61, 0.12, 0.16, 0.29, 0.51, 0.48, 0.27, 0.28, 0.41, 0.48, 0.76, 0.45, 0.59, 0.55, 0.69, 0.46, 0.42, 0.42, 0.22, 0.34, 0.19, 0.11, 0.18, 0.33, 0.48, 0.91, 1.1, 0.32, 0.18, 0.09, NaN, 0.27, 0.31, 0.3, 0.27, 0.79, 0.43, 0.32, 0.48, 0.77, 0.32, 0.28, 0.4, 0.46, 0.69, 0.93, 0.71, 0.41, 0.3, 0.34, 0.44, 0.3, 1.03, 0.97, 0.35, 0.51, 1.21, 1.58, 0.67, 0.37, 0.04, 0.57, 0.67, 0.7, 0.47, 0.48, 0.38, 0.61, 0.8, 1.1, 0.39, 0.38, 0.48, 0.58, 0.55, 0.7, 0.7, 0.86, 0.61, 0.18, 0.9, 0.83, 0.9, 0.83, 0.61, 0.23, 0.22, 0.44, 0.41, 0.52, 0.71, 0.59, 0.9, 1.23, 1.56, 0.73, 0.69, 1.23, 1.28, 0.43, 0.97, 0.58, 0.44, 0.23, 0.46, 0.48, 0.22, 0.21, 0.66, 0.26, 0.55, 0.69, 0.84, 1.04, 0.83, 0.85, 0.63, 0.63, 0.17, 0.58, 0.66, 0.44, 0.53, 0.81, 0.63, 0.51, 0.15, 0.42, 0.77, 0.73, 0.87, 0.34, 0.51, 0.63, 0.05, 0.23, 0.87, 0.84, 0.39, 0.61, 0.89, 1.06, 1.08, 1.01, 1.05, 0.27, 0.79, 0.88, 1.34, 1.26, 1.42, 0.81, 1.46, 0.84, 0.54, 0.95, 1.42, 0.44, 0.73, 1.31, 1.75, 2.1, 2.36, 1.94, 2.31, 2.17, 2.35)), class = "data.frame", row.names = c(NA, -212L))

# fitness function
fitfun <- function(x, data, n){
  if(sum(x) == n){ # only calculate correlation if n genes/variable are included
    incl <- which(x == 1)
    res <- unname(cor.test(x = df[incl,"A"], y = df[incl,"B"], method = "pearson")$estimate)
  }else{
    res <- 0 # otherwise return zero fitness
  }
  return(res)
}

# set-up initial population
popSize = 200 # population size
set.seed(1)
initPop <- matrix(0, nrow = popSize, ncol = nrow(df))
for(i in seq(nrow(initPop))){
  initPop[i,sample(x = nrow(df), size = 50)] <- 1
}  
rowSums(initPop)    

# Run genetic algorithm
fitfun <- memoise::memoise(f = fitfun) # use memoisation to record unique genetic solutions (may help with speed)
fit <- ga(type = "binary", nBits = nrow(df), fitness = fitfun, data = df, 
  n = 50, popSize = popSize, maxiter = 1500, run = 200, seed = 1112,
  pmutation = 0.2, elitism = popSize*0.2,
  suggestions = initPop)
memoise::forget(f = fitfun)

# Result and plot
(incl <- which(fit@solution == 1)) # selected rows of df
fit@fitnessValue ; cor.test(x = df[incl,"A"], y = df[incl,"B"], method = "pearson")$estimate # double check (same)
plot(fit)

enter image description here

As per your comment on how to adjust the fitness function to target a specific correlation, see the example below. Since ga always maximizes fitness, you will need to flip the sign of the output (e.g. -sqrt((res-targ)^2) is the squared error to the target value).

# fitness function - correlation closest to target value
fitfun0 <- function(x, data, n, targ){
  if(sum(x) == n){ # only calculate correlation if n genes/variable are included
    incl <- which(x == 1)
    res <- unname(cor.test(x = df[incl,"A"], y = df[incl,"B"], method = "pearson")$estimate)
    res <- res 
  }else{
    res <- 100
  }
  res <- -sqrt((res-targ)^2) # reverse sign since fitness is maximized
  return(res)
}

# set-up initial population
popSize = 200 # population size
set.seed(1)
initPop <- matrix(0, nrow = popSize, ncol = nrow(df))
for(i in seq(nrow(initPop))){
  initPop[i,sample(x = nrow(df), size = 50)] <- 1
}  
rowSums(initPop)    

# Run genetic algorithm
fitfun0 <- memoise::memoise(f = fitfun0) # use memoisation to record unique genetic solutions (may help with speed)
fit <- ga(type = "binary", nBits = nrow(df), fitness = fitfun0, data = df, targ = -0.1,
  n = 50, popSize = popSize, maxiter = 1500, run = 200, seed = 1112,
  pmutation = 0.2, elitism = popSize*0.2,
  suggestions = initPop)
memoise::forget(f = fitfun0)

# Result and plot
(incl <- which(fit@solution == 1)) # selected rows of df
cor.test(x = df[incl,"A"], y = df[incl,"B"], method = "pearson")$estimate # close to target
plot(fit)


Answered By - Marc in the box
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why is value of beta distribution outside of [0, 1]?

 October 06, 2022     beta, probability, python, random, statistics     No comments   

Issue

This doesn't quite make sense to me. What I think the following code is doing is finding me the value of the beta distribution evaluated when p = 0.5 with alpha and beta equal to 10 each. Why is this value greater than 1?

I've implemented the function myself, seperate to this, using the relationship between the beta and gamma functions and I end up with roughly the same value.

>>> from scipy.stats import beta

>>> beta.pdf (0.5, 10, 10)

3.5239410400390625

Any advice would be appreciated.

There is obviously something lacking in my understanding - is this not actually the PDF?

Cheers.


Solution

see http://en.wikipedia.org/wiki/Beta_distribution

You are mistaking the PDF (Probability density function) and CDF (Cumulative distribution function)

CDF will be less than one at any point



Answered By - Joop
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, September 18, 2022

[FIXED] How do I make my Print Statement print on only one line?

 September 18, 2022     printing, python, random, while-loop     No comments   

Issue

In this program I am trying to print my code as "random letters here" instead of "r" "a" "n" "d" "o" "m" etc.

import random
import time

All = "abcdefghijklmnopqrstuvwxyz1234567890"
i = 0

while i < 6:
    time.sleep(1)
    print(All[random.randint(1,35)])
    i += 1

Solution

You can pass end='' to the print statement so that subsequent prints are not separated by a newline, which is the default behavior. Also, here it makes sense to use a range iterator with for instead of while.

Note: I've taken the liberty to cut the sleep time in half, so it's easier to test it out.

import random
import time

All = "abcdefghijklmnopqrstuvwxyz1234567890"

for _ in range(6):
    time.sleep(0.5)
    print(All[random.randint(1, 35)], end='')


Answered By - rv.kvetch
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, August 29, 2022

[FIXED] how do i get 5 random rows from a list

 August 29, 2022     csv, list, python, random, rows     No comments   

Issue

I'm pretty new to python, and my problem is, I'm trying to get 5 random rows from a list with a user input value condition, i get all the values from a chosen category and supposed to get only 5 rows from that randomly.

I've tried various solutions but it doesn't help me anyway sry for my english

here's the code:

import csv import random

with open("pontos.csv","r")as f:
    r=csv.reader(f,delimiter=",")
    l=list(r)
    
    
    def ex1():
    #ex1
        for x in l:
            val=x[1],x[5]
            print(':'" ".join(val),"\n")
    

    def ex2():
        #ex2
        # escolhe cultura
            val = input("Cat:\n").split(",")

            for row in l:
                if all([x in row for x in val]):
                    print(','.join(row),"\n")
    
    def ex3():
        n=4
    # print("categorias:\n Desporto,cultura,História,Paisagem,Praia,Gastronomia,Natureza,Natureza")
        # escolhe cultura
        val = input("Cat:\n").split(",")
        for row in l:
                if all(x in row for x in val):
                    print(row)
                    
def main():
    while True:
        escolha=int(input("Menu:\n 1-mostrar todos os locais \n 2-Mostrar todos os locais de uma categoria \n 3- mostrar locais de uma categoria ao acaso \n 4-Sair \n Escolha: "))
        if escolha==1:
            ex1()
        if escolha ==2:
            ex2()
        if escolha==3:
            ex3()
            if escolha== 4:
                break
        else:
            print("escolha invalida")

main()

note: its on ex3


Solution

you can use random.sample for select a random row (item) from a list. in main function your if escolha== 4: no effect because inside "if escolha==3:".

import csv
import random


with open("open_position.csv", "r") as f:
    r = csv.reader(f, delimiter=",")
    l = list(r)


def ex1():
    # ex1
    # used random.sample(list, number_sample)
    for x in random.sample(l, 5):
        val = x[1], x[5]
        print(':'" ".join(val), "\n")


def ex2():
    # ex2
    # escolhe cultura
    val = input("Cat:\n").split(",")

    # used random.sample(list, number_sample)
    for row in random.sample(l, 5):
        if all([x in row for x in val]):
            print(','.join(row), "\n")


def ex3():
    n = 4
    # print("categorias:\n Desporto,cultura,História,Paisagem,Praia,Gastronomia,Natureza,Natureza")
    # escolhe cultura
    val = input("Cat:\n").split(",")
    # used random.sample(list, number_sample)
    for row in random.sample(l, 5):
        if all(x in row for x in val):
            print(row)


def main():
    while True:
        escolha = int(input(
            "Menu:\n 1-mostrar todos os locais \n 2-Mostrar todos os locais de uma categoria \n 3- mostrar locais de uma categoria ao acaso \n 4-Sair \n Escolha: "))
        if escolha == 1:
            ex1()
        if escolha == 2:
            ex2()
        if escolha == 3:
            ex3()
            # this is incorrect
            # if escolha == 4:
            #     break
        if escolha == 4:
            break
        else:
            print("escolha invalida")


main()


Answered By - ali
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, August 18, 2022

[FIXED] How to loop print output and write each result to csv?

 August 18, 2022     csv, loops, output, python, random     No comments   

Issue

I have written the following code to generate a random 12 number string:

import uuid

def my_random_string(string_length=12):
    """Returns a random string of length string_length."""
    random = str(uuid.uuid4()) # Convert UUID format to a Python string.
    random = random.upper() # Make all characters uppercase.
    random = random.replace("-","") # Remove the UUID '-'.
    return random[0:string_length] # Return the random string.

print(my_random_string(12)) # For example, D9E50Cd

How can I loop it and save each string output to a .csv file?


Solution

The code below will output random strings (using the code you provided) to a CSV file.

import csv
import uuid

def my_random_string(string_length=12):
    """Returns a random string of length string_length."""
    random = str(uuid.uuid4()) # Convert UUID format to a Python string.
    random = random.upper() # Make all characters uppercase.
    random = random.replace("-","") # Remove the UUID '-'.
    return random[0:string_length] # Return the random string.

def random_string_to_csv(file_name, column_header, num_rows):
    num_cols = len(column_header)
    with open(file_name, mode='w', newline = '') as f:
        rand_string_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
        rand_string_writer.writerow(column_header)
        for i in range(num_rows):
            row = [my_random_string() for j in range(num_cols)]
            rand_string_writer.writerow(row)

column_header = ['col1', 'col2', 'col3', 'col4']
num_rows = 5
random_string_to_csv('test.csv', column_header, num_rows)

CSV files often have column headers, so I included that in the code example. You could easily change the function definition to exclude a column header and explicitly define the number of columns when the function is called, like this:

def random_string_to_csv(file_name, num_cols, num_rows):
    with open(file_name, mode='w', newline = '') as f:
        rand_string_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
        for i in range(num_rows):
            row = [my_random_string() for j in range(num_cols)]
            rand_string_writer.writerow(row)


Answered By - Steve Bremer
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, August 9, 2022

[FIXED] How to generate random Decimal128, Decimal256 numbers with Python

 August 09, 2022     clickhouse, decimal, python, random     No comments   

Issue

I am making a test for ClickHouse database for verifying Decimal data types. According to documentation:

Decimal Parameters:

P - precision. Valid range: [1 : 76]. Determines how many decimal digits number can have (including fraction). S - scale. Valid range: [0 : P]. Determines how many decimal digits fraction can have. Depending on P parameter value Decimal(P, S) is a synonym for:

  • P from [1 : 9] - for Decimal32(S)
  • P from [10 : 18] - for Decimal64(S)
  • P from [19 : 38] - for Decimal128(S)
  • P from [39 : 76] - for Decimal256(S)

I am trying to generate random numbers for all of these data types. I've found a good answer already and this is how I used it:

Decimal32:

>>> decimal.Decimal(random.randint(-2147483648, 2147483647))/1000
Decimal('-47484.47')

Decimal64:

>>> decimal.Decimal(random.randint(-9223372036854775808, 9223372036854775807))/100000000000
Decimal('-62028733.96730274309')

These two give me the expected result. But, my function for Decimal128 already is too long and produces wrong result:

>>> decimal.Decimal(random.randint(-170141183460469231731687303715884105728, 170141183460469231731687303715884105727))/1000000000000000000000
Decimal('149971182339396169.8957534906')

Question:

How can I generate random Decimal128 and Decimal256?

Please suggest what I should use.


Solution

The problem you face, is that the precisison is not set high enough to record all the digits in your division. The simplest way to fix it, is to increase the precision (at the expense of the division and all other operations taking longer to execute. The default precision is set to 28, that is 28 correct fractional digits. This is enough for Decimal64, but too few for Decimal128 and Decimal256

To update the precision you write:

decimal.getcontext().prec = 38 # Maximum number of fractional digits in Decimal128

After this your code should work. Of course, for Decimal256, the precision needs to be set to 76.



Answered By - JohanL
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, August 8, 2022

[FIXED] How do i store a binary number in an array?

 August 08, 2022     arrays, binary, c++, decimal, random     No comments   

Issue

Ok, so i been working on this right here that is intended to be part of a encryption software that works synonymously like 2fa

 #include <iostream>
 #include <cstdio>     
 #include <cstdlib>   
 #include <ctime>    
 using namespace std;

 int main()
 {


int RGX;
int box[32];

srand (time(NULL));


RGX = rand() % 100000000 + 9999999;

cout << "Random Generated One Time HEX #:" << endl;

cout << std::hex << RGX << endl;


while(RGX!=1 || 0)
{

int m = RGX % 2;
cout << " " << m << " ";


RGX = RGX / 2;


cout << RGX << endl;



} 

return 0;
}

Here is a sample of what it outputs:

Random Generated One Time HEX #:
3ff3c70
0 1ff9e38
0 ffcf1c
0 7fe78e
0 3ff3c7
1 1ff9e3
1 ffcf1
1 7fe78
0 3ff3c
0 1ff9e
0 ffcf
1 7fe7
1 3ff3
1 1ff9
1 ffc
0 7fe
0 3ff
1 1ff
1 ff
1 7f
1 3f
1 1f
1 f
1 7
1 3
1 1


** Process exited - Return Code: 0 **

The result is different each time since it's randomized, i'm still not finished. But what i need to know is how do i store the binary value in an array, the binary value are the numbers on the left.


Solution

You can use a std::bitset instead of manually extracting bits and the array:

#include <iostream>
#include <ctime> 
#include <cstdlib>   
#include <bitset>

int main() {
    srand (time(NULL));
    int RGX = rand() % 100000000 + 9999999;

    std::cout << "Random Generated One Time HEX #: \n";
    std::cout << std::hex << RGX << "\n";
    std::bitset<32> box(RGX);
    for (int i=0;i<32;++i){
        std::cout << box[i];
    }
 
}

Possible output:

Random Generated One Time HEX #: 
478ada7
11100101101101010001111000100000

No inside the brackets after " while(RGX!=1 || 0) " it uses % and divides by 2 up until it gets to 1 or 0.

No. Thats not what that condition says. The condition says "loop while (RGX is not equal to 1) or 0". As 0 is always false when converted to bool, your condition is equivalent to while(RGX != 1).



Answered By - 463035818_is_not_a_number
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, July 29, 2022

[FIXED] How to generate a 500x500 pixel image in PIL with random place but i can choose what colors?

 July 29, 2022     colors, image, python, python-imaging-library, random     No comments   

Issue

So for example I want the colors red, blue, and yellow in the 500x500 and the placement has to be random. I was looking at some posts and the documentation but couldn't really find it. With the image I'm going to convert it to a pygame surface using "pygame.image.fromstring".

it should be something like this but in 500x500 and the colors only should be randomized with red, blue and yellow, instead of all those random colors enter image description here

Thank You!


Solution

If you only want three colours (or any other number under 256) you should consider using a palette image where, rather than storing three bytes for the RGB values of each pixel, you store a single byte which is the index into a palette (or table) of 256 colours. It is much more efficient. See discussion here.

So, the fastest and most memory efficient way is to initialise your image to random integers in range 0..2 and then push in a palette of your 3 colours:

import numpy as np
from PIL import Image

# Make a Numpy array 500x500 of random integers 0, 1 or 2
na = np.random.randint(0, 3, (500,500), np.uint8)

# Convert to PIL Image
im = Image.fromarray(na)

# Push in 3-entry palette with red, blue and yellow:
im.putpalette([255,0,0, 0,0,255, 255,255,0])

# Save
im.save('result.png')

enter image description here


That takes 1ms on my Mac compared to 180ms for iterating over the pixels and choosing one of 3 RGB colours for each, and creates a 50kB palletised output file rather than the 120kB RGB output file you get with the other method.



Answered By - Mark Setchell
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to open a random image from specified folder/directory in Python OpenCV

 July 29, 2022     image, opencv, python, random     No comments   

Issue

I want my program to open a random image from the folder.

This works:

import cv2
import os
import random

capture = cv2.imread(".Images/IMG_3225.JPEG")

But when I want to do this random it doesn't work:

file = random.choice(os.listdir("./images/"))
capture = cv2.imread(file)

I'm getting the following error:

cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'

What am I doing wrong??


Solution

This is one of the small mistakes that we usually overlook while working on it. It is mainly because os.listdir returns the contents of a folder. When you are using os.listdir, it just returns file name. As a result it is running like capture = cv2.imread("file_name.png") whereas it should be capture = cv2.imread("path/file_name.png")

So when you are working, try to use the code snippet:

path = './images'
file = random.choice(os.listdir("./images/"))
capture = cv2.imread(os.path.join(path,file))

This will help you run the code.



Answered By - Joyanta J. Mondal
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, July 21, 2022

[FIXED] How to generate random integers with multiple ranges?

 July 21, 2022     integer, python, random     No comments   

Issue

I've run into confusion in generating X amount of random integers from different sets of (a,b). For example, I would like to generate 5 random integers coming from (1,5), (9,15),and (21,27). My code generates 5 random integers but only between 21 and 27 and not from the other two. Ideally I'd like to see something like 1,4,13,22,25 instead of 21,21,25,24,27.

My code:

from random import randint
n = 0
while n < 5:
    n += 1
    for i in (randint(1,5),randint(9,15),randint(21,27)):
        x = i
    print i

Solution

Not ideal but it works.

First it gets random numbers from all ranges and next it selects (randomly) one value.

from random import randint, choice

for _ in range(5):
    print(choice([randint(1,5),randint(9,15),randint(21,27)]))

As Blender said - cleaner version - first it selects (randomly) one range and later it gets random value from this range.

from random import randint, choice

for _ in range(5):
    r = choice([(1,5),(9,15),(21,27)])
    print(randint(*r))


Answered By - furas
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is the fastest way to generate a random integer in javascript?

 July 21, 2022     floating-point, integer, javascript, math, random     No comments   

Issue

Normally this is how you get a random number in javascript.

Math.random();

However, this method seems to be inefficient when it comes to generating random integers.

Firstly, the random function has to generate a random decimal, like 0.1036098338663578, then it has to be multiplied to a suitable range (10.464593220502138). Finally, the floor function subtracts the decimals to produce the result (which in this case, 10).

var random_integer = Math.floor(Math.random()*101);

Is there a faster way to generate random integers in javascript?

Edit1:

I am using this for creating a canvas HTML5 game. The FPS is about 50, and my code is pretty optimized, apart from generating a random number.


Solution

This code is faster... to type.

var random_integer = Math.random()*101|0;

It won't work right for huge numbers though.

(and it doesn't run any faster, at least not in chrome.)

You could achieve a much faster speed during the game if you generate the random numbers beforehand, though.

for (var i=1e6, lookupTable=[]; i--;) {
  lookupTable.push(Math.random()*101|0);
}
function lookup() {
  return ++i >= lookupTable.length ? lookupTable[i=0] : lookupTable[i];
}

lookup will rotate through an array with a million random integers. It is much faster than calling random and floor (of course, there is a "loading time" penalty up front from generating the lookup table).



Answered By - Dagg Nabbit
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 20, 2022

[FIXED] How to generate random BigInt within a range in plain JavaScript (not Node.js)?

 July 20, 2022     bigint, integer, javascript, random     No comments   

Issue

There is this excellent question for basic random numbers in JavaScript within a specific range:

Generating random whole numbers in JavaScript in a specific range?

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

How do you do the same thing with BigInt in plain JavaScript (i.e. not with Node.js or using crypto.randomBytes)? Something that works across environments (with BigInt support)?

(Thinking out loud...) You can't just change the numbers in that formula to be appended with n to make them BigInts, because Math.random() returns a non-BigInt. An example of Math.random() returns 0.5427862726372646, that is 16 decimal places. But if I have a BigInt that is like 41223334444555556666667777777888888889999999997n, that is a 47 digit number, so multiplying 0.5427862726372646 * (10**46) gives 5.4278627263726465e+45. Wrap that in BigInt and you get BigInt(0.5427862726372646 * (10**46)) equal to 5427862726372646467145376115182187925303459840n. Hmmm... Is that the solution?

41223334444555556666667777777888888889999999997n
5427862726372646467145376115182187925303459840n

How did that work out? If that is the solution I just stumbled upon it just now trying to ask this question. Can you double check this is correct and confirm, and perhaps explain how a regular JavaScript number (with e+45 representation), when passed to the BigInt constructor, results in a seemingly accurately detailed BigInt value? So let me try then.

BigInt(Math.random() * (10 ** 45))
// => 329069627052628509799118993772820125779492864n

Hmmm. I don't understand, Math.random() was only to 16 digits?

const rand = Math.random()
// => 0.7894008119121056

BigInt(rand * (10 ** 45))
// => 789400811912105533187528403423793891092987904n

That doesn't make sense, I would have expected:

789400811912105600000000000000000000000000000

That is, 0.7894008119121056 shifted over 45 decimal places.

Not sure why this is working, is this only in Chrome?

So one final test:

console.log('10 ** 35 <=> 10 ** 45')
console.log(rint(10 ** 35, 10 ** 45).toString())
console.log('10 ** 35 <=> 10 ** 45')
console.log(rint(10 ** 35, 10 ** 45).toString())
console.log('10 ** 20 <=> 10 ** 40')
console.log(rint(10 ** 20, 10 ** 40).toString())
console.log('10 ** 20 <=> 10 ** 40')
console.log(rint(10 ** 20, 10 ** 40).toString())

function rint(min, max) {
  return BigInt(Math.random() * max - min + 1) + BigInt(min)
}

I am getting e.g.:

10 ** 35 <=> 10 ** 45 485253180777775593983353876860021068179439616n
10 ** 35 <=> 10 ** 45 178233587725359997576391063983941630941986816n
10 ** 20 <=> 10 ** 40 8245114695932740733462636549119006474240n
10 ** 20 <=> 10 ** 40 7214182941774644957099293094661617352704n

Is this a correct implementation then? How would you implement this then to get a random integer from 0 to an arbitrarily large BigInt then?


Solution

JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard.

This format stores numbers in 64 bits (where the number (the fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and the sign in bit 63).

Math.random() returns only positive numbers, therefore the sign bit is irrelevant. That means that Math.random() can not produce more that 2 ** 63 different values, in fact it is less than that, as Math.random() returns only values between 0 and 1 (which means that depending on the implementation none or not all of the 11 exponent bits are used). When your range is larger than that, Math.random() will not be able to generate every number within that range. Within the limit, your approach should work.



Answered By - Mario Varchmin
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, July 19, 2022

[FIXED] How to convert an integer to its ascii equivalent

 July 19, 2022     ascii, c++, char, integer, random     No comments   

Issue

Context: I am making myself a password generator in c++, basically it uses rand to generate numbers, and these numbers correspond directly to ASCII characters.

So, generating the numbers is easy, but i need to convert this to their ASCII equivalents to actually make a usable password.

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main ()
{
    //Initializing variables.
    int type = 0;
    int character = 0;
    char print = character;

    //Generator.
    srand(time(NULL));
    for (int i=0; i<10;i++)
    {
        type = rand()%(3-1+1)+1;//Determines: 1 = Uppercase, 2 = Lowercase, 3 = Number.
        if (type == 1)//If Uppercase.
        {
            character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
            cout<<print<<endl;
        }
        if (type == 2)//If Lowercase.
        {
            character = rand()%(122-97+1)+97;//Determine Lowercase character to be generated.
            cout<<print<<endl;
        }
        if (type == 3)//If Numerical.
        {
            character = rand()%(57-48+1)+48;//Determines Number to be generated.
            cout<<print<<endl;
        }
    }
}

In the code i posted above, you can see i last tried blatantly telling the program that the variable "character" needs to be used as an actually character.

Ok so there seems to be a bit of confusion. Rand generates a number say between 65 and 90. These numbers correspond to capital letters on the ASCII table. I want to print to the console the letter, not the generated number.


Solution

When you write this

char print = character;

you tell the compiler that you want it to initialize variable print to the current value of variable character (which happens to be zero at the time). If you want the current value to be set to a variable of different type, you need to do it after a reassignment of character:

character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
print = (char)character;
cout<<print<<endl;

You do not have to do reassignment, though, because a cast directly before printing will be sufficient:

character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
cout<<(char)character<<endl;

Note: although it is fine to use decimal values of ASCII characters, the code becomes easier to read if you use character constants instead:

character = rand()%('Z'-'A'+1)+'A';


Answered By - Sergey Kalinichenko
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, July 9, 2022

[FIXED] How do I generate a string that contains a keyword?

 July 09, 2022     keyword, random, string, typescript     No comments   

Issue

I'm currently making a program with many functions that utilise Math.rand(). I'm trying to generate a string with a given keyword (in this case, lathe). I want the program to log a string that has "lathe" (or any version of it, with capitals or not), but everything I've tried has the program hit its call stack size limit (I understand exactly why, I want the program to generate a string with the word without it hitting its call stack size).

What I have tried:

function generateStringWithKeyword(randNum: number) {
  const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
  let result = "";
  for(let i = 0; i < randNum; i++) {
    result += chars[Math.floor(Math.random() * chars.length)];
    if(result.includes("lathe")) {
      continue;
    } else {
      generateStringWithKeyword(randNum);
    }
  }
  console.log(result);
}

This is what I have now, after doing brief research on stackoverflow I learned that it might have been better to add the if/else block with a continue, rather than using

if(!result.includes("lathe")) return generateStringWithKeyword(randNum);

But both ways I had hit the call stack size limit.


Solution

A "correct" version of your algorithm, written as an iterative function instead of as a recursive one so as not to exceed stack depth, would look something like this:

function generateStringWithKeyword(randNum: number) {
    const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
    let result = "";
    let attemptCnt = 0;
    while (!result.toLowerCase().includes("lathe")) {
        attemptCnt++;
        result = "";
        for (let i = 0; i < randNum; i++) {
            result += chars[Math.floor(Math.random() * chars.length)];
        }
        if (attemptCnt > 1e6) {
            console.log("I GIVE UP");
            return;
        }
    }
    console.log(result);
    return result;
}

I don't like when my browser hangs because of a script that won't finish, so I put a maximum attempt count in there. A million chances seems reasonable. When you try it out, this happens:

generateStringWithKeyword(10); // I GIVE UP

Which makes sense; let's perform a rough back-of-the-envelope probability calculation to see how long we might expect this to take. The chance that "lathe" will appear in some case at position 1 of the word is (2/64)×(2/64)×(2×64)×(2/64)×(2/64) ("L" or "l" appears first, followed by "A" or "a", etc) which is approximately 3×10-8. For a word of length 10, "lathe" can appear starting at positions 1, 2, 3, 4, 5, or 6. While this isn't exactly correct, let's think of this as multiplying your chances by 6 of getting the word somewhere, so the actual chance of getting a valid result is somewhere around 1.8×10-7. So we can expect that you'd need to make approximately 1 ÷ 1.8×10-7 = 5.6 million chances to succeed.

Oh, darn, I only gave it a million. Let's up that to 10 million and try again:

generateStringWithKeyword(10); // "lATHELEYSc"

Great! Although, it does sometimes still give up. And really, an algorithm which needs millions of tries before it succeeds is very, very inefficient. You might want to read about bogosort, a sorting algorithm which works by randomly shuffling things and checking to see if they are sorted, and it keeps trying until it works. It's used for educational purposes to highlight how such techniques don't really perform well enough to be practical. Nobody would ever want to use such an algorithm for real.


So how would you do this "the right" way? Well, my suggestion here is to just build your result correctly the first time. If you have 10 characters and 5 of them need to be "lathe" in some case, then you will need 5 truly random characters. So randomly decide how many of those letters should be before "lathe". If you pick 2, for example, then put 2 random characters, plus "lathe" in a random case, plus 3 more random characters.

It could be something like this, where I mostly use your same style of for-loops and += string concatenation:

function generateStringWithKeyword(randNum: number) {
    const keyword = "lathe";
    if (randNum < keyword.length) throw new Error(
        "This is not possible; \"" + keyword + "\" doesn't fit in " + randNum + " characters"
    );
    const actuallyRandNum = randNum - keyword.length;
    const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
    let result = "";
    const kwInsertionPoint = Math.floor(Math.random() * (actuallyRandNum + 1));
    for (let i = 0; i < kwInsertionPoint; i++) {
        result += chars[Math.floor(Math.random() * chars.length)];
    }
    for (let i = 0; i < keyword.length; i++) {
        result += Math.random() < 0.5 ? keyword[i].toLowerCase() : keyword[i].toUpperCase();
    }
    for (let i = kwInsertionPoint; i < actuallyRandNum; i++) {
        result += chars[Math.floor(Math.random() * chars.length)];
    }
    return result;
}

If you run this, you will see that it is very efficient, and never gives up:

console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(5)).join(" "));
// "lathE LaThe lATHe LatHe"

console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(7)).join(" "));
// "p6lAtHe laThE01 nlaTheK lATHeRJ" 

console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(10)).join(" "));
// "giMqzLaTHe 5klAthegBo oVdLatHe0q twNlATheCr"

Playground link to code



Answered By - jcalz
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, May 13, 2022

[FIXED] How to append items in multiple lists having same index into their original lists?

 May 13, 2022     append, for-loop, list, python, random     No comments   

Issue

I have an arbitrary number of lists, 3 taken here for example. The lists will have the same number of items and I want to append the items having the same index into their original list. This has to be done with some probability.

import random

individuals = 6
lists = 3

L1 = ['A', 'A', 'A', 'A', 'a', 'a']
L2 = ['B', 'B', 'B', 'B', 'b', 'b']
L3 = ['C', 'C', 'C', 'C', 'c', 'c']

for i in range(1, lists+1):
    for j in range(0, 6): 
      if random.random() <= 0.8:  
        ((eval(f'L{i}'))).append((eval(f'L{i}{[j]}')))
      else:
        pass

for i in range(1, lists+1):
    print(eval(f'L{i}'))

What I want is that L1[0], L2[0] and L3[0] be appended into their original list if they satisfy a probability. Then we do the same for L1[0], L2[1] and L3[2] and so on until we run out of the original items(6 in this example). If the probability is not satisfied, all items having the same index will not get appended.

The current result is giving me unequal sized lists at the end. The lists should be equal-sized as what I need is either all lists get appended at once or they don't.

Current result:

['A', 'A', 'A', 'A', 'a', 'a', 'A', 'A', 'a', 'a']
['B', 'B', 'B', 'b', 'b', 'b', 'B', 'B', 'B', 'b', 'b']
['C', 'C', 'C', 'c', 'c', 'c', 'C', 'C', 'C', 'c', 'c']

Solution

IIUC, you only need to reverse the order of the two for loops:

import random

individuals = 6
lists = 3

L1 = ['A', 'A', 'A', 'A', 'a', 'a']
L2 = ['B', 'B', 'B', 'B', 'b', 'b']
L3 = ['C', 'C', 'C', 'C', 'c', 'c']

for j in range(0, 6): 
    p = random.random()             # Random probability (same for all lists)
    if p <= 0.8:
        for i in range(1, lists+1): # all list get appended
            ((eval(f'L{i}'))).append((eval(f'L{i}{[j]}')))

for i in range(1, lists+1):
    print(eval(f'L{i}'))

Output

['A', 'A', 'A', 'A', 'a', 'a', 'A', 'A', 'A', 'a', 'a']
['B', 'B', 'B', 'B', 'b', 'b', 'B', 'B', 'B', 'b', 'b']
['C', 'C', 'C', 'C', 'c', 'c', 'C', 'C', 'C', 'c', 'c']
​


Answered By - DarrylG
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing