Giter VIP home page Giter VIP logo

paddim8 / kalker Goto Github PK

View Code? Open in Web Editor NEW
1.6K 16.0 72.0 2.73 MB

Scientific calculator with math syntax that supports user-defined variables and functions, complex numbers, and estimation of derivatives and integrals

Home Page: https://kalker.xyz

License: MIT License

Rust 90.64% Shell 0.26% HTML 0.53% Svelte 6.07% TypeScript 1.29% JavaScript 0.20% Java 0.12% CSS 0.06% Sass 0.09% Python 0.38% Nix 0.36%
calculator rust-crate math rust

kalker's Introduction

Kalker is a calculator program/website that supports user-defined variables, functions, differentiation, and integration. It runs on Windows, macOS, Linux, Android, and in web browsers (with WebAssembly).

Crates.io npm GitHub Docs.rs Build status

Website - Try it out here!

Features

  • Operators: +, -, *, /, !
  • Groups: (), [], ⌈ceil⌉, ⌊floor⌋
  • Vectors: (x, y, z, ...)
  • Matrices: [x, y, z; a, b, c; ...]
  • Pre-defined functions and constants
  • User-defined functions and variables. f(x, y) = xy, x = 5
  • Root finding using Newton's method (eg. x^2 = 64). Note: estimation and limited to one root
  • Derivative of functions (derivatives of noisy functions or of higher order can be a bit inaccurate). f'(2), sin'(-pi)
  • Integration. ∫(0, pi, sin(x) dx) or ∫(0, π, sin(x) dx), maybe sometimes be slightly off
  • Understands fairly ambiguous syntax. Eg. 2sin50 + 2xy
  • Syntax highlighting
  • Special-symbol completion on tab. Eg. write sqrt and press tab. It will be turned into
  • Sum function: sum(start, to, expression) Eg. sum(1, 3, 2n+1) is the same as 2*1+1 + 2*2+1 + 2*3+1 = 15
  • Piecewise functions: f(x) = { f(x + 1) if x <= 1; x otherwise }, pressing enter before typing the final } will make a new line without submitting
  • Load a file including predefined functions and constants. For example, if you're going to use kalker for physics, you load up your file with physics functions/constants when starting kalker. This is done either using the -i file flag or by putting files in a certain directory and then doing load filename inside kalker. More about files here
  • Different number bases: Either with a format like 0b1101, 0o5.3, 0xff or a format like 1101_2. The latter does not support letters, as they would be interpreted as variables
  • Misc: separate expressions by a semicolon to write them on the same line, use the ans variable to get the value of the previously calculated expression

Installation

Package managers

macOS (Homebrew)

brew install kalker

macOS (MacPorts)

sudo port install kalker (info)

Arch Linux

kalker in the AUR, eg. yay -S kalker

Nix/NixOS

kalker in the nixpkgs repository. The most up to date version is also available as a flake.

NetBSD

pkgin install kalker (from the official repositories)

Binaries

Pre-compiled binaries for Linux, Windows, and macOS (64-bit) are available in the releases page.

Compiling

