Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: more docs #1436

Merged
merged 12 commits into from
Sep 6, 2018
Merged

RFC: more docs #1436

merged 12 commits into from
Sep 6, 2018

Conversation

odow
Copy link
Member

@odow odow commented Aug 23, 2018

Continuation of my doc-writing quest in order to learn the new JuMP syntax.

The majority of the quickstart is borrowed from https://github.com/JuliaOpt/JuMP.jl/blob/v0.18.2/doc/example.rst

The most contentious change is that I added GLPK to travis so that we have a solver for the doc tests. We now use a mock optimizer.

@codecov
Copy link

codecov bot commented Aug 23, 2018

Codecov Report

Merging #1436 into master will increase coverage by 0.05%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1436      +/-   ##
==========================================
+ Coverage   89.22%   89.28%   +0.05%     
==========================================
  Files          26       26              
  Lines        3723     3723              
==========================================
+ Hits         3322     3324       +2     
+ Misses        401      399       -2
Impacted Files Coverage Δ
src/parseexpr.jl 94.88% <0%> (+0.78%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4496a54...3598a59. Read the comment docs.

@blegat
Copy link
Member

blegat commented Aug 23, 2018

The output of the doctests on Travis seem to indicate failures:

=====[Test Error]==============================

Location: src/quickstart.md:63-65
Code block:

julia> con = @constraint(model, 1x + 5y <= 3)
x + 5 y <= 3.0

Subexpression:
con = @constraint(model, 1x + 5y <= 3)
Output Diff (REQUIRES COLOR):
x + 5 y <= ≤ 3.0
=====[End Error]===============================
=====[Test Error]==============================
Location: src/quickstart.md:128-139
Code block:

julia> x_upper = JuMP.UpperBoundRef(x)
x <= 2.0
julia> JuMP.resultdual(x_upper)
-4.4
julia> y_lower = JuMP.LowerBoundRef(y)
y >= 0.0
julia> JuMP.resultdual(y_lower)
0.0

Subexpression:
x_upper = JuMP.UpperBoundRef(x)
Output Diff (REQUIRES COLOR):
x <= ≤ 2.0
=====[End Error]===============================
=====[Test Error]==============================
Location: src/quickstart.md:128-139
Code block:

julia> x_upper = JuMP.UpperBoundRef(x)
x <= 2.0
julia> JuMP.resultdual(x_upper)
-4.4
julia> y_lower = JuMP.LowerBoundRef(y)
y >= 0.0
julia> JuMP.resultdual(y_lower)
0.0

Subexpression:
y_lower = JuMP.LowerBoundRef(y)
Output Diff (REQUIRES COLOR):
y >= ≥ 0.0
=====[End Error]===============================

Wouldn't it be preferable to put the using GLPK outside the jldoctest and build a MockOptimizer instead in setup and feed it with the expected outputs ?

@odow
Copy link
Member Author

odow commented Aug 23, 2018

Urgh, this is some platform issue. For me, the docs build locally on v0.6 without errors.

@@ -130,9 +135,9 @@ In the above examples, `x_free` represents an unbounded optimization variable,
`@variable(model, a <= x)`) will result in an error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a=1 above should be a = 1 according to the style guide

familiar with another modeling language embedded in a high-level language such
as PuLP (Python) or a solver-specific interface you will find most of this
familiar, with the exception of *macros*. A deep understanding of macros is not
essential, but if you would like to know more please see the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this, it seems to me that it would be a good idea to first understanding macros while this really not a good idea to learn metaprogramming to use JuMP. This might discourage many users. I don't know if essential is the weak enough, maybe "needed" or "required" ? Not sure :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that pointer to macros is a bit out of place. The quick-start guide should be a gentle introduction that shows how to get a few basic things done using JuMP.

```
!!! note
Your model doesn't have to be called `model` - it's just a name. However,
the JuMP style guide prefers `model`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add add href to the style guide here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second sentence is maybe too much information. The style guide doesn't have an explicit preference for model, just a suggestion to avoid one-letter variable names.

DocTestFilters = r"JuMP\."
```
!!! note
Your model doesn't have to be called `model` - it's just a name. However,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't -> does not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we want to allow shortening or not in fact. If you think it is more friendly then I am ok to leave it :)

