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

Automatically add "ans" if first button is bin op, allow omitting leading zero, add kcal/Cal units, round output of trig functions to zero if small. #29

Merged
merged 21 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
64ec6ea
parse: handle omitting leading zero
alexbarry Jan 11, 2025
b78c273
core: round sin/cos/tan funcs output to 0 if small
alexbarry Jan 11, 2025
30118b7
add kcal/Calorie, big/food calorie
alexbarry Jan 11, 2025
39f6628
html: insert "ans" if user presses op as first button
alexbarry Jan 12, 2025
a4e20fe
android: insert "ans" if user presses op as first button
alexbarry Jan 12, 2025
0e7cb6b
android: update versionCode to 10 and versionName to "1.0.6"
alexbarry Jan 12, 2025
49b2666
metadata: add changelog for android version 10
alexbarry Jan 12, 2025
bda2f4b
html: fix bug with adding unit tokens after recent changes
alexbarry Jan 12, 2025
da33da0
rename calc_ui.js to calc_ui.ts (TS support coming in a later commit)
alexbarry Jan 12, 2025
ca30155
html: added typescript support for calc_ui.ts, used module for JS in …
alexbarry Jan 12, 2025
2d230b3
html: reverted to using raw strings as tokens for now
alexbarry Jan 12, 2025
ce02576
html: add type annotations to calc_ui.ts
alexbarry Jan 12, 2025
36830d0
html: re-include change to automatically add "ans" on first press if …
alexbarry Jan 12, 2025
d3f4532
html: remove unused import
alexbarry Jan 12, 2025
e328196
dockerfile: install npm + typescript in dockerfile
alexbarry Jan 13, 2025
ff5ea23
dockerfile: use uppercase AND in FROM x AS y statements
alexbarry Jan 13, 2025
7441559
add negative and subtraction button info in help.html and README.md
alexbarry Jan 13, 2025
5d9a22e
readme: add build instructions for html (docker), html build.sh, and …
alexbarry Jan 13, 2025
03b6455
core: throw exceptions as values instead of heap pointers
alexbarry Jan 18, 2025
0da9e8e
build: add git hash and build label to alexcalc_info_func
alexbarry Jan 18, 2025
6ee38da
github: add github pages label to workflow build yaml
alexbarry Jan 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ jobs:

- name: Build AlexCalc static HTML via docker
run: |
docker build -t alexcalc_html \
docker build \
--build-arg ALEXCALC_BUILD_TYPE_LABEL=github-pages \
-t alexcalc_html \
-f Dockerfile \
--target=export_output \
--output=./public \
Expand Down
12 changes: 9 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
FROM nginx:latest as base
FROM nginx:latest AS base

ARG ALEXCALC_BUILD_TYPE_LABEL
ENV ALEXCALC_BUILD_TYPE_LABEL=${ALEXCALC_BUILD_TYPE_LABEL}

# Install OS dependencies
RUN apt-get update && apt-get install -y \
cmake \
python3 \
xz-utils \
npm \
git

# Install Emscripten
Expand All @@ -26,6 +30,8 @@ RUN /bin/bash -c "source ./emsdk_env.sh"
ENV PATH="${PATH}:/app/emsdk/upstream/emscripten"
RUN emcc --version

RUN npm -g install typescript


