I'm building an application to help customer calculate various product prices.
Right now I'm building a feature where user enters a single number to the application and submits a form. Based on that number, I would like to define another variables value.
What I'd like to achieve
If user input is number between 1-10, set variable number to 200.
If user input is number between 11-20, set variable number to 400.
If user input is number between 21-30, set variable number to 600.
If user input is number between 31-40, set variable number to 800.
If user input is number between 41-50, set variable number to 1000.
And so on... So basically increasing by 200 every tenth.
Of course, I could do something like this:
$userInput = 11;
$result;
if($userInput => 1 && $userInput =< 10)
$result = 200;
if($userInput => 11 && $userInput =< 20)
$result = 400;
if($userInput => 21 && $userInput =< 30)
$result = 600;
But it isn't really a great solution, because it takes lot of code and if user sets number out of the determined range it doesn't work..
How can I implement this with as little amount of code as possible?
If I have the math right, you just need to divide the number by 10, and use ceil to round the fraction up. From there, multiply it by 200;
function getVariable($num) {
$divisor = ceil($num / 10);
return $divisor * 200;
}
echo getVariable(1)."\n"; // 200
echo getVariable(6)."\n"; // 200
echo getVariable(13)."\n"; // 400
echo getVariable(27)."\n"; // 600
echo getVariable(48)."\n"; // 1000
echo getVariable(50)."\n"; // 1000
echo getVariable(88)."\n"; // 1800
echo getVariable(100)."\n"; // 2000
Related
First post, please be gentle.
I'm trying to create a simple market script where for example I have a number in my database ie 50.00 and I want to run a cron job php script to increase or decrease this randomly to a minimum of 10.00 and a maximum of 75.00.
I thought a random 0,1 follow by 2 if statements 1 rand(-0.01,0.05) if 2 rand(0.01,0.05) then $sql = "UPDATE price SET oil='RESULT'";
I've tried a few times at the above but I can't get it to run and the other crons in the file work.
<?php
//Get Oil Price from database
$oilchange = rand(1, 2);
if ($oilchange == '1') {
$oilnew = rand(0.01,0.05);
//Oil price from database times oil new.
} else {
$oilnew = rand(-0.01,-0.05);
//Oil price from database times oil new.
}
// Update Price
?>
Rand is for integers (whole numbers)
First up, your use of rand between two decimal values (called floats) won't work, as rand is for integers only. So, you'd first want to have a random function which does output floats, like this:
function randomFloat($min = 0, $max = 1) {
return $min + mt_rand() / mt_getrandmax() * ($max - $min);
}
Then we can safely use it between, say, 1% and 5%:
$percentSwing = randomFloat(0.01, 0.05);
Rand defaults to being 0 or 1. We can use that to randomly invert it, so we also cover -1% to -5%:
$percentSwing *= rand() ? 1 : -1;
The above could also be written like this:
if(rand() == 1){
// Do nothing:
$percentSwing *= 1;
}else{
// Invert it:
$percentSwing *= -1;
}
So, we now know how much we need to swing the number by. Let's say it was $oilPrice:
$oilPrice = 48;
We can just multiply the percent swing by that number to get the amount it's changing by, then add it back on:
$oilPrice += $percentSwing * $oilPrice;
So far so good! Now we need to make sure the price did not go out of our fixed range of 10 to 75. Assuming you want to 'clamp' the number - that means if it goes below 10, it's set at 10 and vice-versa, that's done like this:
if( $oilPrice < 10 ){
// It went below 10 - clamp it:
$oilPrice = 10;
}else if( $oilPrice > 75 ){
// It went above 75 - clamp it:
$oilPrice = 75;
}
The above can also be represented in one line, like this:
$oilPrice = max(10, min(75, $oilPrice));
So, that gives us the whole thing:
function randomFloat($min = 0, $max = 1) {
return $min + mt_rand() / mt_getrandmax() * ($max - $min);
}
// Define the oil price (e.g. pull from your database):
$oilPrice = 48;
// get a random 1% to 5% swing:
$percentSwing = randomFloat(0.01, 0.05);
// Invert it 50% of the time:
$percentSwing *= rand() ? 1 : -1;
// Swing the price now:
$oilPrice += $percentSwing * $oilPrice;
// Clamp it:
$oilPrice = max(10, min(75, $oilPrice));
// Output something!
echo $oilPrice;
As a side note here, money in real financial systems is never stored as a float, because rounding errors can cause major problems.
So I have an array of value
if(isset($wholeprices) && !empty($wholeprices)){
foreach($wholeprices as $wholeprice){
$get_wholeUnits[] = $wholeprice->Units;
$get_wholePrices[] = $wholeprice->UnitsPrice;
}
this $get_wholeUnits[] has values such as the following
array(
0=>200,
1=>150
);
this $get_wholePrices[] has values such as the following
array(
0=>50,
1>70
);
for($get_whol_price=0;$get_whol_price<count($get_wholeUnits);$get_whol_price++){
if(350 >= $get_wholeUnits[$get_whol_price]){
$wholesale_price_Set = $get_wholeUnits[$get_whol_price];
$gross_price = 350 * $get_wholePrices[$get_whol_price];
}
}
Now I have a number 350, I want it to be calculated only with 200 as 200 closest to 350. But if I have number as 190 , than it should calculate with 150 , as it is closest.
Since my code (for 350) has 200 at the first index, and the first if condition to true, it will result me the value, but at the same time, at the second index, again the if condition executes.
I just want a simple behavior that, whatever the number is, it should identify the closest number irrespective of the index they fall in.
You have to process the whole array in order to find the closest value.
You need to do something like this
$valueToCompare = 300;
$arrayOfvalues = [/*Some different values here*/];
$closestValue = arrayOfvalues[0];
for($i=1; $i<count($arrayOfvalues);$i++){
if(abs($valueToCompare - $closestValue) > abs($valueToCompare - $arrayOfvalues[$i]))
$closestValue = $arrayOfvalues[$i];
}
At last, you will have the nearest value from the array inside the $closestValue variable.
I'm not 100% if i get what you are asking but if i'm not wrong this would work.
for($get_whol_price=0;$get_whol_price<count($get_wholeUnits);$get_whol_price++){
if(350 >= $get_wholeUnits[$get_whol_price]){
$wholesale_price_Set = $get_wholeUnits[$get_whol_price];
$gross_price = 350 * $get_wholePrices[$get_whol_price];
break; //This will exit from for loop since you have the value that you wants.
}
}
}
If I wanted a random number between one and three I could do $n = mt_rand(1,3).
There is a 33% chance that $n = 1, a 33% chance it's 2, and a 33% chance that it's 3.
What if I want to make it more difficult to get a 3 than a 1?
Say I want a 50% chance that a 1 is drawn, a 30% chance that a 2 is drawn and a 20% chance that a 3 is drawn?
I need a scalable solution as the possible range will vary between 1-3 and 1-100, but in general I'd like the lower numbers to be drawn more often than the higher ones.
How can I accomplish this?
There is a simple explanation of how you can use standard uniform random variable to produce random variable with a distribution similar to the one you want:
https://math.stackexchange.com/a/241543
This is maths.
In your example the just chose a random number between 0 and 99.
Values returned between 0 to 49 - call it 1
Values returned between 50 - 69 - Call it 2
Values returned between 70 - 99 - Call it 3
Simple if statement will do this or populate an array for the distribution required
Assuming a 1 - 10 scale, you can use a simple if statement and have the numbers represent percentages. And just have each if statement set $n to a specific. Only downfall, it isn't universal.
$dummy = mt_rand(1,10);
// represents 50%
if ($dummy <= 5) {
$n = 1;
}
// represents 40%
if ($dummy >= 6 && $dummy <= 9) {
$n = 2;
} else {
// represents 10%
$n = 3;
}
I have to submit all telephone numbers from my database records to URL, but I need to restrict each time send 300 phone numbers only.
I need a php script able to run following scenario:
Retrieve 2,000 records from database.
Loop all rows and save each into a variable or something else. (important)
Count total has 2,000 records.
Loop 300 records each time to write into URL. (very important)
Submit the URL (this part no need to explain)
loop for next 300 records to write into URL, and repeat it until record 2,000.
I believe in this case, 2,000 / 300 = 7 times of looping, which 300 records for first 6 times and final time is sending 200 records only.
As I mentioned above the looping for 300 records is very important, and next looping able to know starting from record 301 until 600, and so on.
EDITED
Below are my original code, but it's reading all phone numbers and dumb them all to my URL:
$smsno = trim($_REQUEST['string_of_phone_number_eg_0123456;0124357;0198723']);
$message = trim($_REQUEST['message']);
$phoneNo = explode(";", $smsno);
// ----------
//
// Need to count total $phoneNo, eg total is 2,000 phone numbers
// Loop 300 times for the phone numbers, eg 001-300, 301-600, 401-900, ..., 1501-1800, 1801-2000
// Every 300 records, eg $phoneStr = '0123456;0124357;0198723;...' total 300 phone numbers in this string
// Write into my URL: $link = "http://smsexample.com/sms.php?destinationnumber=$phoneStr&messagetosms=$message";
//
// ----------
I am seeking solution from here as I have no idea how to loop each 300 records and write into string then throw this string to my URL.
I can make the first 300 records, but how to get next 300 records after first 300 records write into string and throw to my url, and waiting to perform second throw to url.
For example,
first loop for 300 records:
$phoneStr = phoneNumber01;phoneNumber02;phoneNumber03;...;phoneNumber300
$link = "http://smsexample.com/sms.php?destinationnumber=$phoneStr&messagetosms=$message";
second loop for next 300 records
$phoneStr = phoneNumber301;phoneNumber302;phoneNumber303;...;phoneNumber600
$link = "http://smsexample.com/sms.php?destinationnumber=$phoneStr&messagetosms=$message";
and so on.
for ($i = 1; $i <= 2000; $i++)
{
if ($i % 300 == 0 || $i == 2000)
{
//Make URL and send
}
}
// Per-request limit
$limit = 300;
// Get array of numbers
$numbers = explode(';', $_REQUEST['string_of_phone_number_eg_0123456;0124357;0198723']);
// Get message
$message = trim($_REQUEST['message']);
// Loop numbers
while ($numbers) {
// Get a block of numbers
$thisBlock = array_splice($numbers, 0, $limit);
// Build request URL
$url = "http://smsexample.com/sms.php?destinationnumber=".urlencode(implode(';', $thisBlock))."&messagetosms=".urlencode($message);
// Send the request
$response = file_get_contents($url);
}
What I do
I am making graph of fictitious stock options.
The price is updated each second, with this function
function stockVariation($price,$max_up,$max_down)
{
// Price > 1
if($price > 1)
{
// Calculate
$ratio=(mt_rand(0,$max_up/2)-mt_rand(0,$max_down/2))/1000;
$price+=$ratio;
}
// Price <=1 (we don't want 0 or negative price...)
else
$price+=mt_rand(1,$max_up)/1000;
return round($price,3);
}
I use a max_up and max_down values (from 10 to 100) to make the price change progressively and simulate some volatility.
For example, with max_up : 40 and max_down : 45, the price will progressively go down.
My question
But the problem, is that prices generated are too much volatile, even if max_up = max_down.
The result is "non-natural". (for example +10 points in one day for a base price of 15,000).
Result of price evolution per hour in 24 hour
Perhaps making round($price,4) and divisions by 10 000 instead of 1 000, will be better ?
If anyone have an idea or an advice to generate "natural" prices evolution, thanks in advance.
There are 86400 seconds in a day, so you'll need to divide by a much larger number. And rather than adding and subtracting, you may want to multiply the current price by a factor that's slightly larger or smaller than 1. That would simulate a percentage increase or decrease, rather than an absolute gain or loss.
function stockVariation($price, $max_up, $max_down)
{
// Convert up/down to fractions of the current price.
// These will be very small positive numbers.
$random_up = mt_rand(0, $max_up) / $price;
$random_down = mt_rand(0, $max_down) / $price;
// Increase the price based on $max_up and decrease based on $max_down.
// This calculates the daily change that would result, which is slightly
// larger or smaller than 1.
$daily_change = (1 + $random_up) / (1 + $random_down);
// Since we're calling this function every second, we need to convert
// from change-per-day to change-per-second. This will make only a
// tiny change to $price.
$price = $price * $daily_change / 86400;
return round($price, 3);
}
Building upon the idea, you could use an actual volatility number. If you want e.g. a volatility of 35%/year, you can find the volatility per second. In pseudocode:
vol_yr = 0.35
vol_month = vol_yr * sqrt(1.0/12)
vol_second = vol_yr * sqrt(1.0/(252 * 86400)) # or 365 * 86400
Then, every second, you "flip a coin" and either multiply or divide current stock price by (1 + vol_second). This is the principle of how binomial trees are created to evaluate exotic stock options.