This is probably not related to this channel, but ...
# python
b
This is probably not related to this channel, but I have no better idea where to ask. I've been trying to wrap my head around python list slicing assignment, but with very limited success. Could someone help me convert these two snippets in thread to Kotlin (ir python without list slicing) or at least give me some pointers? Much appreciated!
Copy code
def shift_img(img, dx, dy):
     img = np.roll(img, dy, axis=0)
     img = np.roll(img, dx, axis=1)
     if dy>0:
         img[:dy, :] = 0
     elif dy<0:
         img[dy:, :] = 0
     if dx>0:
         img[:, :dx] = 0
     elif dx<0:
         img[:, dx:] = 0
     return img
Copy code
def halftone():
     # for every bandLength rows darken to 10-30% brightness,
     # then don't touch for bandGap rows.
     bandLength, bandGap = 2, 3
     for y in range(holo.shape[0]):
         if y % (bandLength+bandGap) < bandLength:
             holo[y,:,:] = holo[y,:,:] * np.random.uniform(0.1, 0.3)
Both holo and img are 3d arrays
s
Good question! I think we in Python backend should solve it in some point. For now, I think of the following syntax:
Copy code
general case:
x[y:z:s]  # python
x[y until z step s]  # kotlin
without step:
x[y:z]  # python
x[y until z]  # kotlin
without some element:
x[:z]  # python
x[null until z]  # kotlin
But need of course define `operator get/set(PyRange)`for the type and
operator rangeTo
for nullable ints. And regarding multiple dimensions, Kotlin supports commas in brackets too: https://kotlinlang.org/docs/operator-overloading.html#indexed-access-operator So if we define such methods, we can easily write
img[:dy, :]
as
img[null until dy, null until null]
in Kotlin. Of course something else can be used instead of nulls and untils, but the idea is that it looks implementable in Kotlin
WDYT?
b
My main question was how to actually convert that snippet to not use array slicing and instead work with nested for loops with current kotlin :p
i.e. I'm trying to convert these to be usable from Kotlin/JVM
s
Copy code
fun shift_img(img: Tensor, dx: Int, dy: Int): Tensor {
     var img = img
     img = np.roll(img, dy, axis=0)
     img = np.roll(img, dx, axis=1)
     if (dy>0) {
         img[null until dy, null until null] = 0
     } else if (dy<0) {
         img[dy until null, null until] = 0
     }
     if (dx>0) {
         img[null until null, null until dx] = 0
     } else if (dx<0) {
         img[null until null, dx until null] = 0
     }
     return img
}
Will it work?
b
It still uses list slice operator assignment that I'm unable to grasp 😄 Also kotlin/jvm does not support this
img[x until y]
accessor
What I'm after is basically a kotlin or python code with 3 nested for loops (i.e. no
img[:,:,:] = other[:,:,:]
kind of syntax)
s
Also kotlin/jvm does not support this img[x until y] accessor
Why not?
x until y
simply returns
PyRange
object (if you define
operator fun Int?.rangeTo(end: Int?) = PyRange(this, end)
). And
img[x until y]
should be accessible if you define
operator fun Tensor.get(range: PyRange) = ...
b
I know, defining it is exactly the issue. See
It still uses list slice operator assignment that I'm unable to grasp
My problem here is mainly seeing how the code would look like without those operators so I could (hopefully) understand them.
s
There is a similar library in Kotlin: https://github.com/Kotlin/multik. There are code samples, docs, and sources. Maybe it can help
b
Thanks. Finally something to read on 😀
🚀 1
BTW, I've already find out that
arr[:]
syntax is called slicing, so I can goole it. Do you know how
arr[:] = other[:]
syntax is called so I could google that too?
s
Ahh, now I understand your main question 🙂 If you want terms of syntax elements, the most reliable source is Python AST docs: https://docs.python.org/3/library/ast.html. "Slicing" is mentioned there too. For
arr[:] = other[:]
, I don't know a term... In terms of AST, it's just an assignment of two things created via slicing. But I'm not sure how it's called in real life
b
Damn. I'm still trying to find something that would explain how the assignment is actually done. Right side is clear, it is just a subset of original array, but how it's assigned to left side, which is basically a meta-array is a mystery to me.
Eureka! It's called numpy view. So given
arr[:] = other[:]
, the processing is as follows: 1. Create a view of slice
viewImg = arr[:]
that maps to relevant elements in original
arr
matrix. 2. Create a view of
viewOther = other[:]
that maps to relevant elements in original
other
matrix. 3. Loop through elements of
viewOther
and assign them to
viewImg
. Errors if the shapes differ between the two. 4.
viewImg
assignments are translated to reassignments of each element in its original place in
img
🆒 2
Still digesting it, but it's a start! Found it deep in np docs. Reference