I'm using imagefilledrectangle() in my project. The 2nd, 3rd, 4th and 5th parameters accept point coordinates. The function description specifies the type of these should be integer. My problem is, I'm calculating these at run time and ensuring they are integers is proving difficult.
My question:
What are the consequences of using 'real numbers' instead of integers? For example:
imagefilledrectangle( $img, 1.2, 3.4, 4.5, 7.8, $color )
Ref: http://php.net/manual/en/function.imagefilledrectangle.php
As written, your floats will get integerized by truncation, as per PHP's float->int conversion rules. So the function call will effectively be
imagefilledrectangle( $img, 1, 3, 4, 7, $color )
due to the function explicitly defining the position arguments as being int.
e.g.
echo (int)7.8; // outputs '7'
echo (int)1.2; // outputs '1'
Related
I have an array that i need to pack with python to 16bit depth with
I have been doing this with php without any issues.
Array is just just large set of numbers like this - [1, 2, 3, 4, 5, 700, 540...]
With php I do this process in one line:
$encoded_string = pack("s*", ...$array); // Done
I can not for the love of god figure out how same can be done in python
I have read the documentation, I looked at examples and I can not get this done
Best I have is below and it does not work in any variation i have tried.
encoded_string = struct.pack('h', *array)
You have to call struct.pack on each member of your array:
import struct
nums = [1, 2, 3, 4, 5, 700, 540]
as_bytes = [struct.pack('h', i) for i in nums]
# Produces
[b'\x01\x00', b'\x02\x00', b'\x03\x00', b'\x04\x00', b'\x05\x00', b'\xbc\x02', b'\x1c\x02', b'\x08\x00']
and then that you can join into a single byte string if you want:
>>> b''.join(as_bytes)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'
Note: you can also use the endianness modifiers to specify the alignment for the output bytes.
Edit: #Proper reminded me that struct.pack's formatting also supports specifying the number of target packed types, so this can be done more easily by including the data length in an f-string with the format specifier:
>>> struct.pack(f'{len(data)}h', *data)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'
Thank you for the reply b_c to be honest I hate python with a passion at this point, there was another problem that i had to fix, the array was created as str and not int after it was "exploded". So it had to be remapped to int.
Your code does work, thank you.
There is a way to do it with my initial code, however you have to define number of values you want to process. It is possible to simply count number of values in the array and add than in to make it automated
data_array = map(int,data) # converts all values in the array to int
encoded_string = struct.pack('240s',*data_array) # 240 is number of values in the array
I have to do arithmetic with some ternary (base 3) numbers. I know I can use base_convert to get from a ternary string ("2001022210") to an integer. Is there an existing function to do the inverse?
I want "some_function" such that:
$someInteger = base_convert("2001022210", 10, 3);
some_function($someInteger);
answers "2001022210". I'm happy to provide extra arguments ...
some_function($someInteger, 3);
some_function($someInteger, 3, 10);
I know I can code this myself, but I'm hoping it's already there.
$someInteger is now in base 3... so just do $base10Int = base_convert($someInteger, 3, 10); to get it back.
Tom. Please head over to http://php.net/ when you use php functions to see what they actually do. Reading and understanding a languages API is a general key for writing good code.
string base_convert ( string $number , int $frombase , int $tobase )
Returns a string containing number represented in base tobase. The base in which number is given is specified in frombase. Both frombase and tobase have to be between 2 and 36, inclusive. Digits in numbers with a base higher than 10 will be represented with the letters a-z, with a meaning 10, b meaning 11 and z meaning 35.
Now let $number be the number you want to convert:
If you want to convert it from ternary to decimal you use base_convert($number, 3, 10);
If you want to convert it from decimal to ternary you use base_convert($number, 10, 3);
Yes, this can be done with base_convert():
As the PHP Manual says:
base_convert — Convert a number between arbitrary bases
So, the following would work:
base_convert($someinteger, 3, 10);
As a function:
function some_func($someinteger) {
return base_convert($someinteger, 3, 10);
}
I had an interesting discussion with my good developer friends. I wanted to create a random sequence of given array values but with maximum fragmentation, without any detectable patterns. This so called maximum randomness would be practically always identical for any unique sequence.
Example input array:
array(1, 2, 3, 4, 5);
Example result of a standard rand() function:
array(2, 3, 1, 5, 4);
What I don't like in the output above are the sequence values like "2, 3" and "5, 4", It's not fragmented enough.
Expecting result would/could be:
array(3, 5, 1, 4, 2);
So my question; is there any known formula to calculate the maximum randomness or for better choice of words, maximum fragmentation?
So what are you talking about, not randomization, it is sorting. The result of randomization should not depend on order of the initial data.
By fragmentation in this case it is necessary to understand the differences between the array before sorting and after. But it must be evaluated differently depending on the task. For example, one can evaluate the difference between the positions of the elements or it's order.
Sorting example.
<?
// it must be uksort() function with sequence formula, but for me easier do like this
$array = array(1, 2, 3, 4, 5);
uk_sort($array);
function uk_sort(&$array) {
for($i=0;$i<count($array);$i++) {
if($i%2==0) {
$even[] = $array[$i];
} else {
$odd[] = $array[$i];
}
}
$even[] = array_shift($even);
rsort($odd);
$array = array_merge($even, $odd);
}
print_r($array);
?>
Array
(
[0] => 3
[1] => 5
[2] => 1
[3] => 4
[4] => 2
)
You could split the list into two (or more) collections, shuffle those THEN mix them in order?
array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
array(1, 2, 3, 4, 5);
array(6, 7, 8, 9, 10);
array(2, 3, 1, 5, 4);
array(8, 7, 10, 9, 6);
array(2, 8, 3, 7, 1, 10, 5, 9, 4, 6)
This would give you a fairly high fragmentation but not the maximum.
I suspect to get the maximum would require a LOT more work.
Assuming the fragmentation is defined as the sum of the absolute differences of successive values, the maximum fragmentation sequence is not unique -- the reverse sequence will always have the exact same fragmentation and there're many more options, e.g. all the following orderings will have a fragmentation of 11, which is maximal for this array: (3,1,5,2,4), (3,2,5,1,4), (2,5,1,4,3), (2,4,1,5,3), (4,1,5,2,3), (4,2,5,1,3), (3,5,1,4,2), (3,4,1,5,2). There're yet more symmetries if one incorporates the difference between the last and the first element, too.
If one seeks to identify a particular maximum fragmentation sequence, e.g. the one "without a noticeable pattern", the latter notion has to be formalized and a search performed, which, I suspect, would be costly from the computational point of view, unless the objective can be formalized so as to permit efficient decoding. I suspect that for all practical purposes a good heuristic would suffice, e.g. inserting elements into an array one by one (greedy fashion) so as to maximize the gain in fragmentation on each step.
If the elements of the array are not numbers but some entities with a defined distance for each pair, however, the problem does become equivalent to the traveling salesman problem, as user802500 pointed out.
I think this sounds like a traveling salesman type problem, with the "distance" being the difference between two chosen entries, except your goal would be to maximize the total distance rather than minimize it.
I don't actually know a ton about the topic, but here's what I think I know:
There are algorithms for the traveling salesman problem, but they can be quite slow in the limit (they're NP-hard). On the other hand, there are good approximations, and simple cases may be solvable, though it will still be a non-trivial algorithm.
Depending on how important it is to have maximum fragmentation, you could also try a naive method: given an element, choose the next element so that it's quite distant from the given element. Then choose a next element, and so on. The problem with this is that your early choices can back you into a corner. So this won't work if fragmentation is quite important to you.
[2,5,1,3,4] // the first three choices force us to not fragment the last two
I have created a PHP system that is having some problems with rounding. After looking further into this, I found that it goes back to the round function in PHP.
For instance...
Rounding 2047.615 to 2 decimal places gives 2047.62 (as expected)
Rounding 2048.615 to 2 decimal places gives 2048.61 (doesn't round up as expected)
I understand that the issue here most likely goes back to the inaccuracy of representing floating numbers in binary, but what is the most elegant way to take care of such issues?
It rounds as expected for me. Have you tried explicitly setting the mode parameter to round()?
round( 2048.615, 2, PHP_ROUND_HALF_UP); // however, PHP_ROUND_HALF_UP is the default
EDIT: It looks like round() was changed in PHP 5.3.0:
Changed round() to act more intuitively when rounding to a certain
precision and round very large and very small exponents correctly.
(Christian Seiler)2
2048.615 is actually 2048.6149999999998, so it will round down to 2048.61 no matter the rounding method used.
Most likely your particular round function is performing Banker's Rounding (or PHP_ROUND_HALF_EVEN).
If you want a different kind of rounding, use one of the other PHP rounding variants:
<?php
echo round(9.5, 0, PHP_ROUND_HALF_UP); // 10
echo round(9.5, 0, PHP_ROUND_HALF_DOWN); // 9
echo round(9.5, 0, PHP_ROUND_HALF_EVEN); // 10
echo round(9.5, 0, PHP_ROUND_HALF_ODD); // 9
echo round(8.5, 0, PHP_ROUND_HALF_UP); // 9
echo round(8.5, 0, PHP_ROUND_HALF_DOWN); // 8
echo round(8.5, 0, PHP_ROUND_HALF_EVEN); // 8
echo round(8.5, 0, PHP_ROUND_HALF_ODD); // 9
?>
Here's the best solution I've come up with. In the following snippet I separate out the integer and decimal parts of the number and then do my rounding just on the decimal part (which gives me more bits available to work on the decimal accuracy). Does anybody see any problems with this solution?
function my_round($number, $decimals)
return floor($number) + round(round($number - floor($number), $decimals + 4), $decimals);
}
The "+ 4" is somewhat arbitrary (about half of the trailing digits of detail), but is attempting to be accurate enough without being so accurate as to run into the .499999999 issue causing this whole thing.
I have a project where I have to generate random numbers from 00000 till 99999.
The randomizing isn't where I get stuck, but the fact that it always needs 5 characters is. So when it generates the number 14, I want it as 00014.
What is the best way to achieve this?
sprintf() can do that:
echo sprintf('%05d', 0);
Or use str_pad() - but that's a little bit longer in code:
echo str_pad(0, 5, 0, STR_PAD_LEFT);
str_pad() is able to do what you need the code to be done.
Simply:
$s = str_pad('14', 5, '0', STR_PAD_LEFT);
generate integers with leading 0's
An integer will never have leading 0's.
If you need leading 0's you nedd to convert the integer to an string -> see the answer from thephpdeveloper. This is the right way for writing an number with leading 0's into a database - for example.
If you like to work with that integer (for example for calculations) it's better to leave the integer as an integer (don't change to string) and every time you need to output those numbers -> take the solution from "Stefan Gehrig"
Even substr() can do it:
print substr('0000' . $myRandomNumber, -5);
(Not that I would recommend this. Just wanted to contribute :) )