text:
using EngEconomics, Roots, Plots

# Given
# Job1 = a
# Job2 = b
# Job3 = c
aInit = 100000
aAnnual = -75000
aFinal = 200000

bInit = 150000
bAnnual = -100000
bFinal = 230000

cInit = 175000
cAnnual = -150000
cFinal = 300000

MARR = 0.1
N = 3

# Find Best alternative from IRR analysis
# Step 1: Sort from smallest to biggest initial
# - X, c, b, a (where X is do nothing)
ΔCX_Init = cInit
ΔCX_Annual = cAnnual
ΔCX_Final = cFinal
ΔCX_IRR_eq(x) = ΔCX_Init * compoundAmountFactor(MARR, N) + ΔCX_Annual * uniformSeriesCompoundAmoundFactor(x, N) + ΔCX_Final

xVec = collect(0:0.01:1)
yVec = zeros(size(xVec))
plot(xVec, ΔCX_IRR_eq.(xVec))
plot!(xVec, yVec)

ΔCX_IRR = find_zero(ΔCX_IRR_eq, MARR)

if ΔCX_IRR >= MARR
	println("C")
else
	println("Do Nothing")
end

# BC
ΔBC_Init = bInit - cInit
ΔBC_Annual = bAnnual - cAnnual
ΔBC_Final = bFinal - cFinal
ΔBC_IRR_eq(x) = ΔBC_Init * compoundAmountFactor(x, N) + ΔBC_Annual * uniformSeriesCompoundAmoundFactor(MARR, N) + ΔBC_Final

plot(xVec, ΔBC_IRR_eq.(xVec))
plot!(xVec, yVec)

ΔBC_IRR = find_zero(ΔBC_IRR_eq, MARR)

if ΔBC_IRR >= MARR
	println("B")
else
	println("C")
end

# AB
ΔAB_Init = aInit - bInit
ΔAB_Annual1 = aAnnual - bAnnual
ΔAB_Final = aFinal - bFinal
ΔAB_IRR_eq(x) = ΔAB_Init * compoundAmountFactor(x, N) + ΔAB_Annual1 * uniformSeriesCompoundAmoundFactor(MARR, N) + ΔAB_Final

plot(xVec, ΔAB_IRR_eq.(xVec))
plot!(xVec, yVec)

ΔAB_IRR = find_zero(ΔAB_IRR_eq, MARR)

if ΔAB_IRR >= MARR
	println("A")
else
	println("B")
end

# If non-uniform cash flows, then use ERR
# - ERR means that if it's not an investment use the MARR rather than x
# - what this really means is, if \Delta_Job1_Job2_THINGY is negative, use x, because this is an investment so we use x
# - if \Delta_[]_[] is positive, then it is NOT an investment, so we ought to use MARR rather than x


text:
function main(::Robot)
    ox=0
    oy=0
    maxx=0
    while (isborder(r,Sud)==false)
        move!(r,Sud)
        oy=oy+1
    end
    while (isborder(r,West)==false)
        move!(r,West)
        ox=ox+1
    end
    while (isborder(r,Ost)==false)
        move!(r,Ost)
        maxx=maxx+1
    end
    back(r)
    while((maxx>0) || (isborder(r,Nord)==false))
        for i in 1:maxx
            putmarker!(r)
            move!(r,Ost)
        end
        putmarker!(r)
        if (isborder(r,Nord)==false)
            move!(r,Nord)
        end;
        maxx=maxx-1
        back(r)
    end
    while (isborder(r,Sud)==false)
        move!(r,Sud)
    end
    return_back(r,ox,oy)
end

function return_back(::Robot,ox::Int,oy::Int)
    for i in 1:ox
        move!(r,Ost)
    end
    for i in 1:oy
        move!(r,Nord)
    end
end
function back(::Robot)
    while (isborder(r,West)==false)
        move!(r,West)
    end
end

ext: jl

max_stars_repo_name: VladislavBukin/mirea-progs

max_issues_repo_name: VladislavBukin/mirea-progs

max_forks_repo_name: VladislavBukin/mirea-progs


text:
using ImageView.Navigation

import Base: show

# Since we have Tk available, don't force the user to type a filename
import Images.imread
imread() = imread(GetOpenFile())

function scaleinfo(cs::ImageContrast.ContrastSettings, scalei::MapInfo, img)
    if cs.min == nothing && cs.max == nothing
        return scalei
    else
        return ScaleMinMax(RGB24, img, cs.min, cs.max)
    end
end

@linux_only const default_perimeter = RGB(0.85,0.85,0.85)
@osx_only const default_perimeter = RGB(0.93, 0.93, 0.93)
@windows_only const default_perimeter = RGB(1,1,1)  # untested

## Type for storing information about the rendering canvas
# perimeter is the color used around the edges of the image; background is used
# "behind" the image (relevant only if it has transparency)
# render has syntax
#    render!(buf, img)
type ImageCanvas
    render!::Function        # function to fill a UInt32 buffer with image data
    aspect_x_per_y           # relative scaling of the two axes (unconstrained = nothing)
    background               # nothing, RGB color, or checkerboard pattern
    perimeter                # RGB color
    transpose::Bool
    flipx::Bool
    flipy::Bool
    surfaceformat::Int32     # The Cairo format (e.g., Cairo.FORMAT_ARGB32)
    annotations::Dict{UInt, AbstractAnnotation}
    handles::Dict{Symbol, Any}
    c::Canvas                # canvas for rendering image
    surface::CairoSurface    # source surface of the image (changes with zoom region)
    renderbuf::Array{UInt32} # intermediate used if transpose is true
    canvasbb::BoundingBox    # drawing region within canvas, in device coordinates
    navigationstate
    navigationctrls

    function ImageCanvas(fmt::Int32, props::Dict)
        ps = get(props, :pixelspacing, nothing)
        aspect_x_per_y = is(ps, nothing) ? nothing : ps[1]/ps[2]
        if haskey(props, :render!)
            render! = props[:render!]
        else
            if haskey(props, :clim)
                clim = props[:clim]
                render! = (buf, img) -> uint32color!(buf, img, ScaleMinMax(RGB24, img, clim[1], clim[2]))
            elseif haskey(props, :scalei)
                render! = (buf, img) -> uint32color!(buf, img, props[:scalei])
            else
                render! = uint32color!
            end
        end
        background = get(props, :background, fmt == Cairo.FORMAT_ARGB32 ? checker(32) : nothing)
        perimeter = get(props, :perimeter, default_perimeter)
        transpose = props[:transpose]
        flipx = get(props, :flipx, false)
        flipy = get(props, :flipy, false)
        new(render!, aspect_x_per_y, background, perimeter, transpose, flipx, flipy, fmt, Dict{UInt,AbstractAnnotation}(), Dict{Symbol,Any}())
        # c, surface, renderbuf, and canvasbb will be initialized later
    end
end

show(io::IO, imgc::ImageCanvas) = print(io, "ImageCanvas")

canvas(imgc::ImageCanvas) = imgc.c

parent(imgc::ImageCanvas) = Tk.parent(imgc.c)

toplevel(imgc::ImageCanvas) = Tk.toplevel(canvas(imgc))

function setbb!(imgc::ImageCanvas, w, h)
    if !is(imgc.aspect_x_per_y, nothing)
        wc = width(imgc.c)
        hc = height(imgc.c)
        sx = min(wc/w, imgc.aspect_x_per_y*hc/h)
        sy = sx/imgc.aspect_x_per_y
        wdraw = sx*w
        hdraw = sy*h
        xmin = (wc-wdraw)/2
        ymin = (hc-hdraw)/2
        imgc.canvasbb = BoundingBox(xmin, xmin+wdraw, ymin, ymin+hdraw)
    else
        imgc.canvasbb = BoundingBox(0, width(imgc.c), 0, height(imgc.c))
    end
    imgc
end

# Handle z and t slicing, and zooming in x and y
type ImageSlice2d{A<:AbstractImage}
    imslice::A
    pdims::Vector{Int}
    indexes::Vector{RangeIndex}
    dims::Vector{Int}
    zoombb::BoundingBox
    zindex::Int
    tindex::Int
    xdim::Int
    ydim::Int
    zdim::Int
    tdim::Int
end

function ImageSlice2d(img::AbstractImage, pdims::Vector{Int}, indexes, dims, bb::BoundingBox, zindex::Integer, tindex::Integer, xdim::Integer, ydim::Integer, zdim::Integer, tdim::Integer)
    assert2d(img)
    ImageSlice2d{typeof(img)}(img, pdims, RangeIndex[indexes...], Int[dims...], bb, convert(Int, zindex), convert(Int, tindex), convert(Int, xdim), convert(Int, ydim), convert(Int, zdim), convert(Int, tdim))
end

import Base.getindex
function getindex(img2::ImageSlice2d, x::Real, y::Real)
    P = parent(data(img2.imslice))
    indexes = RangeIndex[1:size(P,d) for d = 1:ndims(P)]
    indexes[img2.xdim] = clamp(convert(Int, x), 1, size(P,img2.xdim))
    indexes[img2.ydim] = clamp(convert(Int, y), 1, size(P,img2.ydim))
    if img2.zdim > 0
        indexes[img2.zdim] = img2.zindex
    end
    if img2.tdim > 0
        indexes[img2.tdim] = img2.tindex
    end
    P[indexes...]
end

function show(io::IO, img2::ImageSlice2d)
    print(io, "ImageSlice2d: zoom = ", img2.zoombb)
    if img2.zdim > 0
        print(io, ", z = ", img2.zindex)
    end
    if img2.tdim > 0
        print(io, ", t = ", img2.tindex)
    end
end

function ImageSlice2d(img::AbstractArray, props::Dict)
    sd = sdims(img)
    if !(2 <= sd <= 3)
        error("Only two or three spatial dimensions are permitted")
    end
    if !isa(img, AbstractImage)
        img = Images.Image(img, @compat Dict("colordim" => colordim(img), "spatialorder" => spatialorder(img), "colorspace" => colorspace(img)))
    end
    # Determine how dimensions map to x, y, z, t
    xy = get(props, :xy, Images.xy)
    cs = coords_spatial(img)
    p = spatialpermutation(xy, img)
    xdim = cs[p[1]]
    ydim = cs[p[2]]
    zdim = (sd == 2) ? 0 : cs[p[3]]
    tdim = timedim(img)
    # Deal with pixelspacing here
    if !haskey(props, :pixelspacing)
        if haskey(img, "pixelspacing")
            props[:pixelspacing] = img["pixelspacing"][p]
        end
    end
    props[:transpose] = p[1] > p[2]
    # Start at z=1, t=1
    pindexes = parentindexes(data(img))
    pdims = parentdims(data(img))
    indexes = ntuple(i -> (i == zdim || i == tdim) ? 1 : (1:size(img, i)), ndims(img))
    imslice = sliceim(img, indexes...)
    bb = BoundingBox(0, size(img, xdim), 0, size(img, ydim))
    sz = size(imslice)
    ImageSlice2d(imslice, pdims, pindexes, size(imslice), bb, 1, 1, xdim, ydim, zdim, tdim)
end

parentdims(A::AbstractArray) = [1:ndims(A);]
parentdims(A::SubArray) = Base.parentdims(A)

