# Iterating using Channel

**URL:** https://discourse.julialang.org/t/iterating-using-channel/30762
**Category:** General Usage
**Created:** [November 5, 2019, 6:10pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762 "2019-11-05T18:10:16Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![marouane1994](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@marouane1994](https://discourse.julialang.org/u/marouane1994)
#### Post date: [November 5, 2019, 6:10pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/1 "2019-11-05T18:10:16Z")

</div>

i have some problems in replacing the deprecated function `produce()`with `Channel()`in this code:

```julia
function scan_maker(A)
    m = JuMP.Model(solver=ClpSolver(PrimalTolerance=1e-3, DualTolerance=1e-3, InfeasibleReturn=1, PresolveType=1))
    # m = Model(solver=GurobiSolver())
    level = size(A, 2)
    v = zeros(Int, level)
    ub = zeros(Int, level)
    lb = zeros(Int, level)

    @variable(m, x[1:level])
    @constraint(m, con, A*x.>=0)

    function setc(c)
        for i = 1:size(A, 1)
            m.linconstr[i].lb = float(c[i])
        end
    end
    
    function scan()
        i = 1
        init = 1
        while i > 0
            if i >= init
                @objective(m, Max, x[i])
                res = JuMP.solve(m, suppress_warnings=true)
                if res==:Optimal || res==:Unbounded
                    ub[i] = round(Int, getvalue(x[i]))
                    setobjectivesense(m, :Min)
                    res = JuMP.solve(m, suppress_warnings=true)
                    @assert res==:Optimal || res==:Unbounded
                    lb[i] = round(Int, getvalue(x[i]))

                    v[i] = lb[i]
                    init += 1
                else
                    @assert res==:Infeasible
                    i -= 1
                    continue
                end
            elseif v[i] < ub[i]
                v[i] += 1
            else
                setupperbound(x[i], Inf)
                setlowerbound(x[i], -Inf)
                init -= 1
                i -= 1
                continue
            end

            if i >= level
                produce(v)
                continue
            else
                setupperbound(x[i], v[i])
                setlowerbound(x[i], v[i])
                i += 1
            end
        end
    end
    
    return setc, scan
end

```

i have tried to put `c::Channel` as an argument of the function `scan()`and change `produce(v)`with `put!(c,v)` the function was compiled but when i want to call the functions for example:

```julia
julia> A=[2 2;1 1;4 3]
3×2 Array{Int64,2}:
 2 2
 1 1
 4 3
julia> B=[2;3;7]
3-element Array{Int64,1}:
 2
 3
 7
julia> a,b=scan_maker(A)
(getfield(Main, Symbol("#setc#3")){Array{Int64,2},Model}([2 2; 1 1; 4 3], Feasibility problem with:
 * 3 linear constraints
 * 2 variables
Solver is Clp), getfield(Main, Symbol("#scan#4")){Model,Int64,Array{Int64,1},Array{Int64,1},Array{Int64,1},Array{Variable,1}}(Feasibility problem with:
 * 3 linear constraints
 * 2 variables
Solver is Clp, 2, [0, 0], [0, 0], [0, 0], x[i] ∀ i ∈ {1,2}))

julia> a(B) # i'm calling the new function which is supposed to return nothing and it's working

julia> mychannel=Channel((channel_arg) -> b( pwd(), channel_arg)) # defining a Channel
Channel{Any}(sz_max:0,sz_curr:0)

julia> b(mychannel)
ERROR: MethodError: no method matching (::getfield(Main, Symbol("#scan#4")){Model,Int64,Array{Int64,1},Array{Int64,1},Array{Int64,1},Array{Variable,1}})(::String, ::Channel{Any})
Stacktrace:
 [1] check_channel_state at ./channels.jl:117 [inlined]
 [2] put! at ./channels.jl:273 [inlined]
 [3] push! at ./channels.jl:312 [inlined]
 [4] (::getfield(Main, Symbol("#scan#4")){Model,Int64,Array{Int64,1},Array{Int64,1},Array{Int64,1},Array{Variable,1}})(::Channel{Any}) at ./REPL[3]:50
 [5] top-level scope at REPL[20]:1

```

when i call the function `scan` i get that error above, i don’t know how to deal with this.  
The output should be something like this:

```julia
v = [-1, 6]
v = [0, 4]
v = [1, 2] 

```

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [November 5, 2019, 11:45pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/2 "2019-11-05T23:45:12Z")

</div>

(Hello and welcome!)

It is not really clear what you did exactly, but your approach should work. Here is a minimal example demonstrating it:

```julia
function scan_maker(n)
    function scan(c::Channel)
        for i in 1:n
            put!(c, i)
        end

        close(c)
    end
    return scan
end

```

```julia
julia> scan = scan_maker(5)
scan (generic function with 1 method)

julia> chan = Channel(scan)
Channel{Any}(sz_max:0,sz_curr:1)

julia> for i in chan
           @show i
       end
i = 1
i = 2
i = 3
i = 4
i = 5

```

  

Judging from the error message that you get, your first problem comes from the creation of the channel:

```julia
mychannel=Channel((channel_arg) -> b( pwd(), channel_arg))

```

should be something else, perhaps simply

```julia
mychannel=Channel(b)

```

but it’s difficult to be sure without seeing the modified `scan_maker` code that you actually used to produce `b`…

---

<div class="post-metadata">

### Author: ![marouane1994](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@marouane1994](https://discourse.julialang.org/u/marouane1994)
#### Post date: [November 6, 2019, 10:40am UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/3 "2019-11-06T10:40:09Z")

</div>

the modification was in `scan` function like this

```julia
function scan(c::Channel)
i = 1
        init = 1
        while i > 0
            if i >= init
                @objective(m, Max, x[i])
                res = JuMP.solve(m, suppress_warnings=true)
                if res==:Optimal || res==:Unbounded
                    ub[i] = round(Int, getvalue(x[i]))
                    setobjectivesense(m, :Min)
                    res = JuMP.solve(m, suppress_warnings=true)
                    @assert res==:Optimal || res==:Unbounded
                    lb[i] = round(Int, getvalue(x[i]))

                    v[i] = lb[i]
                    init += 1
                else
                    @assert res==:Infeasible
                    i -= 1
                    continue
                end
            elseif v[i] < ub[i]
                v[i] += 1
            else
                setupperbound(x[i], Inf)
                setlowerbound(x[i], -Inf)
                init -= 1
                i -= 1
                continue
            end

            if i >= level
                put!(c, v)
                close(c)
                continue
            else
                setupperbound(x[i], v[i])
                setlowerbound(x[i], v[i])
                i += 1
            end
        end
    end

```

an now i have tried to create a `Channel` by simply doing the same thing : `mychannel=Channel(b)` i get this one : `Channel{Any}(sz_max:0,sz_curr:1)` and when i call the function after by `b(mychannel)`the code compiles non stop without giving me anything :  
`julia> b(mychannel)`

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [November 6, 2019, 5:16pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/4 "2019-11-06T17:16:12Z")

</div>

Could you please post a complete example of what you did? And if you can, reduce you problem to something minimal like I did in my earlier post: for example, Jump probably has nothing to do with you problem, and you could just keep the logic of your code, but not actually call Jump.

There is a relatively complete list of advice that you might find useful to express your problem in a way that will help us help you more effectively: [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757)

By the way, did you try the example I gave you? Did it work?

---

<div class="post-metadata">

### Author: ![marouane1994](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@marouane1994](https://discourse.julialang.org/u/marouane1994)
#### Post date: [November 7, 2019, 11:29am UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/5 "2019-11-07T11:29:33Z")

</div>

in general i put `c::Channel` as an argument of function `scan` and changed `produce(v)` with `take!(c,v)` and the i closed using `close(c)` .  
your entire approach works now except one problem is that i don’t get all the outputs, when i do :

```julia
julia> chnl=Channel(b)
Channel{Any}(sz_max:0,sz_curr:1)

julia> for i in chnl
       @show i
       end
i = [-2, 6]

```

as you can see i get only one output at the time i’m supposed to get 5 outputs like this :

```julia
v = [-2, 6]
v = [-1, 6]
v = [0, 4]
v = [1, 4]
v = [2, 2]

```

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [November 7, 2019, 12:17pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/6 "2019-11-07T12:17:13Z")

</div>

Again, please post runnable code exhibiting the bad behavior you encounter: it is often not particularly easy to debug code, but it gets very hard when you don’t even know what code you’re debugging 😉

That being said, if the code with which you obtain only one result (instead of 5) is the one you posted above, one mistake in it is that you close the channel as soon as you write in it

```julia
            if i >= level
                put!(c, v)
                close(c)
                continue
            else
                 # ...

```

You should `put` all results in the channel, and only `close` it at the end of the calculation

---

<div class="post-metadata">

### Author: ![marouane1994](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@marouane1994](https://discourse.julialang.org/u/marouane1994)
#### Post date: [November 7, 2019, 1:49pm UTC](https://discourse.julialang.org/t/iterating-using-channel/30762/7 "2019-11-07T13:49:00Z")

</div>

yes you are right, i didn’t know that i was cloing the channel right after the calculation i should’ve close it after the end of the loop , i have compared the outputs that i get using `Channel`and the ones when i use `@show`, they are similar.