Minimum rust version: v1.36.0. Make sure you have diffutils gcc make and m4 installed. If you use windows: follow the instructions here (don't forget to install mingw-w64-x86_64-rust in MSYS2).

Cargo

Run cargo install kalker

Manually

  1. Go into the cli directory.
  2. Run cargo build --release
  3. Grab the binary from targets/release

Libraries

There are currently three different libraries related to kalker.

  • kalk: The Rust crate that powers it all.
  • @paddim8/kalk: JavaScript bindings for kalk. This lets you use it in the browser thanks to WebAssembly.
  • @paddim8/kalk-component: A web component that runs @paddim8/kalk, which let's you use kalk in the browser with a command line-like interface.

Syntax

A complete reference can be found on the website.

Contributing

kalk and cli (Rust)

After making changes to the kalk library (in kalk/), you can easily try them out by going to the root of the project directory, and doing cargo run. This will start kalker (cli), with the new changes. If you're using Windows, you will need to follow the instructions here, but also make sure to install mingw-w64-x86_64-rust in MSYS2.

All Rust code is expected to be formatted with `rustfmt

web (Svelte, TypeScript, Sass)

Run:

  1. npm install
  2. npm run dev - this will automatically re-compile the project when changes are made

mobile (Android)

Run:

  1. npm install
  2. npm run build
  3. npx cap sync
  4. Build the project using Android Studio, or Gradle directly.

kalker's People

Contributors

0323pin avatar 5225225 avatar abrudz avatar aurelj avatar benderblog avatar callum-irving avatar diananites avatar dvishal485 avatar herbygillot avatar kiedtl avatar kloenk avatar kvnxiao avatar matematikaadit avatar mike-lloyd03 avatar monamayrhofer avatar nyarly avatar nyw0102 avatar paddim8 avatar timokoesters avatar ysndr 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  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  avatar  avatar  avatar  avatar  avatar  avatar

kalker's Issues

Add Iverson Bracket

An Iverson Bracket is simply a predicate in square brackets which evaluates to 0 if false or 1 if true. It is great for defining functions in multiple pieces, for example f(x)=x[x<0]+x^2[x>0]:

image

Units

Maybe have optional units in calculations, and convert the output into SI units. The units could be distinguished in some way, such as curly brackets or something: 10{m/s}.

Then in calculations, the output could be returned as SI units, or maybe we could add some other syntax like 10{m/s} = {miles/hour} and it would output in the desired unit.

This would be useful for things like physics/engineering etc where you are given units in various forms. So for example you could do 3{cm} * 100{GHz} to get the speed of a wave in {m/s} (c = wavelength * frequency), or instead do 3{cm} * 100{GHz} = {km/hour} to get it in kilometers per hour.

I think this would be quite tough to implement but I am just throwing out some ideas :)

Error on sin x

>> x=1
>> sin 1x
0.8414709848
>> sin x
Undefined variable: 's'.

Typing a word, followed by a space crashes the program

How to reproduce:

  1. Open kalk
  2. Type test (notice the trailing space)
  3. Press enter

The error:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', kalk/src/lexer.rs:80:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
[1]    18396 abort (core dumped)  ./kalk_cli

Version: 0.1.10

Support for Permutations and Combinations calculation

Forgive me if I am missing it, but it seems like we do not have support permutations and combinations calculation, correct?
Can someone confirm this?

I realized this as I was using kalker in my school test. :)

Add probability logic

By defining AND as multiplication (since the probability that two event will happen is the product of their probabilities) and NOT as 1-x (since the probability that an event won't happen is 100% minus its probability), all other logic/probability operations follow from De Morgan's laws:

and = x∧y = xy
not = ¬x = 1-x
or = x∨y = ¬((¬x)∧(¬y))
implies = x→y = ¬(x∧¬y)
iff = x↔y = (y→x)∧(x→y)

User defined constants

I'm using the windows binary an what I'm missing the most ATM is a way to define constants I use often so I don't have to define them as variables every session.
I suppose it would mean having at least an external config file... which I would prefer to be human-readable/editable, maybe some json?

Installation Fail

Running cargo install kalk_cli is failing for me with:

  Updating crates.io index
  Downloaded kalk_cli v0.1.10
  Downloaded 1 crates (8.4 KB) in 0.94s
  Installing kalk_cli v0.1.10
error: failed to compile `kalk_cli v0.1.10`, intermediate artifacts can be found at `/tmp/cargo-installrPOC9T`

Caused by:
  failed to parse lock file at: /home/ewpratten/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk_cli-0.1.10/Cargo.lock

Caused by:
  invalid serialized PackageId for key `package.dependencies`

cargo -V is outputting:

cargo 1.35.0 (6f3e9c367 2019-04-04)

Slightly inaccurate when integrating over floor/ceil.

I'm not sure if this is a known limitation or something that should be an issue. I suspect it applies to all step-wise functions but I haven't checked.

>> ∫ (0, 1, ⌈x⌉, dx)
0.9995833333

This should be 1 exactly, but I suspect that the code falls back to numerical integration in these cases.

More examples:

>> ∫ (1/10000, 1, ⌈x⌉, dx)
0.9999 # correct
>> ∫ (1/100000, 1, ⌈x⌉, dx)
1  # should be 0.99999
>> ∫ (1/1000000, 1, ⌈x⌉, dx)
1 # should be 0.999999
>> ∫ (1/10000000, 1, ⌈x⌉, dx)
1.0004165666   # over one? should be 0.9999999

Enhancement request: configuration file or environment variable to disable startup banner

When launched without any arguments, kalk will write a banner and a help hint to standard output. This is counter productive when kalk is used as a filter, because you cannot easily use the output from kalk in a pipe — even when output is a file, the banner/help is irrelevant.

Without thinking it through completely, I think kalk could just check if stdin and stdout are TTYs (isatty(3)) and only display banner/help if they both are: when reading expressions from stdin, stdin is not a TTY, and when writing to a pipe or a file, stdout is not a TTY.

Lacking precision when printing numbers

In the latest version on crates.io (0.2.0), and on the current master, there seems to be a problem when printing some numbers, such as

>> 1000.0 - 0.1
1000

It seems the intermediary is computed correctly, as this produces the correct result:

>> (1000.0 - 0.1)*10
9999

Add `help` function

It would be nice to have help() function that will print some kind of documentation and also show a list of supported functions.

Crash on | with missing closing |

>> |4
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 3', kalk\src\parser.rs:772:6
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Support × and ÷

Since you allow Unicode symbols, it'd be nice to use × and ÷ for multiplication and division, with tab completion on * and / too.

Remember last result?

It'd be neat if it remembered the previous result, so that this would work

>> 1 + 1
2
>> + 1
3

Or, probably simpler, store it automatically in a _ variable. Pythons REPL does this, for example.

>> 1 + 1
2
>> _ + 1
3

Name collision with KDE Kalk

KDE Kalk is also a calculator from the KDE project: https://github.com/KDE/kalk

I understand it is different from this project? I installed "kalk" from the AUR and was surprised get a UI ... maybe you are still on time to rename? I know this hurts, but its unfortunate that we have two tools with the same functional scope with the same name :/

Wrong comparing with expressions

I found this while using the program.
The program incorrectly compares an expression with a trigonometric function and a number.

>> 3 * 4 * cos(60deg)
6
>> 3 * 4 * cos(60deg) <= 6
false
>> 3 * 4 * cos(60deg) > 6
true
>> 6 <= 6
true
>> 6 > 6
false

The 2nd and 3rd expressions are incorrect.

Resquest: Auto-insert 'ans'

Hi!

Since I chose Kalker as my pc calculator I am noticing a few things I misss or would like Kalker to do.

One of those things is ability to continue an operation based on previous result.
Yes, that's what ans is for. I use 'ans' when the calculation involving the previous result is complex or ans is not the first item in the command line.

What I miss is the ability to input expressions like '+2' and be interpreted as 'ans+2', or in other words I would like that a command line that starts with an operator was autocompleted with 'ans' before the operator.

BTW, 'ans' defaults to 1. That was not expected, I supposed it would default to 0. For this 'ans autocompletion' I'm talking about maybe it should default to 0.

request for input file format

I have tried some formats, which gave error as shown below :

hread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseFloatError { kind: Invalid }', kalk/src/parser.rs:477:43
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fish: “./kalk -i  maths.txt” terminated by signal SIGABRT (Abort)

input file format for calculations and variables requested. i have not found any related information in README.

Panic when evaluating single quote

Just the input ' given to the web interpreter causes it to break.

Stack trace when using kalk 2.1.1 is

thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:699:58
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/core/src/panicking.rs:103:14
   2: core::panicking::panic_bounds_check
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/core/src/panicking.rs:79:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/core/src/slice/index.rs:184:10
   4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/core/src/slice/index.rs:15:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/alloc/src/vec/mod.rs:2464:9
   6: kalk::parser::split_into_variables
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:699:58
   7: kalk::parser::parse_identifier
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:693:9
   8: kalk::parser::parse_primary
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:544:34
   9: kalk::parser::parse_factorial
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:528:16
  10: kalk::parser::parse_exponent
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:516:16
  11: kalk::parser::parse_unary
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:507:16
  12: kalk::parser::parse_unit
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:487:16
  13: kalk::parser::parse_factor
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:444:20
  14: kalk::parser::parse_sum
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:430:20
  15: kalk::parser::parse_to
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:413:16
  16: kalk::parser::parse_equality
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:362:20
  17: kalk::parser::parse_expr
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:358:8
  18: kalk::parser::parse_stmt
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:202:38
  19: kalk::parser::parse
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/kalk-2.1.1/src/parser.rs:187:25
  20: scratch0RukYFR5I::main
             at ./main.rs:3:5
  21: core::ops::function::FnOnce::call_once
             at /rustc/9dd4ce80fb01d1ff5cb5002f08b7b3847b59e664/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Add piecewise functions

For example
image
could be written as

f(x) = {-x-x if x≤-3; x+3 if -3≤x≤0; 3-2x if 0≤x≤3; 0.5x-4.5 if 3≤x}

or:

f(x) = {x≤-3: -x-x; -3≤x≤0: x+3; 0≤x≤3: 3-2x; 3≤x: 0.5x-4.5}

Idea: Combine web, cli, mobile codebases into one

It might be a good idea to abstract the core functionality of the kalk into one library and then import it in cli, web and mobile wrappers. Otherwise you have to fix all bugs and implement all features 3x times.

The easiest choice would be to implement the core lib in JS, because it can easily run on cli, web and mobile. However, it might be possible to stick to rust and compile to WebAssembly and maybe something like this https://github.com/mozilla/rust-android-gradle for mobile.

Consider using a more robust CLI arguments parser

Currently when I run kalk help (out of habit) I get a weird error of Undefined variable: 'h'.. I think switching to a ready solution would greatly benefit future development.

Something like Clap requires minimal setup while providing a lot of great features (like generating shell completions which are hard to maintain by hand). This will add to compile time though so it is worth thinking about it.

I am willing to help with the transition.

Use proper summation symbol

Currently, Greek letter Sigma is used: Σ

It may look better to use the taller N-ary summation symbol:

Similarly, product could use rather than Π

Precision?

First of all: Extremely cool project! (Found you on reddit)

I am unsure what the --precision flag does. I tried to running kalker --precision 1000, however kalker did not output what I expected it to. Perhaps the flag is for internal precision only?

My session:

>> x=0.00000000001
>> x
0
>> x * 10
10^-10 ≈ 0

Perhaps this is an error on my part, but I would not have expected kalker to ever show me an exact 0 when the value is in fact non-zero, no matter which precision is chosen.

Additionally I would expect it to be able to output numbers to higher precision thatn 10^-10. That's much lower than even the range of an f32.

Use of decimal comma

Is there a way to configure kalker to use a decimal comma instead of the decimal point, like defining a locale? (I can remap my numeric keypad, but that doesn't help with copy-pasting numbers from and to other applications.)

Unexpected variable copy behavior

image

For such a tool, I would expect the y = x line to assign y the value of x and subsequently for the two variables to be completely independent of each other.

Add C api

It would be nice if the project could provide a cdylib and export "C" functions, so the parser can be used from c programs.

function application

$ f(x) =  x^2
$ f 2
4
$ g(x,y) = x^2y
g 1 2
Expected 2 arguments for function g, but got 1.

Haskell-like function application would be very useful, is it meant to be supported only for one-param functions?

Incorrect priority of ^ (power)

>> r=2
>> (4/3)*π*r^3
33.510321638291124
>> (4/3)*πr^3
330.73361792319804

The ^ operator should apply on r alone, not πr

Percentage oddity

$ kalker.exe -10.5%+10.5%
-0.116025

Great, but it does not make sense. Qalc, for example, outputs 0 in this case.

Add prod

You have sum, so prod is natural.

Rename binary

kalk instead of kalk_cli would be much more convenient

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.