# Can you control how indexes are printed when you print a model?

**URL:** <https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377>\
**Category:** Optimization (Mathematical)\
**Created:** [February 13, 2022, 10:17pm UTC](https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377 "2022-02-13T22:17:57Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [February 13, 2022, 10:17pm UTC](https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377/1 "2022-02-13T22:17:57Z")

</div>

Can you control how JuMP prints indexes in `print(model)` beyond overriding `Base.show`? If not, this would be a nice, but not super-important feature.

Take as an example, an excerpt from the JuMP knapsack example, but instead we use `structs`:

```julia
struct Item
    name::String
    profit::Float64
    weight::Float64
end

items = [
    Item("TV", 5, 2),
    Item("Fridge", 3, 8),...
]

@variable(model, x[items], Bin)
...

```

If I print the model, elements of `x` will be printed as `x[Item("TV", 5.0, 2,0)]`, which is ok.

I can do better by defining

```julia
function Base.show(io::IO, i::Item)
    print(io, i.name)
end

```

and then `x`s will be `x[TV]` in the print out of the model. The problem here is that as far as I know, there’s only one `Base.show`, and you can’t pass any formatting information to it, and in other situations I might wish to `show` an `Item` differently.

I work around this by doing things like putting the `Item`s in a dictionary:

```julia
items = Dict(
    "TV" = Item("TV", 5, 2),...
)

@variable(model, x[keys(items)], Bin)

@constraint(model, sum(i.weight * x[key] for (key, i) in items) <= capacity)

```

But that makes the model unnecessarily complicated.

It would be really nice if there was something like a:

```julia
show_as_index(io:IO, x) = Base.show(io, x)

```

In JuMP so you could override `show_as_index`.

Are there any obvious solutions I am missing? This is a really minor gripe, but I’m working on some simple examples of using JuMP as tutorilals, and this would make the examples even simpler.

Thanks!

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [February 13, 2022, 10:25pm UTC](https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377/2 "2022-02-13T22:25:27Z")

</div>

There is no specific way to do this. JuMP interpolates the index as something similar to `"x[$(index)]"`, so it depends on your `show` method.

However, you can write a loop calling `set_name` to explicitly set the name for all indices:

```julia
julia> struct Item
           name::String
       end

julia> items = [Item("a"), Item("b")]
2-element Vector{Item}:
 Item("a")
 Item("b")

julia> model = Model();

julia> @variable(model, x[items])
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, Item[Item("a"), Item("b")]
And data, a 2-element Vector{VariableRef}:
 x[Item("a")]
 x[Item("b")]

julia> for i in items
           set_name(x[i], i.name)
       end

julia> x
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, Item[Item("a"), Item("b")]
And data, a 2-element Vector{VariableRef}:
 a
 b

julia> 2x[items[1]] + x[items[2]]
2 a + b

```

---

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [February 13, 2022, 10:34pm UTC](https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377/3 "2022-02-13T22:34:41Z")

</div>

Thanks Oscar!

You replied to that in between me fat-fingering the submit button (don’t hit tab when you’re writing code in Markdown…) and actually finishing my question. That works! (Also something to explain to newbies, but it does take some explanation).

It seems that the root problem is that you can’t pass formatting flags to `show`.

Thanks

(Fat fingered the submit _again_)

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [February 13, 2022, 11:33pm UTC](https://discourse.julialang.org/t/can-you-control-how-indexes-are-printed-when-you-print-a-model/76377/4 "2022-02-13T23:33:07Z")

</div>

> [@gleyland](#):
>
> `show_as_index(io:IO, x)`

There are a few problems with this:

- It wouldn’t generalize to base types like `Int`. So you wouldn’t be able to modify how `x[1:4]` printed
- Even if you did, it would apply to _all_ variables and constraints that those indices. So you couldn’t have `x[1:3]` and `y[1:3]` printed differently.
- Multiple indices gets tricky. Do you want `show_as_index(io, arg1, arg2, arg3)` Or define the `show` separately for each argument?

It’s come up a few times that people would like a `name` keyword to use as a function that takes the indices as arguments and returns a string, but we haven’t worked through the details given calling `set_name` is pretty easy. (Another reason was that names in macros are already confusing with `basename`, the `String` name, and the registered name. Adding _another_ thing would make it even more complicated.)
