do-while loop only runs once - php

I am trying to make a simple while loop using a class to get the factorial of a number. However, for some reason, the while loop is only returning the value after it has run once.
Here is my code:
<?php
class Factorial {
public function calculate($int){
$intStep = $int-1;
do {
$int*=$intStep;
$int--;
return $int;
} while($int>0);
if (!is_int($int)){
echo "entry is not a number";
}
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);

I see a number of problems with your code:
return $int; is run inside the do while loop, which means it'll only ever run once.
You're decrementing $int instead of $intStep
You're checking if $int is below zero instead of $intStep
Here's your code with all of these problems fixed, it works and returns 15:
class Factorial {
public function calculate ($int) {
if (!is_int($int)) {
echo "entry is not a number";
}
$intStep = $int - 1;
do {
$int += $intStep;
$intStep--;
} while ($intStep > 0);
return $int;
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);
3v4l.org demo

You shouldn't return from your function until your result is ready. Since you return early, you won't finish your calculation.
In general, your life will be easier if you learn how to debug. For PHP, the easiest way would be to echo stuff throughout your code. If you put echo $int inside of your loop it would be more obvious to you what the issue was.

try this
<?php
class Factorial {
public function calculate($num){
$Factorial = 1;
$i =1;
do{
$Factorial *= $i;
$i++;
}while($i<=$num);
return $Factorial;
}
}
$factorial = new Factorial;
echo $factorial->calculate(5);
?>

Factorial ? Maybe the following code is what you want:
Don't forget negative Numbers.
class Factorial {
public function calculate ($int) {
if (!is_int($int)) {
echo "entry is not a number";
}
if ($int == 0 || $int == 1) {
$result = 1;
} else if ($int < 0) {
$result = $this->calculate($int + 1) * $int;
} else {
$result = $this->calculate($int - 1) * $int;
}
return $result;
}
}
$factorial = new Factorial;
echo $factorial->calculate(-4);

Related

how to write prefixed unique coupon code in php

I am trying to write prefixed unique coupon code for get the chance to be a intern at one company. It went well so far, my code is generating 250st, 10 length of codes every time I refresh the page. However, I am issuing a problem with prefixed part. Normally coupon code is looking like this, just one example "1SC476XY3B" but I want every code to start "AB" and then 8 length of code so total will be 10. Can you help me guys? All help will be appreciated, thanks.
<?php
function unique_coupon_codes($number_of_codes,$exclude_codes_array='',$code_length = 10)
{
$characters = "0123456789QWERTYUIOPASDFGHJKLZXCVBNM";
$unique_codes = array();
for($j = 1 ; $j <= $number_of_codes; $j++)
{
$code = "";
for ($i = 1; $i <= $code_length; $i++)
{
$code .= $characters[mt_rand(0, strlen($characters)-1)];
}
if(!in_array($code,$unique_codes))
{
if(is_array($exclude_codes_array))
{
if(!in_array($code,$exclude_codes_array))
{
$unique_codes[$j] = $code;
}
else
{
$j--;
}
}
else
{
$unique_codes[$j] = $code;
}
}
else
{
$j--;
}
}
return $unique_codes;
}
echo '<h1>Unique Coupon Codes</h1>';
echo '<pre>';
print_r(unique_coupon_codes(250,'',10));
echo '</pre>';
It needs a minor change while initializing $code variable. Change $code = ""; to $code = "AB"; And call unique_coupon_codes function as
print_r(unique_coupon_codes(250, '', 8));
Here generate a unique code of 8 digits as you already have prefix AB of length 2 characters.
How about something like this? :-)
function unique_coupon_codes($number_of_codes,$exclude_codes_array=[],$code_length = 10, $code_prefix="") {
$characters="0123456789QWERTYUIOPASDFGHJKLZXCVBNM";
$unique_codes = array();
for($i=1;$i<=$number_of_codes;$i++) {
$code="";
for($o=1;$o<=$code_length;$o++) {
$code .= $characters[mt_rand(0, strlen($characters)-1)];
}
if(in_array($code, $unique_codes) || in_array($code, $exclude_codes_array)) {
$i--;
} else {
$unique_codes[$i] = $code_prefix.$code;
}
}
return $unique_codes;
}
echo '<h1>Unique Coupon Codes</h1>';
echo '<pre>';
print_r(unique_coupon_codes(250,'',8, 'AB'));
echo '</pre>';

PHP find Exponent after remainder is zero

I have this code written but I am having little issue or might be I am missing something,
public function test()
{
$number = "8192";
for ($i=1; $i<=32; $i++)
{
if(($number % pow(2,$i)) == 0)
{
$final = 32-$i;
echo $final;
}
}
exit;
}
I need to get which Exponent aka $i is used and then need to minus the value from 32 (or something else) to get the final results.
Since you want to compare the values just change the if condition, the modulus operator will not give you the exact result,
Here is the complete answer :
public function test()
{
$number = "8192";
for ($i=1; $i<=32; $i++)
{
if($number == pow(2,$i))
{
$final = 32-$i;
echo $final;
break;
}
}
exit;
}

Program to sum the digits of a number working fine for small numbers but not for larger-ones

I am writing a program to sum the digits of a number , it is working fine for small numbers but for large no it is giving unexpected sum?
below is the program.
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
class demo {
private $sum = 0;
private $num = 0;
private $rem = 0;
public function digit_sum($digit) {
//echo gettype($digit).'<br>';
try {
if (gettype($digit) == 'string') {
throw new Exception($digit . ' is not a valid number <br>');
} else {
$this->num = $digit;
while ($this->num > 0) {
$this->rem = $this->num % 10;
$this->sum = $this->sum + $this->rem;
$this->num = $this->num / 10;
}
return "Sum of no $digit is = " . $this->sum . '<br>';
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
}
$sum = new demo();
echo $sum->digit_sum('sfsdfsdfds');
echo $sum->digit_sum(12345);
// outputs correct sum
echo $sum->digit_sum(3253435674);
//outputs incorrect sum
i see the above code results fine for integer no but not for double no'
please guide me what will be the perfect solution to this problem?
Do you know if you put a new echo $sum->digit_sum(32); The output will show you 62. Cause you create object once and call the same function multiple times. The object stores the sum for all the times.
Solution:
Just put an statement $this->sum = 0; before the while loop to clear the previous sum.
Online Example: https://3v4l.org/C7Yli.
Update: I tested the scripts in writephponline.com as per your comment and get the following result.

adding arguments in a PHP

im very new to PHP and im hoping someone here could help me out. i need to write a class, an when the below page echos it, it will show the answers.
<?php
include_once('Math.php');
$Math = new _Math();
echo $Math->calculate(2,3,"+")."<br />";
echo $Math->calculate(2,3,"-")."<br />";
echo $Math->calculate(2,3,"*")."<br />";
echo $Math->calculate(9,3,"/")."<br />";
echo $Math->calculate(9,0,"/")."<br />";
echo $Math->calculate("3",3,"+")."<br />";
echo $Math->calculate(2.5,3,"+")."<br />";
echo $Math->calculate(3,3,"test")."<br />";
I thought the code below would work, but im getting nothing but a blank screen.
<?php
class _Math {
function calculate(2,3,"+"){
$x = 2 + 3;
return $x;
}
function calculate(2,3,"-"){
$x = 2 - 3;
return $x;
}
function calculate(2,3,"*"){
$x = 2 * 3;
return $x;
}
function calculate(9,3,"/"){
$x = 9 / 3;
return $x;
}
function calculate(9,0,"/"){
$x = 9 / 0;
return $x;
}
function calculate("3",3,"+"){
$x = "3"+3;
return $x;
}
function calculate(2.5,3,"+"){
$x = 2.5+3;
return $x;
}
function calculate(3,3,"test"){
$x = 3 test 3;
return $x;
}
Im hoping someone can point me in the right direction. Hopefully im not that far off. Thanks in advance.
Function arguments must be variables, not expressions, which is explained in the manual.
This is a partial implementation:
class _Math
{
function calculate($op1, $op2, $type)
{
switch ($type) {
case '+':
return $op1 + $op2;
case '-':
return $op1 - $op2;
// ...
}
}
}
Inside the function you write a switch that will return the result based on the $type argument.
You function should look like this
function calculate(num1, num2, operation){
switch(operation){
case '+':
return $num1 + $num2;
break;
case '*':
return $num1 * $num2;
break;
// continue here :)
}
}
You only need 1 function. and multiple function with the same name will throw an error in PHP.
This is not how you define functions. Im not even sure what youre trying to do.
The round brackets contain the parameters which you hand over to the function. So you call a function like that:
$Math->calculate(2,3,"+")
These last 3 things are the parameters. You have to define the function like this:
function calculate($x, $y, $operation){
//your code
}
You cannot define multiple functions with the same name, so you have to check the operation and calculate it depending on the input. For example, +
function calculate($x, $y, $operation){
if($operation === "+") {
return $x + $y;
}
}

PHP "Maximum execution time"

I'm trying to program my own Sine function implementation for fun but I keep getting :
Fatal error: Maximum execution time of 30 seconds exceeded
I have a small HTML form where you can enter the "x" value of Sin(x) your looking for and the number of "iterations" you want to calculate (precision of your value), the rest is PhP.
The maths are based of the "Series definition" of Sine on Wikipedia :
--> http://en.wikipedia.org/wiki/Sine#Series_definition
Here's my code :
<?php
function factorial($int) {
if($int<2)return 1;
for($f=2;$int-1>1;$f*=$int--);
return $f;
};
if(isset($_POST["x"]) && isset($_POST["iterations"])) {
$x = $_POST["x"];
$iterations = $_POST["iterations"];
}
else {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
if(isset($x) && is_numeric($x) && isset($iterations) && is_numeric($iterations)) {
$x = floatval($x);
$iterations = floatval($iterations);
for($i = 0; $i <= ($iterations-1); $i++) {
if($i%2 == 0) {
$operator = 1;
global $operator;
}
else {
$operator = -1;
global $operator;
}
}
for($k = 1; $k <= (($iterations-(1/2))*2); $k+2) {
$k = $k;
global $k;
}
function sinus($x, $iterations) {
if($x == 0 OR ($x%180) == 0) {
return 0;
}
else {
while($iterations != 0) {
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
$iterations = $iterations-1;
return $result;
}
}
}
$result = sinus($x, $iterations);
global $result;
}
else if(!isset($x) OR !isset($iterations)) {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
else if(isset($x) && !is_numeric($x)&& isset($iterations) && is_numeric($iterations)) {
$error = "Not a valid number.";
global $error;
}
?>
My mistake probably comes from an infinite loop at this line :
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
but I don't know how to solve the problem.
What I'm tring to do at this line is to calculate :
((pow($x, $k)) / (factorial($k)) + (((pow($x, $k))/(factorial($k)) * ($operator)
iterating :
+ (((pow($x, $k))/(factorial($k)) * $operator)
an "$iterations" amount of times with "$i"'s and "$k"'s values changing accordingly.
I'm really stuck here ! A bit of help would be needed. Thank you in advance !
Btw : The factorial function is not mine. I found it in a PhP.net comment and apparently it's the optimal factorial function.
Why are you computing the 'operator' and power 'k' out side the sinus function.
sin expansion looks like = x - x^2/2! + x^3/3! ....
something like this.
Also remember iteration is integer so apply intval on it and not floatval.
Also study in net how to use global. Anyway you do not need global because your 'operator' and power 'k' computation will be within sinus function.
Best of luck.
That factorial function is hardly optimal—for speed, though it is not bad. At least it does not recurse. It is simple and correct though. The major aspect of the timeout is that you are calling it a lot. One technique for improving its performance is to remember, in a local array, the values for factorial previously computed. Or just compute them all once.
There are many bits of your code which could endure improvement:
This statement:
while($iterations != 0)
What if $iterations is entered as 0.1? Or negative. That would cause an infinite loop. You can make the program more resistant to bad input with
while ($iterations > 0)
The formula for computing a sine uses the odd numbers: 1, 3, 5, 7; not every integer
There are easier ways to compute the alternating sign.
Excess complication of arithmetic expressions.
return $result is within the loop, terminating it early.
Here is a tested, working program which has adjustments for all these issues:
<?php
// precompute the factorial values
global $factorials;
$factorials = array();
foreach (range (0, 170) as $j)
if ($j < 2)
$factorials [$j] = 1;
else $factorials [$j] = $factorials [$j-1] * $j;
function sinus($x, $iterations)
{
global $factorials;
$sign = 1;
for ($j = 1, $result = 0; $j < $iterations * 2; $j += 2)
{
$result += pow($x, $j) / $factorials[$j] * $sign;
$sign = - $sign;
}
return $result;
}
// test program to prove functionality
$pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620;
$x_vals = array (0, $pi/4, $pi/2, $pi, $pi * 3/2, 2 * $pi);
foreach ($x_vals as $x)
{
$y = sinus ($x, 20);
echo "sinus($x) = $y\n";
}
?>
Output:
sinus(0) = 0
sinus(0.78539816339745) = 0.70710678118655
sinus(1.5707963267949) = 1
sinus(3.1415926535898) = 3.4586691443274E-16
sinus(4.7123889803847) = -1
sinus(6.2831853071796) = 8.9457384260403E-15
By the way, this executes very quickly: 32 milliseconds for this output.

Categories