From 7305e8f772fd7ef7739193f8148b89e3cb7724f1 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 12:57:05 +0100 Subject: [PATCH 01/16] cat-read-single-file --- implement-shell-tools/cat/cat.py | 11 +++++++++++ 1 file changed, 11 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..9959c3be7 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,11 @@ +import argparse + +parser = argparse.ArgumentParser(prog="cat", description="Prints the output of a file to the console") +parser.add_argument("-n", "--number", help="Displays the lines along with their number") +parser.add_argument("path", help="The file path", nargs="+") + +args = parser.parse_args() + +f = open(args.path[0]) + +print(f.read()) \ No newline at end of file From 3baaa843aa906ad7f269805d4f3075b199d44ac9 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 13:00:15 +0100 Subject: [PATCH 02/16] cat-read-multiple-files --- implement-shell-tools/cat/cat.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 9959c3be7..023088107 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -6,6 +6,10 @@ args = parser.parse_args() -f = open(args.path[0]) +text = "" -print(f.read()) \ No newline at end of file +for file in args.path: + f = open(file) + text += f.read() + +print(text) \ No newline at end of file From 0a8c55d711d90aae855d95212a54de4fe1854790 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 15:48:46 +0100 Subject: [PATCH 03/16] -n flag --- implement-shell-tools/cat/cat.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 023088107..f221fe83c 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -1,15 +1,27 @@ import argparse parser = argparse.ArgumentParser(prog="cat", description="Prints the output of a file to the console") -parser.add_argument("-n", "--number", help="Displays the lines along with their number") +parser.add_argument("-n", "--number", help="Displays the lines along with their number", action="store_true") parser.add_argument("path", help="The file path", nargs="+") args = parser.parse_args() +show_lines = args.number + text = "" +i = 1 for file in args.path: f = open(file) text += f.read() -print(text) \ No newline at end of file +text_list = text.split("\n") +text_list.pop(len(text_list) - 1) + +if (show_lines == False): + print("\n".join(text_list)) + exit() + +for line in text_list: + print(" " + str(i) + " " + line) + i += 1 \ No newline at end of file From 5ce26516d35da529b368373e4e1cea69c5c0bff1 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 16:15:34 +0100 Subject: [PATCH 04/16] -b flag --- implement-shell-tools/cat/cat.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index f221fe83c..15060d596 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -2,11 +2,13 @@ parser = argparse.ArgumentParser(prog="cat", description="Prints the output of a file to the console") parser.add_argument("-n", "--number", help="Displays the lines along with their number", action="store_true") +parser.add_argument("-b", "--nonblank", help="Displays the lines along with their number", action="store_true") parser.add_argument("path", help="The file path", nargs="+") args = parser.parse_args() show_lines = args.number +non_blank = args.nonblank text = "" i = 1 @@ -18,10 +20,16 @@ text_list = text.split("\n") text_list.pop(len(text_list) - 1) -if (show_lines == False): +if (show_lines == False and non_blank == False): print("\n".join(text_list)) exit() for line in text_list: - print(" " + str(i) + " " + line) - i += 1 \ No newline at end of file + if non_blank == True and line != "": + print(" " + str(i) + " " + line) + i += 1 + elif non_blank == False: + print(" " + str(i) + " " + line) + i += 1 + else: + print("") \ No newline at end of file From e31edff0a15020ce30369abf71b8b3f44b23cfca Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 16:21:09 +0100 Subject: [PATCH 05/16] cat - complete --- implement-shell-tools/cat/cat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 15060d596..db86859b9 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -2,7 +2,7 @@ parser = argparse.ArgumentParser(prog="cat", description="Prints the output of a file to the console") parser.add_argument("-n", "--number", help="Displays the lines along with their number", action="store_true") -parser.add_argument("-b", "--nonblank", help="Displays the lines along with their number", action="store_true") +parser.add_argument("-b", "--nonblank", help="Displays the lines along with their number skipping the blank lines", action="store_true") parser.add_argument("path", help="The file path", nargs="+") args = parser.parse_args() From 64cfdd2f10470686662dab8d2934f57bc7855613 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 16:30:54 +0100 Subject: [PATCH 06/16] cat: error --- implement-shell-tools/cat/cat.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index db86859b9..14df1dd5c 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -10,6 +10,10 @@ show_lines = args.number non_blank = args.nonblank +if show_lines == True and non_blank == True: + print("Error: Cannot use -n and -b together. Please use only one flag at a time.") + exit() + text = "" i = 1 From 21c46a6041cb22e8933113c61c73401a613412c1 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 17:11:02 +0100 Subject: [PATCH 07/16] ls: Init --- implement-shell-tools/ls/ls.py | 9 +++++++++ 1 file changed, 9 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..0e4a21a11 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,9 @@ +import argparse + +parser = argparse.ArgumentParser(prog="ls", description="List directory contents. Ignore files and directories starting with a '.' by default") +parser.add_argument("-1", help="List one file per line.", action="store_true") +parser.add_argument("-a", help="Do not ignore hidden files (files with names that start with '.').", action="store_true") +parser.add_argument("path", help="The directory path (optional).", default=".", nargs="?") + +args = parser.parse_args() + From 2bcbf2f97c4fae943f8a4317c99e9823479bbb09 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 18:51:01 +0100 Subject: [PATCH 08/16] ls: -a flag --- implement-shell-tools/ls/ls.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index 0e4a21a11..efa00dff9 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -1,4 +1,5 @@ import argparse +from os import listdir parser = argparse.ArgumentParser(prog="ls", description="List directory contents. Ignore files and directories starting with a '.' by default") parser.add_argument("-1", help="List one file per line.", action="store_true") @@ -7,3 +8,16 @@ args = parser.parse_args() +path = args.path + +show_hidden = args.a + +contents = [] + +for f in listdir(path): + if show_hidden == False and f[0] != ".": + contents.append(f) + if show_hidden == True: + contents.append(f) + +print(contents) From 9901396e67f24bda7a248ac892473282c113d442 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 18:54:09 +0100 Subject: [PATCH 09/16] ls: -a flag format --- implement-shell-tools/ls/ls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index efa00dff9..a7926d112 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -20,4 +20,4 @@ if show_hidden == True: contents.append(f) -print(contents) +print(" ".join(contents)) From 4b88392c2087e29148cf9462a1e43bc4e7172ee0 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Wed, 8 Apr 2026 19:07:20 +0100 Subject: [PATCH 10/16] ls: complete --- implement-shell-tools/ls/ls.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index a7926d112..ee4cc588d 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -2,7 +2,7 @@ from os import listdir parser = argparse.ArgumentParser(prog="ls", description="List directory contents. Ignore files and directories starting with a '.' by default") -parser.add_argument("-1", help="List one file per line.", action="store_true") +parser.add_argument("-1", dest="one", help="List one file per line.", action="store_true") parser.add_argument("-a", help="Do not ignore hidden files (files with names that start with '.').", action="store_true") parser.add_argument("path", help="The directory path (optional).", default=".", nargs="?") @@ -11,6 +11,7 @@ path = args.path show_hidden = args.a +one_per_line = args.one contents = [] @@ -19,5 +20,10 @@ contents.append(f) if show_hidden == True: contents.append(f) - -print(" ".join(contents)) + +contents.sort() + +if one_per_line == True: + print("\n".join(contents)) +else: + print(" ".join(contents)) From 02de8137db04e6414c8152bffc999fac3df0ce74 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Thu, 9 Apr 2026 16:00:15 +0100 Subject: [PATCH 11/16] Create dictionary --- implement-shell-tools/wc/wc.py | 22 ++++++++++++++++++++++ 1 file changed, 22 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..a0da8bd22 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,22 @@ +import argparse + +parser = argparse.ArgumentParser(prog="wc", description="Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified.") +parser.add_argument("-w", "--words", help="print the word counts", action="store_true") +parser.add_argument("-l", "--line", help="print the newline counts", action="store_true") +parser.add_argument("-c", "--bytes", help="print the byte counts", action="store_true") +parser.add_argument("path", help="The file path", nargs="+") + +args = parser.parse_args() + +dict = {} + +for file in args.path: + f = open(file) + text = [] + text.append(f.read()) + dict[file] = text + +for f in dict: + print(dict[f]) + +# print(dict) \ No newline at end of file From 466c00724694e9a59b154e75694e02486f83be9f Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Thu, 9 Apr 2026 17:24:59 +0100 Subject: [PATCH 12/16] wc: line and word count --- implement-shell-tools/wc/wc.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index a0da8bd22..44ab3712a 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -8,15 +8,25 @@ args = parser.parse_args() +lines = 0 +words = 0 +bytes = 0 + dict = {} for file in args.path: f = open(file) - text = [] - text.append(f.read()) - dict[file] = text - + # text = [] + # text.append(f.read().split("\n")) + # print(f.read().split("\n")) + dict[file] = f.read().split("\n") +# print(dict) for f in dict: - print(dict[f]) + word_per_line = 0 + byte_per_line = 0 + for l in dict[f]: + word_per_line += len(l.split()) + byte_per_line += len(l.encode("utf-8")) + # print(byte_per_line) + print(str(len(dict[f]) - 1) + " " + str(word_per_line) + " " + f) -# print(dict) \ No newline at end of file From f0dc6b0822e89bce6a8576beb78253ced9c7aae4 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Thu, 9 Apr 2026 18:34:12 +0100 Subject: [PATCH 13/16] wc: byte count --- implement-shell-tools/wc/wc.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 44ab3712a..8100eba7e 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -13,20 +13,21 @@ bytes = 0 dict = {} +adict = {} for file in args.path: f = open(file) - # text = [] - # text.append(f.read().split("\n")) - # print(f.read().split("\n")) dict[file] = f.read().split("\n") -# print(dict) + adict[file] = f.read() + +for file in args.path: + f = open(file) + adict[file] = f.read() + for f in dict: word_per_line = 0 byte_per_line = 0 - for l in dict[f]: + for l in adict[f]: word_per_line += len(l.split()) byte_per_line += len(l.encode("utf-8")) - # print(byte_per_line) - print(str(len(dict[f]) - 1) + " " + str(word_per_line) + " " + f) - + print(" " + str(len(dict[f]) - 1) + " " + str(word_per_line) + " " + str(byte_per_line) + " " + f) \ No newline at end of file From 15d73bebd3c32a809c8b674892fd21011293aea3 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Thu, 9 Apr 2026 19:00:55 +0100 Subject: [PATCH 14/16] Print helper --- implement-shell-tools/wc/wc.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 8100eba7e..6210eb573 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -12,6 +12,10 @@ words = 0 bytes = 0 +l = True +w = True +c = True + dict = {} adict = {} @@ -24,10 +28,31 @@ f = open(file) adict[file] = f.read() +def print_helper(line, word, byte, file_name): + text = [" "] + if l == True: + text.append(str(line)) + text.append(" ") + if w == True: + text.append(str(word)) + text.append(" ") + if c == True: + text.append(str(byte)) + text.append(" ") + text.append(file_name) + print("".join(text)) + for f in dict: word_per_line = 0 byte_per_line = 0 - for l in adict[f]: - word_per_line += len(l.split()) - byte_per_line += len(l.encode("utf-8")) - print(" " + str(len(dict[f]) - 1) + " " + str(word_per_line) + " " + str(byte_per_line) + " " + f) \ No newline at end of file + for line in dict[f]: + word_per_line += len(line.split()) + for line in adict[f]: + byte_per_line += len(line.encode("utf-8")) + lines += len(dict[f]) - 1 + words += word_per_line + bytes += byte_per_line + print_helper(len(dict[f]) - 1, word_per_line, byte_per_line, f) + +if len(args.path) > 1: + print_helper(lines, words, bytes, "total") \ No newline at end of file From f89d3d824dceecc707fc87c37180c8a022cd2cd4 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Fri, 10 Apr 2026 10:01:08 +0100 Subject: [PATCH 15/16] Add flag support --- implement-shell-tools/wc/wc.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 6210eb573..8e58b3e72 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -16,6 +16,11 @@ w = True c = True +if args.words == True or args.line == True or args.bytes == True: + l = args.line + w = args.words + c = args.bytes + dict = {} adict = {} From 4a8a83ed5d3e04d9827fc8bec7bbcb8cf2817601 Mon Sep 17 00:00:00 2001 From: Craig D'Silva Date: Fri, 10 Apr 2026 10:06:23 +0100 Subject: [PATCH 16/16] Proper variable names for dicts --- implement-shell-tools/wc/wc.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 8e58b3e72..1b31aa20d 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -21,17 +21,16 @@ w = args.words c = args.bytes -dict = {} -adict = {} +file_data = {} +file_data_with_newline = {} for file in args.path: f = open(file) - dict[file] = f.read().split("\n") - adict[file] = f.read() + file_data[file] = f.read().split("\n") for file in args.path: f = open(file) - adict[file] = f.read() + file_data_with_newline[file] = f.read() def print_helper(line, word, byte, file_name): text = [" "] @@ -47,17 +46,17 @@ def print_helper(line, word, byte, file_name): text.append(file_name) print("".join(text)) -for f in dict: +for f in file_data: word_per_line = 0 byte_per_line = 0 - for line in dict[f]: + for line in file_data[f]: word_per_line += len(line.split()) - for line in adict[f]: + for line in file_data_with_newline[f]: byte_per_line += len(line.encode("utf-8")) - lines += len(dict[f]) - 1 + lines += len(file_data[f]) - 1 words += word_per_line bytes += byte_per_line - print_helper(len(dict[f]) - 1, word_per_line, byte_per_line, f) + print_helper(len(file_data[f]) - 1, word_per_line, byte_per_line, f) if len(args.path) > 1: print_helper(lines, words, bytes, "total") \ No newline at end of file