function _reslice!(img2::ImageSlice2d)
    newindexes = copy(img2.indexes)
    bb = img2.zoombb
    xindx = newindexes[img2.xdim]
    yindx = newindexes[img2.ydim]
    newindexes[img2.xdim] = xindx[max(1,floor(Integer, bb.xmin)+1):min(length(xindx),ceil(Integer, bb.xmax))]
    newindexes[img2.ydim] = yindx[max(1,floor(Integer, bb.ymin)+1):min(length(yindx),ceil(Integer, bb.ymax))]
    if img2.zdim > 0
        newindexes[img2.zdim] = newindexes[img2.zdim][img2.zindex]
    end
    if img2.tdim > 0
        newindexes[img2.tdim] = newindexes[img2.tdim][img2.tindex]
    end
    img2.imslice.data = slice(img2.imslice.data.parent, newindexes...)
    img2
end

function slice2!(img2::ImageSlice2d, z::Int, t::Int)
    img2.zindex = z
    img2.tindex = t
    _reslice!(img2)
end

function zoom2!(img2::ImageSlice2d, bb::BoundingBox)
    img2.zoombb = bb
    _reslice!(img2)
end

function zoom2!(img2::ImageSlice2d)
    img2.zoombb = BoundingBox(0,length(img2.indexes[img2.xdim]),0,length(img2.indexes[img2.ydim]))
    _reslice!(img2)
end

#
width(img2::ImageSlice2d)  = ceil(Integer, xmax(img2))-floor(Integer, xmin(img2))
height(img2::ImageSlice2d) = ceil(Integer, ymax(img2))-floor(Integer, ymin(img2))
xmin(img2::ImageSlice2d) = xmin(img2.zoombb)
xmax(img2::ImageSlice2d) = xmax(img2.zoombb)
ymin(img2::ImageSlice2d) = ymin(img2.zoombb)
ymax(img2::ImageSlice2d) = ymax(img2.zoombb)
sizex(img2::ImageSlice2d) = length(img2.indexes[img2.xdim])
sizey(img2::ImageSlice2d) = length(img2.indexes[img2.ydim])
sizez(img2::ImageSlice2d) = (img2.zdim > 0) ? length(img2.indexes[img2.zdim]) : 1
sizet(img2::ImageSlice2d) = (img2.tdim > 0) ? length(img2.indexes[img2.tdim]) : 1
xrange(img2::ImageSlice2d) = (xmin(img2), xmax(img2))
yrange(img2::ImageSlice2d) = (ymin(img2), ymax(img2))

# Valid properties:
#   render!: supply a function render!(buf, imgslice) that fills UInt32 buffer for display
#   xy: {"y", "x"} chooses orientation of display (which dims are horizontal, vertical)
#   flipx, flipy: set to true if you want to invert one or both axes
#   pixelspacing: [1,1] enforces uniform aspect ratio (will default to use from img if available)
#   name: a string giving the window name
#   background, perimeter: colors

function view{A<:AbstractArray}(img::A; proplist...)
    # Convert keyword list to dictionary
    props = Dict{Symbol,Any}()
    sizehint!(props, length(proplist))
    for (k,v) in proplist
        props[k] = v
    end
    # Extract relevant information from the image and properties
    img2 = ImageSlice2d(img, props)
    imgc = ImageCanvas(cairo_format(img), props)
    w = width(img2)
    h = height(img2)
    zmax = sizez(img2)
    tmax = sizet(img2)
    havecontrols = zmax > 1 || tmax > 1
    # Determine the desired window size
    # (the actual size may be smaller, depending on screen size)
    ww, wh = rendersize(w, h, imgc.aspect_x_per_y)
    whfull = wh
    if havecontrols
        btnsz, pad = Navigation.widget_size()
        whfull += btnsz[2] + 2*pad
    end
    # Create the window and the canvas for displaying the image
    win = Toplevel(get(props, :name, "ImageView"), ww, whfull, false)
    framec = OS_NAME == :Darwin ? Frame(win, padding = 30) : Frame(win) # helps with accidental rubberband on resize
    grid(framec, 1, 1, sticky="nsew")
    grid_rowconfigure(win, 1, weight=1) # scale this cell when the window resizes
    grid_columnconfigure(win, 1, weight=1)
    c = Canvas(framec, ww, wh)
    imgc.c = c
    # Place the canvas and set its resize properties
    grid(c, 1, 1, sticky="nsew")        # fill the edges of its cell on all 4 sides
    grid_rowconfigure(framec, 1, weight=1) # scale this cell when the window resizes
    grid_columnconfigure(framec, 1, weight=1)
    # If necessary, create the navigation controls
    lastrow = 1
    if havecontrols
        ctrls = NavigationControls()
        state = NavigationState(zmax, tmax)
        showframe = state -> reslice(imgc, img2, state)
        fctrls = Frame(win)
        grid(fctrls, lastrow+=1, 1, sticky="ew")  # place the controls below the image
        init_navigation!(fctrls, ctrls, state, showframe)
        if zmax > 1
            try
                # Replace the z label with the name of the z coordinate
                cs = coords_spatial(img)
                ilabel = setdiff(cs, [img2.xdim,img2.ydim])[1]
                ilabel = find(cs .== ilabel)[1]
                set_value(ctrls.textz, spatialorder(img)[ilabel]*":")
            catch
            end
        end
        imgc.navigationstate = state
        imgc.navigationctrls = ctrls
        # Bind mousewheel events to navigation
        bindwheel(c, "Alt", (path,delta)->reslicet(imgc,img2,ctrls,state,parse(Int, delta)))
        bindwheel(c, "Alt-Control", (path,delta)->reslicez(imgc,img2,ctrls,state,parse(Int, delta)))
    end
    # Create the x,y position reporter
    fnotify = Frame(win)
    grid(fnotify, lastrow+=1, 1, sticky="ew")
    xypos = Label(fnotify)
    imgc.handles[:pointerlabel] = xypos
    grid(xypos, 1, 1, sticky="ne")
    # Set up the rendering
    set_visible(win, true)
#     ctx = getgc(c)  # force initialization of canvas
    allocate_surface!(imgc, w, h)
    create_callbacks(imgc, img2)
    c.mouse.motion = (path,x,y) -> updatexylabel(xypos, imgc, img2, x, y)
    if imgc.render! == uint32color! && colorspace(img) == "Gray"
        menu = Menu(framec)
        if haskey(img, "scalei")
            cs = ImageContrast.ContrastSettings(nothing,nothing)
            imgc.render! = (buf,img) -> uint32color!(buf, img, scaleinfo(cs, img["scalei"], img))
        else
            clim = (zero(eltype(img)), one(eltype(img)))
            cs = ImageContrast.ContrastSettings(clim[1], clim[2])
            imgc.render! = (buf,img) -> uint32color!(buf, img, ScaleMinMax(RGB24, img, cs.min, cs.max))
        end
        menu_contrast = menu_add(menu, "Contrast...", path -> ImageContrast.contrastgui(img2.imslice, cs, x->redraw(imgc, img2)))
        tk_popup(c, menu)
    end
    # render the initial state
    rerender(imgc, img2)
    resize(imgc, img2)
    Tk.configure(imgc.c)
    imgc, img2
end

# Display a labeled image: in the status bar that shows information about the pixel under the mouse pointer,
# display the label value rather than the pixel value.
function viewlabeled(img::AbstractArray, label::AbstractArray; proplist...)
    size(img) == size(label) || throw(DimensionMismatch("size $(size(label)) of label array disagrees with size $(size(img)) of the image"))
    if isa(img, AbstractImage) && !isa(label, AbstractImage)
        label = shareproperties(img, label)
    end
    imgc, imsl = view(img, proplist...)
    props = Dict{Symbol,Any}()
    for (k,v) in proplist
        props[k] = v
    end
    lblsl = ImageSlice2d(label, props)
    imgc.c.mouse.motion = (path,x,y) -> updatexylabel(imgc.handles[:pointerlabel], imgc, slice2!(lblsl, imsl.zindex, imsl.tindex), x, y)
    imgc, imsl
end

# Display a new image in an old ImageCanvas, preserving properties
function view{A<:AbstractArray}(imgc::ImageCanvas, img::A; interactive=true, proplist...)
    # Convert keyword list to dictionary
    props = Dict{Symbol,Any}()
    sizehint!(props, length(proplist))
    for (k,v) in proplist
        props[k] = v
    end
    # Extract relevant information from the image and properties
    img2 = ImageSlice2d(img, props)
    w = width(img2)
    h = height(img2)
    allocate_surface!(imgc, w, h)
    interactive && create_callbacks(imgc, img2)
    rerender(imgc, img2)
    resize(imgc, img2)
    Tk.configure(imgc.c)
    imgc, img2
end

# Display an image in a Canvas. Do not create controls.
function view{A<:AbstractArray}(c::Canvas, img::A; interactive=true, proplist...)
    # Convert keyword list to dictionary
    props = Dict{Symbol,Any}()
    sizehint!(props, length(proplist))
    for (k,v) in proplist
        props[k] = v
    end
    # Extract relevant information from the image and properties
    img2 = ImageSlice2d(img, props)
    imgc = ImageCanvas(cairo_format(img), props)
    imgc.c = c
    w = width(img2)
    h = height(img2)
    allocate_surface!(imgc, w, h)
    interactive && create_callbacks(imgc, img2)
    rerender(imgc, img2)
    resize(imgc, img2)
    Tk.configure(imgc.c)
    imgc, img2
end

function canvasgrid(ny, nx; w = 800, h = 600, pad=0, name="ImageView")
    win = Toplevel(name, w, h)
    frame = Frame(win)
    grid(frame, 1, 1, sticky="nsew")
    grid_rowconfigure(win, 1, weight=1)
    grid_columnconfigure(win, 1, weight=1)
    c = Array(Canvas, ny, nx)
    for j = 1:nx
        for i = 1:ny
            c1 = Canvas(frame, w/nx, h/ny)
            grid(c1, i, j, sticky="nsew", padx=pad, pady=pad)
            c[i,j] = c1
        end
    end
    for j = 1:nx
        grid_columnconfigure(frame, j, weight=1)
    end
    for i = 1:ny
        grid_rowconfigure(frame, i, weight=1)
    end
    c
end

function annotate!(imgc::ImageCanvas, img2::ImageSlice2d, ann; anchored::Bool=true)
    len = annotate_nodraw!(imgc, img2, ann; anchored = anchored)
    redraw(imgc)
    len
end

immutable AnnotationHandle{T}
    ann::T
    hash::UInt
end

function annotate_nodraw!(imgc::ImageCanvas, img2::ImageSlice2d, ann; anchored::Bool=true)
    local newann
    if anchored
        newann = AnchoredAnnotation((_)->imgc.canvasbb, (_)->img2.zoombb, ann)
    else
        newann = FloatingAnnotation((_)->imgc.canvasbb, ann)
    end
    h = hash(newann)
    imgc.annotations[h] = newann
    AnnotationHandle(newann, h)
end

function validate_annotations!(imgc::ImageCanvas)
    state = imgc.navigationstate
    for (h,ann) in imgc.annotations
        setvalid!(ann, state.z, state.t)
    end
end

function delete!(imgc::ImageCanvas, h::AnnotationHandle)
    delete!(imgc.annotations, h.hash)
    redraw(imgc)
end

function empty!(imgc::ImageCanvas)
    empty!(imgc.annotations)
    redraw(imgc)
end

function create_callbacks(imgc, img2)
    c = canvas(imgc)
    # Set up the drawing callbacks
    c.draw = x -> resize(imgc, img2)
    # Bind mouse clicks to zoom
    c.mouse.button1press = (c, x, y) -> rubberband_start(c, x, y, (c, bb) -> zoombb(imgc, img2, bb))
    bind(c, "<Double-Button-1>", (path,x,y)->zoom_reset(imgc, img2))
    # Bind mousewheel events to zoom
    bindwheel(c, "Control", (path,delta,x,y)->zoomwheel(imgc,img2,parse(Int, delta),parse(Int, x),parse(Int, y)), "%x %y")
    # Bind keys to zoom
    win = Tk.toplevel(c)
    bind(win, "<Control-Up>", path->zoomwheel(imgc,img2,-1,pointerxy(win)...))
    bind(win, "<Control-Down>", path->zoomwheel(imgc,img2,1,pointerxy(win)...))
    # Bind mousewheel events to pan
    bindwheel(c, "", (path,delta)->panvert(imgc,img2,parse(Int, delta)))
    bindwheel(c, "Shift", (path,delta)->panhorz(imgc,img2,parse(Int, delta)))
    # Bind arrow keys to pan
    bind(win, "<Up>", path->panvert(imgc,img2,-1))
    bind(win, "<Down>", path->panvert(imgc,img2,1))
    bind(win, "<Left>", path->panhorz(imgc,img2,-1))
    bind(win, "<Right>", path->panhorz(imgc,img2,1))
end

### Callback handling ###
# This takes the already-rendered surface and paints it to the canvas
function redraw(imgc::ImageCanvas)
    r = getgc(imgc.c)
    # Define the path that encloses the image
    bb = imgc.canvasbb
    w, h = size(imgc.surface.data)  # the image width, height
    Graphics.save(r)
    reset_clip(r)
    reset_transform(r)
    wbb = width(bb)
    hbb = height(bb)
    rectangle(r, bb.xmin, bb.ymin, wbb, hbb)
    # In cases of transparency, paint the background color
    if imgc.surfaceformat == Cairo.FORMAT_ARGB32 && !is(imgc.background, nothing)
        if isa(imgc.background, CairoPattern)
            set_source(r, imgc.background)
        else
            set_source(r, convert(RGB, imgc.background))
        end
        fill_preserve(r)
    end
    # Paint the image with appropriate antialiasing settings
    Cairo.translate(r, (1-imgc.flipx)*bb.xmin + imgc.flipx*bb.xmax,
                       (1-imgc.flipy)*bb.ymin + imgc.flipy*bb.ymax)
    Cairo.scale(r, (1-2imgc.flipx)*wbb/w, (1-2imgc.flipy)*hbb/h)
    set_source_surface(r, imgc.surface, 0, 0)
    p = get_source(r)
    if wbb > w && hbb > h
        # The canvas is bigger than the image region, show nearest pixel
        Cairo.pattern_set_filter(p, Cairo.FILTER_NEAREST)
    else
        # Fewer pixels in canvas than in image, antialias
        Cairo.pattern_set_filter(p, Cairo.FILTER_GOOD)
    end
    fill(r)
    restore(r)
    # Render any annotations
    for (h,ann) in imgc.annotations
        draw(imgc.c, ann)
    end
    reveal(imgc.c)
    Tk.update()
end

# Used for both window resize and zoom events
function resize(imgc::ImageCanvas, img2::ImageSlice2d)
    w, h = size(imgc.surface.data)
    setbb!(imgc, w, h)
    set_coords(imgc, img2.zoombb)
    r = getgc(imgc.c)
    if !is(imgc.aspect_x_per_y, nothing)
        fill(r, imgc.perimeter)
    end
    redraw(imgc)
end

function updatexylabel(xypos, imgc, img2, x, y)
    w = width(imgc.c)
    xu,yu = device_to_user(getgc(imgc.c), x, y)
    # Image-coordinates
    xi,yi = floor(Integer, 1+xu), floor(Integer, 1+yu)
    if isinside(imgc.canvasbb, x, y)
        val = img2[xi,yi]
        str = "$xi, $yi: $val"
        if length(str)*10>w
            set_value(xypos, "$xi, $yi")
        else
            set_value(xypos, str)
        end
    else
        set_value(xypos, "$xi, $yi")
    end
end

# Navigation in z and t
function reslice(imgc::ImageCanvas, img2::ImageSlice2d, state::NavigationState)
    slice2!(img2, state.z, state.t)
    for (h,ann) in imgc.annotations
        setvalid!(ann, state.z, state.t)
    end
    rerender(imgc, img2)
    redraw(imgc)
end

function reslicet(imgc::ImageCanvas, img2::ImageSlice2d, ctrls::NavigationControls, state::NavigationState, delta::Int)
    t = state.t + 2*(delta>0) - 1
    if 1 <= t <= state.tmax
        state.t = t
        Navigation.updatet(ctrls, state)
        reslice(imgc, img2, state)
    end
end

function reslicez(imgc::ImageCanvas, img2::ImageSlice2d, ctrls::NavigationControls, state::NavigationState, delta::Int)
    z = state.z + 2*(delta>0) - 1
    if 1 <= z <= state.zmax
        state.z = z
        Navigation.updatez(ctrls, state)
        reslice(imgc, img2, state)
    end
end

function zoomwheel(imgc::ImageCanvas, img2::ImageSlice2d, delta, x, y)
    if !isinside(imgc.canvasbb, x, y)
        return
    end
    r = getgc(imgc.c)
    xu, yu = device_to_user(r, x, y)
    local xmn
    local xmx
    local ymn
    local ymx
    if delta < 0
        xmn, xmx = centeredclip(xu, width(img2)/2, xrange(img2))
        ymn, ymx = centeredclip(yu, height(img2)/2, yrange(img2))
    else
        xmn, xmx = centeredclip(xu, 2*width(img2), (1,sizex(img2)), xrange(img2))
        ymn, ymx = centeredclip(yu, 2*height(img2), (1,sizey(img2)), yrange(img2))
    end
    zoombb(imgc, img2, BoundingBox(floor(xmn)-1, ceil(xmx), floor(ymn)-1, ceil(ymx)))
end

function zoombb(imgc::ImageCanvas, img2::ImageSlice2d, bb::BoundingBox)
    bb = BoundingBox(floor(bb.xmin), ceil(bb.xmax), floor(bb.ymin), ceil(bb.ymax))
    w = sizex(img2)
    h = sizey(img2)
    bb = bb & BoundingBox(0, w, 0, h)
    w = convert(Int, width(bb))
    h = convert(Int, height(bb))
    if w > 0 && h > 0
        allocate_surface!(imgc, w, h)
        panzoom(imgc, img2, bb)
        resize(imgc, img2)
    end
end

function zoom_reset(imgc::ImageCanvas, img2::ImageSlice2d)
    w = sizex(img2)
    h = sizey(img2)
    allocate_surface!(imgc, w, h)
    bb = BoundingBox(0, w, 0, h)
    panzoom(imgc, img2, bb)
    resize(imgc, img2)
end

# Used by pan and zoom to change the displayed region
function panzoom(imgc::ImageCanvas, img2::ImageSlice2d, bb::BoundingBox)
    zoom2!(img2, bb)
    rerender(imgc, img2)
end

function set_coords(imgc::ImageCanvas, bb::BoundingBox)
    l, r = bb.xmin, bb.xmax
    if imgc.flipx
        l, r = r, l
    end
    t, b = bb.ymin, bb.ymax
    if imgc.flipy
        t, b = b, t
    end
    bb = imgc.canvasbb
    set_coords(getgc(imgc.c), bb.xmin, bb.ymin, width(bb), height(bb), l, r, t, b)
end

function panvert(imgc::ImageCanvas, img2::ImageSlice2d, delta)
    h = size(imgc.surface.data, 2)
    local dy
    if delta < 0
        dy = -min(ymin(img2), h/10)
    else
        dy = min(sizey(img2)-ymax(img2), h/10)
    end
    dy = round(dy)
    if dy != 0
        bb = img2.zoombb
        bb = BoundingBox(bb.xmin, bb.xmax, bb.ymin+dy, bb.ymax+dy)
        panzoom(imgc, img2, bb)
        set_coords(imgc, bb)
        redraw(imgc)
    end
end

function panhorz(imgc::ImageCanvas, img2::ImageSlice2d, delta)
    w = size(imgc.surface.data, 1)
    local dx
    if delta < 0
        dx = -min(xmin(img2), w/10)
    else
        dx = min(sizex(img2)-xmax(img2), w/10)
    end
    dx = round(dx)
    if dx != 0
        bb = img2.zoombb
        bb = BoundingBox(bb.xmin+dx, bb.xmax+dx, bb.ymin, bb.ymax)
        panzoom(imgc, img2, bb)
        set_coords(imgc, bb)
        redraw(imgc)
    end
end

### Utilities ###
function allocate_surface!(imgc::ImageCanvas, w, h)
    buf = Array(UInt32, w, h)
    imgc.surface = CairoImageSurface(buf, imgc.surfaceformat, flipxy = false)
    if imgc.transpose
        imgc.renderbuf = Array(UInt32, h, w)
    end
end

# Convert the raw image data to the UInt32 buffer that Cairo paints
function rerender(imgc::ImageCanvas, img2::ImageSlice2d)
    if imgc.transpose
        imgc.render!(imgc.renderbuf, img2.imslice)
        Base.transpose!(imgc.surface.data, imgc.renderbuf)
    else
        imgc.render!(imgc.surface.data, img2.imslice)
    end
end

function redraw(imgc::ImageCanvas, img2::ImageSlice2d)
    rerender(imgc, img2)
    redraw(imgc)
end

# Fill the entire canvas with a color
function fill(r::GraphicsContext, col::Color)
    rgb = convert(RGB, col)
    Graphics.save(r)
    reset_clip(r)
    reset_transform(r)
    set_source_rgb(r, rgb.r, rgb.g, rgb.b)
    paint(r)
    restore(r)
end

# Create a checkerboard pattern (for use with transparency)
function checker(checkersize::Int; light = 0xffb0b0b0, dark = 0xff404040)
    buf = Array(UInt32, 2checkersize, 2checkersize)
    fill!(buf, light)
    buf[1:checkersize,checkersize+1:2checkersize] = dark
    buf[checkersize+1:2checkersize,1:checkersize] = dark
    s = CairoImageSurface(buf, Cairo.FORMAT_ARGB32)
    checkerboard = CairoPattern(s)
    pattern_set_filter(checkerboard, Cairo.FILTER_NEAREST)
    pattern_set_extend(checkerboard, Cairo.EXTEND_REPEAT)
    checkerboard
end

