How to Generate incremental range of numbers - php

I want to generate range of numbers based on to total number of users in my database
<?php
//Let's assume the total number of users is 100
foreach( range(0, 100, 20) as $number){
$ranges=$number.'-'.($number+20);
echo'<button>'.$ranges.'</button>';
}
//Result:
0-20
20-40
40-60
60-80
80-100
100-120
?>
What i needed is 0-20, 21-40, 41-60, 61-80, 81-100.
I need to stop at 100 i.e the total number of users and not up to 100-120
or if you have a better approach

So two issues to deal with:
Stop at 100. Then you just decrease the loop's stop value a bit (e.g. reduce by 1, i.e. 99)
Start at one more than the previous range's end value, except for the first range which should start at 0. You can add !!$number to achieve that. This is a boolean which is true when $number is non-zero, and will coerce to a 0 or a 1, exactly what is needed.
Code:
foreach(range(0, 100 - 1, 20) as $number) {
$ranges = ($number + !!$number) . '-' . ($number + 20);
echo '<button>' . $ranges . '</button>';
}

Related

randomness numbers using loop while to draw numbers 21

Using a While loop to create a script that will randomly draw numbers from 0 to 100. Until the draw of number 21. I want a draw number 21 using loop while.
The trick is to keep the loop running until the number is equal to 21.
So in the condition for the while-loop you have to check if the number is not equal to 21, then regenerate a random number. If the number is equal to 21 it will jump out of the loop and in this case display the number which is obviously 21.
$number = -1;
while ($number != 21) {
$number = rand(0, 100);
}
echo $number;

Weighted random with two weights

In PHP I need to pick a random number between 1 and 100 with two weights. These weights can also be between 1 and 100. If both weights are low I would need the random number weighted low, high weighted high. If one weight is high and one is low, or if they are both mid ranged, I would expect random number to be weighted random around the 50s.
I'm not sure the best way to go about this. Any advice would be great!
You would need more information for those weights: how heavy do they weigh on the probability for that index, and how much does that probability increase spread around to neighbouring indexes.
I will here assume that these parameters can be provided, and that the probabilities spread around with a normal distribution.
I would suggest to create an array with the probabilities for each of the indexes. You start out with a constant (e.g. 1) for each of them, which means all indexes have the same probability of being selected.
Then a function could apply one weight to it, given an index where the weight should be centred at, the weight itself (how much does it increase the existing "weight" at that index), and the spread (the standard deviation of the normal distribution with which the generated probability will be spread around).
Here is the code that does such a thing. It is not intended to be statistically sound, but I believe it will do the job in a satisfactory way:
function density($x, $median, $stddev) {
// See https://en.wikipedia.org/wiki/Probability_density_function#Further_details
return exp(-pow($x - $median,2)/(2*pow($stddev,2))/(2*pi()*$stddev));
}
function homogeneous_distribution($size) {
return array_fill(0, $size, 1);
}
function add_weight(&$distr, $median, $weight, $spread) {
foreach ($distr as $i => &$prob) {
$prob += $weight * density($i, $median, $spread);
}
}
function random_float() { // between 0 and 1 (exclusive)
return mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax();
}
function weighted_random($distr) {
$r = random_float() * array_sum($distr);
foreach ($distr as $i => $prob) {
$r -= $prob;
if ($r < 0) return $i;
}
}
// Example use with 20 instead of 100.
$distr = homogeneous_distribution(20); // range is 0 .. 19
add_weight($distr, 0, 4, 1); // at index 0, put a weight of 4, spreading with 1
add_weight($distr, 16, 8, 0.5); // at index 16, put a weight of 8, spreading with 0.2
// Print distribution (weights for every index):
echo "DISTRIBUTION:\n";
print_r($distr);
// Get 10 weighted random indexes from this distribution:
echo "RANDOM SAMPLES:\n";
foreach (range(0, 10) as $i) {
echo weighted_random($distr) . "\n";
}
See it run on rextester.com

PHP or PHPUnit. Select a random option from drop down excluding selected one

If my drop down has 10 options to select from, and option 4 is selected, how can I write the code to select an option from 1-10 exluding 4?
I know rand(1, 10) picks a random number from 1 to 10, but it sometimes can land on 4. How can I make sure that it doesn't pick the number 4, or any number that is already selected?
In general, if you have options between 1 and n and the m-th option is selected, you can generate a number uniformly at random between 1 and n excluding m by using the following algorithm:
<?php
function get_rand($n,$m)
{
$r = rand(1,$n-1); //generate one of $n-1 numbers since $m is not selectable
if($r >= $m) //if $r is smaller than $m we're done
$r++; //otherwise add one to $r
return($r);
}
?>
In your case, with n=10 and m=4, we will generate a number between 1 and 9. If it is in the range [1,3] we will return that number. If it is in the range [4,9] we will add 1 and return a number in the range [5,10]. This means we return with the same probability any integer number in the range [1,3] U [5,10].
What about something like that?
<?php
$filtered_key = 4;
$range = range(1, 10);
unset($range[$filtered_key]);
$key = array_rand($range);
echo $key;

User defined number ranges

I have a function where for a specific number range a percentage has to be applied:
0-100 EUR: 5%
>100 EUR: 3%
This number ranges and percentages should be user-defined.
The implementation should be as simple as possible.
What would you suggest for specifying the ranges and calculating the result?
Assuming you have access to some kind of database, I'd store the values there. You would need 3 tables at minimum:
ranges
id_range
from_number
until_number
percentage
users
id_user
user-ranges
id_range
id_user
Make the from_number and until_number columns nullable, to represent anything up to X and anything after Y.
Here's my short approach for calculating the result with defined rules in an array
$rules = array(
5 => '0-100 EUR', // here the percentages and their corresponding values
3 => '> 100 EUR'
);
$rand = mt_rand(0, 100); // calculate a random percent value
$lastPercentage = 0;
foreach($rules as $percentage => $val) {
// create a range from 0-5 (in the first iteration)
// every next iteration it is lastPercentage + 1 (5 + 1 in this case) to lastPercentage + current percentage
$range = range($lastPercentage, $percentage + $lastPercentage);
// yep, it is in the percentage range
if (in_array($rand, $range)) {
echo $lastPercentage,' < '.$rand.' > '.($percentage + $lastPercentage);
}
$lastPercentage = $percentage + 1; // +1 so that there are no overlapping ranges
}

Generating a random number but with a twist

I need to generate a random number.
But the twist is that the % of lower numbers should be greater than the higher.
For example.
rand > 1 to 100
13,
15,
12,
16,
87,
15,
27,
12,
1,
12,
98,
12,
53,
12,
14....
The bold integers will be the ones return from the 1-100 range.
The math should be like so rand = a number lower than max/2
Hope you guys can help.
Ps, How would a matrix come into this ? im not superior at maths :(
The abs answer seems to be the one.
$up = $down = 0;
while(true)
{
if(abs((rand()%150)-50) < 50)
{
$up++;
}else
{
$down++;
}
if( ($up + $down) == 500){ break;}
}
echo $up . '/' . $down;
how about
n = abs((rand()%150)-50)
$x = rand(0,1) ? rand(1,100) : rand(1,50);
Simple method: the first rand(0,1) selects between the two cases. Either 1..50 or 1..100 as random range. Since 1,100 already encompases 1,50, the latter range is selected 100% of the time, the former case only in 1 of 2 runs.
If you want a distribution where the highest numer 99 gets selected almost never, but the lower numbers 1..20 pretty frequent, then a simple rand(1,rand(1,100)) would do.
$rand = (rand() * rand()) / (getrandmax() * getrandmax());
This will give you a random number between 0 and 1 with a high probability of falling into the lower end of the range and the probability of a larger number decreasing exponentially. You can then scale this result to any range that you want.

Categories