Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"main"
]
}
44 changes: 44 additions & 0 deletions implement-shell-tools/cat/cat.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested that the numbering is working correctly when multiple files are passed in?

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
import argparse

# implement-shell-tools/cat/cat.py
def main():
parser = argparse.ArgumentParser(
prog="cat",
description="Implements a simple version of the 'cat' command to read and display file contents."
)

parser.add_argument("-n", help="Number lines", action="store_true")
parser.add_argument("-b", help="Number non-blank lines", action="store_true")
parser.add_argument("path", nargs="+", help="The file to search")

args = parser.parse_args()

for file_path in args.path:
try:
with open(file_path, 'r') as file:
content = file.read()
lines = content.split("\n")
line_number = 1
non_blank_line_number = 1

for i, line in enumerate(lines):
if i == len(lines) - 1 and line == "": # Skip the last empty line if it exists
break
prefix = ""
if args.n:
prefix = str(line_number).rjust(6) + " "
elif args.b and line != "":
prefix = str(non_blank_line_number).rjust(6) + " "
print(prefix + line)
line_number += 1
if line != "":
non_blank_line_number += 1

except FileNotFoundError:
print(f"cat: {file_path}: No such file or directory")
except Exception as e:
print(f"cat: {file_path}: {e}")

if __name__ == "__main__":
main()
36 changes: 36 additions & 0 deletions implement-shell-tools/ls/ls.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested to make sure your -1 argument is working correctly?

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import argparse
import os

# implement-shell-tools/ls/ls.py
def main():
parser = argparse.ArgumentParser(
prog="ls",
description="Implements a simple version of the 'ls' command to list files in a directory."
)

parser.add_argument("-1", help="", action="store_true")
parser.add_argument("-a", help="", action="store_true")
parser.add_argument("directory", nargs="?", default=".", help="The directory to search")

args = parser.parse_args()

try:
files = os.listdir(args.directory)

if not args.a:
files = [f for f in files if not f.startswith(".")]

files = sorted(files)

for f in files:
print(f)

except FileNotFoundError:
print(f"ls: {args.directory}: No such file or directory")
except NotADirectoryError:
print(args.directory)
except Exception as e:
print(f"ls: {args.directory}: {e}")

if __name__ == "__main__":
main()
67 changes: 67 additions & 0 deletions implement-shell-tools/wc/wc.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some duplication in this code, can you have a look at reducing it?

Also, when you are outputting, make sure that the indentation is working right.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import argparse
import sys

# implement-shell-tools/wc/wc.py
def wc_file(path):
"""Return (lines, words, bytes) for a given file."""
with open(path, "r", encoding="utf-8") as f:
text = f.read()
lines = text.count("\n")
words = len(text.split())
chars = len(text.encode("utf-8")) # byte count
return lines, words, chars


def main():
parser = argparse.ArgumentParser(
prog="wc",
description="Implements a simple version of the 'wc' command to count lines, words, and characters in text files."
)

parser.add_argument("-l", action="store_true", help="Count lines")
parser.add_argument("-w", action="store_true", help="Count words")
parser.add_argument("-c", action="store_true", help="Count characters")
parser.add_argument("path", nargs="+", help="The files to read")

args = parser.parse_args()

if not (args.l or args.w or args.c):
args.l = args.w = args.c = True # Default to all counts if none specified

total_lines = total_words = total_chars = 0

for file_path in args.path:
try:
lines, words, chars = wc_file(file_path)
total_lines += lines
total_words += words
total_chars += chars

counts = []
if args.l:
counts.append(str(lines))
if args.w:
counts.append(str(words))
if args.c:
counts.append(str(chars))
counts.append(file_path)
print(" ".join(counts))

except FileNotFoundError:
print(f"wc: {file_path}: No such file or directory", file=sys.stderr)
except Exception as e:
print(f"wc: {file_path}: {e}", file=sys.stderr)

if len(args.path) > 1:
counts = []
if args.l:
counts.append(str(total_lines))
if args.w:
counts.append(str(total_words))
if args.c:
counts.append(str(total_chars))
counts.append("total")
print(" ".join(counts))

if __name__ == "__main__":
main()
Loading