# r is the aspect ratio, i.e. aspect_x_per_y
function rendersize(w::Integer, h::Integer, r)
    ww = w
    wh = h
    if !is(r, nothing)
        if r > 1
            ww = round(Integer, w*r)
        else
            wh = round(Integer, h/r)
        end
    end
    ww, wh
end

# Create a range of width w centered on x, subject to contraints
# lim and cur are (min,max) tuples
function centeredclip(x, w, lim, cur = lim)
    w = min(w, lim[2]-lim[1])
    f = (x-cur[1])/(cur[2]-cur[1])  # fraction into the range
    xmin = x-f*w                    # preserve the fraction upon resize
    if xmin < lim[1]
        return lim[1], lim[1]+w
    end
    xmax = xmin+w
    if xmax > lim[2]
        return lim[2]-w, lim[2]
    end
    xmin, xmax
end

function resetfirst!(s::SubArray)
    newfirst = 1
    pstride = 1
    for j = 1:length(s.indexes)
        newfirst += (first(s.indexes[j])-1)*pstride
        pstride *= size(s.parent, j)
    end
    s.first_index = newfirst
    s
end

function cairo_format(img::AbstractArray)
    format = Cairo.FORMAT_RGB24
    cs = colorspace(img)
    if cs == "ARGB" || cs == "ARGB32" || cs == "RGBA" || cs == "GrayAlpha"
        format = Cairo.FORMAT_ARGB32
    end
    format
end

function scalebarsize(imsl::ImageSlice2d, width, height)
    indx = findin([imsl.xdim,imsl.ydim], coords_spatial(imsl.imslice))
    ps = pixelspacing(imsl.imslice)
    w = width/ps[indx[1]]/imsl.dims[imsl.xdim]
    h = height/ps[indx[2]]/imsl.dims[imsl.ydim]
    w, h
end

AnnotationScalebarFixed{T}(width::T, height::T, imsl::ImageSlice2d, centerx::Real, centery::Real, color::Color = RGB(1,1,1)) =
    AnnotationScalebarFixed{T}(width, height, (wp,hp) -> scalebarsize(imsl,wp,hp), float64(centerx), float64(centery), color)

scalebar(imgc::ImageCanvas, imsl::ImageSlice2d, length; x = 0.8, y = 0.1, color = RGB(1,1,1)) = annotate!(imgc, imsl, AnnotationScalebarFixed(length/1, length/10, (width,height)->scalebarsize(imsl, width, height), x, y, color), anchored=false)

# Exporting figures

function write_to_png(imgc::ImageCanvas, filename)
    ctx = copy(imgc.c.backcc, imgc.canvasbb)
    Cairo.write_to_png(ctx.surface, filename)
end


text:
function readinput(filename)
    map(group -> filter(!isempty, split(group, " ")), split(read(filename, String), "\n", keepempty=false))
end

function findindex!(accumulators, instructions)
    index, accumulator = 1, 0
    visited = falses(length)
    while true
        if index > length || visited[index]
            append!(accumulators, accumulator)
            accumulator = 0
            break
        else
            visited[index] = true
            instruction = instructions[index][1]
            amount = parse(Int64, instructions[index][2])
            if instruction == "jmp"
                index += amount
            elseif instruction == "acc"
                accumulator += amount
                index += 1
            else
                index += 1
            end
        end
    end
    return index
end

function swap(frominstructions, index)
    toinstructions = deepcopy(frominstructions)
    if toinstructions[index][1] == "nop"
        toinstructions[index][1] = "jmp"
    else
        toinstructions[index][1] = "nop"
    end
    return toinstructions
end

original = readinput("d08.in")
length = size(original, 1)

changeable = Set()
for i in 1:length
    if original[i][1] == "jmp" || original[i][1] == "nop"
        push!(changeable, i)
    end
end

instructions = deepcopy(original)
accumulators = []

while true
    lastindex = findindex!(accumulators, instructions)
    if lastindex > length
        break
    else
        changed = pop!(changeable)
        global instructions = swap(original, changed)
    end
end

println("P1: ", first(accumulators))
println("P2: ", last(accumulators))

max_stars_repo_name: eduellery/adventofcode

max_issues_repo_name: eduellery/adventofcode

max_forks_repo_name: eduellery/adventofcode


text:
module DataFrameTools

# Write your package code here.
using DataFrames, MAT, CSV
include("readtable.jl")
export readtable

using DataFrames
include("dfvstack.jl")
export dfvstack

include("filtern.jl")
export filtern!

include("dfgadflysegplot.jl")
export dfgadflysegplot # no need to using Gadfly

using DataFrames
include("dfpreview.jl");
export preview, middle

end


text:
using Test
include("module-2-exercise-1.jl")

@testset "$(get_module_2_excersise_1_author_name()): powers of three tests" begin
     powers_of_three = get_powers_of_three(0)
     @test powers_of_three == []
     powers_of_three = get_powers_of_three(1)
     @test powers_of_three == [1]
     powers_of_three = get_powers_of_three(2)
     @test [3^0, 3^1] == powers_of_three
     powers_of_three = get_powers_of_three(5)
     @test [3^0, 3^1, 3^2, 3^3, 3^4] == powers_of_three
end


text:
## 调包
using CSV
using CurveFit
using DataFrames
using Interpolations
using PyCall
using PyPlot

## 调 Python 的包
@pyimport numpy as np
pygui(true)

## 读原始数据
"""
原始数据格式
|  q_v  |  t_1  |  t_2  |  T_1  |  T_2  |

变量名  变量含义              变量单位
q_v    换热管内流体流量       m ^ 3 * L ^ -1
t_1    冷空气进换热器处的温度  C
t_2    冷空气出换热器处的温度  C
T_1    冷空气进口处蒸汽的温度  C
T_1    冷空气出口处蒸汽的温度  C
"""

source_file_name = "data_of_smooth_pipe.csv"
source_data = CSV.read(source_file_name, DataFrame)

## 温度计算
# 换热器壳程蒸汽的温度
source_data.T = [
    np.mean([source_data.T_1[i], source_data.T_2[i]])
    for i = 1:size(source_data)[1]
]
# 进口处温差 K
Δt_1 = source_data.T - source_data.t_1
# 出口处温差 K
Δt_2 = source_data.T - source_data.t_2
# 冷空气与蒸汽的对数平均温差计算 K
Δt_m = @. (Δt_1 - Δt_2) / log(Δt_1 / Δt_2)
# 定性温度 C
t_m = @. (source_data.t_1 + source_data.t_2) / 2

## 管路参数计算
# 管内径 m
d = (21 - 2.5 * 2) * 1e-3
# 管程长 m
l = 1000e-3
# 流速 m / s
u = @. source_data.q_v / (π / 4 * d ^ 2 * 3600)
# 表面积 m ^ 2
A = π * d * l

## 气体物性计算
# 空气数据
air = CSV.read("air.csv", DataFrame)
# 密度插值
interp_ρ = Interpolations.LinearInterpolation(air.t, air.rho)
# 空气密度 kg * m ^ (-3)
ρ = interp_ρ(t_m)
# 热导率插值
interp_λ = Interpolations.LinearInterpolation(air.t, air.lambda)
# 空气热导率 W * m ^ (-1) * K ^ (-1)
λ = interp_λ(t_m)
# 比热容插值
interp_c_p = Interpolations.LinearInterpolation(air.t, air.c_p)
# 空气比热容 J * (kg * K) ^ (-1)
c_p = @. interp_c_p(t_m)
# 空气粘度插值
interp_μ = Interpolations.LinearInterpolation(air.t, air.mu)
# 空气粘度 Pa * s
μ = @. interp_μ(t_m)

## 传热参数埏
# 传热量
Q = @. c_p * ρ * source_data.q_v * (source_data.t_2 - source_data.t_1) / 3600
# 总传热系数
K = @. Q / (A * Δt_m)

## 准数计算
Nu = @. K * d / λ
Re = @. d * u * ρ / μ
Pr = @. c_p * μ / λ

## 线性拟合
x = @. log(Re)
y = @. log(Nu / Pr ^ 0.4)
p = linear_fit(x, y)
yy = @. p[1] + p[2] * x
println("y = $(p[1]) + $(p[2]) * x")

## 决定系数
y_avg = np.mean(y)
SSreg = sum(@. (yy - y_avg) ^ 2)
SStot = sum(@. (y - y_avg) ^ 2)
R2 = SSreg / SStot
println("R2 = $R2")

## 绘图
PyPlot.plot(x, y, "o", x, yy, "-")
PyPlot.xlabel("\$ \\ln{Re} \$")
PyPlot.ylabel("\$ \\ln \\frac{Nu}{Pr ^ {0.4}} \$")
PyPlot.title("\$ \\ln \\frac{Nu}{Pr ^ {0.4}} - \\ln{Re} \$ figure")

## 输出结果到文件
result = DataFrame(
    :q_v => source_data.q_v,
    :Q => Q,
    :K => K,
    :Nu => Nu,
    :Re => Re,
    :Pr => Pr,
)
target_file_name = "resul_of_smooth_pipe.csv"
CSV.write(target_file_name, result)


text:
prices = Dict(
    "milk" => 1.0,
    "eggs" => 2.0,
    "cheese" => 3.5,
    "bread" => 0.9,
    "chocolate" => 2.2,
    "flour" => 0.5,
    "tomatoes" => 1.5
)

stock = Dict(
    "milk" => 0,
    "eggs" => 0,
    "cheese" => 0,
    "bread" => 0,
    "chocolate" => 0,
    "flour" => 0,
    "tomatoes" => 0
)

mutable struct Store
    stock::Dict
    prices::Dict
    funds::Float64
end

store = Store(stock, prices, 100)

println(store.stock["milk"])
println(store.prices["tomatoes"])
println(sum(values(store.prices)))

### Second part
function delivery(item_list::Array)
    for item in item_list
        if haskey(store.stock, item)
            store.stock[item] += 1
        else
            push!(store.stock, item => 1)
        end
    end
end

function delivery(item_dict::Dict)
    for item in item_dict
        if haskey(store.stock, item[1])
            store.stock[item[1]] += item[2]
        else
            push!(store.stock, item[1] => item[2])
        end
    end
end

delivery(["cheese", "tomatoes", "tomatoes", "tomatoes", "baguette", "baguette"])
delivery( Dict(
    "milk" => 1,
    "bread" => 25,
    "sugar" => 42
))

println(store.stock["tomatoes"])
println(store.stock["baguette"])
println(store.stock["cheese"])
println(store.stock["milk"])

println(store.stock["sugar"])

## part 3
#delivery(Dict("eggs" => 12, "bread" => 2, "tomatoes" => 3))

function is_available(item::String, nb::Int64)
    try
    if store.stock[item] - nb >= 0 #& haskey(store.prices, item) #haskey(store.stock, item) &
        return true
    #elseif haskey(store.prices, item)
    #    println("There is no price there, it must be added first")
    else
        println("The product $(item) is not available in stock")
        return false
    end
    catch
        return false
        println("There was a problem with the item: the item does not exist")
    end
end

#is_available("eggs", 12)

function sell(sellable::Array{String})
    total = 0
    for item in sellable
        if is_available(item, 1)
            store.stock[item] -= 1
            total += store.prices[item]
        end
    end
    store.funds += total
    println("$total was added to your shop funds, new amount: $(store.funds)")
end

function sell(sellable::Dict{String, Int64})
    total = 0
    for item in sellable
        if is_available(item[1], item[2])
            store.stock[item[1]] -= item[2]
            total += store.prices[item[1]] * item[2]
        end
    end
    store.funds += total
    println("$total was added to your shop funds, new amount: $(store.funds)")
end

delivery(Dict("eggs" => 12, "bread" => 2, "tomatoes" => 3))
store.stock
store.funds

sell(["eggs", "foo", "bread", "bread", "eggs", "bread"])
store.stock
store.funds

sell(Dict("tomatoes" => 1, "eggs" => 5, "foes" => 5))
store.stock
store.funds


text:
# VectorAffineDecisionFunction #
# ========================== #
mutable struct VectorAffineDecisionConstraintBridge{T, S} <: MOIB.Constraint.AbstractBridge
    constraint::CI{MOI.VectorAffineFunction{T}, S}
    decision_function::VectorAffineDecisionFunction{T}
    set::S
end

function MOIB.Constraint.bridge_constraint(::Type{VectorAffineDecisionConstraintBridge{T, S}},
                                           model,
                                           f::VectorAffineDecisionFunction{T},
                                           set::S) where {T, S}
    # All decisions have been mapped to the variable part terms
    # at this point.
    F = MOI.VectorAffineFunction{T}
    # Add the bridged constraint
    constraint = MOI.add_constraint(model,
                                    f.variable_part,
                                    set)
    # Save the constraint index, the decision function, and the set, to allow modifications
    return VectorAffineDecisionConstraintBridge{T, S}(constraint, f, set)
end

function MOI.supports_constraint(::Type{<:VectorAffineDecisionConstraintBridge{T}},
                                 ::Type{<:VectorAffineDecisionFunction{T}},
                                 ::Type{<:MOI.AbstractVectorSet}) where {T}
    return true
end
function MOIB.added_constrained_variable_types(::Type{<:VectorAffineDecisionConstraintBridge})
    return Tuple{DataType}[]
end
function MOIB.added_constraint_types(::Type{<:VectorAffineDecisionConstraintBridge{T, S}}) where {T, S}
    return [(MOI.VectorAffineFunction{T}, S)]
end
function MOIB.Constraint.concrete_bridge_type(::Type{<:VectorAffineDecisionConstraintBridge{T}},
                                              ::Type{<:VectorAffineDecisionFunction{T}},
                                              S::Type{<:MOI.AbstractVectorSet}) where T
    return VectorAffineDecisionConstraintBridge{T, S}
end

MOI.get(b::VectorAffineDecisionConstraintBridge{T, S}, ::MOI.NumberOfConstraints{MOI.VectorAffineFunction{T}, S}) where {T, S} = 1
MOI.get(b::VectorAffineDecisionConstraintBridge{T, S}, ::MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{T}, S}) where {T, S} = [b.constraint]

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintFunction,
                 bridge::VectorAffineDecisionConstraintBridge{T}) where T
    f = bridge.decision_function
    # Remove mapped variables to properly unbridge
    from_decision(v) = begin
        result = any(t -> t.variable_index == v, f.decision_part.terms)
    end
    g = VectorAffineDecisionFunction(
        MOIU.filter_variables(v -> !from_decision(v), f.variable_part),
        copy(f.decision_part))
    return g
end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintSet,
                 bridge::VectorAffineDecisionConstraintBridge{T}) where T
    return bridge.set
end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
                 bridge::VectorAffineDecisionConstraintBridge{T}) where T
    return MOI.get(model, attr, bridge.constraint)
end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual,
                 bridge::VectorAffineDecisionConstraintBridge{T}) where T
    return MOI.get(model, attr, bridge.constraint)
end

function MOI.get(model::MOI.ModelLike, ::DecisionIndex,
                 bridge::VectorAffineDecisionConstraintBridge{T}) where T
    return bridge.constraint
end

function MOI.delete(model::MOI.ModelLike, bridge::VectorAffineDecisionConstraintBridge)
    MOI.delete(model, bridge.constraint)
    return nothing
end

function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintFunction,
                 bridge::VectorAffineDecisionConstraintBridge{T,S},
                 f::VectorAffineDecisionFunction{T}) where {T,S}
    # Update bridge functions and function constant
    bridge.decision_function = f
    # Modify constraint function
    MOI.set(model, MOI.ConstraintFunction(), bridge.constraint,
            f.variable_part)
    return nothing
end

function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintSet,
                 bridge::VectorAffineDecisionConstraintBridge{T,S}, change::S) where {T,S}
    f = bridge.decision_function
    bridge.set = change
    MOI.set(model, MOI.ConstraintSet(), bridge.constraint, change)
    return nothing
end

function MOI.modify(model::MOI.ModelLike, bridge::VectorAffineDecisionConstraintBridge{T,S}, change::MOI.VectorConstantChange) where {T,S}
    f = bridge.decision_function
    # Modify variable part of decision function
    f.variable_part.constants .= change.new_constant
    MOI.set(model, MOI.ConstraintFunction(), bridge.constraint,
            f.variable_part)
    return nothing
end

function MOI.modify(model::MOI.ModelLike, bridge::VectorAffineDecisionConstraintBridge{T,S}, change::MOI.MultirowChange) where {T,S}
    f = bridge.decision_function
    # Modify variable part of decision function
    modify_coefficients!(f.variable_part.terms, change.decision, change.new_coefficients)
    # Modify decision part if variable originated from a decision
    if !isempty(findall(t -> t.scalar_term.variable_index == change.variable, f.decision_part.terms))
        modify_coefficients!(f.decision_part.terms, change.variable, change.new_coefficients)
    end
    # Modify the variable part of the constraint as usual
    MOI.modify(model, bridge.constraint, change)
    return nothing
end

function MOI.modify(model::MOI.ModelLike, bridge::VectorAffineDecisionConstraintBridge{T,S}, change::DecisionMultirowChange) where {T,S}
    f = bridge.decision_function
    # Update the decision coefficient
    modify_coefficients!(f.decision_part.terms, change.decision, change.new_coefficients)
    # Update mapped variable through MultiRowChange
    MOI.modify(model, bridge, MOI.MultiRowChange(change.decision, change.new_coefficients))
    return nothing
end


text:
function model_test()
    m = init_model();
    @test validate_model(m);
end

@testset "Model" begin
    model_test();
end

# ------------


text:
using TreeTools
using StaticArrays
using NearestNeighbors
reload("HeightOrderedGrid")

function means_hogrid_new(points_svec, grid)
    #n = Vector{Vector{SVector{3,Float64}}}(length(points_svec))
    means = fill(zeros(SVector{3,Float64}), length(points_svec))
    for i ∈ 1:length(points_svec)
        @inbounds p = points_svec[i]
        neighbors = HeightOrderedGrid.SpatialQuery(grid, p, 0.4)
        j = 0
        #n[i] = Vector{SVector{3,Float64}}()
        for p2 ∈ neighbors
            #if i == 1
        #        println(p2-p)
        #    end
            #push!(n[i], p2-p)
            j += 1
            @inbounds means[i] += p2 - p
            #if vecnorm(p2 - p) > 0.4
            #    println("?")
            #end
        end
        @inbounds means[i] /= j
    end
    return means
end

function means_hogrid(points_svec, grid)
    #n = Vector{Vector{SVector{3,Float64}}}(length(points_svec))
    means = fill(zeros(SVector{3,Float64}), length(points_svec))
    for i ∈ 1:length(points_svec)
        @inbounds p = points_svec[i]
        neighbors = HeightOrderedGrid.inrange(grid, p, 0.4)
        j = 0
        #n[i] = Vector{SVector{3,Float64}}()
        for p2 ∈ neighbors
            #if i == 1
            #    println(p2-p)
            #end
            #push!(n[i], p2-p)
            j += 1
            @inbounds means[i] += p2 - p
            #if vecnorm(p2 - p) > 0.4
            #    println("?")
            #end
        end
        @inbounds means[i] /= j
    end
    return means
end

function means_kdtree(points_svec, tree)
    #n = Vector{Vector{SVector{3,Float64}}}(length(points_svec))
    means = fill(zeros(SVector{3,Float64}), length(points_svec))
    for i ∈ 1:length(points_svec)
        @inbounds p = points_svec[i]
        @inbounds neighbors = inrange(tree, [p], 0.4)[1]
        j = 0
        #n[i] = Vector{SVector{3,Float64}}()
        for i2 ∈ neighbors
            #if i == 1
            #    println(points_svec[i2]-p)
            #end
            #push!(n[i], points_svec[i2] - p)
            j += 1
            @inbounds means[i] += points_svec[i2] - p
            #if vecnorm(points_svec[i2] - p) > 0.4
            #    println("!")
            #end
        end
        @inbounds means[i] /= j
    end
    return means
end

points_svec = 100*randn(SVector{3,Float64}, 1_000_000)

print("Constructing HOGrid:  ")
HeightOrderedGrid.HOGrid(points_svec, 0.4)
@time grid = HeightOrderedGrid.HOGrid(points_svec, 0.4)

print("Querying HOGrid (new):")
means_hogrid_new(points_svec, grid)
@time means_1 = means_hogrid_new(points_svec, grid)

#print("Constructing HOGrid:  ")
#HeightOrderedGrid.HOGrid(points_svec, 0.4)
#@time grid = HeightOrderedGrid.HOGrid(points_svec, 0.4)

print("Querying HOGrid:      ")
means_hogrid(points_svec, grid)
@time means_2 = means_hogrid(points_svec, grid)

println()
print("Constructing KDTree:  ")
KDTree(points)
@time tree = KDTree(points)

print("Querying KDTree:      ")
means_kdtree(points_svec, tree)
@time means_3 = means_kdtree(points_svec, tree)

println()


text:
export ParticleMeshCoupling2D

"""
    ParticleMeshCoupling2D( pg, grid, degree, smoothing_type)

- n_grid(2) : no. of spline coefficients
- domain(2,2) : lower and upper bounds of the domain
- no_particles : no. of particles
- degree : Degree of smoothing kernel spline
- smoothing_type : Define if Galerkin or collocation smoothing for right scaling in accumulation routines
"""
struct ParticleMeshCoupling2D <: AbstractParticleMeshCoupling
    grid::TwoDGrid
    npart::Int
    spline1::SplinePP
    spline2::SplinePP
    n_span::Int
    degree::Int
    scaling::Float64
    values::Array{Float64,2}

    function ParticleMeshCoupling2D(
        pg::ParticleGroup{2,2}, grid::TwoDGrid, degree::Int, smoothing_type::Symbol
    )
        npart = pg.n_particles
        spline1 = SplinePP(degree, grid.nx)
        spline2 = SplinePP(degree, grid.ny)

        n_span = degree + 1

        if smoothing_type == :collocation
            scaling = 1.0 / (grid.dx * grid.dy)
        elseif smoothing_type == :galerkin
            scaling = 1.0
        else
            println(
                "Smoothing Type $smoothing_type not implemented for kernel_smoother_spline_2d. ",
            )
        end

        values = zeros(n_span, 2)

        return new(grid, npart, spline1, spline2, n_span, degree, scaling, values)
    end
end

"""
    compute_shape_factor(pm, xp, yp)

Helper function computing shape factor
- pm : kernel smoother object
- xp, xp : poisition of the particle
"""
function compute_shape_factor(pm::ParticleMeshCoupling2D, xp, yp)
    xp = (xp - pm.grid.xmin) / pm.grid.dx
    yp = (yp - pm.grid.ymin) / pm.grid.dy
    ip = ceil(Int, xp)
    jp = ceil(Int, yp)
    dxp = xp - (ip - 1)
    dyp = yp - (jp - 1)

    uniform_bsplines_eval_basis!(pm.values, pm.degree, dxp, dyp)

    return (ip - pm.degree, jp - pm.degree)
end

"""
    index_1dto2d_column_major(pm, index1d_1, index_1d_2)

Self function computes the index of a 1D array that stores 2D data in column major ordering.
It also takes periodic boundary conditions into account.
- index1d_1 !< indice along x (start counting with zero).
- index1d_2 !< indice along y (start counting with zero).
- index2d   !< Corresponding index in 1d array representing 2d data (start counting with one).
"""
function index_1dto2d_column_major(pm, index1d_1, index1d_2)
    index1d_1 = mod(index1d_1, pm.grid.nx)
    index1d_2 = mod(index1d_2, pm.grid.ny)
    index2d = index1d_1 + index1d_2 * pm.grid.nx + 1

    return index2d
end

export add_charge!

"""
    add_charge!(ρ_dofs, pm, xp, yp, wp)

Add charge of single particle
- position : Particle position
- wp : Particle weight times charge
- ρ_dofs : spline coefficient of accumulated density
"""
function add_charge!(ρ_dofs, pm::ParticleMeshCoupling2D, xp, yp, wp)
    ind_x, ind_y = compute_shape_factor(pm, xp, yp)

    @inbounds for i1 in 1:(pm.n_span)
        index1d_1 = ind_x + i1 - 2
        for i2 in 1:(pm.n_span)
            index1d_2 = ind_y + i2 - 2
            index2d = index_1dto2d_column_major(pm, index1d_1, index1d_2)
            ρ_dofs[index2d] += (wp * pm.scaling * pm.values[i1, 1] * pm.values[i2, 2])
        end
    end
end

export add_charge_pp!

"""
    add_charge_pp!(ρ_dofs, pm, xp, yp, wp)

## Add charge of single particle

- Information about the 2d mesh
  * delta_x(2)  : Value of grid spacing along both directions.
  *  domain(2,2) : Definition of the domain: domain(1,1) = x1_min, domain(2,1) = x2_min,  domain(1,2) = x1_max, domain(2,2) = x2_max
- Information about the particles
  * no_particles : Number of particles of underlying PIC method (processor local)
  * n_span : Number of intervals where spline non zero (degree + 1)
  * scaling

- position : Particle position
- wp : Particle weight times charge
- ρ_dofs : spline coefficient of accumulated density

"""
function add_charge_pp!(ρ_dofs, pm::ParticleMeshCoupling2D, xp, yp, wp)
    xp = (xp - pm.grid.xmin) / pm.grid.dx
    yp = (yp - pm.grid.ymin) / pm.grid.dy
    ip = floor(Int, xp) + 1
    jp = floor(Int, yp) + 1
    dxp = xp - (ip - 1)
    dyp = yp - (jp - 1)

    ip = ip - pm.degree
    jp = jp - pm.degree

    horner_m_2d!(pm.values, pm.spline1, pm.spline2, pm.degree, dxp, dyp)

    for i1 in 1:(pm.n_span)
        index1d_1 = ip + i1 - 2
        for i2 in 1:(pm.n_span)
            index1d_2 = jp + i2 - 2
            index2d = index_1dto2d_column_major(pm, index1d_1, index1d_2)
            ρ_dofs[index2d] += (wp * pm.scaling * pm.values[i1, 1] * pm.values[i2, 2])
        end
    end
end

export evaluate_pp, evaluate

"""
    evaluate_pp(pm, xp, yp, pp)

Evaluate field at position using horner scheme
- pm : kernel smoother object
- position : Position where to evaluate
- field_dofs_pp(:,:) : Degrees of freedom in kernel representation.
- field_value : Value of the field

"""
function evaluate_pp(pm::ParticleMeshCoupling2D, xp, yp, pp)
    xi = (xp - pm.grid.xmin) / pm.grid.dx
    yi = (yp - pm.grid.ymin) / pm.grid.dy

    idx = floor(Int, xi) + 1
    idy = floor(Int, yi) + 1

    xi = xi - (idx - 1)
    yi = yi - (idy - 1)

    d = pm.degree

    nx = pm.grid.nx
    ny = pm.grid.ny

    return horner_2d((d, d), pp, (xi, yi), (idx, idy), (nx, ny))
end

"""
    evaluate(pm, xp, yp, field_dofs)

- position(pm.dim) : Position where to evaluate
- field_dofs(pm.n_dofs) : Degrees of freedom in kernel representation.
- field_value : Value of the field

Evaluate field with given dofs at position
"""
function evaluate(pm, xp, yp, field_dofs)
    ix, iy = compute_shape_factor(pm, xp, yp)

    value = 0.0
    for i1 in 1:(pm.n_span)
        index1d_1 = ix + i1 - 2
        for i2 in 1:(pm.n_span)
            index1d_2 = iy + i2 - 2
            index2d = index_1dto2d_column_major(pm, index1d_1, index1d_2)
            value += field_dofs[index2d] * pm.values[i1, 1] * pm.values[i2, 2]
        end
    end

    return value
end

"""
    evaluate_multiple(pm, position, field_dofs)

## Evaluate multiple fields at position \a position
- position(pm%dim) : Position where to evaluate
- components(:) : Components of the field that shall be evaluated
- field_dofs(:,:) : Degrees of freedom in kernel representation.
- field_value(:) : Value of the field
"""
function evaluate_multiple(pm, position, field_dofs)
    indices = compute_shape_factor(pm, position...)

    field_value1 = 0.0
    field_value2 = 0.0
    for i1 in 1:(pm.n_span)
        index1d_1 = indices[1] + i1 - 2
        for i2 in 1:(pm.n_span)
            index1d_2 = indices[2] + i2 - 2
            index2d = index_1dto2d_column_major(pm, index1d_1, index1d_2)
            c = pm.values[i1, 1] * pm.values[i2, 2]
            field_value1 += field_dofs[1][index2d] * c
            field_value2 += field_dofs[2][index2d] * c
        end
    end

    return field_value1, field_value2
end


text:
using GAIO
using BenchmarkTools

SUITE = BenchmarkGroup(["GAIO"])

# TODO: include benchmark files here
include("samplebench.jl")


text:
"""
```
orb_params = ORB([num_keypoints = 500], [n_fast = 12], [threshold = 0.25], [harris_factor = 0.04], [downsample = 1.3], [levels = 8], [sigma = 1.2])
```

| Argument | Type | Description |
| :--------| :--- | :---------- |
| **num_keypoints** | Int | Number of keypoints to extract and size of the descriptor calculated |
| **n_fast** | Int | Number of consecutive pixels used for finding corners with FAST. See [`fastcorners`] |
| **threshold** | Float64 | Threshold used to find corners in FAST. See [`fastcorners`] |
| **harris_factor** | Float64 | Harris factor `k` used to rank keypoints by harris responses and extract the best ones |
| **downsample** | Float64 | Downsampling parameter used while building the gaussian pyramid. See [`gaussian_pyramid`] in Images.jl |
| **levels** | Int | Number of levels in the gaussian pyramid.  See [`gaussian_pyramid`] in Images.jl |
| **sigma** | Float64 | Used for gaussian smoothing in each level of the gaussian pyramid.  See [`gaussian_pyramid`] in Images.jl |
"""
mutable struct ORB <: Params
    num_keypoints::Int
    n_fast::Int
    threshold::Float64
    harris_factor::Float64
    downsample::Float64
    levels::Int
    sigma::Float64
end

function ORB(; num_keypoints::Int = 500, n_fast::Int = 12, threshold::Float64 = 0.25, harris_factor::Float64 = 0.04, downsample::Real = 1.3, levels::Int = 8, sigma::Float64 = 1.2)
    ORB(num_keypoints, n_fast, threshold, harris_factor, downsample, levels, sigma)
end

function create_descriptor(img::AbstractArray{T, 2}, params::ORB) where T<:Gray
    pyramid = gaussian_pyramid(img, params.levels, params.downsample, params.sigma)
    keypoints_stack = map(image -> Keypoints(fastcorners(image, params.n_fast, params.threshold)), pyramid)
    patch = ones(31, 31)
    orientations_stack = map((image, keypoints) -> corner_orientations(image, keypoints, patch), pyramid, keypoints_stack)
    harris_response_stack = map(image -> harris(image, k = params.harris_factor), pyramid)
    descriptors = BitVector[]
    ret_keypoints = Keypoint[]
    harris_responses = Float64[]
    scales = Float64[]

    for i in 1:params.levels + 1
        desc, ret_key = create_descriptor(pyramid[i], keypoints_stack[i], orientations_stack[i], params)
        ret_key_scaled = [Keypoint(floor(Int, rk[1] * (params.downsample ^ (i - 1))), floor(Int, rk[2] * (params.downsample ^ (i - 1)))) for rk in ret_key]
        append!(descriptors, desc)
        append!(ret_keypoints, ret_key_scaled)
        append!(harris_responses, harris_response_stack[i][ret_key])
        append!(scales, ones(length(ret_key)) * floor(Int, (params.downsample ^ (i - 1))))
    end

    if params.num_keypoints < length(descriptors)
        first_n_indices = partialsortperm(harris_responses, 1:params.num_keypoints, rev = true)
        return descriptors[first_n_indices], ret_keypoints[first_n_indices], scales[first_n_indices]
    end

    descriptors, ret_keypoints, scales
end

function create_descriptor(img::AbstractArray{T, 2}, keypoints::Keypoints, orientations::Array{Float64}, params::ORB) where T<:Gray
    descriptors = BitVector[]
    ret_keypoints = Keypoint[]
    for (i, k) in enumerate(keypoints)
        orientation = orientations[i]
        sin_angle = sin(orientation)
        cos_angle = cos(orientation)
        descriptor = BitVector([])
        for (y0, x0, y1, x1) in orb_sampling_pattern
            pixel0 = CartesianIndex(floor(Int, sin_angle * y0 + cos_angle * x0), floor(Int, cos_angle * y0 - sin_angle * x0))
            pixel1 = CartesianIndex(floor(Int, sin_angle * y1 + cos_angle * x1), floor(Int, cos_angle * y1 - sin_angle * x1))
            checkbounds(Bool, img, k + pixel0) && checkbounds(Bool, img, k + pixel1) || @goto endofloop
            push!(descriptor, img[k + pixel0] < img[k + pixel1])
        end
        push!(ret_keypoints, k)
        push!(descriptors, descriptor)
        @label endofloop
    end
    descriptors, ret_keypoints
end


text:
include("../src/utils/readfiles.jl")
import PyPlot
const plt = PyPlot

function get_perterbation_1(tag::String)
    tao_basedir = "/work/05880/tg851791/stampede2/model/FWEA18_smooth"
    s362ani_basedir = "/work/05880/tg851791/stampede2/specfem/20190115/tao_h_files/DATABASES_MPI"

    nproc = 336
    nspec = 4960
    tao_gll = zeros(Float64, NGLLX, NGLLY, NGLLZ, nspec, nproc)
    s362ani_gll = zeros(Float64, NGLLX, NGLLY, NGLLZ, nspec, nproc)
    dummy = zeros(Float64, NGLLX, NGLLY, NGLLZ, nspec)

    for iproc in 0:nproc - 1
        sem_io_read_gll_file_1!(tao_basedir, iproc, tag, dummy)
        tao_gll[:,:,:,:,iproc + 1] = dummy
        sem_io_read_gll_file_1!(s362ani_basedir, iproc, tag, dummy)
        s362ani_gll[:,:,:,:,iproc + 1] = dummy
    end
    return (tao_gll .- s362ani_gll) ./ s362ani_gll
end

function plot()
    tags = ["vpv","vph","vsv","vsh"]
    fig = plt.figure(figsize = (20, 8))
    for tag in tags
        data = get_perterbation_1(tag)
        plotdata = reshape(data, reduce(*, size(data)))
        plt.hist(plotdata, bins = 50, histtype = "stepfilled")
        plt.xlabel("perterbation")
        plt.ylabel("number")
        plt.title(tag)
        plt.savefig("./$(tag).eps")
        plt.clf()
    end
end

max_stars_repo_name: ziyixi/SeisScripts

max_issues_repo_name: ziyixi/SeisScripts

max_forks_repo_name: ziyixi/SeisScripts


text:
"""
Local nonlinearity, with energy ∫f(ρ) where ρ is the density
"""
struct LocalNonlinearity
    f
end
struct TermLocalNonlinearity{TF} <: TermNonlinear
    f::TF
end
(L::LocalNonlinearity)(::AbstractBasis) = TermLocalNonlinearity(L.f)

function ene_ops(term::TermLocalNonlinearity, basis::PlaneWaveBasis{T}, ψ, occ; ρ, kwargs...) where {T}
    fp(ρ) = ForwardDiff.derivative(term.f, ρ)
    E = sum(term.f.(ρ)) * basis.dvol
    potential = convert_dual.(T, fp.(ρ))

    # In the case of collinear spin, the potential is spin-dependent
    ops = [RealSpaceMultiplication(basis, kpt, potential[:, :, :, kpt.spin])
           for kpt in basis.kpoints]
    (E=E, ops=ops)
end

function compute_kernel(term::TermLocalNonlinearity, ::AbstractBasis; ρ, kwargs...)
    fp(ρ) = ForwardDiff.derivative(term.f, ρ)
    fpp(ρ) = ForwardDiff.derivative(fp, ρ)
    Diagonal(vec(fpp.(ρ)))
end

function apply_kernel(term::TermLocalNonlinearity, ::AbstractBasis, δρ; ρ, kwargs...)
    fp(ρ) = ForwardDiff.derivative(term.f, ρ)
    fpp(ρ) = ForwardDiff.derivative(fp, ρ)
    fpp.(ρ) .* δρ
end


text:
function build_arg_table()
    settings = ArgParseSettings(
        description="\033[32mLocal Sequence Alignment\033[0m\n\n\n\n" *
        "\033[31m Dynamic Programming algorithms for local sequence alignment\033[0m"
    )

    @add_arg_table settings begin
        "align"
            action = :command
            help = "run package from command line arguments"
        "ls"
            action = :command
            help = "list all modified simulations available"
        "align_many"
            action = :command
            help = "run package for multiple different sequences at once"
        "compare_pr"
            action = :command
            help = "run package for benchmarking the false positive rate"
        "roc"
            action = :command
            help = "run package for generating ROC data between pos and neg pairs"
    end

    settings["ls"].description = "Prints out the chosen algorithm for sequence alginment. "

    @add_arg_table settings["align"] begin
        "--addprocs", "-p"
            help = "Add additional processors"
            arg_type = Int
            default = 0
        "--algorithm", "-a"
            help = "Which algorithm to run"
            arg_type = Compat.String
            default = "smithwaterman"
        "--gap_penalty", "-g"
            help = "Gap penalty"
            arg_type = Float64
            default = 1.0
        "--extension_penalty", "-e"
            help = "Penalty for extending a gap"
            arg_type = Float64
            default = 1.0
        "--score_mat", "-s"
            help = "File path for scoring matrix"
            required = true
        "sequence_1"
            help = "Fasta file 1 for sequence alignemnt"
            required = true
        "sequence_2"
            help = "Fasta file 2 for sequence alignment"
            required = true
        "output_file"
            help = "File to output results to [.CSV, .TSV, etc]"
            required = true
    end

    settings["align"].description

    @add_arg_table settings["align_many"] begin
        "--addprocs", "-p"
            help = "Add additional processors"
            arg_type = Int
            default = 0
        "--algorithm", "-a"
            help = "Which algorithm to run"
            arg_type = Compat.String
            default = "smithwaterman"
        "--gap_penalty", "-g"
            help = "Gap penalty"
            arg_type = Float64
            default = 1.0
        "--extension_penalty", "-e"
            help = "Penalty for extending a gap"
            arg_type = Float64
            default = 1.0
        "--score_mat", "-s"
            help = "File path for scoring matrix"
            required = true
        "--write_alignments"
            help = "Write all alignments"
            default = false
        "sequences"
            help = "File containing list of FASTA files"
            required = true
        "output_file"
            help = "File to output results to [.CSV, .TSV, etc]"
            required = true
    end

    settings["align_many"].description

    @add_arg_table settings["compare_pr"] begin
        "--addprocs", "-p"
            help = "Add additional processors"
            arg_type = Int
            default = 0
        "--algorithm", "-a"
            help = "Which algorithm to run"
            arg_type = Compat.String
            default = "smithwaterman"
        "--score_mat", "-s"
            help = "File path for scoring matrix"
            required = true
        "--tpr"
            help = "true positive rate for thresholding"
            arg_type = Float64
            default = 0.7
        "--gp_min"
            help = "minimum gap penalty to test"
            arg_type = Int64
            default = 1
        "--gp_max"
            help = "maximum gap penalty to test"
            arg_type = Int64
            default = 20
        "pos_seqs"
            help = "File containing list of 'positive' FASTA files"
            required = true
        "neg_seqs"
            help = "File containing a list of 'negative' FASTA files"
            required = true
        "output_file"
            help = "File to output results to [.CSV, .TSV, etc]"
            required = true
    end

    settings["compare_pr"].description

    @add_arg_table settings["roc"] begin
        "--addprocs", "-p"
            help = "Add additional processors"
            arg_type = Int
            default = 0
        "--algorithm", "-a"
            help = "Which algorithm to run"
            arg_type = Compat.String
            default = "smithwaterman"
        "--score_mat", "-s"
            help = "File path for scoring matrix"
            required = true
        "--gap_penalty", "-g"
            help = "Gap penalty"
            arg_type = Float64
            default = 1.0
        "--extension_penalty", "-e"
            help = "Penalty for extending a gap"
            arg_type = Float64
            default = 1.0
        "pos_seqs"
            help = "File containing list of 'positive' FASTA files"
            required = true
        "neg_seqs"
            help = "File containing a list of 'negative' FASTA files"
            required = true
        "output_file"
            help = "File to output results to [.CSV, .TSV, etc]"
            required = true
    end

    settings["roc"].description

    if typeof(Base.source_dir()) != Void
        settings.epilog = readstring(normpath(joinpath(Base.source_dir(),"..","LICENSE")))
    end

    return settings
end


text:
struct FastReadBuffer{V<:AbstractVector{UInt8}} <: IO
    data::V
    position::Base.RefValue{Int} # last read position
end

FastReadBuffer(data::AbstractVector{UInt8}) = FastReadBuffer(data, Ref(0))
FastReadBuffer() = FastReadBuffer(Vector{UInt8}())

"""
    setdata!(buf::FastReadBuffer, data::AbstractVector{UInt8))

Copy the data in `data` to the internal data buffer in `buf`
and reset the position to the beginning.
"""
function setdata!(buf::FastReadBuffer, data::AbstractVector{UInt8})
    n = length(data)
    resize!(buf.data, n)
    unsafe_copyto!(buf.data, 1, data, 1, n)
    buf.position[] = 0
    buf
end

@inline function Base.read(buf::FastReadBuffer, ::Type{UInt8})
    nextpos = buf.position[] + 1
    nextpos > length(buf.data) && throw(EOFError())
    buf.position[] = nextpos
    @inbounds return buf.data[nextpos]
end

@inline Base.read(buf::FastReadBuffer, ::Type{Int8}) = reinterpret(Int8, read(buf, UInt8))

@inline function Base.read(
            buf::FastReadBuffer,
            ::Type{T}) where T<:Union{Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128,Float16,Float32,Float64}
    n = Core.sizeof(T)
    pos = buf.position[]
    nextpos = pos + n
    nextpos > length(buf.data) && throw(EOFError())
    data = buf.data
    ret = @static if isdefined(Base, :GC)
        GC.@preserve data begin
            ptr::Ptr{T} = pointer(data, pos + 1)
            unsafe_load(ptr)
        end
    else
        ptr::Ptr{T} = pointer(data, pos + 1)
        unsafe_load(ptr)
    end
    buf.position[] = nextpos
    ret
end

function Base.unsafe_read(buf::FastReadBuffer, ptr::Ptr{UInt8}, nb::UInt)
    # from https://github.com/JuliaLang/julia/blob/5a456f398408718cf9dff123e0355fb68319064f/base/iobuffer.jl#L158
    avail = bytesavailable(buf)
    adv = min(avail, nb)
    @static if isdefined(Base, :GC)
        GC.@preserve buf unsafe_copyto!(ptr, pointer(buf.data, buf.position[] + 1), adv)
    else
        unsafe_copyto!(ptr, pointer(buf.data, buf.position[] + 1), adv)
    end
    buf.position[] += adv
    if nb > avail
        throw(EOFError())
    end
    nothing
end

function Base.readbytes!(buf::FastReadBuffer, b::Array{UInt8}, nb=length(b))
    # from https://github.com/JuliaLang/julia/blob/9d85f7fd738febabab46275678e3987ac477dbfc/base/iobuffer.jl#L429
    nr = min(nb, bytesavailable(buf))
    if length(b) < nr
        resize!(b, nr)
    end
    if nr > length(b) || nr < 0
        throw(BoundsError())
    end
    @static if isdefined(Base, :GC)
        GC.@preserve b begin
            unsafe_read(buf, pointer(b), UInt(nr))
        end
    else
        unsafe_read(buf, pointer(b), UInt(nr))
    end
    nr
end

function Base.seek(buf::FastReadBuffer, n::Integer)
    buf.position[] = max(min(n, length(buf.data)), 0)
    buf
end

