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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules
/.venv
implement-cowsay/.venv/
44 changes: 44 additions & 0 deletions implement-shell-tools/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import argparse

parser = argparse.ArgumentParser(
prog="cat",
usage="implement a simple cat"
)

# Flag to number all lines
parser.add_argument(
"-n",
action="store_true",
help="Number all output lines"
)

# Flag to number only non-blank lines
parser.add_argument(
"-b",
action="store_true",
help="Number non-blank output lines"
)

# Positional argument for files to read
parser.add_argument(
"path",
nargs="*",
help="Files to read"
)

args = parser.parse_args()
# print(args)
line_number=1
for per_file in args.path :
with open(per_file,"r") as f:
if args.n or args.b :
lines=f.readlines()
for line in lines :
if line=="\n" and args.b :
print(line,end="")
else :
print(line_number,line,end="")
line_number=line_number+1
else :
print(f.read(),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 os
import argparse

parser=argparse.ArgumentParser(prog="cat",usage="implement a simple ls python")
parser.add_argument("-1",dest="one",action="store_true")
parser.add_argument("-a",action="store_true")
parser.add_argument("path",nargs="*",help="path to list files")
args=parser.parse_args()

paths=args.path
if len(paths)==0 : paths=["."]

for path in paths :
files_list=os.listdir(path)
files_list.sort(key=str.lower)

# Divide into hidden and non-hidden
non_hidden = [f for f in files_list if not f.startswith(".")]
hidden = [f for f in files_list if f.startswith(".")]

# Sort each list
non_hidden.sort(key=str.lower)
hidden.sort(key=str.lower)

# Add '.' and '..' at the start if -a
if args.a:
files_list = ['.', '..'] + non_hidden + hidden
else:
files_list = non_hidden

for item in files_list :
if args.one and args.a :
print(item)
elif args.one :
if not item.startswith(".") :
print(item)

Choose a reason for hiding this comment

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

Did you test all the combinations of arguments?

Copy link
Author

Choose a reason for hiding this comment

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

Fix -a output order to match ls: non-hidden files first, hidden files last, with '.' and '..' at the top. Previously I tested all combinations and thought showing all files/folders was enough, but now I fixed the order to fully match ls behavior.

Choose a reason for hiding this comment

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

If you test this without the -1 option, can you see what happens. What would you expect to happen?

58 changes: 58 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import argparse
import os


# Set up argument parser for wc command
parser=argparse.ArgumentParser(prog="wc",usage="implement a simple wc in python")
parser.add_argument("-l",action="store_true",help="count of lines")
parser.add_argument("-w",action="store_true",help="count of words")
parser.add_argument("-c",action="store_true",help="count of bytes")
parser.add_argument("path",nargs="+")
args=parser.parse_args()


paths=args.path
words_count=0
total_lines=0
total_words=0
total_bytes=0

# Function to print counts for a file or total
def print_wc(lines, words, bytes_, name):
# Print selected counts in formatted columns
print(
(f"{lines:<5}" if args.l else "") +
(f"{words:<5}" if args.w else "") +
(f"{bytes_:<5}" if args.c else "") +
f"{name:<20}"
)

# Loop through all files
for file in paths :
with open(file,"r") as f :
# Get file size in bytes
bytes_count=os.path.getsize(file)
# Read all lines
lines=f.readlines()
lines_count=len(lines)
for line in lines :
# Count words in file
words_count+=len(line.split())

# Update totals
total_lines +=lines_count
total_bytes += bytes_count
total_words +=words_count

# If no flags provided, default to showing all counts
if not (args.l or args.w or args.c):
args.l = True
args.w = True
args.c = True
# Print counts for this file
print_wc(lines_count, words_count, bytes_count, file)

# If multiple files, print totals at the end
if len(paths)>1 :
print_wc(total_lines, total_words, total_bytes, "total")