This looks pretty cool. I've long been looking for something similar to Soulver (https://soulver.app/) that I can use on Linux. This seems promising.
One small criticism: In my opinion, no web-based writing app is useful unless the tab key inserts a tab. The default behavior of most browsers to move focus to the next field is tremendously infuriating in this context. Unfortunately, that's what happens here, at least for Firefox.
(Related: key combinations that normally perform cursor movements but which are often used by browser for navigation.)
Couldn't agree more with the last two paragraphs. Web standards purists will trot out a reference to some standard and point out the imagined (and terrifying) consequences of making the TAB or ENTER key behave just as they would in a non-web application, AKA a real data-entry program. This is just a version of the "lest thou cause thy brother to stumble" club used to nudge the religious into compliance with strictures that make no sense to them (and yeah, the quote is probably not verbatim, but hopefully the gist of it is clear).
Example: I (who am not a programmer) once wrote a tangled mess of HTML and JavaScript to accept, and tabulate data entry for rebar (reinforcing steel) estimates. I was inordinately proud of it, bird's nest of bad programming practice that it was. I could TAB or ENTER-key my way through all fields, the up and down arrows performed the same tasks as the TAB-key, just like on a desktop program.
So why was it important to do things this way, and break the conventions so dear to the heart of the standard's purist? Because this is how I (and many others) estimated rebar in the 1990's:
You sat at a wide desk or table with a set of plans 30" to 48"-wide spread out to your left (if you were lucky) and another 30"-48" of table was needed to catch the plan pages turned to reveal the one you were working on. You right hand rested on the keyboard's ten-key pad some 3-5 feet away. You didn't look at your right hand -- you looked at your left hand index finger which was glued to (and rarely left) the large page at precisely the item you wanted to enter into your tabulation program, as you entered the SAC code, the qty per unit, the number of units, the bar size number, the bend category, the grade of steel, and the total length. Your eyes never left the drawing as you did this, and immediately upon completing that line item, your left hand picked up a yellow highlighter and highlighted that item -- one of many hundreds or thousands that would be necessary in a materials take-off of any appreciable size. To force the use of the TAB-key, or the mouse to move through data-entry fields would simply guarantee that no one would use your program. Ever.
But the purist says, "Someone may stumble."
Aunt Loreen said, "Sometimes the 'You shoulds' are the sh-ts."
Note: I had this response typed up but didn't submit...
One related app that I absolutely love is Qalculate![1] (yes, it has a built-in exclamation for default enthusiasm :) )
It can do cool stuff like converting N (newtons) to kg.m/s^2 when you specify units as ?kg. It also converts units like 1kW x 1year = 31.55... GJ
It's fantastic for engineering and specially back-of-envelope calculations. This notepad aspect does seem useful though. One alternative is to use Jupyter notebooks, sometimes I work problems with Sage[2]+Jupyter. Sage is extremely powerful (you can do calculus, linear algebra, and more) but doesn't support units (that I know of), it's more geared toward advanced maths.
[2] https://www.sagemath.org/ It's a bit on the heavy side although it's definitely worth it if you're doing a lot of math. I think the flatpak is preferred due to its significant size.
> Cruncher can also automatically plot changes as you adjust a variable
Well that's pretty neat. I've seen it in fancier setups, but not something Soulver-like. It seems a lot more usable here, since practically any equation can show it.
I have as well :-) but I lose for not having released. This version is pretty cool though, will probably not gonna use it because same reason I didn’t evolve my version. Don’t need it, and when I need it I don’t need for it to be dynamic.
I came here to deposit this exact same comment with one addition. Great project but seems to be lacking base support. As an engineer I need hex at least.
Yeah, honestly this has been annoying me too, I just haven't got around to fixing it. It's using CodeMirror 6 as the editor, the author said he deliberately made this version not "break" the default tab behaviour, which I think is understandable as a library author, but that makes it my job to fix!
I thought CM had some example code on how to override the tab behaviour. Might be worth checking out as I agree it sucks to not have tab = indent 4 spaces
This is now essentially an offline CalcPad that still leverages LocalStorage, since the UI is your browser. I've configured this specific build to automatically launch your default browser when you run it.
SoulVer on macOS as you know. OpalCalc on Windows. Speedcrunch on all three platforms, though I will categorically state that whilst Speedcrunch is very good, it is no Soulver/OpalCalc.
Good Feedback! I would think a checkbox that enables tab function would be best, how would you feel about a FF Plugin that achieves this? My only concern would be that FF has reserved that particular key and it would require special permissions to map it to your needs.
I think it should just be a toggle on the page: "Hijack keyboard shortcuts? Y/N". Figma, Miro, Google and co do it without asking. It's something we've come to expect with web apps, so a toggle would be a fair middle ground.
and give it a pass for not supporting pre 1963 UK | US historic weights and measures .. that's getting into a pretty specific use case where Standards nerds like to have a clear display of what conversion factors are in play and what provenance those factors have.
Time Zone support (on your About ToDo) will be interesting, historic computations with daytime savings support will be a quagmnire :-)
The SHARE DOC URLs seem a bit long - something like "base64 full text of doc as an URL" I guess.
Will this hit a URL length limit if widespread use becomes a thing?
You're right, I'm using lz-string to compress the text before shoving it in the URL. This is definitely a necessary evil for the time being so I don't need a back end component to the app. But eventually I do want prettier URLs and collaborative editing if I can make that work without it bankrupting me or driving me insane.
For what it's worth, the typescript playground takes the exact same approach as you, placing a compressed (lz-string) copy of the text after the #code/ in a sharing url.
On the gnarly scale dealing with with pre-WGS84 paper maps from about the globe is arguably worse ..
there are so many reference ellipsoids and datums used in different parts of the world at different times .. and then there are the many variations on curved surface to flat map projections to deal with.
Super cool. I wish this was open source so I could see how you did some things, but I understand you've decided to keep it closed. Just to satisfy my curiosity, would you mind sharing how you did parsing at a high level? Did you use some publicly available parser/lexer or did you just implement pattern matching yourself with something like regex or other token splitting measures?
I'm very glad you asked. I wrote my own parser combinator library in TypeScript partly based on eulalie[0], so it doesn't have a separate lexer and parser and doesn't rely heavily on regexes (though it does use them to do things like match a single alphanumeric character). I plan on open sourcing this library one day once I can tidy up the API because I think it would be useful to other people.
But to give you an idea of what that all looks like this is the code for the parser that parses the "as a % of" operator:
I wasn't familiar with Eulalie, that's a really interesting approach. I built functionality [0] similar to numpad into a larger record-keeping system, Tap [1]. Precedence rules kindof scramble my brain so I ended up implementing s-expression syntax for Tap formulas.
I ended up writing the parser myself, called sowhat, but used a library for tokenization, moo.js [2]. You can see a demo of just the sowhat editor here [3].
I've found that a super simple way to parse basic expressions is a recursive descent parser. It is very simple to implement. No need to to break into tokenizer/parser, no need to generate an AST, just evaluate the expression while parsing.
I am the author of NoteCalc, and it warms my heart that my project is mentioned here :)
As a sidenote I would like to mention that NoteCalc is still in active (but slow) development, though I do it privately, and the next big release will be definitely this year.
The docs say that this is using CodeMirror. The CodeMirror license says that you're allowed to use CodeMirror for your stuff, but that stuff has to in turn include:
1. the copyright notice
2. the text itself that explains that you/others have this permission/obligation
Currently, it looks like NumPad isn't doing either.
From comments here, NumPad is evidently also using decimal.js, which has similar terms.
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
I think that second part is relevant to the discussion.
Just when I thought I understood the MIT license, I'm back to confused. Can you link me to where this is clearly outlined? Do you need to attribute somewhere in artifacts or not?
Not sure what you want. A link where this is clearly outlined? The license is two sentences and sets out the terms.
The repeated distinction between source code and "artifacts" in this context is pure make-believe. The license doesn't even have those words in it, let alone say something like "Redistribution and use in source form requires inclusion of this permission notice and the above copyright notice, but if you're just building a product and publishing it as non-source code artifacts instead of distributing source, then lol don't worry about it bro" (or whatever it is the people here seem to think).
The CodeMirror maintainer definitely expects people who build closed source stuff to include the notices that are in the CodeMirror LICENSE file. And anyone telling you the license doesn't require this (and e.g. this is a peculiarity of CodeMirror itself) is delusional.
Well, I wasn't trying to prove or disprove anything. Just seeking clarity.
Not sure if you were referring directly to me, but I don't think my comment was harmful. Others may have also been led astray and an exchange like this might be educational for them to read.
The way that "Well, there's tons of conflicting advice out there if that's the case" was situated/employed in the discussion makes it sound like an attempt to say that there are merits on both sides of the argument--that there are conflicting opinions and the argument is as of yet still unresolved. The problem is that the comments you linked to are uninformed and just flat out wrong--bad advice from people who don't know what they're talking about and in no position to be giving advice. (Another example: the comment by samatman above, which should be buried in downvotes but inexplicably is not even in the grey--and I suspect is actually ranked somewhere at >1.) The only prudent thing to do is to clearly bracket it as such, in order to minimize harm.
Don't look to people who don't know what they're talking about to "clear things up" for you. If you think they have any qualms about leaving you to deal with the blowback after misleading you with uninformed takes (and pointing the finger at you for putting your faith in them to begin with), then you're setting yourself up to be burned.
There's a reason why everyone who has their ducks in a row (in other words, people with competent legal counsel along with something to lose, e.g. Mozilla, Google, Apple, Microsoft, etc) will bake something like about:license into the stuff they work on, even if it's buried in some "open source licenses" entry of an About screen reachable by the last menu item in the system settings. Spoiler alert: it's because they have to—in order to comply with the terms of the license. It's not because they just think it's the nice thing to do. (And definitely not because it's fun and easy to do, because it's not.)
It would be cool if "6 minutes / 1 mile in min/km" showed `3:44` instead of (in addition to?) `3.7268`
I wrote my own little calculator, much less general than this, to answer running time questions like "to run an 18 minute 5k, what would my mile pace be"? and it would be neat if that were cleanly solvable in a tool like this
Impressed you found that. I don't have anything set up to automatically update it currently, but I do have an intention to have something set up to automatically update it.
Ha, yes, I was being nosy. It was quite easy to spot as it's the only XHR/Fetch request.
I was intrigued what you had used to build it, and if you had built your own solver (which you have), and what editor you used (Code Mirror) so went looking at the code. Interesting to see you left the source maps for production, made it easy for my sleuthing...
I experimented with a similar idea last year, but used ProseMirror/TipTap as the editor to enable rich text editing, and the MathJS (https://mathjs.org) solver. I also combined it with PouchDB and Yjs for offline editing and syncing between devices. Never finished it though, you have kept your nice and simple!
Oops, didn't realise I'd left source maps in, thanks for pointing it out!
Your project sounds really interesting, I'm following you on twitter now, so tweet about it if you ever finish it and hopefully I'll see.
Having CRDT-based syncing/collaboration is a direction I'd like to take NumPad in eventually, and if I have time. But I definitely think that ignoring that part completely has allowed me to get it to an MVP state.
The right operator for unit conversions is "in." "to" is used for ranges, so it's doing 100 euros _goes to_ 1 us dollar and giving you back the answer in dollars.
But it seems the parser is breaking when trying to do the inverse, anyway: "100 usd in eur" seems to do "e*ur" and gives "Values must be converted to units."
This is really neat, but you need to rethink the date/time/duration arithmetics. You’re equating 12 months with 365.25 days, which gives rise to results like “1 month - 31 days” giving “-0.0184804928 months”. At the same time, “30th January + 1 month” gives “28 Feb 2022 at 12:00:00” (why “2022”, and why “at 12:00:00”? — this is only a date calculation without reference to a year or to a time of day), while “30th January + 30 days” gives “1 Mar 2022 at 12:00:00”, although “1 month in days” gives “30.4375 days”.
In reality, months/years are simply not convertible to days/weeks arithmetically, and you can’t sensibly add months to certain dates, and sometimes also not years (for February 29th). The former should give “Incompatible units”, and the latter should result in something like “Undefined” for incompatible dates.
I've avoided adding mpg because the UK and US disagree on what a gallon is and mpUKg/mpUSg is not very nice to look at. You can write "miles per gallon" or "miles per US gallon" because per is the same as the "/" operator, and you can sort of do "L/100km" but you can't convert to it.
I think I see where you’re going. I’d be comfortable with “litres per hundred kilometres” if that’s possible and especially if there was a “did you mean” suggestion prompt
Nice work on getting this out. I think it looks pretty neat and simple to use.
I’ve had some issues when using it though:
- on mobile, moving the cursor in a calculation doesn’t work very well;
- More important, multiplying “200 * 10%” results in “2000%”, I believe the result should be “20”; https://www.wolframalpha.com/input?i=200+*+10%25
I also had issues navigating on mobile (iPad). There seem to be hover states that get in the way (example: I tapped on a line to move to that line and it had a small popup to say something was copied)
Looks nice! Making the result blocks non-text is handy. Any plans to open source this or sell a desktop version? I've long been a fan of http://calca.io but it doesn't run on Linux. There's some other versions out there but they tend to be flaky.
I'm trying to figure out how many "miles per hour" I get while charging my vehicle. I have a 3.3KW charger and I average 3.1 miles per KWh while driving. I expect that I am charging at a rate of 10.23 miles per hour.
So
3.3 KW * 3.1 miles per KWh
Says "3.3". The math is wrong and the units are gone.
Actually, it doesn't seem to understand the concept of a KW. I'll try "kilowatt" and "kilowatt-hour" respectively.
3.3 kilowatt * 3.1 miles per kilowatt-hour
Says "Incompatible units".
The closest I got was
3.3 kilowatt * 3.1 miles per kiloWh
Says "10.23 kW mi".
insect.sh is able to do that last one.
3.3 kilowatt * 3.1 miles per kiloWh
3.3 kW × (3.1 mi / kW·h)
= 10.23 mi/h
THIS IS AMAZING. the next step is adding variables and assignments and conditionals, and you have something very powerful that can be used by just about anybody to do really interesting things. provided you have a way to integrate with other services that a lot of people use
Thanks! Turning the current language into a Turing complete one would be a huge step up in complexity and I'm not sure it will ever make sense to implement. But I have thought about adding the ability for users to define their own functions in JS and might get around to that one day.
One thing it's missing which is trivial to implement. Have a little checkbox adjacent to line numbers, default true, that when unchecked would simply not parse the calculations, just leave it as simple text.
This way writing "and here is a little example of 9^9^9" and simply copy paste that to next line would allow me to not have it evaluate on text, but only on next line. OF course, a little more complicated to implement would be next step of actually select the text and within the pop-up have "Don't evaluate". This way writing a documentation without having always calculation be in your way would be very easy.
Other than that, this looks great ma' dude. Keep it up!
> Frink is a practical calculating tool and programming language designed to make physical calculations simple, to help ensure that answers come out right, and to make a tool that's really useful in the real world. It tracks units of measure (feet, meters, kilograms, watts, etc.) through all calculations, allowing you to mix units of measure transparently, and helps you easily verify that your answers make sense. It also contains a large data file of physical quantities...
Looks much like the original idea behind lighttable IDE which is basically a REPL plugin that allows to evaluate certain lines within it. There are several similar projects around.
I was a big fan of Light Table when it first came out and the developers behind it have gone on to do some really interesting things, but I want to keep this project more limited in scope for now.
Coding comes with the implicit responsibility over one’s mess. Everyone understands that hanging your computer for your own actions it’s own’s fault.
That can be an issue if you provide a limitless cloud instance, but you can roll the ball to user’s roof with client a side engine, either JS or a local instance, depending your vision for such an app.
Nice work! I like that you're using rational numbers, I thought about going that route but decided to compromise by using Decmial.js in the end. Also really like the "Same Use Case" section in your readme. It's a good summary of the reasons I made this app :)
Just a little bug: I found that if I click a number to copy, then click it again, I'll get the original string in my clipboard concatenated with " Copied!"
1. Doesn't seem to support area conversions (tried 400 square meters, 400 m^2, and abbreviations in between).
2. If I only give a time, it would be more useful if it gave a time-only result rather than defaulting to the current date - unless it rolls over to a different date. (E.g. in Soulver, "2:30pm + 20hr" gives "Tomorrow at 10:30".)
3. It would be nice to support multiple abbreviations for minutes (mn/min are both used in various countries).
1. "square" before a unit I probably will implement that in the future. I'm not sure why "400 m^2" isn't working for you, I've just tried it and it works as expected for me?
2. It's a little bit clunky, but I decided to always specify the time and date being shown because there's so much potential for ambiguity. I might revisit this if I can think of a better way of doing it that's still unambiguous (the Soulver way isn't bad tbh)
3. "min" is supported, I've never come across "mn", do you know where it's used?
Funny, almost at the same time I published a similar tool on github.
https://github.com/SimonWaldherr/liveCalc
Mine is released under the MIT license and is mostly based on math.js. Suggestions for improvement and pull requests are very welcome.
Super cool and congrats on shipping! Something I'd love to see is the ability to embed a document on other sites via iframes a la GitHub Gist embeds. That way I could, say, write a blog post describing an algorithm, embed an example of the calculations, and allow visitors to tweak the values and see how they affect the output. Well done!
This is great, I use `bc` a lot at work (particularly when away from desk and my actual calculator) but I'll probably bookmark this to use instead.
One bit of very minor feedback:
`x^y tonnes` errors 'exponent must be unitless'. The more expected (IMO) grouping `(x^y) tonnes` works, so why not have the non-error grouping be the implied one, when no parens given?
I hadn't thought about that before but I think you're right, I've added it to my roadmap.
Getting operator precedence right has been pretty fraught tbh. For example "1km / 3 hours" is evaluated as "(1km) / (3 hours)", but "1 / 3 hours" is evaluated as "(1 / 3) hours", which is odd from a PL perspective, but I think it's more intuitive from a user perspective for this sort of thing.
It's very nicely done, but I'm afraid I don't "get it" with things like this and written out calculators in general. Why would I type out something long like:
It's particularly suited to calculations I'm doing by fetching various numbers from websites, and for the most part it 'composes' by just copypasting a calca into another one.
Basically where the numbers mean something, aren't stable / I don't know them all when I start, but there's no tabular data or significant aggregation going into the question.
I can see this being useful as a narrative document for collaboration. Explaining to someone how a business process might work given x/y/z pricing. Easy to embed the "why" aspects of things but also it autocalcs things so they could play with the numbers and see the change in impact. Some people can "think in spreadsheet" (I'm quite happy there) but that's not the best medium for everyone.
Very cool! Any plans to support vector/matrix operations? I occasionally do some work with 2D/3D graphics or physics and having some basic linalg would be nice.
I can see myself using this a lot as a scratch pad to hash out ideas while implementing stuff. The ability to define custom functions would be very helpful for that.
It's something I've thought about but I'm not sure I'm going to implement it for a while as it would be quite a big undertaking. The same is true of complex numbers unfortunately.
Minor bug report: for whatever reason entering a space on my Android keyboard enters the next suggestion on your editor. That's a feature I explicitly disabled, but is active on your website. On top of that if that enters an unrenderable character I see a red dot that's undeletable.
Mini feedback: The difference between a defined variable and an undefined variable could be clearer. And should an expression with an undefined variable still give a value?
So if you had: Alice's food + Bob's foood = £30 then I think there should be more to highlight the typo.
This is correct, the idea is that you can type things like "6 foot 3 inches" and have it evaluate as an addition. But the example shown above is definitely a problem, I'll try to think of a work around.
I'd think that rule only makes sense after a symbol representing a unit (including potentially 6'3"). Certainly <number> <named constant> should logically assume multiplication.
It would be nice if "1 mm / inch" would be returned as a unitless number. I know that you can enter "1 mm in inch" but there are cases where it would help to have the calculator reduce the units for you.
I have a side project slightly similar to the functionality your tool offers focused on expense tracking (or other measures) over time, adding date parsing to the equation in order to plot metrics into a graph and with tags and locations for filtering.
I'm (slowly) working on something that can eat up PSD2 data from banks and parse it into some usable data, but I'm bad at nicely presenting stuff. It would be great to see your tool and get some inspiration, or maybe even use it.
I've been thinking of ways to parser phone screenshots with payment data or use bank APIs to add data to my expense tracker, as opposed to adding everything manually, which is the best way I've found for consistency and to make sure everything is properly formatted.
I didn't know about PSD2. Do you have any links or references for me to look at?
I was trying to divide an area by a smaller area to get the number of widgets, and it insists on making that into a percentage. Is there a way to make it report a raw number instead of percentages when the two quantities are the same unit?
I would really appreciate if there were units for si prefixes, common orders of magnitude, and compute, i.e. "G", "M", "billion" "million", "megabytes" and "gigabytes"
Looks very interesting. I think there is some ambiguity with respect to currency symbols, $ converts to USD and £ to GBP. However, depending on user location those symbols can be used to mean very different currencies.
Is there anywhere else that uses "£"? I didn't feel great about having $ default to USD but it is probably what most users want. I'll probably make it location-aware and/or allow the user to decide which it defaults to in the future.
Fantastic, thank you for implementing one of my future side projects.
I was planning to build a web-based version of Soulver with sharing/collaboration. I hope this can fill that spot for me.
After reading the sibling comments to mine, I've worked out what it is doing.
> * 5 feet 8 inches to centimeters -> -171.72 cm
As @defrost said, the 'to' operator instructs NumPad to calculate the distance from the unit before 'to' and the unit after 'to'.
To the nearest mm, 5 feet 8 inches = 172.72cm
It appears that NumPad is defaulting to a value of '1' where no value is specified, so it is calcuating the distance BACK from '5 feet 8 inches' TO '1 centimeters'.
It correctly responds with -171.72, which is 1cm less than 172.72.
> * 5 feet 8 inches to meters -> -0.7272 m
Same as above, except the calucation is the distance back from '5 feet 8 inches' TO '1 metres'.*
If you use the operator 'in', NumPad calculates the answer correctly:
Inline whitespace summation at the same time as mathematical operations seems like a problem. I don't think that there's a standard order of operation for that sort of thing.
This is really cool.
I usually end up doing some weird math during development and I usually use the browser developer tools which is a bit cumbersome.
This might help me replace it.
When starting a new line, and the first character is 'e', it gets evaluated to the euler constant. Would be cool if you could find a way to prevent that. :)
Maybe there's already a way to do this, but it seems to me that it would be useful to be able to refer to the answer on a previous line, like the Ans key on a TI calculator. So:
Very cool idea, would love to see it work with recipes if you could manage it. I always have to look it up when I see a cup of butter listed in the ingredients of a cake
This is an excellent tool, would be good to have some simple rounding functionality. Perhaps a generic visible decimal points settings or a round() method of some sort.
This is awesome!
Some feature requests:
it would be great though if you could have multiple sessions/tabs in stead of 1. Also a clear button would be nice.
When using it to make simple calculations while on a phone I think it would be easier than the long click select all delete combo, but perhaps this is not really the aim of the tool.
TIL that it is convention in the English language to place the euro sign in front of the amount and not after it, like in most other European languages.
Yeah, I'm British and I'll concede that how we write it doesn't make sense. I do intend to localise it/add options in the future.
NumPad currently accepts numbers in the "9,999.9" format, which is the default in the anglosphere, but "9.999,9" is common elsewhere. So that's another thing I'd like to address in the future.
Slovenian here, we put it after. It makes more sense, at least to me, since you do say that apple costs five euros, where as the other way around: That apple costs euro five. Which would here mean that it costs 1.05€ and not 5€.
there are several inline repl extensions, for many many programming languages. One of the first ones to do it was clojure, imitating the lighttable IDE. I believe you will find similar ones for other languages
I would love to have a plain text "notepad" for iOS, because the built in app is horrendous and converts links to clickable hyperlinks. Etc. Hate that piss shit.
One small criticism: In my opinion, no web-based writing app is useful unless the tab key inserts a tab. The default behavior of most browsers to move focus to the next field is tremendously infuriating in this context. Unfortunately, that's what happens here, at least for Firefox.
(Related: key combinations that normally perform cursor movements but which are often used by browser for navigation.)