Base.seekend(buf::FastReadBuffer) = buf.position[] = length(buf.data)
Base.position(buf::FastReadBuffer) = buf.position[]
Base.readavailable(buf::FastReadBuffer) = read(buf, bytesavailable(buf))
Base.isopen(buf::FastReadBuffer) = true
Base.close(buf::FastReadBuffer) = throw(MethodError("Unsupported operation"))
Base.skip(buf::FastReadBuffer, n::Integer) = seek(buf, buf.position[] + n)
Base.bytesavailable(buf::FastReadBuffer) = length(buf.data) - buf.position[]
Base.eof(buf::FastReadBuffer) = buf.position[] >= length(buf.data)
Base.iswritable(buf::FastReadBuffer) = false
Base.isreadable(buf::FastReadBuffer) = true


text:
module TestUtils

using Jute

export nested_run
export nested_run_with_output
export test_match_text

strip_colors(s) = replace(s, r"\e\[\d+m" => "")

function _nested_run(tcs, options, output_pass_through)
    exitcode, output = Jute.with_output_capture(output_pass_through) do
        Jute.runtests(tcs; options=options, ignore_commandline=true)
    end
    exitcode, strip_colors(output)
end

function nested_run(tcs, options=nothing)
    if options === nothing
        options = Dict{Symbol, Any}()
    else
        options = Dict{Symbol, Any}(options)
    end
    options[:verbosity] = 0
    exitcode, output = _nested_run(tcs, options, true)
    exitcode
end

function nested_run_with_output(tcs, options=nothing)
    _nested_run(tcs, options, false)
end

function escape_for_regex(s)
    replace(s, r"([\.\[\]\(\)\\\*\+\?\^\$])" => s"\\\1")
end

function normalize_template(s)
    m = match(r"^(\s*)", s)
    s = replace(s, Regex("^$(m[1])", "m") => "")
    strip(s)
end

function test_match_text(template, text)
    text_lines = split(strip(text), "\n")
    template_lines = split(normalize_template(template), "\n")

    text_i = 1
    template_i = 1

    r_multiline = r"^<<<MULTILINE>>>$"
    r_variable = r"<<<([\w\d_]+)>>>"

    skipping_multiline = false
    while true
        if text_i > length(text_lines) && template_i > length(template_lines)
            break
        elseif text_i > length(text_lines)
            @test_fail "Exhausted the text"
            return
        elseif template_i > length(template_lines)
            if skipping_multiline
                break
            end
            @test_fail "Exhausted the template"
            return
        end

        text_line = text_lines[text_i]
        template_line = template_lines[template_i]

        if occursin(r_multiline, template_line)
            skipping_multiline = true
            template_i += 1
        else
            s = "^" * escape_for_regex(template_line) * "\$"
            s = replace(s, r_variable => s"(?<\1>.*)")
            if !occursin(Regex(s), text_line)
                if !skipping_multiline
                    @test_fail (
                        "Failed to match the text line $text_i\n  $text_line\n" *
                        "with the template line $template_i\n  $template_line")
                    return
                else
                    text_i += 1
                end
            else
                skipping_multiline = false
                text_i += 1
                template_i += 1
            end
        end
    end
end

end


text:
export DDECPSolver

# Solver object to indicate a solver is not set
type UnsetSolver <: MathProgBase.AbstractMathProgSolver
end

# DD-ECP solver
type DDECPSolver <: MathProgBase.AbstractMathProgSolver
    lp_solver::MathProgBase.AbstractMathProgSolver   # LP solver
end

function DDECPSolver(;
    lp_solver = UnsetSolver(),
    )

    if lp_solver == UnsetSolver()
        error("LP solver not specified; set lp_solver")
    end
end

max_stars_repo_name: ctjandra/ddopt-ecp

max_issues_repo_name: ctjandra/ddopt-ecp

max_forks_repo_name: ctjandra/ddopt-ecp


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

@doc raw"""PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.

    IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus(;
        currentHealthy=nothing,
        desiredHealthy=nothing,
        disruptedPods=nothing,
        disruptionsAllowed=nothing,
        expectedPods=nothing,
        observedGeneration=nothing,
    )

    - currentHealthy::Int32 : current number of healthy pods
    - desiredHealthy::Int32 : minimum desired number of healthy pods
    - disruptedPods::Dict{String, IoK8sApimachineryPkgApisMetaV1Time} : DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.
    - disruptionsAllowed::Int32 : Number of pod disruptions that are currently allowed.
    - expectedPods::Int32 : total number of pods counted by this disruption budget
    - observedGeneration::Int64 : Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status information is valid only if observedGeneration equals to PDB's object generation.
"""
mutable struct IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus <: SwaggerModel
    currentHealthy::Any # spec type: Union{ Nothing, Int32 } # spec name: currentHealthy
    desiredHealthy::Any # spec type: Union{ Nothing, Int32 } # spec name: desiredHealthy
    disruptedPods::Any # spec type: Union{ Nothing, Dict{String, IoK8sApimachineryPkgApisMetaV1Time} } # spec name: disruptedPods
    disruptionsAllowed::Any # spec type: Union{ Nothing, Int32 } # spec name: disruptionsAllowed
    expectedPods::Any # spec type: Union{ Nothing, Int32 } # spec name: expectedPods
    observedGeneration::Any # spec type: Union{ Nothing, Int64 } # spec name: observedGeneration

    function IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus(;currentHealthy=nothing, desiredHealthy=nothing, disruptedPods=nothing, disruptionsAllowed=nothing, expectedPods=nothing, observedGeneration=nothing)
        o = new()
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("currentHealthy"), currentHealthy)
        setfield!(o, Symbol("currentHealthy"), currentHealthy)
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("desiredHealthy"), desiredHealthy)
        setfield!(o, Symbol("desiredHealthy"), desiredHealthy)
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("disruptedPods"), disruptedPods)
        setfield!(o, Symbol("disruptedPods"), disruptedPods)
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("disruptionsAllowed"), disruptionsAllowed)
        setfield!(o, Symbol("disruptionsAllowed"), disruptionsAllowed)
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("expectedPods"), expectedPods)
        setfield!(o, Symbol("expectedPods"), expectedPods)
        validate_property(IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus, Symbol("observedGeneration"), observedGeneration)
        setfield!(o, Symbol("observedGeneration"), observedGeneration)
        o
    end
end # type IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus

const _property_map_IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus = Dict{Symbol,Symbol}(Symbol("currentHealthy")=>Symbol("currentHealthy"), Symbol("desiredHealthy")=>Symbol("desiredHealthy"), Symbol("disruptedPods")=>Symbol("disruptedPods"), Symbol("disruptionsAllowed")=>Symbol("disruptionsAllowed"), Symbol("expectedPods")=>Symbol("expectedPods"), Symbol("observedGeneration")=>Symbol("observedGeneration"))
const _property_types_IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus = Dict{Symbol,String}(Symbol("currentHealthy")=>"Int32", Symbol("desiredHealthy")=>"Int32", Symbol("disruptedPods")=>"Dict{String, IoK8sApimachineryPkgApisMetaV1Time}", Symbol("disruptionsAllowed")=>"Int32", Symbol("expectedPods")=>"Int32", Symbol("observedGeneration")=>"Int64")
Base.propertynames(::Type{ IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus }) = collect(keys(_property_map_IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus))
Swagger.property_type(::Type{ IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus[name]))}
Swagger.field_name(::Type{ IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus }, property_name::Symbol) =  _property_map_IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus[property_name]

function check_required(o::IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus)
    (getproperty(o, Symbol("currentHealthy")) === nothing) && (return false)
    (getproperty(o, Symbol("desiredHealthy")) === nothing) && (return false)
    (getproperty(o, Symbol("disruptionsAllowed")) === nothing) && (return false)
    (getproperty(o, Symbol("expectedPods")) === nothing) && (return false)
    true
end

function validate_property(::Type{ IoK8sApiPolicyV1beta1PodDisruptionBudgetStatus }, name::Symbol, val)
end


text:
module Tools

using ..Comonicon: cmd_error

"""
    prompt(msg::AbstractString[, yes::Bool=false])

Prompt with message to ask user Yes or No.

# Arguments

- `msg`: the message to show in prompt.

# Keyword Arguments

- `yes`: skip the prompt and always return `true`, default is `false`.
- `require`: require user to input the answer explicitly. This will repeat
    3 times to ask user to input the answer then throw an [`CommandError`](@ref).
"""
function prompt(msg::AbstractString; yes::Bool = false, require::Bool = false)
    prompt(; yes, require) do
        print(msg)
    end
end

"""
    prompt(f, [io=stdin,] yes::Bool=false)

Prompt with custom printing to ask user Yes or No.

# Arguments

- `f`: a function with no arguments, which prints the prompt message.
- `io`: user input stream, default is `stdin`.

# Keyword Arguments

- `yes`: skip the prompt and always return `true`, default is `false`.
- `require`: require user to input the answer explicitly. This will repeat
    3 times to ask user to input the answer then throw an [`CommandError`](@ref).
"""
prompt(f; yes::Bool = false, require::Bool = false) = prompt(f, stdin; yes, require)

function prompt(f, io::IO; yes::Bool = false, require::Bool = false)
    if yes
        f() # print message
        println(" Yes.")
    elseif require
        msg = "expect yes (y) or no (n)"
        for _ in 1:3
            f() # print message
            print(" [y/n] ")
            input = yes_or_no(io)
            println()
            (input == 'Y' || input == 'y') && return true
            (input == 'N' || input == 'n') && return false
            println(msg)
        end
        cmd_error(msg)
    else
        f() # print message
        print(" [Y/n] ")
        input = yes_or_no(io)
        println()
        input in ['Y', 'y', '\n', '\r'] || return false
    end
    return true
end

function yes_or_no(io::IO)
    run(`stty raw`)
    input = read(io, Char)
    run(`stty cooked`)
    return input
end

end


text:
function calc_seat_id(pass)
    digits = map(c -> c == 'F' || c == 'L' ? '0' : '1', pass)
    row = parse(Int64, digits[1:7]; base = 2)
    column = parse(Int64, digits[8:end]; base = 2)
    row * 8  + column
end

function calc_highest_id(boarding_passes)
    function update(acc, pass)
        id = calc_seat_id(pass)
        id > acc ? id : acc
    end

    foldl(update, boarding_passes; init = 0)
end

function main()
    lines = readlines("../resources/input_05.txt")
    result = calc_highest_id(lines)
    println(result)
end

main()


text:
module JuliaRL

using Random
using Logging

greet() = println("Hello Reinforcement Learning!")

export
    AbstractEnvironment,
    get_actions,
    get_reward,
    is_terminal,
    AbstractAgent,
    start!,
    step!

include("core/environment.jl")
include("core/agent.jl")

export
    GVF,
    Horde,
    GVFParamFuncs
include("core/gvf.jl")

export
    AbstractFeatureConstructors,
    create_features,
    feature_size
include("core/feature_constructors.jl")

export
    TileCoder,
    MinMaxNormalize,
    MeanStdNormalize
include("features/TileCoder.jl")
include("features/Normalize.jl")

export
    RandomAgent
include("agent/random.jl")

end

max_stars_repo_name: mkschleg/JuliaRL

max_issues_repo_name: mkschleg/JuliaRL

max_forks_repo_name: mkschleg/JuliaRL