Created
January 30, 2021 11:42
-
-
Save jasim/99c7b54431c64c0502cfe6f677512a87 to your computer and use it in GitHub Desktop.
A possible solution for the CoronaSafe Fellowship Todo CLI application
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://fullstack.pupilfirst.org | |
https://github.com/nseadlc-2020/package-todo-cli-task/tree/master/shared | |
*/ | |
const EOL = require('os').EOL | |
const fs = require('fs') | |
const PENDING_TODOS_FILE = 'todo.txt' | |
const COMPLETED_TODOS_FILE = 'done.txt' | |
const HELP_STRING = `Usage :- | |
$ ./todo add \"todo item\" # Add a new todo | |
$ ./todo ls # Show remaining todos | |
$ ./todo del NUMBER # Delete a todo | |
$ ./todo done NUMBER # Complete a todo | |
$ ./todo help # Show usage | |
$ ./todo report # Statistics`; | |
/* https://stackoverflow.com/a/57163283 */ | |
let isEmpty = x => !Boolean(x); | |
/* https://stackoverflow.com/a/50130338 */ | |
let getToday = () => { | |
let date = new Date(); | |
return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)) | |
.toISOString() | |
.split("T")[0]; | |
} | |
let readFile = (filename) => { | |
if (!fs.existsSync(filename)) { | |
return [] | |
} | |
let text = fs.readFileSync(filename, {encoding: 'utf8', flag: 'r'}) | |
lines = text.split(EOL) | |
return lines | |
} | |
let appendToFile = (filename, text) => { | |
fs.appendFileSync(filename, text, {encoding: 'utf8', flag: 'a+'}); | |
} | |
let writeFile = (filename, lines) => { | |
let text = lines.join(EOL) | |
fs.writeFileSync(filename, text, {encoding: 'utf8'}); | |
} | |
let updateFile = (filename, updaterFn) => { | |
let contents = readFile(filename) | |
contents = updaterFn(contents) | |
writeFile(filename, contents) | |
} | |
let cmdHelp = () => { | |
console.log(HELP_STRING); | |
} | |
let cmdLs = () => { | |
let todos = readFile(PENDING_TODOS_FILE) | |
if (todos.length == 0) { | |
console.log("There are no pending todos!") | |
return | |
} | |
let length = todos.length | |
todos = todos.reverse().map((todo, index) => `[${length - index}] ${todo}`) | |
console.log(todos.join("\n")) | |
} | |
let cmdAddTodo = (text) => { | |
if (isEmpty(text)) { | |
console.log("Error: Missing todo string. Nothing added!") | |
return | |
} | |
updateFile(PENDING_TODOS_FILE, todos => { | |
return todos.concat([text]) | |
}) | |
console.log(`Added todo: "${text}"`) | |
} | |
let cmdDelTodo = (number) => { | |
if (isEmpty(number)) { | |
console.log(`Error: Missing NUMBER for deleting todo.`) | |
return | |
} | |
number = Number(number) | |
updateFile(PENDING_TODOS_FILE, todos => { | |
if (number < 1 || number > todos.length) { | |
console.log(`Error: todo #${number} does not exist. Nothing deleted.`) | |
} else { | |
todos.splice(number, 1) | |
console.log(`Deleted todo #${number}`) | |
} | |
return todos | |
}); | |
} | |
let cmdMarkDone = (number) => { | |
if (isEmpty(number)) { | |
console.log(`Error: Missing NUMBER for marking todo as done.`) | |
return | |
} | |
number = Number(number) | |
let todos = readFile(PENDING_TODOS_FILE) | |
if (number < 1 || number > todos.length) { | |
console.log(`Error: todo #${number} does not exist.`) | |
return | |
} | |
let completedTodo = todos.splice(number, 1) | |
writeFile(PENDING_TODOS_FILE, todos) | |
completedTodo = completedTodo[0] + EOL | |
appendToFile(COMPLETED_TODOS_FILE, completedTodo) | |
console.log(`Marked todo #${number} as done.`) | |
} | |
let cmdReport = () => { | |
let pending = readFile(PENDING_TODOS_FILE).length - 1 | |
let completed = readFile(COMPLETED_TODOS_FILE).length - 1 | |
console.log(`${getToday()} Pending : ${pending} Completed : ${completed}`) | |
} | |
let argv = process.argv | |
let command = argv[2]; | |
let arg = argv[3]; | |
if (isEmpty(command)) { | |
cmdHelp(); | |
} else { | |
switch (command.trim().toLowerCase()) { | |
case 'help': | |
cmdHelp() | |
break; | |
case 'ls': | |
cmdLs() | |
break | |
case 'add': | |
cmdAddTodo(arg) | |
break | |
case 'del': | |
cmdDelTodo(arg) | |
break | |
case 'done': | |
cmdMarkDone(arg) | |
break | |
case 'report': | |
cmdReport() | |
break | |
default: | |
cmdHelp() | |
} | |
} |
@mohamedhazzali3 Sorry, we won't be able to port this to other languages.
impressive way of handling the io operations, I used js too and found it hard to keep the code clean, thank you for this
@mohamedhazzali3 You can see my approach todo-cli-c. I have divided the program into separate modules.
- fileHandling.c : to handle file operations
- commands.c: to handle the commands
- main.c: main entrypoint for the program
It passed all the tests as well.
Tried to follow the good practices in C. See if you can find some room for improvement.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Good Morning Sir,
Iam beginner for this programming Language,Could you Please post the above program in C language for better understanding to me .
Thank you sir