Skip to content

Commit

Permalink
Smath + npx (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicfv authored Mar 21, 2024
1 parent f0eb246 commit ef0c436
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ dist
types
docs
*.tgz
*/examples/*.js
*.out
6 changes: 6 additions & 0 deletions smath/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 1.2.0

- Add `npx` scripts. Run `npx smath` to learn more!
- Add more package examples in readme
- Add package example sources in repository

## 1.1.8

- Update internal packing scripts
Expand Down
60 changes: 46 additions & 14 deletions smath/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,63 @@ Similar to JavaScript's builtin [`Math`](https://developer.mozilla.org/en-US/doc

## Example

A temperature conversion tool using [`SMath.translate`](https://npm.nicfv.com/smath/classes/SMath.html#translate) to convert units and [`SMath.approx`](https://npm.nicfv.com/smath/classes/SMath.html#approx) to validate the result. The translation uses freezing and boiling points for 2 unit systems to linearly interpolate between them.
Here are a few examples written in JavaScript for a quick start into `SMath`.

### JavaScript Math Oddities

```js
import { SMath } from 'smath';

// Determine the value of 0.1 + 0.2 using vanilla JavaScript and SMath
console.log('0.1 + 0.2 == 0.3 is ' + (0.1 + 0.2 == 0.3));
console.log('SMath.approx(0.1 + 0.2, 0.3) is ' + SMath.approx(0.1 + 0.2, 0.3));
```

```text
0.1 + 0.2 == 0.3 is false
SMath.approx(0.1 + 0.2, 0.3) is true
```

### Temperature Conversion

A temperature conversion tool using [`SMath.translate`](https://npm.nicfv.com/smath/classes/SMath.html#translate) to convert units. The translation uses freezing and boiling points for 2 unit systems to linearly interpolate between them.

```js
import { SMath } from 'smath';

// Water always freezes at the
// same temperature, but the
// units might be different.
// Define some constants to
// define the number ranges
// create two number ranges.
const C_Freeze = 0,
C_Boil = 100,
F_Freeze = 32,
F_Boil = 212;

// Use the `SMath` class to
// translate the temperature in the
// generate an array of five
// linearly spaced temperature
// values from 0 to 20.
const C = SMath.linspace(0, 20, 5);

// Use the `SMath` class to linearly
// interpolate the temperature in the
// C number range to a temperature
// in the F number range
const C = 20,
F_expected = 68,
F_actual = SMath.translate(C, C_Freeze, C_Boil, F_Freeze, F_Boil);

// Determine whether the
// temperature conversion
// is valid using `approx`
const valid = SMath.approx(F_expected, F_actual);
if (!valid) {
throw new Error('Invalid result.');
// in the F number range.
const F = C.map(c => SMath.translate(c, C_Freeze, C_Boil, F_Freeze, F_Boil));

// Print out each temperature
// in both units of C and F.
for (let i = 0; i < C.length; i++) {
console.log(C[i].toFixed() + 'C is ' + F[i].toFixed() + 'F')
}
```

```text
0C is 32F
5C is 41F
10C is 50F
15C is 59F
20C is 68F
```
5 changes: 5 additions & 0 deletions smath/examples/comparison.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SMath } from 'smath';

// Determine the value of 0.1 + 0.2 using vanilla JavaScript and SMath
console.log('0.1 + 0.2 == 0.3 is ' + (0.1 + 0.2 == 0.3));
console.log('SMath.approx(0.1 + 0.2, 0.3) is ' + SMath.approx(0.1 + 0.2, 0.3));
10 changes: 10 additions & 0 deletions smath/examples/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"type": "module",
"scripts": {
"start": "rm -f *.out && touch success && find *.js -exec bash -c \"node {} > {}.out || rm success\" \\; && rm success",
"clean": "rm -rf node_modules package-lock.json *.out"
},
"dependencies": {
"smath": "file:smath-1.1.8.tgz"
}
}
29 changes: 29 additions & 0 deletions smath/examples/temperature-convert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { SMath } from 'smath';

// Water always freezes at the
// same temperature, but the
// units might be different.
// Define some constants to
// create two number ranges.
const C_Freeze = 0,
C_Boil = 100,
F_Freeze = 32,
F_Boil = 212;

// Use the `SMath` class to
// generate an array of five
// linearly spaced temperature
// values from 0 to 20.
const C = SMath.linspace(0, 20, 5);

// Use the `SMath` class to linearly
// interpolate the temperature in the
// C number range to a temperature
// in the F number range.
const F = C.map(c => SMath.translate(c, C_Freeze, C_Boil, F_Freeze, F_Boil));

// Print out each temperature
// in both units of C and F.
for (let i = 0; i < C.length; i++) {
console.log(C[i].toFixed() + 'C is ' + F[i].toFixed() + 'F')
}
6 changes: 4 additions & 2 deletions smath/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "smath",
"version": "1.1.8",
"version": "1.2.0",
"description": "Small math function library",
"homepage": "https://npm.nicfv.com/smath",
"bin": "dist/bin.js",
"main": "dist/index.js",
"types": "types/index.d.ts",
"files": [
Expand Down Expand Up @@ -47,7 +48,8 @@
"repository": "github:nicfv/npm",
"license": "MIT",
"devDependencies": {
"@types/node": "20.11.30",
"typedoc": "0.25.12",
"typescript": "5.4.2"
}
}
}
92 changes: 92 additions & 0 deletions smath/src/bin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env node

import { SMath } from '.';

const args: Array<string> = process.argv.slice(2);

/**
* Try to convert an argument into a numeric value.
*/
function N(index: number, defaultVal: number = NaN): number {
if (index >= args.length) {
if (Number.isFinite(defaultVal)) {
return defaultVal;
} else {
console.error('Required argument ' + index + ' is missing!');
process.exit(1);
}
}
const arg: number = Number.parseFloat(args[index]);
if (Number.isFinite(arg)) {
return arg;
} else if (Number.isFinite(defaultVal)) {
return defaultVal;
} else {
console.error('Argument #' + index + ' is ' + arg + ' but a number was expected.');
process.exit(1);
}
}

if (args.length < 1 || args[0].includes('help')) {
console.log('Key: <required> [optional]');
console.log('Arguments:');
console.log(' help : Show this page');
console.log(' approx <a> <b> [eps] : Check if `a` and `b` are approximately equal');
console.log(' avg <c0> [c1] ... [cn] : Take an average of `n` numbers');
console.log(' clamp <n> <min> <max> : Clamp `n` between `min` and `max`');
console.log(' expand <n> <min> <max> : Expand normalized `n` between `min` and `max`');
console.log(' linspace <min> <max> <n> : Generate `n` linearly spaced numbers between `min` and `max`');
console.log(' logspace <min> <max> <n> : Generate `n` logarithmically spaced numbers between `min` and `max`');
console.log(' normalize <n> <min> <max>');
console.log(' : Normalize `n` between `min` and `max`');
console.log(' translate <n> <min1> <max1> <min2> <max2>');
console.log(' : Linearly interpolate `n` from `min1`, `max1` to `min2`, `max2`');
process.exit(1);
}

switch (args[0]) {
case ('approx'): {
console.log(SMath.approx(N(1), N(2), N(3, 1e-6)));
break;
}
case ('avg'): {
if (args.length < 2) {
console.error('Need at least 1 argument.');
process.exit(1);
}
const operands: Array<number> = [];
for (let i = 1; i < args.length; i++) {
operands.push(N(i));
}
console.log(SMath.avg(...operands));
break;
}
case ('clamp'): {
console.log(SMath.clamp(N(1), N(2), N(3)));
break;
}
case ('expand'): {
console.log(SMath.expand(N(1), N(2), N(3)));
break;
}
case ('linspace'): {
console.log(SMath.linspace(N(1), N(2), N(3)));
break;
}
case ('logspace'): {
console.log(SMath.logspace(N(1), N(2), N(3)));
break;
}
case ('normalize'): {
console.log(SMath.normalize(N(1), N(2), N(3)));
break;
}
case ('translate'): {
console.log(SMath.translate(N(1), N(2), N(3), N(4), N(5)));
break;
}
default: {
console.error('Unknown argument "' + args[0] + '". Use with "help" for a list of commands.');
process.exit(1);
}
}
6 changes: 4 additions & 2 deletions smath/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"compilerOptions": {
"strict": true,
"rootDir": "src",
"outDir": "dist",
}
},
"include": [
"src",
],
}

0 comments on commit ef0c436

Please sign in to comment.