I have a percentage calculation, but if no data is available, I get the following error message:
Division by zero
calculation
$ratio = ($postup*100)/($postup + $postdown);
Devision by zero is undefined.
If both $postup and $postdown are null (not set) you will get a division by zero i.e. null + null == 0.
Furthermore the same problem will occur if $postup * -1 == $postdown.
Since a division by zero is undefined you will need to add a fallback for this.
What this fallback would be is application specific but would look something like
$ratio = null;
if($postup + $postdown == 0) {
$ratio = xxx;
} else {
$ratio = ($postup*100)/($postup + $postdown);
}
Please also be aware that $postup * 100 will be equal to 0 if $postup == null
You can handle this, like the following to get rid of the error:
$ratio = 0;
$dividedBy = $postup + $postdown;
if($dividedBy != 0) {
$ratio = ($postup * 100) / $dividedBy;
echo $ratio;
} else {
echo "Can not divide by zero!!";
}
Related
I got the code that compare current element with the next element in array. But it crashes with out of bound because I guess when its on the last element there is no next element to compare with so it crashes.How to handle this to avoid crash and stop comparing on the last element? Here is my code
fun myFunction(arr: Array<Int>): Int{
if (arr.isEmpty()) return 0
var result = 0
for (item in arr.indices) {
if (arr[item] > 0 && arr[item + 1] < 0){
result ++
}
if (arr[item] < 0 && arr[item + 1] > 0){
result ++
}
}
return result
}
The direct answer to your question:
Instead of
for (item in arr.indices)
you should write
for (item in 0..(arr.lastIndex - 1))
Explanation: arr.indices returns the range 0..arr.lastIndex but in the loop you are checking the element after the current index; therefore you should only go up to arr.lastIndex - 1.
Some further advice:
IntArray is more efficient than Array<Int>
You can combine the two if statements into one using the || (or) operator.
If you are counting the number of sign changes, you need to consider how to interpret 0. In your code, an input of [1,-1] would give a result of 1 sign change, but [1,0,-1] would give 0, which seems wrong. To fix that, treat 0 as positive:
if ((arr[item] >= 0 && arr[item + 1] < 0) || arr[item] < 0 && arr[item + 1] >= 0) {
result++
}
You don't need to check if the array is empty; just remove that line. The loop won't be entered if the array is empty or if it has only 1 element.
Finally, you can use some cool features of the standard libray (look them up in the documentation to learn them) which can make your function succinct:
fun myFunction(arr: IntArray): Int {
var result = 0
arr.asList().zipWithNext().forEach { (a, b) ->
if ((a >= 0 && b < 0) || (a < 0 && b >= 0))
result++
}
return result
}
and even more succinct still:
fun myFunction(arr: IntArray) =
arr.asList().zipWithNext().count { (a, b) -> (a >= 0) != (b >= 0) }
References: single-expression functions, zipWithNext, count, destructuring.
I have been trying to solve the problem below in multiple ways (recursively, with the Go-version of do while loop, and with a for loop). But each one of them goes to an infinite loop. I tried using the same solution in JavaScript, and it works perfectly fine. Can someone please help me understand why the solution below is not working/going on an infinite loop?
// Write a function that takes in a number and returns the next number that is divisible by 7
package main
func solution9(num int) int {
var done bool = false
var result int = 0
for i := 1; done != true; i++ {
if (num + i % 7 == 0) {
result = num + i
done = true
}
}
return result
}
Your issue is operator precedence. The % operator has a higher precedence than the + operator, so if your num is, say, 10, your test is functionally:
10 + (0 % 7) == 0 => false (10)
10 + (1 % 7) == 0 => false (11)
10 + (2 % 7) == 0 => false (12)
etc.
Obviously, for any num > 0, you'll never satisfy the condition. Change your test to (num+i)%7 == 0 and you should find it works as expected.
Having IPv4 address ranges for a given country, how would one generate random address? For example, a single current set of ranges (one of many) for Singapore is:
+----------+----------+--------------+
| ip_from | ip_to | country_code |
+----------+----------+--------------+
| 18925568 | 18926079 | SG |
+----------+----------+--------------+
source: lite.ip2location.com
FAQ(3) explains that
IP_Number = 16777216*w + 65536*x + 256*y + z
where
IP_Address = w.x.y.z
IP_Number standing either for ip_from or ip_to. For the Singapore range presented above, it gives me:
16777216*w + 65536*x + 256*y + z >= 18925568; // from
16777216*w + 65536*x + 256*y + z <= 18926079; // to
How can I generate random w, x, y and z?
Here is a testable implementation (in JavaScript since that can be run directly here) and a little bit of a description.
First you need to generate random number from the specified range. If you have a function (let's call it random) that generates random real numbers between 0 and 0.999... [0,1) then you can do this.
num = (random() * (end - start + 1)) + start
Then you need to use mod 256 4 times to split the number into 4 parts and also use div 256 3 times on the given number (the fourth div operation would be unnecessary but if we are doing it in loop then we can just keep it there for the sake of simplicity as it doesn't change a thing).
(% - modulo, // - div)
first = num % 256
num = num // 256
second = num % 256
num = num // 256
third = num % 256
num = num // 256
fourth = num % 256
You can then push them into an array [fourth, third, second, first] (note the order here) and do some validation - some addresses are reserved for private internets so if you happen to generate one of them, just throw it away and generate a new one (you can either loop or recurse here till you generate a valid one).
Ip addresses in these ranges are reserved according to RFC 1918:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
And here is the implementation.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = Math.floor(Math.random() * (end - start + 1)) + start;
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
The above snippet will generate a random ip address in that range each time you run it.
And here is the test case from the page that you have mentioned which says that number 3401190660 should be converted into 202.186.13.4, so let's just switch that randomly generated number for this one and try it.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = 3401190660; // here is that specific number
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
And as we can see, this algorithm produced the correct result.
Is it possible to simplify this if statement?
and if so what's the answer?
if (type)
{
if(NdotL >= 0.0)
{
color += Idiff + Ispec;
}
}
else
{
color += Idiff + Ispec;
}
Think about this in terms of Boolean algebra. You have two conditions
A = (type)
B = (NdotL >= 0.0 )
And you execute your statement when
A * B
/A
( I use /A to indicate "NOT A", and * to indicate "AND" )
So the only time you don't execute is
A * /B
This means your statement should be
if (!((type) && NdotL < 0.0 )) {
// do your thing
}
Or, using Boolean identity
(A * B) = /(/A + /B)
you can rewrite your condition as
( /A + B )
if ( !(type) || ( NdotL >= 0 ) ) {
// do your thing
}
if (!type || NdotL >= 0.0)
{
color += Idiff + Ispec;
}
Use
if (type && NdotL > 0.0){
Blah....
} else {
Buegh...
}
Just so that it combines the two conditions.
Really sorry about indentations and such, but the mobile version of this site doesn't let you enter code, I just wanted to help you so much XD!
Try that :
color+=(type && NdotL >= 0.0)? Idiff + Ispec:Idiff + Ispec;
I have two functions for GNU bc in a Bash script.
BC_CEIL="define ceil(x) { if (x>0) { if (x%1>0) return x+(1-(x%1)) else return x } else return -1*floor(-1*x) }\n"
BC_FLOOR="define floor(x) { if (x>0) return x-(x%1) else return -1*ceil(-1*x) }\n"
echo -e "scale=2"$BC_CEIL$BC_FLOOR"ceil(2.5)" | bc
Both functions work fine in interactive bc. bc does not seem to allow multiple functions on one line separated by ; though, so I have to echo -n | bc with newlines at the end of each function. The above output is 2.5, not the expected 3.0 that I get if I type it into bc -i myself. It seems that bash calls bc for each line of echo output, rather than echo'ing it all to a single instance. Is there any workaround for this?
The scale needs to be zero for x%1 to work. You should normally only have one return from a function.
define ceil(x) { auto savescale; savescale = scale; scale = 0; if (x>0) { if (x%1>0) result = x+(1-(x%1)) else result = x } else result = -1*floor(-1*x); scale = savescale; return result }
define floor(x) { auto savescale; savescale = scale; scale = 0; if (x>0) result = x-(x%1) else result = -1*ceil(-1*x); scale = savescale; return result }
This needs a newline after the scale statement:
echo -e "scale=2\n"$BC_CEIL$BC_FLOOR"ceil(2.5)" | bc
I believe 1. is incorrect.
The if() comparison needs to be X >= 0 .
I find this works
define ceil(x) {
if (x >= 0) { if (x%1>0) return x+(1-(x%1)) else return x }
else return -1*floor(-1*x)
}
define floor(x) {
if (x >= 0) return x-(x%1)
else return -1*ceil(-1*x)
}