Giter Club home page Giter Club logo

quantum-sheet's Introduction

(Prototype) QuantumSheet

QuantumSheet - A user friendly mathematics worksheet and solver

Try it out here

Screenshot

Looking for collaborators

I would really love to develop this project much further and am looking for collaborators. If you want to give it a shot, just respond here #14

Roadmap

Roadmap

Used Technology

For Developers

  1. Clone the project
  2. npm install
  3. npm run download:pyodide
  4. npm run dev

Check out CONTRIBUTING.md for more

quantum-sheet's People

Contributors

phcreery avatar stefnotch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quantum-sheet's Issues

Selection rectangle

With #26 we can select blocks and move them. This should be expanded to make multi-selections and dragging possible.

Ref #8

User supplied code

If we want to run user-supplied code, we have a few different options to explore

  • Properly sandboxed WebAssembly (with strict memory and CPU limits)
  • Running code in an iframe-webworker (and setting the iframe rules to be as strict as possible)
  • Running code in a super sandboxed manner (like https://github.com/endojs/endo )
  • Having a "trust" button, that lets the user run arbitrary code (preferably signed code or something?)
  • Using a language with a linear runtime as much as possible (see https://github.com/google/cel-go )

Unknown function parsing

We have to wait for the next compute-engine version https://cortexjs.io/docs/compute-engine/#(ParseLatexOptions%3Atype)

Compute-engine: parser should recognize unknown functions (like silly())
so, basically

  1. check if its a known token
  2. if not, check if brackets come right after it x()
  3. if there are brackets, its a function
  4. otherwise, split the letters and treat them as individual stuff

From Gitter

@stefnotch you can provide a parse function for xrightarrow that would parse for valid functions in the "above" argument.
Arno Gourdol
@arnog
12:16
For recursive functions, you have two options I can think of: use the parseUnknownToken option in the LatexSyntax parser to recognize foo as a function token.
The second option would be for the definition of the := operator to create a scope (using ce.pushScope()) with a custom definition for the foo symbol. This gives you more flexibility (such as defining a domain, an argument list, etc...) in defining the symbol.

Working With Arrays

I want a flexible approach for working with stuff like arrays, tables, and piecewise functions. Instead of following a set procedure, the user gives constraints and possible solutions are returned. This issue's just on arrays and iteration.

Approach

The Fibonacci numbers would usually be created iteratively like this:

Fib=[]
Fib[0]=0
Fib[1]=1
for (i=2;i<5;i++){
  Fib[i]=Fib[i-1]+Fib[i-2]
}

Instead I’m proposing something like this (these are all equations in a system, order does not matter):

Fib[0]=0
Fib[1]=1
Fib[i]=Fib[i-1]+Fib[i-2]
2<=i<5

Which can then be solved:
Fib=[0,1,1,2,3]

This allows you to use any piece of information. For example if you want to make something following the rules of Fibonacci numbers but the 5th element is 6 instead, you would just do:

Fib[0]=0
Fib[4]=6
Fib[i]=Fib[i-1]+Fib[i-2]
2<=i<5

This would return:
Fib=[0,3,3,6]

Application

This would be useful for engineering applications, where what is known and unknown varies from case to case. For example, the total pressure from soil layers is determined by adding the weight from each layer:

SoilLayers

p=rho*g*h
p_cum[i+1]=p_cum[i]+p[i]

If instead you wanted to find the depth required to get to a certain pressure with two soil layers, for example, you could do:

SoilLayers
rho=[1200,1700]
g=9.8
h=[15,depth-15]
p_cum[0]=0
p_cum[2]=20000

Basically, by building it around solving systems of equations, you are not constrained to a set of input or outputs as you would be using loops.

A similar approach could be used for piecewise functions and tables, which I could show in another issue.

I think the main challenge is to figure out exactly how the program should interpret arrays and how it should convert it to systems of equations.

Add defined variables to dictionary

When parsing or serializing an expression, we need to get all the currently defined variables and add them to the dictionary. That way, cat := 3 followed by cat = will work correctly

Custom evaluate

#31 (comment)

I took a look at this and there are two quite reasonable options:

  1. Adding \\solve, \\factor, and \\expand to the dictionary like you suggested. If we do that, then we should also make it possible to call them like \\solve(3x+5==5, x)
  2. Adding the ability to parse unknown functions and using that #33 However, for that we'll need to wait for the next compute engine version

Offline mode

It'd be quite sweet if this site worked in offline mode as well.

IndexedDb Backups

It would be nice to periodically save a backup of the document in an indexeddb. That way, if something crashes or goes horribly wrong, not all is lost.

Quotes to type text

It'd be pretty useful if one could type text in quotes. Like "this function does a+b"

Mathematical Functions, Constants, Evaluations (with Sympy)

This is an attempt to document and create a running list all the desired mathematical Functions, Constants, and Evaluations.
This issue is aimed at Sympy but the list should be compatible with or easily inclusive to competitive CASs.

https://en.wikipedia.org/wiki/Template:Areas_of_mathematics
https://en.wikipedia.org/wiki/Glossary_of_mathematical_symbols

Operations

https://cortexjs.io/compute-engine/guides/dictionaries/

MathJSON MathJSON -> Sympy Sympy -> MathJSON
MathJSON name Sympy function name Sympy printer function/name
(checked if fully tested) (checked if implemented) (checked if implemented)
Arithmatic
☒ Parentheses ☒   ☒  
☒ Add ☒ Sympy.Add ☒ _print_Add
☒ Subtract ☒ Sympy.Add(x,sympy.mul(y,-1)) ☒  
☐ Negate (*-1) ☒  
☒ Multiply ☒ Sympy.Mul ☒  
☒ (Divide) ☒  
☒ Power ☒ Sympy.Pow ☒  
☐ Root ☒ sympy.root  ☐  
☐ Sqrt * ☒ Sympy.sqrt ☒ Sqrt (capital s?)
☐ Square ☐   ☐  
☐ Exp * ☐   ☐ exp
☐   ☐   ☐  
Algebra
☐ Log * ☐   ☒ ln
☐ Log2 * ☐   ☒ log2
☐ Log10 * ☐   ☒ log10
☐ LogOnePlus ☐   ☒ log1p
☐ Abs * ☒ Sympy.Abs ☐  
☐ Ceil * ☐   ☒ ceiling
☐ Chop ☐   ☐  
☐ Floor * ☐   ☒ floor
☐ Round ☐   ☐  
☐ Factorial ☒ sympy.factorial ☒ factorial
☐   ☐  
Trigonometry
☒ Sin ☒ sympy.sin ☒ sin
☒ Cos ☒ sympy.cos ☒ cos
☒ Tan (defaults to tg?) ☒ sympy.tan ☒ tan
☐ Sec ☒ sympy.sec ☒ sec
☐ Csc ☒ sympy.csc ☒ csc 
☐ Cot ☒ sympy.cot ☒ cot 
☒ Arcsin** ☒ Sympy.asin ☒ asin
☒ Arccos** ☒ Sympy.acos ☒ acos
☒ Arctan** ☒ Sympy.atan ☒ atan
☒ Arctan2** ☒ sympy.atan2 ☒ atan2
☐ Asec** ☒ Sympy.asec ☒ asec
☐ Acsc** ☒ Sympy.acsc ☒ acsc
☐ Acot** ☒ Sympy.acot ☒ acot
☒ Sinh ☒ Sympy.sinh ☒ sinh
☒ Cosh ☒ Sympy.cosh ☒ cosh
☒ Tanh ☒ Sympy.tanh ☒ tanh
☐ Sech** ☒ Sympy.sech ☒ sech 
☐ Csch** ☒ Sympy.csch ☒ csch 
☐ Coth** ☒ Sympy.coth ☒ coth 
☒ Arsinh** ☒ Sympy.asinh ☒ asinh
☒ Arcosh** ☒ Sympy.acosh ☒ acosh
☒ Artanh** ☒ Sympy.atanh ☒ atanh
☐ Asech** ☒ Sympy.asech ☒ asech 
☐ Acsch** ☒ Sympy.acsch ☒ acsch 
☐ Arcoth** ☒ Sympy.acoth ☒ acoth 
☐ Degrees ☐   ☐  
☐ FromPolarCoordinates ☐   ☐  
☐ ToPolarCoordinates ☐   ☐  
☐ Hypot ** ☐  
☐ Haversine ☐   ☐  
☐ InverseHaversine ☐   ☐  
☐   ☐   ☐  
Calculus
☐ Integrate * ☐   ☐ _print_Integral
☐ Derivative/Prime (D, ') * ☐   ☐ _print_Derivative 
☐ (Partial Derivative) ☐  
☐ (Limit - lim(f,x,a)?) ☐   ☐ _print_Limit
☐ (SumSeries) ☐   ☐ _print_Sum 
☐ (Product of Sequence- CapitalPi) ☐   ☐  
☐   ☐   ☐  
Linear Algebra
☐ (System of Equations)  ☐   ☐  
☐ (EigenValues)  ☐   ☐  
☐ (EigenVectors)  ☐   ☐  
☐ (Matricies)  ☐   ☐  
☐ (Vectors)  ☐   ☐  
Matrix Operations
☐ (Matrix Define)  ☐   ☐  
☐ (Addition)  ☐   ☐  
☐ (Multiplication)  ☐   ☐ _print_MatMul ? 
☐ (Transpose)  ☐   ☐ _print_Transpose 
☐ (Multiplication)  ☐   ☐  
☐ (Power)  ☐   ☐ _print_MatPow ? 
☐ (Normal)  ☐   ☐  
Logic/Relational
☐ True**  ☐  ☐ _print_BooleanTrue 
☐ False** ☐  ☐  _print_BooleanFalse
☐ Maybe** ☐  ☐   
☐ And ☐  ☐  _print_And
☐ Or ☐  ☐ _print_Or
☐ (Xor) ☐  ☐ _print_Xor
☐ Not ☐  ☐  _print_Not
☐ Equivalent (\equiv) ☐  ☐   
☐ Implies ☐  ☐   
☐ Equal (taken) ☐  ☐   
☐ NotEqual ☐  ☐   
☐ GreaterEqual ☐ sympy.GreaterThan ☐   
☐ LessEqual ☐ sympy.LessThan ☐   
☐ Greater ☐ sympy.GreaterThanStrict ☐   
☐ Less  ☐ sympy.LessThanStrict ☐   
☐   ☐  ☐   
Special
☐ Gamma ☒ sympy.gamma ☒ gamma
☐ LogGamma ☒ sympy.loggamma ☒ loggamma
☐ Erf ☒ sympy.erf ☒ erf
☐ Erfc ☒ sympy.erfc ☒ erfc
☐ EulerGamma ☒ Sympy.EulerGamma ☒ _print_EulerGamma
☐   ☐  ☐   
Misc
☐ List   ☐  ☐ _print_list  
☐ Set ☐  ☐  _print_set
☐ Lambda  ☐ sympy.Lambda ☐ _print_Lambda
☐ InverseFunction  ☐  ☐  _print_Inverse ?
☐ Parse (Latex)  ☐  ☐ 
☐ String  ☐  ☐ 
☐  ☐  ☐ 
☐  ☐  ☐ 

* MathLive broken at the moment? Usually happens when the expression is converted to latex then parsed back.
** MathLive Unsupported

Constants

http://www.ebyte.it/library/educards/constants/ConstantsOfPhysicsAndMath.html
https://cortexjs.io/mathlive/reference/commands/

MathJSON MathJSON -> Sympy Sympy -> MathJSON
Mathematical
☒ Pi ☒ Sympy.pi ☒ _print_Pi
☒ ImaginaryUnit (\imaginaryI) ☒ Sympy.I ☒ _print_ImaginaryUnit
☒ ExponentialE (\exponentialE) ☒ Sympy.E  ☒ _print_Exp1
☐ GoldenRatio ☒ Sympy.GoldenRatio ☒ _print_GoldenRatio
☐ (Infinity)   ☐  ☐  _print_Infinity
☐ (-Infinity)   ☐  ☐  _print_NegativeInfinity
☐   ☐  ☐  _print_TribonacciConstant
☐ (NaN)   ☐  ☐  _print_NaN
☐   ☐  ☐   

Evaluations

Some examples: https://docs.sympy.org/latest/tutorial/simplification.html#simplification

  • Solve (for variable)
  • Expand
  • Factor

This list is nowhere near complete.
Please comment with more expressions you wish to see supported

Interrupt Web Worker or Python

When a computation takes very long, it should be possible to stop it. I'd prefer to not have to .terminate() the web worker for that.

Relevant issues

Floats not always desired?

Example:

>>> _HI = sympy.symbols('a')
>>> sympy.expand(sympy.Pow(sympy.Add(_HI,sympy.Float(1)),sympy.Float(2)))
(a + 1.0)**2.0
>>> sympy.expand(sympy.Pow(sympy.Add(_HI,sympy.Float(1)),sympy.Integer(2)))
a**2 + 2.0*a + 1.0
>>>

Approach For Working With Equations

My approach is to use just equality, solve and substitute for algebraic manipulation. I think that would be sufficient and make it simple to use. as well as easy to build off of.

I know this is very different from the MathCAD approach, so we'll have to figure out what would work best.

Layout

Each block contains a system of equations. The user types stuff in on the left side and the result is shown on the right side. Farther right than that, it could potentially show numeric results if there are any.
layout

Scopes

For each line in the block, you can type an equation or the name of another block. In this way, you can create nested scopes, where in this case, Block2 has access to Block1 and Block3 has access to Block2 and Block1.
scopes

Evaluation

Numeric evaluation would occur automatically on the result side:
eval

Assignment

The equivalent of assignment can be performed as shown:
preview
which is analogous to:
Screenshot 2021-08-29 171807

Functions

The equivalent of functions would be created as shown:
myfunc
The advantage of this is that the "function" can consist of a system of equations and you could solve for any variable. I think this would be useful if we want to make libraries for engineering, where we would write the equations, and the user would choose how to combine them and what to solve for.

Fix expression result referring to another, now defined variable

There is this edge case where an expression first refers to an undefined variable (a bit like a unit).

Then, the variable gets defined.

And then we try to re-evaluate the expression by putting more = signs at the end

image

The place where it needs to be fixed is
// TODO: This can result in more getters existing

Use new Pyodide

https://github.com/pyodide/pyodide/releases

Refactor document model

I've decided to useXY() to create anything ranging from a document to an expression element. This returns a state and some functions to modify it. Then, to keep a reference to it, I'm always using shallow references shallowRef or shallowReactive<Set>.

Focusing and selection have now also been refactored into their own, internal composition function.

To use this nested structure in the UI layer without mutating props, I'm only passing the element ID to the components and then looking up the element based on that ID.

@type to insert different elements

It might be worthwhile to support something like
@graph to insert a graph
@text to insert a text-block
@latex to insert a latex-block, where the LaTeX will not be evaluated
and so on

Reassign built-in values

pi := 3 should work and actually assign a different value to the variable named pi. That variable should then be useable in the document and should have the value 3.

QoL fixes

Is the \ when you press Esc intentional?

It switches between the normal mode and the command mode. Replace that with a Esc to escape command mode and Esc to escape the mathfield.

Completed!

This might be a bit annoying.
hq13L7GHFl
When you want to make the := and type [:] -> [something else] -> [Backspace] -> [=], it doesn't make it.

Yep, that's annoying. I'll have to fix that.

If you don't need the colon for anything else, you could make it like MathCAD does, so you only need to type :.

Good idea. That would also make typing :=[Backspace] less annoying.

Other than that, it's just that when you type something, it's not at the position of the cursor, but rather quite a bit below.

Yeah, true

Brackets are broken

Uhhh, seems like it.

Typing tan doesn't work. However, typing a*tan works

Typing \tan and then clicking somewhere else results doesn't work

Units

Units would be great to include, and would make it much more useful for engineering.
Check out https://github.com/sharkdp/insect

Notation for Units

I think requiring the user to import the units they want to use would be a bit annoying. Instead I think there should be a way for the user to indicate they are typing a unit; this would also avoid ambiguities.

Here's some possibilities:

  • units in curly braces, for example {m/s}
  • user types "unit", it then converts italicized text to standard text (same as when a user types a trig function) with parentheses, for example "unit(m/s)"
  • user types "unit", new box with border appears, similar to SwiftCalcs

If we have a result section on the right side, the units could be displayed with a separate color, similar to how SwiftCalcs shows units.
swiftcalcsunits

Check Input

It should check whether the unit typed makes sense. If the user types in {m/s^2}:

  • Operations are valid (multiplication, division, and exponents only)
  • All the parts (e.g. m and s) are valid units

It should also check for dimensional consistency of the equation (e.g. LHS and RHS have same dimensions, added values have same dimensions, exponents are dimensionless), and the output should have the proper dimensions. I have code for this, which produces and solves equations for dimensional consistency. I will need to modify it a bit to have it work for this project.

Change Output Units

The user should be able to change the units of the output to one of the same dimension. SwiftCalcs has a nice interface for this.
swiftcalcschangeunits

Standard Units

For now, I think we could focus on Mass, Length, and Time units although we could extend to all seven basic quantities (Mass, Length, Time, Current, Luminosity, Temperature, and Amount).

We definitely should have SI units. Especially if we want to make this useful for engineering, we should also include important U.S. customary units.

  • notation for units
  • check input
  • change output units
  • standard units
  • custom defined units

Selecting blocks

Maybe something like this (inspired by MathCad, I think)

An element has 3 states: unselected, focused and selected

Unselected

No selection, no editing

  • no effect
  • hover: hover effect
  • pointerdown: clear selection and focus
  • pointermove: select text

Focused

When editing the element

  • focus effect
  • hover: focus effect
  • hover border: hover effect and move cursor
  • pointerdown: put cursor at position
  • pointermove: select text
  • pointerdown border: select and capture pointer
  • pointermove border: move
  • pointerup border: release pointer

Selected

When explicitly selecting the element

  • select effect and move cursor
  • hover: select effect and move cursor
  • hover border: select effect and move cursor
  • pointerdown: capture pointer
  • pointermove: move
  • pointerup: release pointer
  • pointerup and no movement: release pointer and select

Mathematics Input

The mathematics input should support the following features

  • Assignment
  • Solve Arrow
  • Multiple lines (3+4\xrightarrow{\begin{equation}cat \\ neko \\ lol\end{equation}}7)
  • Matrix
  • Vectors
  • Absolute Value
  • Range
  • if-else
  • nth-root
  • vectorisation operator
  • Si units
  • equation wrapping
  • cut and paste
  • paste ascii equations

Maybe contributing to https://github.com/arnog/mathlive would get me closer to a decent editor

Text input

The text input thingy should support

  • formatting
  • hyperlinks
  • contenteditable and browser spell-checking
  • multiple instances
  • undo/redo history

Optimized Python side

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.