I'm pretty new to PHP, especially object oriented php, and I'm working on some simple code, and I'm not quite sure what's wrong with what I've written so far. I'm sure it's something simple but I've beat my head against this wall for a little bit, figured I'd ask here.
class primes
{
$TestValues = array(0, 1, 2, 3, 4);
function IsPrime($number)
{
//if number is a number, perform the rest of the tests, else, return -1 (error)
if(is_numeric($number))
{
//if number is less than 0, return -1 (error)
if($number < 0)
return -1;
//if number is 0, then return 0 (false, not prime)
if($number == 0)
return 0;
//if number is greater than 1024, return -1 (error)
if($number > 1024)
return -1;
//if number is 1, return 0 (false, not prime)
if($number == 1)
return 0;
//if number is 2, return 1 (true, is prime)
if($number == 2)
return 1;
//if number mod 2 is 0, then it is even, and no even number is prime except 2, which is handled above. so return 0 (false, not prime)
if($number % 2 == 0)
return 0;
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i +2)
{
//if any numbers mod 3 to its square root equal 0, return 0, (false, not prime)
if($number % $i == 0)
return 0;
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
else
{
return -1;
}
}
}
function TestIsPrime()
{
foreach($TestValues as $value)
IsPrime($value);
if(IsPrime() == 0)
echo($value . "=> Is not Prime");
elseif(IsPrime() == 1)
echo($value . "=> Is Prime");
elseif(IsPrime() == -1)
echo($value . "=> Is an Error");
}
function main()
{
TestIsPrime();
}
}
main();
I'm getting an error saying I don't place my array where it is currently. I'm not quite sure how the structure of php code is supposed to work with a class, so I wasn't sure where to put the $TestValues array, so I tried a few places, and none would be accepted. Also, I'm getting an error on the else statement connected to the first if(is_numeric($number)), but I couldn't be sure that the error wasn't caused by another small error I was getting. The last error is that I'm not sure where in this single page of code to call the functions inside the class. Any help would be appreciated. Once again, I'm new to doing anything useful in php, but I'm liking it so far. Thanks,
Your code was missing several braces, also you your $TestValues is part of the class, not a global variable.
I fixed the code, however you have to check the math and read the oop tutorial on php's site.
<?php
class Primes {
public $TestValues = array(0, 1, 2, 3, 4);
function IsPrime($number) {
//if number is a number, perform the rest of the tests, else, return -1 (error)
if(is_numeric($number)) {
if($number < 0 || $number > 1024)
return -1;
if($number === 0 || $number === 1 || $number % 2 === 0)
return 0;
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i + 2) {
//if any numbers mod 3 to its square root equal 0, return 0, (false, not prime)
if($number % $i == 0)
return 0;
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
} else {
return -1;
}
}
function test() {
foreach($this->TestValues as $value) {
$t = $this->IsPrime($value);
if($t === 0) {
echo($value . "=> Is not Prime");
} elseif($t === 1) {
echo($value . "=> Is Prime");
} elseif(IsPrime() == -1) {
echo($value . "=> Is an Error");
}
echo "\n";
}
}
}
function main() {
$prime = new Primes();
$prime->test();
}
main();
You have some syntax errors in your code. I made some modification to your code now it is working :
<?php
// Check the number to be prime or not
function IsPrime($number)
{
// If the variable is not numeric, negative or greater than 1024, exit
if (!is_numeric($number) || $number < 0 || $number > 1024)
{
return -1;
}
// Perform the tests
switch($number)
{
//if number is 0 or 1, then return 0 (false, not prime)
case 0 :
case 1 :
return 0;
break;
//if number is 2, return 1 (true, is prime)
case 2 :
return 1;
break;
}
//if number mod 2 is 0, then it is even, and no even number is prime except 2, return 0 (false, not prime)
if($number % 2 == 0)
{
return 0;
}
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i +2)
{
if($number % $i == 0)
{
return 0;
}
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
} // End of isprime function
// create an array of numbers
$testvalues = range(-2, 100);
foreach($testvalues as $value)
{
switch(isprime($value))
{
case 0 :
echo("<p style='color:gainsboro;'>" . $value . "=> Is not Prime</p>");
break;
case 1 :
echo("<p style='color:green;'>" . $value . "=> Is Prime</p>");
break;
case -1 :
echo("<p style='color:red;'>" . $value . "=> Is an Error</p>");
break;
}
}
?>
Notes :
I think you don't need a class here. It is a simple program and using
classes will make it a bit complex and php is known for its
simplicity. So keep it simple.
In some cases switch is better and more readable than if, so use it if
possible http://php.net/manual/en/control-structures.switch.php
Every language has it preferred syntax. In php it is common not to
use capitals in naming variable (except for classes) unlike other
languages
there is no main() in php
Hope this helps, excuse my english and correct me if I am wrong
The reason why u getting error for else statement is because of the closing braces } of your if statement, notice that you have a closing brace after your else condition,instead of doing that, you have to close if statement first then do else statement which in your case else means if is not numeric then do sth, also you have so many if statements which looks a little bit redundant. what you could do is to put them in same condition like if($number ==0 || $number == 2 || $number % 2 ==0 ) return 0 elseif // do sth
The reason why you can't get $Testvalues is that you need to pass the array to your function then you can use it, where did u call your TestIsPrime function? when you call it, do sth like
TestIsPrime($TestValues);
btw, it's better not to use Capital letter for variable...
Related
I'm currently working on a function as described in the tittle, where I need to get and array of X values and see if they get in a perfectly increasing order by removing one and only one of it's elements, the problem is that this must be made in PHP, while the logic seems to be adding up, even tried this on another language successfully, but it doesn't work on PHP probably due to my own limited knowledge, any help is appreciated.
Conditions:
If the array can be ordened by removing one and only one value, return True.
Arrays with only one element after the change are ordened by default.
Repeated numbers don't count as ordened.
<?php
function SequenciaCrescente($arr, $n){
if($n == 2){
return true;
}
$modify = 0;
for($i=0; $i<$n-1; $i++) {
if($arr[$i] >= $arr[$i+1] || $arr[$i] >= $arr[$i+2]){
$modify++;
}
if($modify > 1)
break;
}
if($arr[$n-2]>=$arr[$n-1])
$modify++;
if($modify > 1)
return false;
return true;
}
$arr = array(1, 2, 3, 4, 5, 3, 5, 6);
$n = sizeof($arr);
if (SequenciaCrescente($arr, $n) == true)
echo "True";
else
echo "False";
?>
Example of arrays it should return True but returns False:
1, 2, 3, 4, 3, 6 and 3, 5, 67, 98, 3.
Its pretty simple, run the loop to check the sequence, if not in order then increase the counter. Check if the counter is greater than 1, then break the loop. Finally check the last the values applying same logic.
And you are not calling your function, check() is not defined.
function SequenciaCrescente($arr, $n){
$modify = 0;
for($i=0; $i<$n-1; $i++) {
if($arr[$i] >= $arr[$i+1])
$modify++;
if($modify > 1)
break;
}
if($arr[$n-2]>=$arr[$n-1])
$modify++;
if($modify > 1)
return false;
return true;
}
$arr = array(1,3,2,4);
$n = sizeof($arr);
if (SequenciaCrescente($arr, $n) == true)
echo "Yes";
else
echo "No";
im trying to create a script that generates a number and depending on the number generated it prints something specific but it's not working properly, Heres the code:
<?php
for($zz = 1; $zz <= 20; $zz++) {
$rangen = rand(1,100);
$a = (1 <= 0) && (0 <= 7);
$b = (8 <= 0) && (0 <= 17);
echo ("<br>".$rangen . "<br>");
if($a) {
echo "a";
} elseif ($b) {
echo "b";
} else {
echo "c";
}
}
?>
The error is that it keeps printing "c" no matter what the number is.
If anyone could help that would be great, thanks.
Your conditions are all wrong. Your comparing the same numbers and never using $rangen, this is why you obtain the same result each time.
1 <= 0 and 8 <= 0 will always return false which is why you always go to the else statement.
I have the following code to find the largest prime factors of a number, it works good if I use numbers from 11 digits, but when I use this number: 600851475143, it keeps loading and loading and just don't show the result.
Any advice is welcome
<?php
$number = 600851475143;
$prime = 2;
do {
if($number % $prime == 0) {
$number = $number / $prime;
$primes[] = $prime;
} else {
while(true) {
$prime++;
$true = is_prime($prime);
if($true === true) {
break;
}
}
}
if($number < $prime) break;
} while(true);
function is_prime($number, $prime = 2) {
if($number % $prime == 0) {
return false;
} else if ($number % $prime++ == 0) {
return false;
}
return true;
}
var_dump(max($primes));
?>
It should not be related to the overflow problem, but I think your is_prime() function, doesn't work in fact
var_dump(is_prime(9)); // bool(true)
Anyway to handle arbitrary precision numbers in PHP you should look here
We are looking for the Nth root in PHP. We need to do this with a very large number, and the windows calculator returns 2. With the following code we are getting 1. Does anybody have an idea how this works?
echo bcpow(18446744073709551616, 1/64);
Well it seems that PHP and the BC lib has some limits, and after searching on the internet i found this interesting article/code:
So you should use this function:
<?php
function NRoot($num, $n) {
if ($n<1) return 0; // we want positive exponents
if ($num<=0) return 0; // we want positive numbers
if ($num<2) return 1; // n-th root of 1 or 2 give 1
// g is our guess number
$g=2;
// while (g^n < num) g=g*2
while (bccomp(bcpow($g,$n),$num)==-1) {
$g=bcmul($g,"2");
}
// if (g^n==num) num is a power of 2, we're lucky, end of job
if (bccomp(bcpow($g,$n),$num)==0) {
return $g;
}
// if we're here num wasn't a power of 2 :(
$og=$g; // og means original guess and here is our upper bound
$g=bcdiv($g,"2"); // g is set to be our lower bound
$step=bcdiv(bcsub($og,$g),"2"); // step is the half of upper bound - lower bound
$g=bcadd($g,$step); // we start at lower bound + step , basically in the middle of our interval
// while step!=1
while (bccomp($step,"1")==1) {
$guess=bcpow($g,$n);
$step=bcdiv($step,"2");
$comp=bccomp($guess,$num); // compare our guess with real number
if ($comp==-1) { // if guess is lower we add the new step
$g=bcadd($g,$step);
} else if ($comp==1) { // if guess is higher we sub the new step
$g=bcsub($g,$step);
} else { // if guess is exactly the num we're done, we return the value
return $g;
}
}
// whatever happened, g is the closest guess we can make so return it
return $g;
}
echo NRoot("18446744073709551616","64");
?>
Hope this was helpful ...
I had problems with HamZa's solution getting to work with arbitrary precission, so i adopted it a little.
<?php
function NthRoot($Base, $NthRoot, $Precision = 100) {
if ($NthRoot < 1) return 0;
if ($Base <= 0) return 0;
if ($Base < 2) return 1;
$retVal = 0;
$guess = bcdiv($Base, 2, $Precision);
$continue = true;
$step = bcdiv(bcsub($Base, $guess, $Precision), 2, $Precision);
while ($continue) {
$test = bccomp($Base, bcpow($guess, $NthRoot, $Precision), $Precision);
if ($test == 0) {
$continue = false;
$retVal = $guess;
}
else if ($test > 0) {
$step = bcdiv($step, 2, $Precision);
$guess = bcadd($guess, $step, $Precision);
}
else if ($test < 0) {
$guess = bcsub($guess, $step, $Precision);
}
if (bccomp($step, 0, $Precision) == 0) {
$continue = false;
$retVal = $guess;
}
}
return $retVal;
}
I am making an ajax call in jquery
$.get("validate_isbn.php", {isbn: obj[16]},
function(answer)
{
console.log(answer);
if (answer == "valid")
{
var checked1 = $(elements[index]).val();
//$(elements[index]).val().append("<img src = 'pics/green_checkmark.png'>"); //doesn't work
//elements.after("<img src = 'pics/green_checkmark.png'>"); //sets all the elements with this pic
elements.eq(index).after("<img src='pics/green_checkmark.png' id='checkmark'>");
var checked = $(elements[index]).val();
}
});
which worked fine. I saw in the debugger that it was properly sending over the variable isbn with a isbn number from the obj array. My problem is on the php side. When I was testing, I simply had the code echo "valid" and everything worked out fine. But now when I put the real code in it stopped working:
<?php
//This algorithm is for ISBN 10
function is_isbn_10_valid($n){
$check = 0;
for ($i = 0; $i < 9; $i++)
{
$check += (10 - $i) * substr($n, $i, 1); //starting at the leftmost digit, multiple each digit by a constant, starting at 10, add the total
}
$t = substr($n, 9, 1); // tenth digit (aka checksum or check digit)
$check += ($t == 'x' || $t == 'X') ? 10 : $t; //now add the tenth digit
return $check % 11 == 0;
}
//The algorithm for ISBN 13 validation is as follows:
//Multiply each digit of teh isbn, starting at the left, with 1,3,3... etc for the entire isbn (including the check digit becuase its
//just going to be multiplied by 1 anyways.
//Add them all together, do mod 10 and voila!
function is_isbn_13_valid($n){
$check = 0;
for ($i = 0; $i < 13; $i+=2) //this does digits 1,3,5,7,9,10,11,13
{
$check += substr($n, $i, 1);
}
for ($i = 1; $i < 12; $i+=2) //this does digits 2,4,6,8,10,12
{
$check += 3 * substr($n, $i, 1);
}
return $check % 10 == 0;
}
$isbn = $_GET["isbn"];
if (strlen($isbn) = 10)
{
$result = is_isbn_10_valid($isbn);
}
else if (strlen($isbn) = 13)
{
$result = is_isbn_13_valid($isbn);
}
else
{
$result false;
}
if ($result === true)
{echo "valid";}
else if ($result === false)
{echo "not valid";}
?>
(Note: I'm sure that I can be more efficient and just return the boolean, but I refrained from that at the moment since I wasn't sure how the jquery .get would take it, as a boolean or text...)
Anyways, it doesn't work. The error on the console.log gives me:
Fatal error: Can't use function return value in write context in ...pathname here...\validate_isbn.php on line 31
On line 31, you have this:
if ($strlen($isbn) = 10)
Remove the $ on the strlen function, and change the = (assignment operator) to a == (equivalence operator). It should now look like this:
if (strlen($isbn) == 10)
You'll need to do the same a few lines after that, too.
Edit: One more thing. About five lines from the bottom, you're missing an equal sign.
$result false;
Should be:
$result = false;