DocTestSetup = nothing
```

Next we'll set our objective. Note again the `model`, so we know which model's
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll -> we will

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I started reading the Google documentation style guide. They recommend using contractions: https://developers.google.com/style/contractions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok let's follow Google's style guideline for contraction

familiar with another modeling language embedded in a high-level language such
as PuLP (Python) or a solver-specific interface you will find most of this
familiar, with the exception of *macros*. A deep understanding of macros is not
essential, but if you would like to know more please see the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that pointer to macros is a bit out of place. The quick-start guide should be a gentle introduction that shows how to get a few basic things done using JuMP.

as PuLP (Python) or a solver-specific interface you will find most of this
familiar, with the exception of *macros*. A deep understanding of macros is not
essential, but if you would like to know more please see the
[Julia documentation](http://docs.julialang.org/en/latest/manual/metaprogramming/).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Link to versioned docs.

```
!!! note
Your model doesn't have to be called `model` - it's just a name. However,
the JuMP style guide prefers `model`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second sentence is maybe too much information. The style guide doesn't have an explicit preference for model, just a suggestion to avoid one-letter variable names.

it! Feel free to stick with `*` if it makes you feel more comfortable, as we
have done with `3*y`:
```jldoctest quickstart_example
julia> @objective(model, Max, 5x + 3*y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The style guide recommends spaces around binary operators, so 3 * y.

```
In this case, `GLPK` returned `Success`. This does not mean that it has found
the optimal solution. Instead, it indicates that GLPK has finished running and
did not encounter any errors or termination limits.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: user-provided termination limits

@@ -130,9 +135,9 @@ In the above examples, `x_free` represents an unbounded optimization variable,
`@variable(model, a <= x)`) will result in an error.

**Extra for experts:** the reason for this is that at compile time, JuMP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole note is maybe too much information. I don't remember anyone ever being confused by why @variable(model, a <= x) doesn't work. The error message should be helpful enough to figure it out if it ever happens.

MathOptInterface
```

To delete variables, we can use the `MOI.delete!` method. We can also check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's implement JuMP.delete! and JuMP.is_valid instead of documenting the MOI way.

@odow
Copy link
Member Author

odow commented Sep 1, 2018

We're good to go on my end.

Doctests pass on v0.6. Annoyingly, they fail on v0.7 because it does not print the module that defines the type. For example, v0.6 will print JuMP.VariableRef whereas v0.7 prints VariableRef. However, Documenter only has the ability to filter output that appears in both the docs and actual output.

@odow odow changed the title WIP: more docs RFC: more docs Sep 1, 2018
@mlubin
Copy link
Member

mlubin commented Sep 1, 2018 via email


julia> for key in [:A, :B]
variables[key] = @variable(model, [1:2, 1:2], Symmetric)
global variables[key] = @variable(model, [1:2, 1:2])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still can't believe that this global is necessary.

@odow
Copy link
Member Author

odow commented Sep 2, 2018

Doctests now run only on v1.0 and pass.

Copy link
Member

@mlubin mlubin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the slow review... was on vacation.

it! Feel free to stick with `*` if it makes you feel more comfortable, as we
have done with `3 * y`:
```jldoctest quickstart_example
julia> @objective(model, Max, 5x + 3 * y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe point out that this example is intentionally inconsistent, but it's good practice to use one way or the other consistently in your code.

less-than-or-equal-to constraint using `<=`, but we can also create equality
constraints using `==` and greater-than-or-equal-to constraints with `>=`:
```jldoctest quickstart_example; filter=r"≤|<="
julia> con = @constraint(model, 1x + 5y <= 3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use the anonymous constraint syntax here and the named variable syntax above? (I'd recommend using the named constraint syntax for consistency.)

julia> JuMP.termination_status(model)
Success::TerminationStatusCode = 0
```
In this case, `GLPK` returned `Success`. This does not mean that it has found
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emphasis on not

@@ -44,6 +44,10 @@ This code does three things:
To reduce confusion, we will attempt, where possible, to always refer to
variables with their corresponding prefix.

!!! warn
If you create two JuMP variables with the same name, an error will be
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More directly: "Creating two JuMP variables with the same name results in an error at runtime."

Because `y` is a Julia variable, I can bind it to a different value. For example,
if I go:
Because `y` is a Julia variable, we can bind it to a different value. For
example, if we go:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"if we go" sounds a bit too informal and might be confusing for non-native speakers. "if we write" instead?

@odow
Copy link
Member Author

odow commented Sep 6, 2018

Sorry for the slow review... was on vacation.

We're not paying you enough to need to apologize...

@mlubin mlubin merged commit a2f1285 into master Sep 6, 2018
@mlubin mlubin deleted the od/more-docs branch September 6, 2018 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants