Skip to content

Commit

Permalink
add osa9 9.1-9.21 and 9.23-9.25
Browse files Browse the repository at this point in the history
  • Loading branch information
vaisest committed May 21, 2022
1 parent 5c74823 commit 62ce7d3
Show file tree
Hide file tree
Showing 42 changed files with 38,695 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules/
.env
.env
.vscode
build
34 changes: 34 additions & 0 deletions osa9/calculators/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"plugins": [
"@typescript-eslint"
],
"env": {
"node": true,
"es6": true
},
"rules": {
"@typescript-eslint/semi": [
"error"
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_"
}
],
"no-case-declarations": "off"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
}
}
54 changes: 54 additions & 0 deletions osa9/calculators/bmiCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
type Centimeter = number;

type Kilogram = number;

interface BmiOptions {
height: Centimeter;
weight: Kilogram;
}

const parseBmiArgs = (args: string[]): BmiOptions => {
if (args.length < 4) throw new Error("Not enough arguments");
if (args.length > 4) throw new Error("Too many arguments");

const height = parseInt(args[2], 10);
const weight = parseInt(args[3], 10);

if (isNaN(height) || isNaN(weight))
throw new Error("Provided values were not numbers!");

return { height, weight };
};

const calculateBmi = (length: Centimeter, weight: Kilogram): string => {
const lengthMeters = length / 100;
const bmi = weight / (lengthMeters * lengthMeters);
switch (true) {
// https://en.wikipedia.org/wiki/Body_mass_index#Categories
case bmi < 16:
return "Underweight (severe thinness)";
case bmi <= 16.9:
return "Underweight (moderate thinness)";
case bmi <= 18.4:
return "Underweight (mild thinness)";
case bmi <= 24.9:
return "Normal (healthy weight)";
case bmi <= 29.9:
return "Overweight";
case bmi <= 34.9:
return "Obese (class I)";
case bmi <= 39.9:
return "Obese (class II)";
default:
return "Obese (class III)";
}
};

if (require.main === module) {
const { height: personLength, weight: personWeight } = parseBmiArgs(
process.argv
);
console.log(calculateBmi(personLength, personWeight));
}

export default calculateBmi;
71 changes: 71 additions & 0 deletions osa9/calculators/exerciseCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
interface ExerciseResult {
periodLength: number;
trainingDays: number;
success: boolean;
rating: number;
ratingDescription: string;
target: number;
average: number;
}

interface ExerciseOptions {
target: number;
hoursEachDay: number[];
}

const parseArgs = (args: string[]): ExerciseOptions => {
if (args.length < 4) throw new Error("Not enough arguments");

const target = parseFloat(args[2]);
const hoursEachDay = args.slice(3).map((arg) => parseFloat(arg));
console.log(hoursEachDay);

if (isNaN(target) || hoursEachDay.some(isNaN))
throw new Error("Provided values were not numbers!");

return { target, hoursEachDay };
};

const calculateExercises = (
hoursEachDay: number[],
target: number
): ExerciseResult => {
const periodLength = hoursEachDay.length;
const trainingDays = hoursEachDay.filter((n) => n > 0).length;
const average =
hoursEachDay.reduce((last, curr) => last + curr, 0) / periodLength;
const success = average >= target;

let rating;
let ratingDescription;
switch (true) {
case average < target - 0.5:
rating = 1;
ratingDescription = "not quite enough";
break;
case average <= target:
rating = 2;
ratingDescription = "not too bad but could be better";
break;
default:
rating = 3;
ratingDescription = "good enough";
}

return {
periodLength,
trainingDays,
success,
rating,
ratingDescription,
target,
average,
};
};

if (require.main === module) {
const { target, hoursEachDay } = parseArgs(process.argv);
console.log(calculateExercises(hoursEachDay, target));
}

export default calculateExercises;
58 changes: 58 additions & 0 deletions osa9/calculators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import express from "express";
import calculateBmi from "./bmiCalculator";
import calculateExercises from "./exerciseCalculator";

const app = express();
app.use(express.json());
const PORT = 3000;

app.get("/", (_req, res) => {
res.send("Hello Full Stack!");
});

app.get("/bmi", (req, res) => {
if (
typeof req.query.height !== "string" ||
typeof req.query.weight !== "string"
) {
res.status(400).json({ error: "malformatted paramters" });
return;
}

const height = parseInt(req.query.height, 10);
const weight = parseInt(req.query.weight, 10);

if (isNaN(height) || isNaN(weight)) {
res.status(400).json({ error: "malformatted paramters" });
return;
}

res.json({ weight, height, bmi: calculateBmi(height, weight) });
});

app.post("/exercise", (req, res) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { daily_exercises, target } = req.body;

if (!daily_exercises || !target) {
res.status(400).json({ error: "parameters missing" });
return;
}

if (
!Array.isArray(daily_exercises) ||
daily_exercises.some((item) => typeof item !== "number" || isNaN(item)) ||
typeof target !== "number" ||
isNaN(target)
) {
res.status(400).json({ error: "malformatted parameters" });
return;
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
res.json(calculateExercises(daily_exercises, target));
});

app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
});
Loading

0 comments on commit 62ce7d3

Please sign in to comment.