# Build AlexCalc
WORKDIR /app
Expand All @@ -37,13 +43,13 @@ RUN bash ./build.sh
# TODO only copy html/css/js/wasm/png?
RUN cp -r out/* /usr/share/nginx/html/

FROM scratch as export_output
FROM scratch AS export_output
COPY --from=base /app/build/wasm/out/*.html /
COPY --from=base /app/build/wasm/out/*.png /
COPY --from=base /app/build/wasm/out/*.txt /
COPY --from=base /app/build/wasm/out/js /js/
COPY --from=base /app/build/wasm/out/css /css/
COPY --from=base /app/build/wasm/out/graphics /graphics/

FROM base as server
FROM base AS server
# Use base nginx entrypoint to host HTTP server
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,46 @@ Available on:
* **Complex numbers**: enter rectangular form (`3 + 4i`) or polar (`5 angle 30`). The **angle** button replaces the **i** button when **alt** is pressed. If typing, `j` can be used in place of `i` ([more info](https://en.wikipedia.org/wiki/Imaginary_unit)).
* **Variables**: store variables by typing an expression, then pressing the "store" button in the bottom left (or typing the `->` operator), and then entering a variable name (e.g. `1.23e5 -> x`). Then simply reference this variable name in other expressions (e.g. `x^2 - 4*x -> y`)
* **Units**: select or type a desired unit, e.g. `1 kg` or `3 m s^-2`. The default output is in SI units, but arbitrary unit conversion can be accomplished with the ` to ` operator (e.g. `1 kg to lb`) which can be typed directly or by pressing the **alt** then "**to units**" button (which appears in place of the **units** button when **alt** is pressed). Note that the division slash (`/`) **can not be used** within units, e.g. "1 metre per second" can only be defined as `1 m s^-1`, and **not** `1 m/s` because that means "1 metre divided by variable s". This is unfortunate, but I'm not sure if there is any way to resolve the ambiguity. (Of course you are free to do `1 m / 1 s`)
* **Negative numbers**: the "subtraction" button can also serve as a negative sign.
* **Negative numbers**: There is a subtraction button (`-`) near the other operators, and a negative (`(-)`) button. In most cases you can use either one for either subtraction or a negative sign, unless it is the first button pressed. When it is the first button pressed, the subtraction button will automatically add `ans` before the subtraction, to operate on the result of the previous expression. When typing, you can use `-` for either purpose.

## How to build

### Web

You can build the web app via docker, which will place the output in `./public`:

```
sudo docker build -t alexcalc_html \
-f Dockerfile \
--target=export_output \
--output=./public \
.
sudo chown "${USER}" ./public
```

There may be a more convenient way to use Docker.

### Web (install dependencies manually incremental builds)

I find that Docker takes a while, so I simply run:

build/wasm/build.sh -- -j32

But this requires installing the various dependencies: CMake, emscripten, typescript.

### Android

```
cd src/android/
./gradlew build
```

Outputs will be here and in surrounding folders for different build variants:

```
src/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk
```


## Discussion

Expand Down
16 changes: 15 additions & 1 deletion build/wasm/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,28 @@ cd "${DIR}"

. ./setup_env.sh

: "${ALEXCALC_BUILD_TYPE_LABEL:=}"

mkdir -p out
cd out
emcmake cmake ../
emcmake cmake -DBUILD_TYPE_LABEL="${ALEXCALC_BUILD_TYPE_LABEL}" ../
cmake --build . $@

SRC_DIR="../../../src"
rm -f bin/index.html

# TODO only copy specific file types
cp -r "${SRC_DIR}/html"/* ./

ts_files="${SRC_DIR}/html/js"/*.ts
echo "Transpiling $ts_files..."
tsc \
--strict --noImplicitAny --strictNullChecks \
$ts_files \
--module ES6 \
--target ES6 \
--outDir ./js/

mv calc_wasm.js js/
mv calc_wasm.wasm js/
mkdir -p graphics
Expand Down
5 changes: 5 additions & 0 deletions metadata/en-US/changelogs/10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* allow omitting leading decimal place, e.g. support `.6` instead of only `0.6`.
* insert "ans" if binary operator is pressed as first button, allowing user to operate on previous result. (e.g. "1+1" <enter>, then "*3" <enter> will result in "ans*3")
* above requires adding unary negative `(-)`, which is different from subtraction `-`. If you want to enter "-1" as your input, use unary negative. If you want to enter "<previous calculation result> - 1" as your input, use subtraction.
* round output of trig functions if output is small (<1e-15). sin(pi) is now 0 instead of 1.224646799e-16
* add kilocalrie and "big"/"food" Calorie units
4 changes: 2 additions & 2 deletions src/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ android {
applicationId "net.alexbarry.calc_android"
minSdkVersion 23
targetSdkVersion 34
versionCode 9
versionName "1.0.5"
versionCode 10
versionName "1.0.6"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
4 changes: 2 additions & 2 deletions src/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="9"
android:versionName="1.0.5">
android:versionCode="10"
android:versionName="1.0.6">

<application
android:allowBackup="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ private enum ButtonId {
SUB,
ANS,
E,
NEG,
NUM1,
NUM2,
NUM3,
Expand Down Expand Up @@ -141,7 +142,7 @@ public CalcButtonsHelper(ButtonCallback callback) {
button_id_to_android_layout_elem_id.put(ButtonId.VAR, R.id.button_var);
button_id_to_android_layout_elem_id.put(ButtonId.LN, R.id.button_ln);
button_id_to_android_layout_elem_id.put(ButtonId.LPAREN, R.id.button_lparen);
button_id_to_android_layout_elem_id.put(ButtonId.DELIM, R.id.button_delim);
//button_id_to_android_layout_elem_id.put(ButtonId.DELIM, R.id.button_delim);
button_id_to_android_layout_elem_id.put(ButtonId.RPAREN, R.id.button_rparen);
button_id_to_android_layout_elem_id.put(ButtonId.DIV, R.id.button_div);
button_id_to_android_layout_elem_id.put(ButtonId.UNITS, R.id.button_units);
Expand All @@ -158,6 +159,7 @@ public CalcButtonsHelper(ButtonCallback callback) {
button_id_to_android_layout_elem_id.put(ButtonId.SUB, R.id.button_sub);
button_id_to_android_layout_elem_id.put(ButtonId.ANS, R.id.button_ans);
button_id_to_android_layout_elem_id.put(ButtonId.E, R.id.button_e);
button_id_to_android_layout_elem_id.put(ButtonId.NEG, R.id.button_neg);
button_id_to_android_layout_elem_id.put(ButtonId.NUM1, R.id.button_1);
button_id_to_android_layout_elem_id.put(ButtonId.NUM2, R.id.button_2);
button_id_to_android_layout_elem_id.put(ButtonId.NUM3, R.id.button_3);
Expand Down Expand Up @@ -210,6 +212,7 @@ public CalcButtonsHelper(ButtonCallback callback) {
button_id_to_token_func.put(ButtonId.ADD, getTokenStateless(new TokenInfo(TokenType.OP,"+")));
button_id_to_token_func.put(ButtonId.STO, getTokenStateless(new TokenInfo(TokenType.OTHER,"->")));

button_id_to_token_func.put(ButtonId.NEG, getTokenStateless(new TokenInfo(TokenType.DIGIT,"-")));
button_id_to_token_func.put(ButtonId.NUM0, getTokenStateless(new TokenInfo(TokenType.DIGIT,"0")));
button_id_to_token_func.put(ButtonId.NUM1, getTokenStateless(new TokenInfo(TokenType.DIGIT,"1")));
button_id_to_token_func.put(ButtonId.NUM2, getTokenStateless(new TokenInfo(TokenType.DIGIT,"2")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ public void add_token(TokenType type, String token, boolean is_unit) {
this.pos++;
}
InputToken inputToken = new InputToken(token, type, is_unit);

// https://github.com/alexbarry/AlexCalc/issues/24
// If the first button press is a binary operator, insert the "ans" variable before it.
// This way the user can continue operating on their previous calculation.
if (this.input_tokens.size() == 0 && type == TokenType.OP) {
InputToken ansInputToken = new InputToken("ans", TokenType.VAR, false);
this.input_tokens.add(this.pos, ansInputToken);
this.pos++;
}
this.input_tokens.add(this.pos, inputToken);
this.pos++;
}
Expand Down
35 changes: 22 additions & 13 deletions src/android/app/src/main/res/layout/fragment_first.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
android:layout_height="wrap_content"
android:columnCount="6">

<!-- Row 0 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_clear"
style="@style/AlexCalcButtonImportant"
Expand All @@ -78,6 +79,7 @@
android:layout_column="4"
android:text="@string/arrow_up" />

<!-- Row 1 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_inv"
style="@style/AlexCalcButtonMeta"
Expand Down Expand Up @@ -110,6 +112,7 @@
style="@style/AlexCalcButtonMeta"
android:text="@string/arrow_right" />

<!-- Row 2 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_alt"
style="@style/AlexCalcButtonMeta"
Expand Down Expand Up @@ -140,6 +143,7 @@
style="@style/AlexCalcButtonOp"
android:text="@string/pow" />

<!-- Row 3 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_var"
style="@style/AlexCalcButtonVar"
Expand All @@ -151,14 +155,14 @@
android:text="@string/ln" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_lparen"
style="@style/AlexCalcButtonOp"
android:text="@string/lparen" />
android:id="@+id/button_sqrt"
style="@style/AlexCalcButtonFunc"
android:text="@string/sqrt" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_delim"
android:id="@+id/button_lparen"
style="@style/AlexCalcButtonOp"
android:text="@string/delim" />
android:text="@string/lparen" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_rparen"
Expand All @@ -170,6 +174,7 @@
style="@style/AlexCalcButtonOp"
android:text="@string/div" />

<!-- Row 4 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_units"
style="@style/AlexCalcButtonVar"
Expand All @@ -178,9 +183,9 @@
android:text="@string/units" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_sqrt"
style="@style/AlexCalcButtonFunc"
android:text="@string/sqrt" />
android:id="@+id/button_pi"
style="@style/AlexCalcButtonVar"
android:text="@string/pi" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_7"
Expand All @@ -202,6 +207,7 @@
style="@style/AlexCalcButtonOp"
android:text="@string/mult" />

<!-- Row 5 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_var1"
style="@style/AlexCalcButtonVar"
Expand All @@ -210,9 +216,9 @@
android:text="@string/var_x" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_pi"
android:id="@+id/button_e"
style="@style/AlexCalcButtonVar"
android:text="@string/pi" />
android:text="@string/e" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_4"
Expand All @@ -234,6 +240,7 @@
style="@style/AlexCalcButtonOp"
android:text="@string/sub" />

<!-- Row 6 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_ans"
style="@style/AlexCalcButtonVar"
Expand All @@ -242,9 +249,10 @@
android:text="@string/ans" />

<com.google.android.material.button.MaterialButton
android:id="@+id/button_e"
style="@style/AlexCalcButtonVar"
android:text="@string/e" />
android:id="@+id/button_neg"
style="@style/AlexCalcButtonNum"
android:text="@string/neg" />


<com.google.android.material.button.MaterialButton
android:id="@+id/button_1"
Expand All @@ -266,6 +274,7 @@
style="@style/AlexCalcButtonOp"
android:text="@string/add" />

<!-- Row 7 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/button_sto"
style="@style/AlexCalcButtonOp"
Expand Down
1 change: 1 addition & 0 deletions src/android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<string name="units">units</string>
<string name="to_units">to units</string>
<string name="sqrt">sqrt</string>
<string name="neg">(-)</string>
<string name="num1">1</string>
<string name="num2">2</string>
<string name="num3">3</string>
Expand Down
12 changes: 11 additions & 1 deletion src/calc_core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 3.12.2)

set(BUILD_TYPE_LABEL "" CACHE STRING "Specifies the type of build")

#add_library(hello-jni SHARED
# hello-jni.c)

Expand All @@ -25,9 +27,17 @@ target_include_directories(calc_core PUBLIC "includes")
target_include_directories(calc_core PUBLIC "../calc_core_ui/")

string(TIMESTAMP BUILD_DATETIME "%Y-%m-%d %H:%M:%S%z")

execute_process(
COMMAND git rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)

# TODO add a variable here that can be set to indicate who built it,
# e.g. github pages
add_compile_definitions(ALEXCALC_BUILD_INFO="Built on ${BUILD_DATETIME}")
add_compile_definitions(ALEXCALC_BUILD_INFO="Built on ${BUILD_DATETIME}, version ${GIT_HASH}, label \\\"${BUILD_TYPE_LABEL}\\\"")

add_library(calc_json STATIC
calc_json.cpp)
Expand Down
Loading
Loading