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

feat(m4): add solution exercise 012 completed #3535

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
43ce8ec
feat(projects): add modules library
carlolombardini Apr 3, 2023
dd57c90
feat(m1): added date utilities to the modules library
carlolombardini Apr 4, 2023
820e2c4
fix(m1): added the ES module way to export the functions, renamed par…
carlolombardini Apr 13, 2023
b18f07b
fix(m1): added the function parseOrdinalNumberNew to convert integer …
carlolombardini Apr 13, 2023
3dee586
fix(m1): removed askDay, askMonth and askYear functions from the modu…
carlolombardini Apr 19, 2023
4dbc79d
fix(m1): edited isDayValue, isMonthValue and isYearValue functions fo…
carlolombardini Apr 19, 2023
60adf89
fix(m1): changed all console.log to console.warn in module.js library…
carlolombardini Apr 19, 2023
47f3974
fix(m1): added more tests so the --coverage is 100% in modules.test.j…
carlolombardini Apr 19, 2023
92cd081
Merge branch 'tomorrowdevs-projects:main' into main
carlolombardini Jul 11, 2023
cedb274
feat(projects): add sort order library and its test file
carlolombardini Jul 14, 2023
414eda4
fix(projects): removed unnecessary spread operator in all sort functi…
carlolombardini Jul 18, 2023
528dcdc
fix(lib): add coverage to jest, in package.json
carlolombardini Aug 24, 2023
cbcd154
fix(lib): removed redundant code changing iteration loops in bubbleSo…
carlolombardini Aug 24, 2023
9c9c3c4
fix(lib): replaced order string value with boolean consistently with …
carlolombardini Aug 24, 2023
b54eb74
fix(lib): filter was used instead of for in the cleanForSortingNumber…
carlolombardini Aug 24, 2023
75b88f0
feat(lib): added the file files-promises-modules.js containing a list…
carlolombardini Jan 14, 2024
f5ce4e3
feat(m4): add solution exercise 012 completed
carlolombardini Jan 14, 2024
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
219 changes: 219 additions & 0 deletions projects/lib/files-promises-modules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
const prompt = require("prompt-sync")({ sigint: true}) ;
// import {promises as fs} from 'fs';
const fs = require('fs').promises;
/**
* Asks the user for the name of a file
* @returns {string} the name of the file
*/
function askFileName(){
const fileName = prompt('Please enter the name of a file, including the extension: ');

if( /\s/.test(fileName.trim()) ){
console.log('You have entered more than one file name');
return false;
}

return fileName;
}
/**
* Determines and displays the frequencies of all of the letters in a file
* @param {string} content the content of a file
* @returns {Object} list of letters and their frequencies
*/
function calculateLettersFrequencies(content){
const lettersFrequencies = {};
const alphabet = 'abcdefghijklmnopqrstuvwxyz';

for (let i = 0; i < content.length; i++) {
let letter = content[i].toLowerCase();

if(alphabet.includes(letter)){
if( Object.keys(lettersFrequencies).includes(letter) ){
lettersFrequencies[letter]++;
} else {
lettersFrequencies[letter] = 1;
}
}
}

return lettersFrequencies;
}
/**
* Determines and displays the frequencies of all of the words in a file
* @param {string} content the content of a file
* @returns {Object} list of words and their frequencies
*/
function calculateWordsFrequencies(content){
const wordsFrequencies = {};
const lines = content.split(/\r?\n/);

lines.forEach(line => {
const words = line.split(/\W+/);

words.forEach(word => {
word = word.trim().toLowerCase();

if(word !== ''){
if( Object.keys(wordsFrequencies).includes(word) ){
wordsFrequencies[word]++;
} else {
wordsFrequencies[word] = 1;
}
}
})
});

return wordsFrequencies;
}
/**
* Check if a name for a new file fits
* @param {string} fileName the name to check
* @returns
*/
function checkNewFileName(fileName){
if(fileName === ''){
console.log('You entered an empty name for the file to create.');
return false;
} else if (! /^[a-zA-Z0-9]+\.[a-z]+$/.test(fileName)){
console.log('You did not enter a valid name, use only numbers, letters plus the extension.');
return false;
}

return fileName;
}
/**
* Display a list of names and a contextual message
* @param {Set} names the list to display
* @param {string} text the name of the list items
* @returns
*/
function displayNames(names, text){
if(names instanceof Set && names.size > 0){
if(typeof text === 'string' && text !== '' ){
console.log(text);
}

names.forEach(name => {
console.log(name);
});
}

return;
}
/**
* Creates the list of all the words contained in a string
* @param {string} content the content of a file
* @returns {Array} list of words
*/
function generateWords(content){
if(typeof content === 'string' && content.trim() !== ''){
return content.split(/\W+/)
}

return [];
}
/**
* Identify names in a file
* @param {string} fileName the file to use
* @param {boolean} popular If true, only the popular names will be saved
* @returns
*/
async function getNames(fileName, popular = false){
const popularNames = {};

try {
const response = await readTheFile(fileName);
if(response){
const lines = response.split(/\r?\n/);

for (let i = 0; i < lines.length; i++) {
const line = lines[i];

if (/,/.test(line)){
const values = line.split(',');

if (values[1] === 'M' && ! popularNames.hasOwnProperty('boys')){
popularNames.boys = values[0];
} else if(values[1] === 'F' && ! popularNames.hasOwnProperty('girls')){
popularNames.girls = values[0];
}

if (popularNames.hasOwnProperty('boys') && popularNames.hasOwnProperty('girls') && popular){
break;
}
}
};

}

} catch (error) {
console.log('The following error occurred: ', error.message);
}

return popularNames;
}
/**
* Reads the contents of a text file
* @param {string} filePath the path of the file to read
* @returns the contents of the text file
*/
async function readTheFile(filePath){
try {
return await fs.readFile(filePath, 'utf-8');
} catch (error) {
if(error.errno === -4058){
if(error.path === ''){
console.log('A file name was not entered');
return false;
}
console.log(`The file ${filePath} does not exist`);
return false;
}
}
}
/**
* Reads the contents of a text file
* @param {string} filesPath the path of the file to read
* @returns the content of the text file
*/
async function readDirectoryFiles(filesPath){
try {
return await fs.readdir(filesPath, 'utf-8');
} catch (error) {
if(error.errno === -4058){
if(error.path === ''){
console.log('A file name was not entered');
return false;
}
console.log('The file does not exist');
return false;
}
}
}
/**
* Write the content in a text file
* @param {string} filePath the path of the file to write
* @param {string} content the content to write
* @returns
*/
function writeTheFile(filePath, content){
try {
return fs.writeFile(filePath, content);
} catch (error) {
console.log(error.message);
return false;
}
}
module.exports = { // For CommonJS environment
// export { // For ES module environment. In addition for Visual Studio Code two package.json files must be created, one in this file folder, the other one in the application file folder, they must contain the following code { "type": "module" }
askFileName,
checkNewFileName,
calculateLettersFrequencies,
calculateWordsFrequencies,
displayNames,
generateWords,
getNames,
readTheFile,
readDirectoryFiles,
writeTheFile
}
117 changes: 117 additions & 0 deletions projects/lib/modules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const prompt = require("prompt-sync")({ sigint: true}) ;


