I have to translate two Python functions into PHP. The first one is:
def listspaces(string):
return [i -1 for i in range(len(string)) if string.startswith(' ', i-1)]
I am assuming that this will check for space in provided string and return True when first occurrence of space is found, is this correct ?
What is i-1
here ? is it -1
?
In PHP we use []
for arrays . Here we are []
with return, will this function return true or false or array of locations of spaces ?
Second function is
def trimcopy(copy, spaces, length=350):
try:
if len(copy) < length:
return copy
else:
loc = 0
for space in spaces:
if space < length:
loc = space
else:
return copy[:loc]
except :
return None
Whats for space in spaces: here and whats is this return copy[:loc]
You may notice that the first function could also have been written as
def listspaces(str):
return [i for i, c in enumerate(str) if c==' ']
That version has the following straightforward conversion to PHP:
function listspaces($str) {
$spaces = array();
foreach (str_split($str) as $i => $chr)
if ($chr == ' ') $spaces[] = $i;
return $spaces;
}
As for the other function, this seems to do the same thing in very nearly the same idiom:
function trimcopy($copy, $spaces, $length=350) {
if (strlen($copy) < $length) {
return $copy;
} else {
foreach ($spaces as $space) {
if ($space < $length) {
$loc = $space;
} else {
return substr($copy, 0, $loc);
}
}
}
}
As others have pointed out, the intent of both of these functions could probably be better expressed by using wordwrap
.
Why don't you just test those functions to see what they are doing?
listspaces(string)
returns an array with the positions of all spaces within the string:
$ ipython
IPython 0.10.2 -- An enhanced Interactive Python.
In [1]: def listspaces(string):
...: return [i -1 for i in range(len(string)) if string.startswith(' ', i-1)]
...:
In [2]: listspaces('Hallo du schöne neue Welt!')
Out[2]: [5, 8, 16, 21]
(i -1
is the position of a space when starting to count with zero)
I don't know much about Python and I can't paste the second function as there are to many "IndentationError"'s.
I think that trimcopy()
will return a string (from input copy
), where everything behind the last space position given in the array spaces
(obviously a return value from listspaces()
) is trimmed, unless the input is no longer than length
. In other words: the input is cut off at the highest space position that is smaller than length
.
As of the example above, the part ' Welt!'
will get cut off:
s = 'Hallo du schöne neue Welt!'
trimcopy( s, listspaces( s ) )
/* should return: 'Hallo du schöne neue' */
The first function returns indexes of all spaces in given string.
range(len(string))
results in list with numbers from 0 to length of the input stringif string.startswith(' ', i-1)]
condition is evaluated for each index i
, it returns true when string (here it is not a keyword) starts with ' ' at position given by the index i-1
The result is as feela posted.
For the second function I don't know what the spaces parameter is.
Hope this will help you to create a PHP version.
I think a good process for these type of conversions is:
work out what the code is doing
refactor it into a PHP-style in Python (this enables you to check that the logic still works, e.g. using assertion tests). e.g. convert list comprehensions to for loops
convert to PHP
For example, listspaces(string)
returns the positions of spaces in string
, and although using a list comprehension is Pythonic, it's not very "PHP-onic".
def listspaces2(string): #PHP-onic listspaces
space_positions = []
for i in range(len(string))]:
if string[i] == ' ':
space_positions.append(i)
return space_positions
The second example, trimcopy
is rather trickier (since the try, except may purposefully be catching some expected - to the writer (!) - exceptions - two possibles are string
not having a len
and spaces
containing values longer than len(copy)
), but it's hard to say so it's a good idea to refactor in Python and test.
You can do array slicing in PHP like copy[:loc]
using array_slice($copy, 0, $loc);
.
Note: usually in Python we would state explicitly which exception we are defending against (as opposed to Pokemon exception handling).
This is equivalent to both the functions in Python
list($short) = explode("
",wordwrap($string,350));