# Problem updating a variable in a loop

How i acn upadate the value of the variable “square=0” as mention in my code so that after every loop it will update it by addind + 1 in “square=0”

this is my code :

``````def findcontours(path) do
#squares=0
{:ok, {_, thrash}} = OpenCV.threshold(imgGrey, 240, 255, OpenCV.cv_THRESH_BINARY())
{:ok, {contours, _}} =OpenCV.findContours(thrash, OpenCV.cv_RETR_TREE(), OpenCV.cv_CHAIN_APPROX_NONE())

square = 0
for contour <- contours do
{:ok,peri} = OpenCV.arcLength(contour,true)
{:ok,approx} = OpenCV.approxPolyDP(contour, 0.01 * peri,true)
ap=OpenCV.Nx.to_nx(approx)
{len,_,_}=Nx.shape(ap)

if len==4 do #to bound squares from the countor
{:ok,{x1, y1, w, h}}= OpenCV.boundingRect(approx)
aspectRatio = (w/1)/h
if aspectRatio >= 0.95 and aspectRatio <= 1.05 and (y1+h)*(x1+w) < 985000 do
square=square +1
end
end
end
end
``````

pls help me to update my value of square as i know there i a big problem of scope in elixir and also it is immutable so pls help me for this.

or suggest me another way so that i can do the whole process by another way if possible.

In Elixir, variables are actually constants. You can’t reassign values to an existing variable. You can only create a new variable with the same name and shadow the old one.

This line `square = square + 1` reads the value of `square` outside the for-loop, adds 1 to it, and creates a new variable also named `square`, which is not used at all, because this new `square` variable is inside a sub-sub scope of the for-loop, and the old `square` is outside the for-loop. They are in different scopes.

How to fix this?

``````square = for contour <- contours, reduce: 0 do
acc ->
{:ok,peri} = OpenCV.arcLength(contour,true)
{:ok,approx} = OpenCV.approxPolyDP(contour, 0.01 * peri,true)
ap=OpenCV.Nx.to_nx(approx)
{len,_,_}=Nx.shape(ap)

if len==4 do #to bound squares from the countor
{:ok,{x1, y1, w, h}}= OpenCV.boundingRect(approx)
aspectRatio = (w/1)/h
if aspectRatio >= 0.95 and aspectRatio <= 1.05 and (y1+h)*(x1+w) < 985000 do
acc + 1
else
acc
end
else
acc
end
end
``````

can u explain me briefly what u have done in this

``````square = for contour <- contours, reduce: 0 do
acc ->
{:ok,peri} = OpenCV.arcLength(contour,true)
{:ok,approx} = OpenCV.approxPolyDP(contour, 0.01 * peri,true)
ap=OpenCV.Nx.to_nx(approx)
{len,_,_}=Nx.shape(ap)

if len==4 do #to bound squares from the countor
{:ok,{x1, y1, w, h}}= OpenCV.boundingRect(approx)
aspectRatio = (w/1)/h
if aspectRatio >= 0.95 and aspectRatio <= 1.05 and (y1+h)*(x1+w) < 985000 do
acc + 1
else
acc
end
end
end
``````

so that in further code if i will face problem regarding this i can rectify it

Here’s a simple example of the `for` comprehension with the option `:reduce`:

``````for n <- 1..10, reduce: 0 do
acc -> acc + n
end

# returns 55
``````

It’s equivalent to this code (I’m using the same variable names as in the snippet above):

``````Enum.reduce(1..10, 0, fn n, acc ->
acc + n
end)
``````

The `for` comprehension first passes `0`, the value of the option `:reduce`, to `acc`, the first element in `1..10` to `n`, and apply the anonymous function to `acc` and `n`. Then it passes the return value of the anonymous function to `acc`, the second element in `1..10` to `n`, and apply the anonymous function again. So on and so forth, until there’s no element to take from `1..10`, then it returns the return value of the last call of that anonymous function.

1 Like

And note that both `for ... do ... end` and `if ... else ... end` are expressions, and they have return values.

The `if` without `else` returns whatever inside the `if` block returns, if the condition is met, otherwise, it returns `nil`, which usually is not what you want, so be careful.

1 Like

I was trying to use tesseract-Ocr in elixir
but i am getting error pls :

``````iex(4)> import TesseractOcr.Utils
TesseractOcr.Utils
iex(5)> path="lib/grid_1.png"
"lib/grid_1.png"
** (ErlangError) Erlang error: :enoent
(elixir 1.13.4) lib/system.ex:1044: System.cmd("tesseract", ["lib/grid_1.png", "stdout"], [])
iex(6)>

``````

pls help me to rectify it

It means the file path you specified does not exist.

Use `File.exists?` inside `iex` to find the right file path.

I am getting error again :

``````iex(6)> import TesseractOcr.Utils
TesseractOcr.Utils
iex(8)> File.exists?(path)
true
** (ErlangError) Erlang error: :enoent
iex(9)>
nil
``````

why it is showing again this .

also i think i have the tesseract dependencies in mix.exs

``````  defp deps do
[
{:evision, "~> 0.1.0-dev", github: "cocoa-xu/evision", branch: "main"},
{:nx, "~> 0.2"},
{:tesseract_ocr, "~> 0.1.5"}
]
end
end

``````

but still it is showing me the error

It’s expecting you to have `tesseract` installed and put in the system PATH.

What does `which tesseract` show you when you run it in a terminal?

This the path i have added in my system.

``````erts@eyrc:~/Downloads/task1b_evision_resource\$ echo \$PATH
``````

and this is my file location and location of my image grid_1.png is also there:

and this is my code with error i have written :

``````erts@eyrc:~/Downloads/task1b_evision_resource\$ iex -S mix
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [jit:ns]

Compiling 1 file (.ex)
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> import TesseractOcr.Utils
TesseractOcr.Utils
** (ErlangError) Erlang error: :enoent
iex(3)>

``````

Now I am not getting where is the error , i am not able to read a single image.

Have you run `which tesseract`? If so, can you paste the output of the command?

I am getting this :

``````erts@eyrc:~/Downloads/task1b_evision_resource\$ which tesseract
Then you have a very easy problem: find exactly in which directory the `tesseract` program binary resides and add that to \$PATH. Because right now it’s not there.