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


parser = argparse.ArgumentParser(
prog="cat implemnet by Python"
)

parser.add_argument("-n", action="store_true")
parser.add_argument("-b", action="store_true")
parser.add_argument("files", nargs="+")

args = parser.parse_args()

line_number = 1

for filename in args.files:
try:
with open(filename) as file:
for line in file:
line = line.rstrip("\n")

if args.b and line == "":
print()
continue

if args.n or args.b:
print(f"{line_number} {line}")
line_number += 1
else:
print(line)

except FileNotFoundError:
print(f"{filename}: No such file or directory")
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

parser = argparse.ArgumentParser(
prog="ls implemnet by Python"
)

parser.add_argument("-1", action="store_true", dest="one_per_line")
parser.add_argument("-a", action="store_true", dest="show_all")
parser.add_argument("paths", nargs="*")

args = parser.parse_args()

if not args.paths:
args.paths = ["."]

for path in args.paths:
if os.path.isdir(path):
files = sorted(os.listdir(path))

if not args.show_all:
files = [file for file in files if not file.startswith(".")]

if args.one_per_line:
for file in files:
print(file)
else:
for file in files:
print(file, end=" ")
print()

elif os.path.isfile(path):
print(path)

else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

what happens if we try like python ls.py completely_fake_file.txt?

Your current condition checks if it's a directory but what if it is a file. Shall we just print or do something with that condition?

And what if it's neither of dir nor file? How do we handle that?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@Khantdotcom thanks, I didn’t pay attention to that issue. I added another check so it now handles existing files, directories, and nonexistent paths.

print(f"{path}: No such file or directory")
51 changes: 51 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import argparse


parser = argparse.ArgumentParser()

parser.add_argument("-l", action="store_true")
parser.add_argument("-w", action="store_true")
parser.add_argument("-c", action="store_true")
parser.add_argument("files", nargs="+")

args = parser.parse_args()


def add_count(output, value):
output.append(str(value))


total_lines = 0
total_words = 0
total_bytes = 0

for filename in args.files:

with open(filename, "rb") as file:
content = file.read()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reading the whole file with .read() is putting that data into RAM. What if you point this at a 50GB log file? Check out this code for learning a better approach here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@Khantdotcom I didn’t have any clue about this. Thanks, I’ll use this approach next time.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@BoshraM It's completely okay with your current approach! The whole idea of suggested one is just chunking, which means reading the file in part by part. Hope you learned something.


lines = content.count(b"\n")
words = len(content.split())
bytes_count = len(content)

total_lines += lines
total_words += words
total_bytes += bytes_count

if not args.l and not args.w and not args.c:
print(f"{lines:8} {words:8} {bytes_count:8} {filename}")

else:
output = []

if args.l:
add_count(output, lines)

if args.w:
add_count(output, words)

if args.c:
add_count(output, bytes_count)

print(f"{' '.join(output):>8} {filename}")

Loading