Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
36 changes: 36 additions & 0 deletions implement-shell-tools/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import argparse

parser = argparse.ArgumentParser(
prog="cat",
description="read, display, and concatenate text files.",
)

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

args = parser.parse_args()

for path in args.paths:
try:
with open(path, mode='r', encoding='utf-8') as f:
lines = f.readlines()

except Exception as err:
print(f"Error reading file '{path}': {err}")
continue

line_num = 1

for line in lines:
if args.b:
if line.strip() != "":
print(f"{line_num:5} {line}", end="")
line_num += 1
else:
print()
elif args.n:
print(f"{line_num:5} {line}", end="")
line_num += 1
else:
print(line, end="")
36 changes: 36 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import argparse
import os
import sys

parser = argparse.ArgumentParser(
prog="ls",
description="List all the files in a directory"
)


parser.add_argument("-a", "--all",action="store_true", help="Include hidden files")
parser.add_argument("-1", "--one", action="store_true",help="One entry per line")
parser.add_argument("dir", nargs="?" ,default=".", help="directory to list")


args = parser.parse_args()


try:
# Gets all file names (including hidden ones)
files = os.listdir(args.dir)
except (FileNotFoundError, NotADirectoryError) as err:
print(f"ls: can't access: '{args.dir}': {err}")

Choose a reason for hiding this comment

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

It is good that you are handling errors. Here you are handling a NotADirectoryError. What happens if you try to use the original ls application with a regular file?

sys.exit(1)

visible_names = [
entry for entry in files
if args.all or not entry.startswith(".")
]

visible_names.sort()

if args.one:
print("\n".join(visible_names))
else:
print("\t".join(visible_names))
59 changes: 59 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.

I have a few questions to ask about this file:

  • Why are you making extra variables for lines, words, etc which are the same as the values in the args dictionary?
  • Can you see what happens in your program if you try to combine multiple arguments in one command?
  • Can you see where there is duplication that could be reduced?

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

parser = argparse.ArgumentParser(
prog="wc",
description="Display numbers of line, words, and bytes in each file"
)

parser.add_argument("-l", action="store_true", help="Number of lines")
parser.add_argument("-w", action="store_true" ,help="Number of words")
parser.add_argument("-c", action="store_true" ,help="Number of bytes")
parser.add_argument("paths", nargs="+", help="The file to search")

args = parser.parse_args()

totalLines = 0
totalWords = 0
totalBytes = 0

lines = args.l
words = args.w
bytes = args.c

for path in args.paths:
try:
with open(path, "r") as f:
content = f.read()

except Exception as err:
print(f"Error reading file '{path}': {err}")
continue

lineCount = len(content.split("/n"))
wordCount = len(content.split())
byteCount = os.path.getsize(path)

totalLines += lineCount
totalWords += wordCount
totalBytes += byteCount

if lines:
print(f"\t{lineCount} {path}")
lineCount += 1
elif words:
print(f"\t{wordCount} {path}")
elif bytes:
print(f"\t{byteCount} {path}")
else:
print(f"\t{lineCount} \t{wordCount} \t{byteCount} {path}")

if len(args.paths) > 1:
if lines:
print(f"{totalLines} total")
elif words:
print(f"{totalWords} total")
elif bytes:
print(f"{totalBytes} total")
else:
print(f"\t{totalLines} \t{totalWords} \t{totalBytes} total")