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
60 changes: 60 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.

Your implementation works well, but your code could be improved a bit. Can you see any issues with the code style you could fix?

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

def main():
parser = argparse.ArgumentParser(
prog="display-content-of-a-file",
description="cat is used to display the content of a file or print the content of a file."
)
parser.add_argument('-n', action='store_true', help='number output lines')
parser.add_argument('-b', action='store_true', help='number non-empty output lines')
parser.add_argument('paths', nargs='+', help="The file path(s) to process")

options = parser.parse_args()

combined_data = ""
for path in options.paths:
try:
with open(path, 'r', encoding='utf-8') as f:
combined_data += f.read() + "\n"
except Exception as e:
print(f"Error reading {path}: {e}", file=sys.stderr)
sys.exit(1)

# If user used -b
if options.b:
line_num = 1
numbered_lines = []
for line in combined_data.split('\n'):
if line.strip() == '':
numbered_lines.append(line) # Keep empty lines unnumbered
else:
numbered_lines.append(f"{line_num:6} {line}")
line_num += 1
sys.stdout.write('\n'.join(numbered_lines) + '\n')

# If user used -n
elif options.n:
numbered_lines = [
f"{i+1:6} {line}"
for i, line in enumerate(combined_data.split('\n'))
]
sys.stdout.write('\n'.join(numbered_lines) + '\n')

# If user didn't use -n or -b
else:
sys.stdout.write(combined_data)

if __name__ == "__main__":
main()










#python3 cat.py -b sample-files/*
37 changes: 37 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import argparse #for parsing command-line arguments and options
import os #to interact with the os for listing files and handling paths
import sys #Allows interaction with the Py runtime env like reading/writing output,exiting.


def list_directory(directory, show_all, one_per_line):
try:
files = os.listdir(directory)
except Exception as e:
print(f"ls: cannot access '{directory}': {e}", file=sys.stderr)
return 1

if not show_all:
files = [f for f in files if not f.startswith('.')]
files.sort()

if one_per_line:
for file in files:
print(file)
else:
print(' '.join(files))

return 0

def main():
parser = argparse.ArgumentParser(description="A simplified ls implementation.")
parser.add_argument('-1', dest='one_per_line', action='store_true', help='list one file per line')
parser.add_argument('-a', action='store_true', help='include hidden files')
parser.add_argument('directory', nargs='?', default='.', help='directory to list (default: current directory)')

args = parser.parse_args()

exit_code = list_directory(args.directory, args.a, args.one_per_line)
sys.exit(exit_code)

if __name__ == "__main__":
main()
49 changes: 49 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import argparse
import sys
import os

def format_output(lines, words, bytes_, label, options):
output = ""
if not (options.l or options.w or options.c):
output += f"{lines:8}{words:8}{bytes_:8}"
else:
if options.l:
output += f"{lines:8}"
if options.w:
output += f"{words:8}"
if options.c:
output += f"{bytes_:8}"
return f"{output} {label}"

def main():
parser = argparse.ArgumentParser(description="Count lines, words, and bytes in files (like wc)")
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 bytes")
parser.add_argument("files", nargs="+", help="files to read")
options = parser.parse_args()

total_lines = total_words = total_bytes = 0

for file_path in options.files:
try:
with open(file_path, "r", encoding="utf-8") as f:
data = f.read()

lines = data.count("\n")
words = len(data.split())
bytes_ = len(data.encode("utf-8"))

total_lines += lines
total_words += words
total_bytes += bytes_

print(format_output(lines, words, bytes_, os.path.basename(file_path), options))
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)

if len(options.files) > 1:
print(format_output(total_lines, total_words, total_bytes, "total", options))

if __name__ == "__main__":
main()