function isBoolean( value ) {
return typeof value === 'boolean';
}

/** Function from exercise m1/015-is-it-a-leap-year */
function isLeapYear( value ){
if ( value % 400 === 0){
return true;
}

if ( value % 100 !== 0 && value % 4 === 0 ){
return true;
}

return false;
}

/** Function from exercise m1/034-integer-to-ordinal */
function parseOrdinalNumber( number ){
const textualOrdinalNumbers = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'];

if ( number < 1 || number > 12 ){
return '';
}

return textualOrdinalNumbers[number - 1];
}

/** Function from exercise m1/034-integer-to-ordinal */
function parseOrdinalNumberNew( number, maxValue ){

let currentNumber = '';

for (let i = 1; i <= maxValue; i++) {
if( number % 10 === 1 ){
currentNumber = number + 'st';
} else if( number % 10 === 2 ){
currentNumber = number + 'nd';
} else if( number % 10 === 3 ){
currentNumber = number + 'rd';
} else {
currentNumber = number + 'th';
}
}

return currentNumber
}

function isDayValue( day ){
if ( ! isNaN( day ) && day > 0 && day <= 31 ){
return true;
}

console.warn( 'The day entered is not correct, enter a positive number between 1 and 31.' );
return false;
}

function isMonthValue( month ){
if ( ! isNaN( month ) && month > 0 && month <= 12 ){
return true;
}

console.warn( 'The month entered is not correct, enter a positive integer number between 1 and 12.' );
return false;
}

function isYearValue( year ){
if ( ! isNaN( year ) && year >= 0 ){
return true;
}

console.warn( 'The year entered is not correct, enter a positive integer number from 0 and above.' );
return false;
}

function verifyDay( day, month, year ){

if ( isDayValue( day ) && isMonthValue( month ) && isYearValue( year ) ){
const maxMonthsDuration = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

if ( ! isLeapYear( year ) ){
maxMonthsDuration[1] = 28;
}

if( day <= maxMonthsDuration[month -1] ){
return true;
}

console.warn( 'The day exceeds the number of days in the month.' );
}

return false;
}

function calculateFebruaryDays( year ){
if ( isYearValue( year ) ){
return isLeapYear( year ) ? 29 : 28;
}

return false;
}

module.exports = { // For CommonJS environment
// export { // For ES module environment. In addition for Visual Studio Code two package.json files must be created, one in this file folder, the other one in the application file folder, they must contain the following code { "type": "module" }
isBoolean,
isLeapYear,
parseOrdinalNumber,
parseOrdinalNumberNew,
isDayValue,
isMonthValue,
isYearValue,
verifyDay,
calculateFebruaryDays
};
Loading