Skip to content

Instantly share code, notes, and snippets.

@jasim
Created January 30, 2021 11:42
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jasim/99c7b54431c64c0502cfe6f677512a87 to your computer and use it in GitHub Desktop.
Save jasim/99c7b54431c64c0502cfe6f677512a87 to your computer and use it in GitHub Desktop.
A possible solution for the CoronaSafe Fellowship Todo CLI application
/*
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
Copy link

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

@jasim
Copy link
Author

jasim commented Feb 2, 2021

@mohamedhazzali3 Sorry, we won't be able to port this to other languages.

@gex7777
Copy link

gex7777 commented Feb 2, 2021

impressive way of handling the io operations, I used js too and found it hard to keep the code clean, thank you for this

@arnabsen1729
Copy link

@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