Skip to content

initial push of new concept 'randomness' #1633

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions concepts/randomness/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "Random numbers can be generated with the Math.random() method in JavaScript.",
"authors": ["atj-craig"],
"contributors": []
}
1 change: 1 addition & 0 deletions concepts/randomness/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provide information about the concept for a student who has completed the corresponding concept exercise to learn from and refer back to
26 changes: 26 additions & 0 deletions concepts/randomness/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Introduction

JavaScript provides a method on the Math object called `Math.random()` to create pseudo-random numbers.

Math.random will return a number between 0 (inclusive) and 1 (exclusive). This means that 0 is a possible result, while 1 is not. To be clear, we can express this range as 0 to 0.999999...

## How to create psuedo-random numbers

To demonstrate how to use this method, here is a simple function that employs it:

```javascript
function randomNumber() {
return Math.random();
}
// => will return a number between 0 (inclusive) and 1 (exclusive)
```

## Creating pseudo-random integers

## Seeds

## Cryptographically secure random numbers

// Links
Why Randomness is hard
What pseudo-random numbers are
1 change: 1 addition & 0 deletions concepts/randomness/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provide helpful links that provide more reading or information about a concept
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,14 @@
"concepts": ["classes"],
"prerequisites": ["objects", "functions", "conditionals-ternary"],
"status": "beta"
},
{
"slug": "captains-log",
"name": "Captain's Log",
"uuid": "need-to-generate",
"concepts": ["randomness"],
"prerequisites": ["numbers"],
"status": "wip"
}
],
"practice": [
Expand Down
1 change: 1 addition & 0 deletions exercises/concept/captains-log/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Still need to start this
42 changes: 42 additions & 0 deletions exercises/concept/captains-log/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Instructions

Mary is a big fan of the TV series _Star Trek: The Next Generation_. She often plays pen-and-paper role playing games, where she and her friends pretend to be the crew of the _Starship Enterprise_. Mary's character is Captain Picard, which means she has to keep the captain's log. She loves the creative part of the game, but doesn't like to generate random data on the spot.

Help Mary by creating random generators for data commonly appearing in the captain's log.

## 1. Generate a random stardate

What's the use of a log if it doesn't include dates?

A stardate is a floating point number. The adventures of the _Starship Enterprise_ from the first season of _The Next Generation_ take place between the stardates 41000.0 and 42000.0. The "4" stands for the 24th century, the "1" for the first season.

Implement the function `randomStardate(min, max)` that returns a floating point number between 41000.0 (inclusive) and 42000.0 (exclusive).

```javascript
randomStardate();
// => 41458.851814302536
```

## 2. Generate a random starship registry number

Enterprise (registry number NCC-1701) is not the only starship flying around! When it rendezvous with another starship, Mary needs to log the registry number of that starship.

Registry numbers start with the prefix "NCC-" and then use a number from 1000 to 9999 (inclusive).

Implement the `randomShipRegistryNumber(min, max)` function that returns a random starship registry number.

```javascript
randomShipRegistryNumber();
// => "NCC-1947"
```

## 3. Generate a random planet

The _Starship Enterprise_ encounters many planets in its travels. Planets in the Star Trek universe are split into categories based on their properties. For example, Earth is a class M planet. All possible planetary classes are: D, H, J, K, L, M, N, R, T, and Y.

Implement the `randomPlanetClass()` function. It should return one of the planetary classes at random.

```javascript
randomPlanetClass();
// => "K"
```
1 change: 1 addition & 0 deletions exercises/concept/captains-log/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
still need to do this
14 changes: 14 additions & 0 deletions exercises/concept/captains-log/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"root": true,
"extends": "@exercism/eslint-config-javascript",
"env": {
"jest": true
},
"overrides": [
{
"files": [".meta/proof.ci.js", ".meta/exemplar.js", "*.spec.js"],
"excludedFiles": ["custom.spec.js"],
"extends": "@exercism/eslint-config-javascript/maintainers"
}
]
}
3 changes: 3 additions & 0 deletions exercises/concept/captains-log/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
yarn-error.log

11 changes: 11 additions & 0 deletions exercises/concept/captains-log/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"blurb": "Practice randomness with -----",
"authors": ["atj-craig"],
"contributors": [],
"files": {
"solution": ["captains-log.js"],
"test": ["captains-log.spec.js"],
"exemplar": [".meta/exemplar.js"]
},
"forked_from": []
}
1 change: 1 addition & 0 deletions exercises/concept/captains-log/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
still need to do this
33 changes: 33 additions & 0 deletions exercises/concept/captains-log/.meta/exemplar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @ts-check

/**
* Generates a random stardate
*
* @param {number} min
* @param {number} max
* @returns {number} a random number between min (inclusive) and max (exclusive)
*/
export function randomStardate(min, max) {
return Math.random() * (max - min) + min;
}

/**
* Generates a starship registry number
*
* @param {number} min
* @param {number} max
* @returns {string} starting with "NCC-" followed by a random integer between min (inclusive) and max (inclusive)
*/
export function randomShipRegistryNumber(min, max) {
return "NCC-" + Math.floor(Math.random() * (max - min + 1) + min);
}

