From 04e5ac6c682c95bbb9a1319380ddad0ee9a5ccd9 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Wed, 22 Oct 2025 21:07:32 +0100 Subject: [PATCH 1/9] Implement ls command in py --- implement-shell-tools/ls/ls.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 implement-shell-tools/ls/ls.py diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py new file mode 100644 index 000000000..b98b5d170 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,26 @@ +import argparse +import os + +parser = argparse.ArgumentParser( + prog="Implement ls command in Python", + description="List files in a directory" + ) + +parser.add_argument("-a", action="store_true", help="Display all files include hidden files") +parser.add_argument("-o", action="store_true", help="list one file per line") +parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") + +args = parser.parse_args() + +files = os.listdir(args.dir) + +if not args.a: + files = [f for f in files if not f.startswith(".")] +files.sort() + +if args.o: + for f in files: + print(f) +else: + print(' '.join(files)) + From dc2226755b19644a9124afdf08fb46f2b2178a83 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Wed, 22 Oct 2025 21:49:47 +0100 Subject: [PATCH 2/9] Implement cat command --- implement-shell-tools/cat/cat.py | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 implement-shell-tools/cat/cat.py diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..776dfcfe3 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,40 @@ +import argparse +import sys + +# def main(): +parser = argparse.ArgumentParser( + prog="Implment cat command", + description="cat is used to display the content of a file." + ) +parser.add_argument('-n', action='store_true', help='number output lines') +parser.add_argument('-b', action='store_true', help='number non-empty output lines') +parser.add_argument('paths', nargs='+', help="The file path(s) to process") + +args = parser.parse_args() + + +for path in args.paths: + with open(path, 'r') as f: + content= f.read() + + if args.b: + line_num = 1 + lines_arr = [] + + for line in content.split('\n'): + if line.strip() == '': + lines_arr.append(line) + else: + lines_arr.append(f"{line_num:6} {line}") + line_num += 1 + sys.stdout.write('\n'.join(lines_arr) + '\n') + + elif args.n: + lines_arr = [ + f"{i+1:6} {line}" + for i, line in enumerate(content.split('\n')) + ] + sys.stdout.write('\n'.join(lines_arr) + '\n') + + else: + sys.stdout.write(content) From 33da6dc93237ff05b5793955c901399288e090c5 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Wed, 22 Oct 2025 23:19:22 +0100 Subject: [PATCH 3/9] Implement wc command with py --- implement-shell-tools/wc/wc.py | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 implement-shell-tools/wc/wc.py diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 000000000..6c1c20df7 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,69 @@ +import argparse + + +parser = argparse.ArgumentParser( + prog="Implment wc command", + description="Count lines, words, and characters in text files." +) + +parser.add_argument("paths", nargs='+', type=str, help="The path to process") +parser.add_argument('-l', action="store_true", help='Ouput number of lines') +parser.add_argument('-w', action="store_true", help='Ouput number of words') +parser.add_argument('-c', action="store_true", help='Ouput number of characters') + +args = parser.parse_args() +is_lines_option = args.l +is_words_option = args.w +is_chars_option = args.c +output_list = [] +output_total=[] +total_lines = 0 +total_words = 0 +total_chars = 0 + +for path in args.paths: + with open(path, 'r') as f: + content= f.read() + + line_count = content.count('\n') + word_count = len(content.split()) + char_count = len(content) + + total_lines += line_count + total_words += word_count + total_chars += char_count + + file_output = [] + + if not (args.l or args.w or args.c): + file_output = [str(line_count), str(word_count), str(char_count)] + else: + if args.l: + file_output.append(str(line_count)) + if args.w: + file_output.append(str(word_count)) + if args.c: + file_output.append(str(char_count)) + + file_output.append(path) + output_list.append(" ".join(file_output)) + +print("\n".join(output_list)) + + + +if len(args.paths) > 1: + if not (args.l or args.w or args.c): + output_total = [str(total_lines), str(total_words), str(total_chars)] + + else: + if args.l: + output_total.append(str(total_lines)) + if args.w: + output_total.append(str(total_words)) + if args.c: + output_total.append(str(total_chars)) + + output_total.append("total") + print(" ".join(output_total)) + \ No newline at end of file From af697217e4bf87e36e471492428b20c29c545eeb Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 12:27:22 +0000 Subject: [PATCH 4/9] refactor splitline method and print --- implement-shell-tools/cat/cat.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 776dfcfe3..7ce3d0b69 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -21,13 +21,15 @@ line_num = 1 lines_arr = [] - for line in content.split('\n'): + for line in content.splitlines(): if line.strip() == '': lines_arr.append(line) else: lines_arr.append(f"{line_num:6} {line}") line_num += 1 - sys.stdout.write('\n'.join(lines_arr) + '\n') + # sys.stdout.write('\n'.join(lines_arr) + '\n') + print('\n'.join(lines_arr) + '\n') + elif args.n: lines_arr = [ From 27d97d09db875ce2e3baa6ed85848503850a85d7 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 12:38:16 +0000 Subject: [PATCH 5/9] Change o flag to 1 for display per line --- implement-shell-tools/ls/ls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index b98b5d170..21afbf609 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -7,7 +7,7 @@ ) parser.add_argument("-a", action="store_true", help="Display all files include hidden files") -parser.add_argument("-o", action="store_true", help="list one file per line") +parser.add_argument("-1", action="store_true", help="list one file per line") parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") args = parser.parse_args() @@ -18,7 +18,7 @@ files = [f for f in files if not f.startswith(".")] files.sort() -if args.o: +if args.__dict__["1"]: for f in files: print(f) else: From d9592376f18fdb289d79f64f5bc3f3f3a0e900f6 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 13:03:37 +0000 Subject: [PATCH 6/9] refactoring --- implement-shell-tools/ls/ls.py | 81 +++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index 21afbf609..c18f7caff 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -1,26 +1,73 @@ import argparse import os -parser = argparse.ArgumentParser( - prog="Implement ls command in Python", - description="List files in a directory" - ) +def main(): + parser = argparse.ArgumentParser( + prog="Implement ls command in Python", + description="List files in a directory" + ) + parser.add_argument("paths", nargs='+', help="Path(s) to process") + parser.add_argument("-a", action="store_true", help="Display all files include hidden files") + parser.add_argument("-1", action="store_true", help="list one file per line") + parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") -parser.add_argument("-a", action="store_true", help="Display all files include hidden files") -parser.add_argument("-1", action="store_true", help="list one file per line") -parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") + args = parser.parse_args() -args = parser.parse_args() + + total_lines = total_words = total_chars = 0 + outputs = [] -files = os.listdir(args.dir) + for path in args.paths: + line_count, word_count, char_count = wc(path) + total_lines += line_count + total_words += word_count + total_chars += char_count + outputs.append(format_output((line_count, word_count, char_count), path, args)) -if not args.a: - files = [f for f in files if not f.startswith(".")] -files.sort() + print("\n".join(outputs)) -if args.__dict__["1"]: - for f in files: - print(f) -else: - print(' '.join(files)) + # Print totals if multiple files + if len(args.paths) > 1: + totals = [] + if not (args.l or args.w or args.c): + totals = [str(total_lines), str(total_words), str(total_chars)] + else: + if args.l: + totals.append(str(total_lines)) + if args.w: + totals.append(str(total_words)) + if args.c: + totals.append(str(total_chars)) + totals.append("total") + print(" ".join(totals)) +def wc(path): + """Return (line_count, word_count, char_count) for the given file.""" + with open(path, 'r') as f: + content = f.read() + line_count = content.count('\n') + word_count = len(content.split()) + char_count = len(content) + return line_count, word_count, char_count + + +def format_output(counts, path, args): + """Format output for a single file based on provided flags.""" + line_count, word_count, char_count = counts + parts = [] + + if not (args.l or args.w or args.c): + parts = [str(line_count), str(word_count), str(char_count)] + else: + if args.l: + parts.append(str(line_count)) + if args.w: + parts.append(str(word_count)) + if args.c: + parts.append(str(char_count)) + + parts.append(path) + return " ".join(parts) + +if __name__ == "__main__": + main() \ No newline at end of file From cde860bdf691404600192e5bf3291bab3909e3f1 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 21:24:26 +0000 Subject: [PATCH 7/9] remove comment line --- implement-shell-tools/cat/cat.py | 1 - 1 file changed, 1 deletion(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 7ce3d0b69..cea347863 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -27,7 +27,6 @@ else: lines_arr.append(f"{line_num:6} {line}") line_num += 1 - # sys.stdout.write('\n'.join(lines_arr) + '\n') print('\n'.join(lines_arr) + '\n') From 3f4d46348b5134cc19d90a36ed2d9bded2544301 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 21:41:23 +0000 Subject: [PATCH 8/9] Revert "refactoring" This reverts commit d9592376f18fdb289d79f64f5bc3f3f3a0e900f6. --- implement-shell-tools/ls/ls.py | 81 +++++++--------------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index c18f7caff..21afbf609 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -1,73 +1,26 @@ import argparse import os -def main(): - parser = argparse.ArgumentParser( - prog="Implement ls command in Python", - description="List files in a directory" - ) - parser.add_argument("paths", nargs='+', help="Path(s) to process") - parser.add_argument("-a", action="store_true", help="Display all files include hidden files") - parser.add_argument("-1", action="store_true", help="list one file per line") - parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") +parser = argparse.ArgumentParser( + prog="Implement ls command in Python", + description="List files in a directory" + ) - args = parser.parse_args() +parser.add_argument("-a", action="store_true", help="Display all files include hidden files") +parser.add_argument("-1", action="store_true", help="list one file per line") +parser.add_argument("dir", nargs="?", default=".", help="Directory to list, default curent directory") - - total_lines = total_words = total_chars = 0 - outputs = [] +args = parser.parse_args() - for path in args.paths: - line_count, word_count, char_count = wc(path) - total_lines += line_count - total_words += word_count - total_chars += char_count - outputs.append(format_output((line_count, word_count, char_count), path, args)) +files = os.listdir(args.dir) - print("\n".join(outputs)) +if not args.a: + files = [f for f in files if not f.startswith(".")] +files.sort() - # Print totals if multiple files - if len(args.paths) > 1: - totals = [] - if not (args.l or args.w or args.c): - totals = [str(total_lines), str(total_words), str(total_chars)] - else: - if args.l: - totals.append(str(total_lines)) - if args.w: - totals.append(str(total_words)) - if args.c: - totals.append(str(total_chars)) - totals.append("total") - print(" ".join(totals)) +if args.__dict__["1"]: + for f in files: + print(f) +else: + print(' '.join(files)) -def wc(path): - """Return (line_count, word_count, char_count) for the given file.""" - with open(path, 'r') as f: - content = f.read() - line_count = content.count('\n') - word_count = len(content.split()) - char_count = len(content) - return line_count, word_count, char_count - - -def format_output(counts, path, args): - """Format output for a single file based on provided flags.""" - line_count, word_count, char_count = counts - parts = [] - - if not (args.l or args.w or args.c): - parts = [str(line_count), str(word_count), str(char_count)] - else: - if args.l: - parts.append(str(line_count)) - if args.w: - parts.append(str(word_count)) - if args.c: - parts.append(str(char_count)) - - parts.append(path) - return " ".join(parts) - -if __name__ == "__main__": - main() \ No newline at end of file From ff6eb2c9afe67412d332727efec5636349f882b8 Mon Sep 17 00:00:00 2001 From: Rihanna P <114884466+RihannaP@users.noreply.github.com> Date: Mon, 27 Oct 2025 22:10:17 +0000 Subject: [PATCH 9/9] Impement main function for wc --- implement-shell-tools/wc/wc.py | 86 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 6c1c20df7..79678e45e 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -1,40 +1,31 @@ import argparse +def parse_arguments(): + parser = argparse.ArgumentParser( + prog="Implment wc command", + description="Count lines, words, and characters in text files." + ) -parser = argparse.ArgumentParser( - prog="Implment wc command", - description="Count lines, words, and characters in text files." -) + parser.add_argument("paths", nargs='+', type=str, help="The path to process") + parser.add_argument('-l', action="store_true", help='Ouput number of lines') + parser.add_argument('-w', action="store_true", help='Ouput number of words') + parser.add_argument('-c', action="store_true", help='Ouput number of characters') + return parser.parse_args() -parser.add_argument("paths", nargs='+', type=str, help="The path to process") -parser.add_argument('-l', action="store_true", help='Ouput number of lines') -parser.add_argument('-w', action="store_true", help='Ouput number of words') -parser.add_argument('-c', action="store_true", help='Ouput number of characters') - -args = parser.parse_args() -is_lines_option = args.l -is_words_option = args.w -is_chars_option = args.c -output_list = [] -output_total=[] -total_lines = 0 -total_words = 0 -total_chars = 0 -for path in args.paths: +def wc(path): with open(path, 'r') as f: content= f.read() line_count = content.count('\n') word_count = len(content.split()) char_count = len(content) - - total_lines += line_count - total_words += word_count - total_chars += char_count + return line_count, word_count, char_count + +def format_output(path, counts, args): + line_count, word_count, char_count = counts file_output = [] - if not (args.l or args.w or args.c): file_output = [str(line_count), str(word_count), str(char_count)] else: @@ -46,24 +37,39 @@ file_output.append(str(char_count)) file_output.append(path) - output_list.append(" ".join(file_output)) + return(" ".join(file_output)) -print("\n".join(output_list)) +def main(): + args = parse_arguments() + total_lines = total_words = total_chars = 0 + output_lines =[] + for path in args.paths: + line_count, word_count, char_count = wc(path) + total_lines += line_count + total_words += word_count + total_chars += char_count + output_lines.append(format_output(path, (line_count, word_count, char_count), args)) + + print("\n".join(output_lines)) -if len(args.paths) > 1: - if not (args.l or args.w or args.c): - output_total = [str(total_lines), str(total_words), str(total_chars)] + if len(args.paths) > 1: + output_total =[] + if not (args.l or args.w or args.c): + output_total = [str(total_lines), str(total_words), str(total_chars)] - else: - if args.l: - output_total.append(str(total_lines)) - if args.w: - output_total.append(str(total_words)) - if args.c: - output_total.append(str(total_chars)) - - output_total.append("total") - print(" ".join(output_total)) - \ No newline at end of file + else: + if args.l: + output_total.append(str(total_lines)) + if args.w: + output_total.append(str(total_words)) + if args.c: + output_total.append(str(total_chars)) + + output_total.append("total") + print(" ".join(output_total)) + + +if __name__ == "__main__": + main() \ No newline at end of file