This calculator is supposed to take a typed input with spaces, (like "2 + 2") in the web page text box, and then echo the answer above it. Currently, the output is either "0", or it will seemingly clip a random number off of the input.
I'm 95% sure the problem is within the substr functions - they are not being assigned the correct values. This is my guess because of the output behavior. To demonstrate,
1 + 1 will = 0
2 + 2 will = 0
...
9 + 9 will = 0
10 + 10 will = 1
20 + 20 will = 2
note: The $firstNumber, $secondNumber, and $operator initial declaration values starting on line 16 are arbitrary.
Here are substr( , ) examples from PHP manual:
echo substr('abcdef', 1); // bcdef <br>
echo substr('abcdef', 1, 3); // bcd<br>
echo substr('abcdef', 0, 4); // abcd<br>
echo substr('abcdef', 0, 8); // abcdef<br>
echo substr('abcdef', -1, 1); // f<br>
.
//'if' is executed when submit is pressed
if (isset($_POST['test']))
{
$input = $_POST['test'];
$answer = calculate($input);
echo $answer;
}
//does string processing and number calculation
function calculate($input)
{
//declarations (random)
$firstNumber = 20;
$secondNumber = 30;
$operator = "+";
$answer = 7;
//string processing.
for($i = 0; $i <= strlen($input); $i++)
{
//if current position of the string scan is an operator,
if( trim(substr($input, $i, $i + 1), " ") == "+" ||trim(substr($input, $i, $i + 1), " ") == "-"
||trim(substr($input, $i, $i + 1), " ") == "*" ||trim(substr($input, $i, $i + 1), " ") == "/")
{
//then
//$operator = current position TO current position + 1
$operator = substr($input, $i, $i + 1);
//trim $operator
$operator = trim($operator, " ");
//$firstNumber = 0 TO current position - 1
$firstNumber = substr($input, 0, $i - 1);
//trim $operator
$firstNumber = trim($firstNumber, " ");
//$secondNumber = current position + 1 TO end of string
$secondNumber = substr($input, $i + 1, strlen($input));
//trim $operator
$secondNumber = trim($secondNumber, " ");
}
}
//if operator is ... then do that operation.
//example: if "+", then add $firstNumber and $secondNumber
if($operator == "+")
{
$answer = $firstNumber + $secondNumber;
}
else if($operator == "-")
{
$answer = $firstNumber - $secondNumber;
}
else if($operator == "*")
{
$answer = $firstNumber * $secondNumber;
}
else if($operator == "/")
{
$answer = $firstNumber / $secondNumber;
}
//return the calculated answer for echo
return $answer;
}
?>
<form action="test.php" method="POST">
<textarea name="test" rows="3" cols="30"></textarea>
<input type="submit" value="calculate!">
</form>
Your problem is your use of substr.
substr take a string, a start position and a length. It's the length that you are misusing. As you pan through the input string, you are increasing the length of the substring that you are looking for. Since operators have length of 1, you should be using
//if current position of the string scan is an operator,
if( trim(substr($input, $i, 1), " ") == "+" || trim(substr($input, $i, 1), " ") == "-"
||trim(substr($input, $i, 1), " ") == "*" || trim(substr($input, $i, 1), " ") == "/")
{
....
You also need to update your code here:
//$operator = current position TO current position + 1
$operator = substr($input, $i, 1);
//trim $operator
$operator = trim($operator, " ");
You could simplify this a little by doing
potentialOperator = trim(substr($input, $i, 1), " ")
and comparing that to your supported operators. That'll save you multiple unnecessary calls to trim and substr
It'll also mean that you identify the operator once and once only.
You might also want to look at preg_split with PREG_SPLIT_DELIM_CAPTURE for parsing the input string, instead of scanning it char by char.
Related
I am trying to make it so that my code displays if entered array of numbers can be divided into 2 groups, and if yes then it displays"yes" or if no then"no. The yes or no part works fine, but if the code says yes then I want the code to also display the 2 columns with the numbers, I tried a lot but I just can't figure it out, please help.
function helper(&$arr, $n, $start, $lsum, $rsum) {
if ($start == $n)
return $lsum == $rsum;
if ($arr[$start] % 5 == 0)
$lsum += $arr[$start];
else if ($arr[$start] % 3 == 0)
$rsum += $arr[$start];
else
return helper($arr, $n, $start + 1, $lsum + $arr[$start], $rsum)
|| helper($arr, $n, $start + 1, $lsum, $rsum + $arr[$start]);
return helper($arr, $n, $start + 1, $lsum, $rsum);
}
function splitArray($arr, $n) {
return helper($arr, $n, 0, 0, 0);
}
$arr = array( 7,1, 7,3,4,6);
$n = count($arr);
if (splitArray($arr, $n))
print("Yes");
else
print("No");
Provided you want to split them into two parts
Replace your code at the bottom with...
$arr = array( 7,1, 7,3,4,6);
$n = count($arr);
list($group1, $group2) = array_chunk($arr, ceil(count($arr) / 2)); //Split the initial array into 2 if you want 3 just change 2 to 3 and so forth
if (splitArray($arr, $n)){
echo "Yes";
print_r($group1);
print_r($group2); //Each array assigned to new variable
} else {
echo "No";
}
I created this function to converting numbers to words. And how I can convert words to number using this my function:
Simple function code:
$array = array("1"=>"ЯК","2"=>"ДУ","3"=>"СЕ","4"=>"ЧОР","5"=>"ПАНҶ","6"=>"ШАШ","7"=>"ҲАФТ","8"=>"ХАШТ","9"=>"НӮҲ","0"=>"НОЛ","10"=>"ДАҲ","20"=>"БИСТ","30"=>"СИ","40"=>"ЧИЛ","50"=>"ПАНҶОҲ","60"=>"ШАСТ","70"=>"ҲАФТОД","80"=>"ХАШТОД","90"=>"НАВАД","100"=>"САД");
$n = "98"; // Input number to converting
if($n < 10 && $n > -1){
echo $array[$n];
}
if($n == 10 OR $n == 20 OR $n == 30 OR $n == 40 OR $n == 50 OR $n == 60 OR $n == 70 OR $n == 80 OR $n == 90 OR $n == 100){
echo $array[$n];
}
if(mb_strlen($n) == 2 && $n[1] != 0)
{
$d = $n[0]."0";
echo "$array[$d]У ".$array[$n[1]];
}
My function so far converts the number to one hundred. How can I now convert text to a number using the answer of my function?
So, as #WillParky93 assumed, your input has spaces between words.
<?php
mb_internal_encoding("UTF-8");//For testing purposes
$array = array("1"=>"ЯК","2"=>"ДУ","3"=>"СЕ","4"=>"ЧОР","5"=>"ПАНҶ","6"=>"ШАШ","7"=>"ҲАФТ","8"=>"ХАШТ","9"=>"НӮҲ","0"=>"НОЛ","10"=>"ДАҲ","20"=>"БИСТ","30"=>"СИ","40"=>"ЧИЛ","50"=>"ПАНҶОҲ","60"=>"ШАСТ","70"=>"ҲАФТОД","80"=>"ХАШТОД","90"=>"НАВАД","100"=>"САД");
$postfixes = array("3" => "ВУ");
$n = "98"; // Input number to converting
$res = "";
//I also optimized your conversion of numbers to words
if($n > 0 && ($n < 10 || $n%10 == 0))
{
$res = $array[$n];
}
if($n > 10 && $n < 100 && $n%10 != 0)
{
$d = intval(($n/10));
$sd = $n%10;
$ending = isset($postfixes[$d]) ? $postfixes[$d] : "У";
$res = ($array[$d * 10]).$ending." ".$array[$sd];
}
echo $res;
echo "\n<br/>";
$splitted = explode(" ", $res);
//According to your example, you use only numerals that less than 100
//So, to simplify your task(btw, according to Google, the language is tajik
//and I don't know the rules of building numerals in this language)
if(sizeof($splitted) == 1) {
echo array_search($splitted[0], $array);
}
else if(sizeof($splitted) == 2) {
$first = $splitted[0];
$first_length = mb_strlen($first);
if(mb_substr($first, $first_length - 2) == "ВУ")
{
$first = mb_substr($first, 0, $first_length - 2);
}
else
{
$first = mb_substr($splitted[0], 0, $first_length - 1);
}
$second = $splitted[1];
echo (array_search($first, $array) + array_search($second, $array));
}
You didn't specify the input specs but I took the assumption you want it with a space between the words.
//get our input=>"522"
$input = "ПАНҶ САД БИСТ ДУ";
//split it up
$split = explode(" ", $input);
//start out output
$c = 0;
//set history
$history = "";
//loop the words
foreach($split as &$s){
$res = search($s);
//If number is 9 or less, we are going to check if it's with a number
//bigger than or equal to 100, if it is. We multiply them together
//else, we just add them.
if((($res = search($s)) <=9) ){
//get the next number in the array
$next = next($split);
//if the number is >100. set $nextres
if( ($nextres = search($next)) >= 100){
//I.E. $c = 5 * 100 = 500
$c = $nextres * $res;
//set the history so we skip over it next run
$history = $next;
}else{
//Single digit on its own
$c += $res;
}
}elseif($s != $history){
$c += $res;
}
}
//output the result
echo $c;
function search($s){
global $array;
if(!$res = array_search($s, $array)){
//grab the string length
$max = strlen($s);
//remove one character at a time until we find a match
for($i=0;$i<$max; $i++ ){
if($res = array_search(mb_substr($s, 0, -$i),$array)){
//stop the loop
$i = $max;
}
}
}
return $res;
}
Output is 522.
How can I show and hide the some numbers of a phone number by replacing it with * like 0935***3256 by PHP?
EX:
09350943256 -> 0935***3256 09119822432 -> 0911***2432
09215421597 -> 0921***1597...
$number = '09350943256';
echo str_pad(substr($number, -4), strlen($number), '*', STR_PAD_LEFT);
Top php code result is as: *******3256 but i want result as: 0935***3256
How is it?
You could use substr and concat this way
to work for any $number with any number of n digit length
<?php
$number = "112222";
$middle_string ="";
$length = strlen($number);
if( $length < 3 ){
echo $length == 1 ? "*" : "*". substr($number, - 1);
}
else{
$part_size = floor( $length / 3 ) ;
$middle_part_size = $length - ( $part_size * 2 );
for( $i=0; $i < $middle_part_size ; $i ++ ){
$middle_string .= "*";
}
echo substr($number, 0, $part_size ) . $middle_string . substr($number, - $part_size );
}
The output if you make $number = "1" is * and if $number = "12" is *2 and for $number = "112222" is 11**22. and it goes on.
In short:
$phone = 01133597084;
$maskedPhone = substr($phone, 0, 4) . "****" . substr($phone, 7, 4);
// Output: 0113****7084
You can use substr_replace() function
<?php
$mobnum ="09350943256";
for($i=4;$i<7;$i++)
{
$mobnum = substr_replace($mobnum,"*",$i,1);
}
echo $mobnum;
?>
You can use substr() to fetch the first 4 and last 4, and add four * in the middle manually, and put it all together in a string.
$phone = "09350943256";
$result = substr($phone, 0, 4);
$result .= "****";
$result .= substr($phone, 7, 4);
echo $result;
The above would output
0935****3256
Live demo
<?php
$phone='05325225990';
function stars($phone)
{
$times=strlen(trim(substr($phone,4,5)));
$star='';
for ($i=0; $i <$times ; $i++) {
$star.='*';
}
return $star;
}
$result=str_replace(substr($phone, 4,5), stars($phone), $phone);
echo $result;
?>
0532*****90
Instead of doing the math of calculating indices, I suggest this „declarative“ solution:
<?php
$number='0123456789';
$matches=[];
preg_match('/(\\d{4})(\\d+)(\\d{4})/', $number, $matches);
$result=$matches[1].str_repeat('*',strlen($matches[2])).$matches[2];
print($result);
?>
I have written a small program to solve a mathematical problem. But when I run, it gives an undefined offset error on line number 9,11,13,15.
I have searched various questions, but didn't find anything useful.
What might be causing this. ?
<?php
$arr = [1,3,5,7,9,11,13,15];
$tries=0;
$answer=0;
while(($answer!=30) && ($tries!=1000))
{
$tries = $tries+1;
$num1=getRandomNumber();
$num2=getRandomNumber();
$num3=getRandomNumber();
$num4=getRandomNumber();
$num5=getRandomNumber();
if($num5 + $num4 + $num3 + $num2 + $num1 == 30)
{
$answer = 30;
echo $num1 + "+" + $num2 + "+" + $num3 + "+" + $num4 + "+" + $num5 + " = 30";
break;
}
}
if($tries==1000)
{
echo "1000 tries completed";
}
function getRandomNumber()
{
$arr = [1,3,5,7,9,11,13,15];
$r = mt_rand(1,15);
if(($r%2)!=0)
{
return $arr[$r];
}
}
?>
In your getRandomNumber() function, you're generating an array index between 1 and 15, but your array is only 8 elements long.
To fix this, update the call to mt_rand() to support your actual array size:
$r = mt_rand(0, count($arr) - 1);
Side-note (not answer specific), string concatenation in PHP is done with the period, . and not the +:
echo $num1 + "+" + $num2 + "+" + $num3 + "+" + $num4 + "+" + $num5 + " = 30";
// should be:
echo $num1 . "+" . $num2 . "+" . $num3 . "+" . $num4 . "+" . $num5 . " = 30";
You should change line:
$r = mt_rand(1,15);
into
$r = mt_rand(0,count($arr)-1);
because your $arr in your getRandomNumber function has only 8 elements (not 16)
function getRandomNumber()
{
$arr = [1,3,5,7,9,11,13,15];
$r = mt_rand(1,15);
if(($r%2)!=0)
{
return $arr[$r];
}
}
The mt_rand function returns a number higher then the array index witch is 7. You can either extend the array and make it have 16 index or reduce the range in mt_rand function to 0-7.
I want to generate alphanumeric unique numbers but the format should be like this
that should be starts from AA001 to AA999 after that AB001 to AB999 .... BA001 to BA999 end with ZZ999. if i give the input is
1 = result AA001
999 = result AA999
1000 = result AB001
any one can help this ?
Complete solution (see it running):
function formatNum1000($num) {
$tail = $num % 1000;
$head = (int)($num / 1000);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
function formatNum999($num) {
$tail = (($num - 1 ) % 999) + 1;
$head = (int)(($num - $tail) / 999);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
$ns = array(1, 500, 999, 1000, 1998, 1999, 2000, 25974, 25975, 25999, 26000, 675324, 675999);
foreach($ns as $n) {
$formatted1000 = formatNum1000($n);
$formatted999 = formatNum999 ($n);
echo "Num: $n => $formatted1000 / $formatted999\n";
}
Note: you need to make sure that the input number is within the valid range (0...675999 when including 000-numbers, 1...675324 otherwise)
Note: answer revised, missed the point earlier that 000 is not allowed
How about:
$start = 'AA997';
for($i = 0; $i < 5; $i++) {
$start++;
if (substr($start, 2) == '000') continue;
echo $start,"\n";
}
output:
AA998
AA999
AB001
AB002