/**
* Generates a random planet class
*
* @param {array} classes an array of strings filled with the classes of planets
* @returns {string} a single random item from the classes parameter
*/
export function randomPlanetClass(classes) {
return classes[Math.floor(Math.random() * classes.length)];
}
1 change: 1 addition & 0 deletions exercises/concept/captains-log/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
audit=false
21 changes: 21 additions & 0 deletions exercises/concept/captains-log/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Exercism

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.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
42 changes: 42 additions & 0 deletions exercises/concept/captains-log/TO-DO
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
To-do:
/javascript
/concepts
/randomness
/.meta
config.json
- mostly done
about.md
- not started
introduction.md
- started but wondering about the balance between showing students what they need VS getting them to learn in the exercise
links.json
- not started
/exercises
/concept
/captains-log
/.docs
hints.md
- not done
instructions.md
- copied from other exercise
introduction.md
- not done
/.meta
config.json
- semi-done
design.md
- not done
exemplar.js
- done
captains-log.js
- mostly done
captains-log.spec.js
- mostly done
- note: Testing for randomness proved a bit tricky. I went for a simple solution that runs the functions multiple times and tests to see that the results are random by seeing if different outputs would be made. It's not perfect. I had to adjust the number of times the tests are run, otherwise there can be false positive / false negative results. The current settings should be working, but please do test this a few times to verify it.
LICENSE
- standard
package.json
- mostly done
config.json
- generate UUID
- see if additional prereq's are needed
15 changes: 15 additions & 0 deletions exercises/concept/captains-log/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
useBuiltIns: 'entry',
corejs: '3.19',
},
],
],
plugins: ['@babel/plugin-syntax-bigint'],
};
46 changes: 46 additions & 0 deletions exercises/concept/captains-log/captains-log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// @ts-check

/**
* Generates a random stardate
*
* @param {number} min
* @param {number} max
* @returns {number} a random number between min (inclusive) and max (exclusive)
*/
export function randomStardate(min, max) {
// return Math.random() * (max - min) + min;
return 1000000000000;
// throw new Error('Implement the randomStardate function');
}
// console.log(randomStardate(1, 2))

/**
* Generates a starship registry number
*
* @param {number} min
* @param {number} max
* @returns {string} starting with "NCC-" followed by a random integer between min (inclusive) and max (inclusive)
*/
export function randomShipRegistryNumber(min, max) {
return "NCC-" + Math.floor(Math.random() * (max - min + 1) + min);
// throw new Error('Implement the randomShipRegistryNumber function');
}

// integer test
// see if there is a decimal in the result

// inclusive test
// console.log(randomShipRegistryNumber(0, 1))
// => will return NCC-0 or NCC-1 if working.
// => will return NCC-0 if not inclusive

/**
* Generates a random planet class
*
* @param {array} classes an array of strings filled with the classes of planets
* @returns {string} a single random item from the classes parameter
*/
export function randomPlanetClass(classes) {
return classes[Math.floor(Math.random() * classes.length)];
// throw new Error('Implement the randomPlanetClass function');
}
81 changes: 81 additions & 0 deletions exercises/concept/captains-log/captains-log.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { randomStardate, randomShipRegistryNumber, randomPlanetClass } from './captains-log';

describe('randomStardate', () => {
test('returns a non-integer number', () => {
const min = 1;
const max = 2;
const result = randomStardate(min, max);
expect(typeof result).toBe('number');
expect(Number.isInteger(result)).toBe(false);
});

test('returns a number between 41000 and 42000', () => {
const min = 41000;
const max = 42000;
const result = randomStardate(min, max);
expect(result).toBeGreaterThanOrEqual(min);
expect(result).toBeLessThan(max);
});

test('returns a random number', () => {
const min = 1;
const max = 1000;
const resultArray = [];
for (let i = 0; i < 10; i++) {
resultArray.push(randomStardate(min, max));
}
expect(resultArray).toEqual(expect.not.arrayContaining([randomStardate(min, max)]));
});
});

//type needs to be string
describe('randomShipRegistryNumber', () => {
const min = 1000;
const max = 9999;
const regexNumber = /(?<=NCC\-).+/;
const regexFull = /^(NCC\-)(\d\d\d\d)$/;

test('returns the correct format of NCC-####', () => {
const result = randomShipRegistryNumber(min, max).match(regexFull);
expect(result).not.toBe(null);
});

test('number after NCC- is random', () => {
const resultArray = [];
for (let i = 0; i < 10; i++) {
resultArray.push(randomShipRegistryNumber(min, max).match(regexNumber)[0])
}
expect(resultArray).toEqual(expect.not.arrayContaining([randomShipRegistryNumber(min, max).match(regexNumber)[0]]))
});

test('returns the max value', () => {
const resultArray = [];
for (let i = 0; i < 10; i++) {
resultArray.push(randomShipRegistryNumber(0, 1).match(regexNumber)[0])
}
expect(resultArray).toEqual(expect.arrayContaining(["1"]))
});
});

describe('randomPlanetClass', () => {
const planetClasses = ["D", "H", "J", "K", "L", "M", "N", "R", "T", "Y"];
const regex = /^\w$/;

test('returns a string with a single character', () => {
const result = typeof randomPlanetClass(planetClasses).match(regex)[0];
expect(result).toBe("string")
});

test('when repeated, will return the entire array', () => {
const expected = planetClasses.sort().join('');
const resultArray = [];
for (let i = 0; i < 100; i++) {
const item = randomPlanetClass(planetClasses).match(regex)[0];
if (!resultArray.includes(item)) {
resultArray.push(item)
}
}
const result = resultArray.sort().join('');
expect(result).toEqual(expected);
});
});
Loading