From 8a9931b25f0a3ab8ad0cfc643f6b5dea902c5824 Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Wed, 1 Apr 2026 11:48:47 +0100 Subject: [PATCH 1/6] Ignore virtual environment --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3c3629e64..2ab7bcc2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ node_modules +.venv/ +__pycache__/ +*.pyc \ No newline at end of file From a79265c04e79c011b38f802f111f50e508994e16 Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Wed, 1 Apr 2026 13:10:40 +0100 Subject: [PATCH 2/6] cat with python completed --- implement-shell-tools/cat/cat.py | 48 ++++++++++++++++++++++ implement-shell-tools/cat/requirements.txt | 1 + 2 files changed, 49 insertions(+) create mode 100644 implement-shell-tools/cat/cat.py create mode 100644 implement-shell-tools/cat/requirements.txt diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..594c6d902 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,48 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="cat shell tool", + description="making cat tool with oython" +) + +parser.add_argument( + "files", + nargs="+", + help="file to read" +) + +parser.add_argument( + "-n", + "--number", + action="store_true", + help="add number to the lines" +) + +parser.add_argument( + "-b", + "--number_nonblank", + action="store_true", + help="does not number the blank lines" +) + +args = parser.parse_args() + +number_line = 0 +for file in args.files: + with open(file, "r") as f: + lines = f.readlines() + + for line in lines: + if args.number_nonblank: + if line.strip(): + number_line += 1 + print(f"{number_line} {line}", end="") + elif args.number: + number_line += 1 + print(f"{number_line} {line}", end="") + else: + print(line) + + + + diff --git a/implement-shell-tools/cat/requirements.txt b/implement-shell-tools/cat/requirements.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/implement-shell-tools/cat/requirements.txt @@ -0,0 +1 @@ + From a49c3d432673dd47bd6089579cc6ef4ecf982407 Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Wed, 1 Apr 2026 13:54:29 +0100 Subject: [PATCH 3/6] le with python completed --- implement-shell-tools/ls/ls.py | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 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..c07255552 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,42 @@ +import argparse +import os + +parser = argparse.ArgumentParser( + prog="ls shell tool", + description="making ls tool with python" +) + +parser.add_argument( + "-1", + dest="one_per_line", + action="store_true", + help="lists one per line" +) +parser.add_argument( + "-a", + dest="show_hidden", + action="store_true", + help="show files even hidden files" +) +parser.add_argument( + "items", + nargs="*", #defualt to current directory + help="items to list" +) + +args = parser.parse_args() + +paths = args.items if args.items else ['.'] + +for path in paths: + try: + entries = os.listdir(path) + if not args.show_hidden: + entries = [e for e in entries if not e.startswith(".")] + if args.one_per_line: + for entry in entries: + print(entry) + else: + print(" ".join(entries)) + except: + print(f"ls can not access this directory: {path}") From 04b1d1a71f4bea00e2f29f8915ca9303fe45e13d Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Wed, 1 Apr 2026 16:01:45 +0100 Subject: [PATCH 4/6] wc with python completed --- implement-shell-tools/wc/wc.py | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 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..740fc3cf5 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,51 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="wc shell tool", + description="making wc tool with python" +) + +parser.add_argument( + "files", + nargs="+", + help="file or files to work on" +) +parser.add_argument( + "-w", + action="store_true", + help="counting words" +) +parser.add_argument( + "-l", + action="store_true", + help="counting lines" +) +parser.add_argument( + "-c", + action="store_true", + help="counting char" +) + +args = parser.parse_args() + +for file in args.files: + try: + with open(file, "r") as f: + content = f.read() + word_count= len(content.split()) + line_count = content.count("\n") + char_count = len(content) + if args.w: + print(f"word count of file {file} is : ", word_count) + elif args.l: + + print(f"line count of file {file} is : ", line_count) + elif args.c: + + print(f"char count of file {file} is : ", char_count) + else: + print(f"line: {line_count}, word: {word_count}, char: {char_count}, {file}") + except FileNotFoundError: + print(f"wc: {file}: file or directory not found") + + From 4ddced5d10a2ce95041145705f69a87778604ce0 Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Sat, 6 Jun 2026 21:26:39 +0100 Subject: [PATCH 5/6] update wc --- implement-shell-tools/wc/wc.py | 55 ++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) mode change 100644 => 100755 implement-shell-tools/wc/wc.py diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py old mode 100644 new mode 100755 index 740fc3cf5..a7bbf9b98 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -1,4 +1,5 @@ import argparse +import os parser = argparse.ArgumentParser( prog="wc shell tool", @@ -28,24 +29,54 @@ args = parser.parse_args() +total_lines = 0 +total_words = 0 +total_chars = 0 + for file in args.files: try: - with open(file, "r") as f: + if os.path.isdir(file): + print(f"wc: {file}: read: Is a directory") + continue + + with open(file, "rb") as f: content = f.read() - word_count= len(content.split()) - line_count = content.count("\n") + word_count = len(content.decode('utf-8', errors='ignore').split()) + line_count = content.count(b"\n") char_count = len(content) + + total_lines += line_count + total_words += word_count + total_chars += char_count + + output_parts = [] + if args.l: + output_parts.append(f"{line_count:>7}") if args.w: - print(f"word count of file {file} is : ", word_count) - elif args.l: - - print(f"line count of file {file} is : ", line_count) - elif args.c: + output_parts.append(f"{word_count:>7}") + if args.c: + output_parts.append(f"{char_count:>7}") - print(f"char count of file {file} is : ", char_count) + if not args.w and not args.l and not args.c: + print(f"{line_count:>7}{word_count:>7}{char_count:>7} {file}") else: - print(f"line: {line_count}, word: {word_count}, char: {char_count}, {file}") + output_parts.append(f" {file}") + print("".join(output_parts)) + except FileNotFoundError: - print(f"wc: {file}: file or directory not found") - + print(f"wc: {file}: open: No such file or directory") +if len(args.files) > 1: + total_parts = [] + if args.l: + total_parts.append(f"{total_lines:>7}") + if args.w: + total_parts.append(f"{total_words:>7}") + if args.c: + total_parts.append(f"{total_chars:>7}") + + if not args.w and not args.l and not args.c: + print(f"{total_lines:>7}{total_words:>7}{total_chars:>7} total") + else: + total_parts.append(" total") + print("".join(total_parts)) From 139e3ad2ffbeac7b88a52fa10305337c2e090db0 Mon Sep 17 00:00:00 2001 From: ZabihollahNamazi Date: Fri, 12 Jun 2026 20:59:43 +0100 Subject: [PATCH 6/6] update --- implement-shell-tools/wc/wc.py | 42 +++++++++++++--------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index a7bbf9b98..226e29e76 100755 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -29,10 +29,24 @@ args = parser.parse_args() +show_all = not (args.l or args.w or args.c) total_lines = 0 total_words = 0 total_chars = 0 +def format_output(lines, words, chars, label): + output_parts = [] + + # If the specific flag is requested, or no flags were passed at all + if args.l or show_all: + output_parts.append(f"{lines:>7}") + if args.w or show_all: + output_parts.append(f"{words:>7}") + if args.c or show_all: + output_parts.append(f"{chars:>7}") + + return "".join(output_parts) + f" {label}" + for file in args.files: try: if os.path.isdir(file): @@ -49,34 +63,10 @@ total_words += word_count total_chars += char_count - output_parts = [] - if args.l: - output_parts.append(f"{line_count:>7}") - if args.w: - output_parts.append(f"{word_count:>7}") - if args.c: - output_parts.append(f"{char_count:>7}") - - if not args.w and not args.l and not args.c: - print(f"{line_count:>7}{word_count:>7}{char_count:>7} {file}") - else: - output_parts.append(f" {file}") - print("".join(output_parts)) + print(format_output(line_count, word_count, char_count, file)) except FileNotFoundError: print(f"wc: {file}: open: No such file or directory") if len(args.files) > 1: - total_parts = [] - if args.l: - total_parts.append(f"{total_lines:>7}") - if args.w: - total_parts.append(f"{total_words:>7}") - if args.c: - total_parts.append(f"{total_chars:>7}") - - if not args.w and not args.l and not args.c: - print(f"{total_lines:>7}{total_words:>7}{total_chars:>7} total") - else: - total_parts.append(" total") - print("".join(total_parts)) + print(format_output(total_lines, total_words, total_chars, "total"))