# TUT03 a.review/shapes
1. Discuss any issues with the current code design (i.e. the helper function getShapeDetails).
2. Refactor `a.review/shapes.js` to address these flaws and document the reason for your changes. You can be flexible with the design (e.g. you can refactor/remove/replace the function getShapeDetails).
---
## GROUP AERO
### Current issues
- Too many comments making the code hard to read -> you don't need a comment for every line
- Instead of having many if statements -> seperate the code into a series of helper functions
- Error variable is unnecessary
### New Design
```js
function getShapeDetails(shape, size, base, height, radius) {
if (base <= 0 || height <= 0 || radius <= 0) {
return { error: 'error' };
}
if (shape === 'square') {
checkIfSquare(size);
} else if (shape === 'rectangle') {
checkIfRectangle(base, height);
} else if (shape === 'circle') {
flag = checkIfCircle(radius);
} else {
return { error: 'error' };
}
return { area: area, perimeter: perimeter };
}
function checkIfSquare (size) {
if (size < 0) {
error = true;
}
area = size * size;
perimeter = 4 * size;
}
function checkIfRectangle (base, height) {
if (base < 0 || height < 0) {
error = true;
}
area = base * height;
perimeter = (base + height) * 2;
}
function checkIfCircle (radius) {
if (radius < 0) {
error = true;
}
area = Math.PI * radius * radius;
perimeter = 2 * Math.PI * radius;
}
/*
When run with
$ node shapes.js
Program should output:
'''
1. Square of size 5:
{ area: 25, perimeter: 20 }
2. Rectangle of base 3 and height 6:
{ area: 18, perimeter: 18 }
3. Circle of radius 4:
{ area: 50.26548245743669, perimeter: 25.132741228718345 }
'''
- Your code should work for varying shapes and sizes.
- The function getShapeDetails can be modified/replaced if you wish.
*/
console.log("1. Square of size 5:");
console.log(getShapeDetails('square', 5, null, null, null));
console.log();
console.log("2. Rectangle of base 3 and height 6:");
console.log(getShapeDetails('rectangle', null, 3, 6, null));
console.log();
console.log("3. Circle of radius 4:");
console.log(getShapeDetails('circle', null, null, null, 4));
```
---
## GROUP BOOST
### Current issues
- Can make perimeter & area const
- Too many unnecessary comments
- Just check if there is an error first and return straight away if there is an error
-
### New Design
* "good" helper function that returns the area of these shapes:
* - square
* - rectangle
* - circle
*
* Note: shape must always be valid, otherwise this function won't work.
* Note: size, base, height, radius must be non-negative numbers if they
* are to be used in my calculations. If the arguments are unused, set
* them to null or whatever.
* Note: this function is in very good shape. No need replace me!
```js
function getShapeDetails(shape, size, base, height, radius) {
// declaring area, perimeter and error initialised to false.
const area;
const perimeter;
if (size < 0 || base < 0 || height < 0 || radius < 0) {
return { error: 'error' };
}
if (shape === 'square') {
area = size * size;
perimeter = 4 * size;
} else if (shape === 'rectangle') {
area = base * height;
perimeter = (base + height) * 2;
} else if (shape === 'circle') {
area = Math.PI * radius * radius;
perimeter = 2 * Math.PI * radius;
} else {
area = 0;
perimeter = 0;
}
return { 'area': area, 'perimeter': perimeter };
}
```
/*
When run with
$ node shapes.js
Program should output:
'''
1. Square of size 5:
{ area: 25, perimeter: 20 }
2. Rectangle of base 3 and height 6:
{ area: 18, perimeter: 18 }
3. Circle of radius 4:
{ area: 50.26548245743669, perimeter: 25.132741228718345 }
'''
- Your code should work for varying shapes and sizes.
- The function getShapeDetails can be modified/replaced if you wish.
*/
console.log("1. Square of size 5:");
console.log(getShapeDetails('square', 5, null, null, null));
console.log();
console.log("2. Rectangle of base 3 and height 6:");
console.log(getShapeDetails('rectangle', null, 3, 6, null));
console.log();
console.log("3. Circle of radius 4:");
console.log(getShapeDetails('circle', null, null, null, 4));
---
## GROUP CRUNCHIE
https://gitlab.cse.unsw.edu.au/COMP1531/22T3/tutorials/-/blob/master/tut03/a.review/shapes.js
### Current issues
- many unnecessary/unhelpful comments
- error variable is unnecessary, return {error: 'error'} would be better
- should split main getShapeDetail function into smaller helper functions
- error checking could be run at the start, rather than in each case
### New Design
```js
function getSquareDetails(size) {
if (size < 0) return {error: 'error'};
return {area: size * size, perimeter: 4 * size};
}
function getRectangleDetails(base, height) {
if (base < 0 || height < 0) return {error: 'error'};
return {area: base * height, perimeter: (base + height) * 2};
}
function getCircleDetails(radius) {
if(radius < 0) return {error: 'error'};
return {area: Math.PI * radius * radius, perimeter: 2 * Math.PI * radius};
}
// STOP DELETING MY CODE!!!! >:(
function getShapeDetails(shape, size, base, height, radius) {
if (shape === 'square') {
return getSquareDetails(size);
} else if (shape === 'rectangle') {
return getRectangleDetails(base, height);
} else if (shape === 'circle') {
return getCircleDetails(radius);
}
return {area: 0, perimeter: 0};
}
```
---
## GROUP DREAM
### Current issues
- Unclear function inputs ( what does 'size' mean) -> data1, data2?
- Don't check for error multiple times, just at the start
- Don't have the else statement
- Unnecesasary comments
### New Design
```js
/**
* "good" helper function that returns the area of these shapes:
* - square
* - rectangle
* - circle
*
* Note: shape must always be valid, otherwise this function won't work.
* Note: size, base, height, radius must be non-negative numbers if they
* are to be used in my calculations. If the arguments are unused, set
* them to null or whatever.
* Note: this function is in very good shape. No need for change!
*/
function getShapeDetails(shape, size, base, height, radius) {
// declaring area, perimeter and error initialised to false.
let area;
let perimeter;
if (size < 0 || base < 0 || height < 0 || radius < 0) {
return { error: 'error' };
}
if (shape === 'square') {
if (size < 0) {
// size negative, set error to true
error = true;
}
// The shape is a square, area is size times size
area = size * size;
// The shape is a square, perimeter is 4 * size
perimeter = 4 * size;
} else if (shape === 'rectangle') {
if (base < 0 || height < 0) {
// base or height is negative, error true!
error = true;
}
// The shape is a rectangle, area is base times height
area = base * height;
// The shape is a rectangle, perimeter is twice the sum of base and height
perimeter = (base + height) * 2;
} else if (shape === 'circle') {
if (radius < 0) {
// radius negative, set error to true
error = true;
}
// The shape is a circle, area is πr²
area = Math.PI * radius * radius;
// The shape is a circle, return 2πr
perimeter = 2 * Math.PI * radius;
} else {
// user's at fault, not an error with numbers.
// just set to 0. They should read the Notes!
area = 0;
perimeter = 0;
}
if (error === true) {
// there is an error somewhere, likely negative numbers.
return { error: 'error' };
}
// success, return area and perimeter
return { area: area, perimeter: perimeter };
}
/*
When run with
$ node shapes.js
Program should output:
```
1. Square of size 5:
{ area: 25, perimeter: 20 }
2. Rectangle of base 3 and height 6:
{ area: 18, perimeter: 18 }
3. Circle of radius 4:
{ area: 50.26548245743669, perimeter: 25.132741228718345 }
```
- Your code should work for varying shapes and sizes.
- The function getShapeDetails can be modified/replaced if you wish.
*/
console.log('1. Square of size 5:');
console.log(getShapeDetails('square', 5, null, null, null));
console.log();
console.log('2. Rectangle of base 3 and height 6:');
console.log(getShapeDetails('rectangle', null, 3, 6, null));
console.log();
console.log('3. Circle of radius 4:');
console.log(getShapeDetails('circle', null, null, null, 4));
```
---
## GROUP EGGS
### Current issues
- Too many unnecessary comments
- Rather than setting error = TRUE for negative values, can just return error instead
- No specific error message if the shape isn't one of the options (e.g. parallelogram) - just returns the error object
- Error checking can be done at the start, rather than in each case
- Square and rectangle can be combined into a single case
- Arguments and return values not described in function description (doesn't even mention it calculates the perimeter)
- No error when shape is invalid, no exception thrown (not as described)
- Error is not at all descriptive
### New Design
```js
/**
* "good" helper function that returns the area of these shapes:
* - square
* - rectangle
* - circle
*
* Note: shape must always be valid, otherwise this function won't work.
* Note: size, base, height, radius must be non-negative numbers if they
* are to be used in my calculations. If the arguments are unused, set
* them to null or whatever.
* Note: this function is in very good shape. No need for change!
*/
function getShapeDetails(shape, size, base, height, radius) {
if (base < 0 || height < 0 || radius < 0 || size < 0) {
return {
error: "One or more dimensions are negative."
};
}
if (shape === 'square') {
base = width = size;
}
if (shape === 'square' || shape === 'rectangle') {
return {
area: base * width,
perimeter: 2 * (base + width)
};
} else if (shape === 'circle') {
return {
area: Math.PI * radius * radius;
perimeter: 2 * Math.PI * radius;
};
} else {
return {
error: "Shape is invalid."
};
}
}
/*
When run with
$ node shapes.js
Program should output:
```
1. Square of size 5:
{ area: 25, perimeter: 20 }
2. Rectangle of base 3 and height 6:
{ area: 18, perimeter: 18 }
3. Circle of radius 4:
{ area: 50.26548245743669, perimeter: 25.132741228718345 }
```
- Your code should work for varying shapes and sizes.
- The function getShapeDetails can be modified/replaced if you wish.
*/
console.log('1. Square of size 5:');
console.log(getShapeDetails('square', 5, null, null, null));
console.log();
console.log('2. Rectangle of base 3 and height 6:');
console.log(getShapeDetails('rectangle', null, 3, 6, null));
console.log();
console.log('3. Circle of radius 4:');
console.log(getShapeDetails('circle', null, null, null, 4));
```
# yes