From 116b25ef4b49a927c542978015f78ee9b7ecda1a Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 27 Aug 2026 14:03:41 +0100 Subject: [PATCH 1/2] Implement shell tools in Python --- implement-shell-tools/cat/cat.py | 21 +++++++++ implement-shell-tools/ls/ls.py | 42 +++++++++++++++++ implement-shell-tools/wc/wc.py | 77 ++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 implement-shell-tools/cat/cat.py create mode 100644 implement-shell-tools/ls/ls.py create mode 100644 implement-shell-tools/wc/wc.py diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..137e6cf9b --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,21 @@ +import sys + +if sys.argv[1] == "-n" or sys.argv[1] == "-b": + filenames = sys.argv[2:] +else: + filenames = sys.argv[1:] +line_number = 1 +for filename in filenames: + file = open(filename) + for line in file: + if sys.argv[1] == "-n": + print(line_number, line, end = "") + line_number += 1 + elif sys.argv[1]== "-b": + if line.strip() != "": + print(line_number, line, end = "") + line_number += 1 + else: + print(line, end="") + else: + print(line, end = "") diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py new file mode 100644 index 000000000..d7675c560 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,42 @@ +import sys +import os + +show_all = "-a" in sys.argv +one_per_line = "-1" in sys.argv + +paths = [] + +for argument in sys.argv[1:]: + if not argument.startswith("-"): + paths.append(argument) + +if not paths: + paths.append(".") + +for path in paths: + if os.path.isfile(path): + if len(paths) == 1 or one_per_line: + print(path) + else: + print(path, end = (" ")) + else: + if len(paths) > 1: + print() + print() + print(path + ":") + + files = sorted(os.listdir(path)) + + if show_all: + files = ["."] + [".."] + files + + for file in files: + if show_all or not file.startswith("."): + if one_per_line: + print(file) + else: + print(file, end=(" ")) + if not one_per_line: + print() + + diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 000000000..ab8ad16d0 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,77 @@ +import sys +import os + +count_lines = "-l" in sys.argv +count_words = "-w" in sys.argv +count_bytes = "-c" in sys.argv +filenames = [] + +for argument in sys.argv[1:]: + if not argument.startswith("-"): + filenames.append(argument) + +total_lines = 0 +total_words = 0 +total_bytes = 0 + +for filename in filenames: + file = open(filename) + + line_count = 0 + word_count = 0 + + for line in file: + line_count += 1 + word_count += len(line.split()) + byte_count = os.path.getsize(filename) + + total_lines += line_count + total_words += word_count + total_bytes += byte_count + + output = [] + + if count_lines: + output.append(line_count) + + if count_words: + output.append(word_count) + + if count_bytes: + output.append(byte_count) + + + if not count_lines and not count_words and not count_bytes: + output.append(line_count) + output.append(word_count) + output.append(byte_count) + + formatted_output = [] + + for number in output: + formatted_output.append(f"{number:3}") + + print(" ".join(formatted_output), filename) + +if len(filenames) > 1: + total_output = [] + + if count_lines: + total_output.append(total_lines) + + if count_words: + total_output.append(total_words) + + if count_bytes: + total_output.append(total_bytes) + + if not count_lines and not count_words and not count_bytes: + total_output.append(total_lines) + total_output.append(total_words) + total_output.append(total_bytes) + + formatted_total = [] + + for number in total_output: + formatted_total.append(f"{number:3}") + print(" ".join(formatted_total), "total") From 403ac52f494bfba8402497c799edd7c2ce64fecf Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Fri, 4 Sep 2026 11:06:58 +0100 Subject: [PATCH 2/2] Add a function to avoid duplication. --- implement-shell-tools/wc/wc.py | 68 +++++++++++++++------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index ab8ad16d0..a36d5e694 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -4,31 +4,14 @@ count_lines = "-l" in sys.argv count_words = "-w" in sys.argv count_bytes = "-c" in sys.argv + filenames = [] for argument in sys.argv[1:]: if not argument.startswith("-"): filenames.append(argument) -total_lines = 0 -total_words = 0 -total_bytes = 0 - -for filename in filenames: - file = open(filename) - - line_count = 0 - word_count = 0 - - for line in file: - line_count += 1 - word_count += len(line.split()) - byte_count = os.path.getsize(filename) - - total_lines += line_count - total_words += word_count - total_bytes += byte_count - +def format_counts(line_count, word_count, byte_count): output = [] if count_lines: @@ -40,7 +23,6 @@ if count_bytes: output.append(byte_count) - if not count_lines and not count_words and not count_bytes: output.append(line_count) output.append(word_count) @@ -51,27 +33,35 @@ for number in output: formatted_output.append(f"{number:3}") - print(" ".join(formatted_output), filename) + return " ".join(formatted_output) -if len(filenames) > 1: - total_output = [] +total_lines = 0 +total_words = 0 +total_bytes = 0 - if count_lines: - total_output.append(total_lines) +for filename in filenames: + file = open(filename) - if count_words: - total_output.append(total_words) + line_count = 0 + word_count = 0 - if count_bytes: - total_output.append(total_bytes) + for line in file: + line_count += 1 + word_count += len(line.split()) - if not count_lines and not count_words and not count_bytes: - total_output.append(total_lines) - total_output.append(total_words) - total_output.append(total_bytes) - - formatted_total = [] - - for number in total_output: - formatted_total.append(f"{number:3}") - print(" ".join(formatted_total), "total") + byte_count = os.path.getsize(filename) + + total_lines += line_count + total_words += word_count + total_bytes += byte_count + + print( + format_counts(line_count, word_count, byte_count), + filename, + ) + +if len(filenames) > 1: + print( + format_counts(total_lines, total_words, total_bytes), + "total", + )