2

I'm using Julia, and I tried to test out a function that creates an image and assigns Red values based on the string given. Just from hearing that sentence I'm sure you can think of a million things I could have done to receive an error message, but this error:

enter image description here

was generated at line 13.

Here's line 13:

r = (i + 64*rand(0:3) - 1)/255

That's just math! r is a new variable I'm assigning just there. i is the index of each character in an array. This seems to work in the console, so maybe something weird is happening in the code before and it just isn't being caught. Here's the whole function:

function generate(string, width)
  img = rand(RGB,width,floor(Int,length(string)/width) + 1)
  for n in 1:length(string)
    i = indexin(string[n], alphabet)
    r = (i + 64*rand(0:3) - 1)/255
    g = img[n].g
    b = img[n].b
    img[n] = RBG(r,g,b)
  end
  return img
end

Does anyone know what this error message means, or what I did wrong?

mcabbott
  • 2,329
  • 1
  • 4
  • 8
  • 1
    Instead of doing floating point division followed by rounding with `floor(Int,length(string)/width)`, you should use integer division directly with the `div` function: `div(length(mystring), width)`. – DNF Jul 12 '21 at 06:30
  • 2
    Please do not post images of code/errors/data. Instead post the code/errors/data as text in a code block. See [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – Scratte Jul 12 '21 at 08:19

1 Answers1

6

Your i here isn't an integer, it's an array. indexin is intended for finding positions of each element of an array in another; to find just one element you probably want findfirst:

julia> findfirst(isequal('c'), collect("abcde"))
3

julia> indexin(collect("cab"), collect("abcde"))
3-element Vector{Union{Nothing, Int64}}:
 3
 1
 2

julia> indexin('c', collect("abcde"))
0-dimensional Array{Union{Nothing, Int64}, 0}:
3

Note also that both of these will give nothing if they cannot find the letter, which you may want to decide how to handle. (Possibly with if else, you can also use the function something.)

julia> indexin('z', collect("abcde"))
0-dimensional Array{Union{Nothing, Int64}, 0}:
nothing

julia> findfirst(isequal('z'), collect("abcde")) === nothing
true

Finally, note that indexing a string like this isn't very robust, you may want to iterate it:

julia> "cañon"[4]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'ñ', [5]=>'o'

julia> for (n, char) in enumerate("cañon")
       @show n, char
       end
(n, char) = (1, 'c')
(n, char) = (2, 'a')
(n, char) = (3, 'ñ')
(n, char) = (4, 'o')
(n, char) = (5, 'n')
mcabbott
  • 2,329
  • 1
  • 4
  • 8