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

Support for Julia #133

Open
junder873 opened this issue Mar 21, 2020 · 4 comments
Open

Support for Julia #133

junder873 opened this issue Mar 21, 2020 · 4 comments

Comments

@junder873
Copy link

I decided to take a stab at adding support for Julia, I have put together a minimally working set that is pretty straightforward. The main thing I still need to do is deal with packages (right now it assumes the DataFrames package exists, for example).

The main feature that I cannot implement is deleting variables, something that Julia does not support (though I added the functionality to automatically skip variables that are missing, so reassigning a variable to missing will delete it from the list. I cannot do this in a function, however.)

Here is the code as it currently exists (feel free to make suggestions):

using DataFrames
try
    using JSON
catch
    using Pkg
    Pkg.add("JSON")
    using JSON
end
using Base: format_bytes, summarysize

function _jupyterlab_createDict(v, value)
    retDict = Dict{String, Any}()
    
    retDict["varName"] = string(v)
    retDict["varSize"] = format_bytes(summarysize(value))
    retDict["isWidget"] = false
    
    if typeof(value) <: Function
        retDict["varType"] = "Function"
    else
        retDict["varType"] = string(typeof(value))
    end
    
    retDict["varShape"] = if typeof(value) <: Function
        "Function"
    else
        summary(value)
    end
    
    if typeof(value) <: DataFrame
        retDict["varContent"] = string(names(value))
    elseif typeof(value) <: Array
        retDict["varContent"] = if length(value) > 10
            string(vcat(value[1:5], value[end-5:end]))
        else
            retDict["varContent"] = string(value)
        end
    elseif typeof(value) <: Function
        retDict["varContent"] = string(methods(value))
    else
        retDict["varContent"] = string(value)
    end
    
    retDict["isMatrix"] = if typeof(value) <: DataFrame || typeof(value) <: Array
        true
    else
        false
    end
    
    return retDict
end

function _jupyterlab_get_list()
    skips = ["Base", "Core", "Main"]
    vars = []
    for v in names(Main)
        if string(v) in skips
            continue
        end
        if length(string(v)) >= 12 && string(v)[1:12] == "_jupyterlab_"
            continue
        end
        if typeof(getfield(Main, v)) == Missing
            continue
        end
        push!(vars, _jupyterlab_createDict(v, getfield(Main, v)))
    end
    s = replace(json(vars), "\\\"" => "'")
    return s
end

and the JavaScript component:

        "julia": {
            initScript: Languages.julia_script,
            queryCommand: "_jupyterlab_get_list()",
            matrixQueryCommand: "_jupyterlab_getmatrixcontent",
            widgetQueryCommand: "TODO",
            deleteCommand: "TODO"
        },

The piece I am struggling with is getting the matrix function to work as expected (to display the variable in a spreadsheet-like manner). I have set it up to mirror the Pandas to_json (with the default_handler option), however, nothing ever happens. Is there anything special that needs to be done to get the data to display? Here is my code as it currently exists to try and create the matrix:

function _jupyterlab_getmatrixcontent(x, max_rows=10000)
    if typeof(x) == DataFrame
        return _jupyterlab_convert_dataframe(x)
    else # Need to do still
        return 0
    end
end

function _jupyterlab_identify_type(x::Array{T, 1}) where T
    return T
end
function _jupyterlab_convert_dataframe(df)
    fieldList = [OrderedDict("name" => "index", "type" => "integer")]
    for name in names(df)
        push!(fieldList, OrderedDict("name" => string(name),
                "type" => string(_jupyterlab_identify_type(df[:, name]))))
    end
    
    schemaDict = OrderedDict("fields" => fieldList, "primaryKey" => ["index"],
        "pandas_version" => "0.20.0")
    dataList = []
    for i in 1:size(df, 1)
        x = (; zip(vcat([:index], names(df)), vcat([i-1], [df[i, name] for name in names(df)]))...)
        push!(dataList, x)
    end
    s = OrderedDict("schema" => schemaDict, "data" => dataList)
    return s
end
@lckr
Copy link
Collaborator

lckr commented Mar 23, 2020

Hey, big thanks for working on this.

The main feature that I cannot implement is deleting variables, something that Julia does not support (though I added the functionality to automatically skip variables that are missing, so reassigning a variable to missing will delete it from the list. I cannot do this in a function, however.)

In this we could either remove the delete-icon if julia is used or set the variables to Nothing (and still display them s.t. a user knows that this variable name is already taken).

Regarding the matrix function I will have a look at it later today.

@lckr
Copy link
Collaborator

lckr commented Mar 23, 2020

If you want you can already start a WIP pull request.

@AntonioLoureiro
Copy link

I would like to have this feature, what's the status, how can i help?

@junder873
Copy link
Author

I have not had much time to work on this, and my familiarity with Javascript is low. The code mostly works as is, except that there seems to be a loading problem (when I first start the notebook, the functions are loaded but do not start working until I run them again directly in a cell). I have not done anything more on the matrix support, so that is still not working. If you want to work on it and start a pull request, feel free to use some or all of my code. Towards the end of summer, I should be able to circle back to this and work on it more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants