-
-
Notifications
You must be signed in to change notification settings - Fork 27
ZA | 25-SDC-July | Luke Manyamazi | Sprint 4 | Python Implement Shell Tools Exercises #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3a31fbf
d443669
1900a28
ff86f10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import glob | ||
import argparse | ||
|
||
def cat(filepath, n=False, b=False, line_counter=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you always pass values for these arguments - why are you supplying default values for them? Particularly for |
||
try: | ||
with open(filepath) as f: | ||
for line in f: | ||
if b: | ||
if line.strip(): | ||
print(f"{line_counter[0]:6}\t{line}", end='') | ||
line_counter[0] += 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this value in an array? You always seem to look at exactly one value in the array? |
||
else: | ||
print(line, end='') | ||
elif n: | ||
print(f"{line_counter[0]:6}\t{line}", end='') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's some repetition here between the |
||
line_counter[0] += 1 | ||
else: | ||
print(line, end='') | ||
except FileNotFoundError: | ||
print(f"cat: {filepath}: No such file or directory") | ||
|
||
def main(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How did you test this implementation? I created two files and tried using |
||
parser = argparse.ArgumentParser(description = "Concatenate files and print on the standard output.") | ||
parser.add_argument('-n', action='store_true', help='number all output lines') | ||
parser.add_argument('-b', action='store_true', help='number non-empty output lines') | ||
parser.add_argument('files', nargs='+', help='files to concatenate') | ||
args = parser.parse_args() | ||
|
||
files = [] | ||
for pattern in args.files: | ||
files.extend(glob.glob(pattern) or [pattern]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's interesting you're globbing here - I would expect a shell to handle this. What would break if you removed the glob expansion yourself? |
||
|
||
line_counter = [1] | ||
for file in sorted(files): | ||
cat(file, args.n, args.b, line_counter) | ||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import os | ||
import argparse | ||
|
||
def ls(path='.', one_column=False, show_hidden=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question as above about default args |
||
try: | ||
files = os.listdir(path) | ||
if not show_hidden: | ||
files = [f for f in files if not f.startswith('.')] | ||
files.sort() | ||
|
||
if one_column: | ||
print(*files, sep='\n') | ||
else: | ||
print(*files) | ||
except FileNotFoundError: | ||
print(f"ls: cannot access '{path}': No such file or directory") | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-1', dest='one_column', action='store_true', help='list one file per line') | ||
parser.add_argument('-a', action='store_true', help='show hidden files') | ||
parser.add_argument('path', nargs='?', default='.', help='directory to list') | ||
args = parser.parse_args() | ||
|
||
ls(args.path, args.one_column, args.a) | ||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import argparse | ||
|
||
def wc(path, count_lines, count_words, count_bytes): | ||
try: | ||
with open(path, 'r') as f: | ||
content = f.read() | ||
lines = content.splitlines() | ||
words = content.split() | ||
bytes_ = len(content.encode('utf-8')) | ||
|
||
parts = [] | ||
if count_lines: parts.append(str(len(lines))) | ||
if count_words: parts.append(str(len(words))) | ||
if count_bytes: parts.append(str(bytes_)) | ||
|
||
if not parts: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works, but it feels like it's testing for a side-effect ("We didn't add any paths") rather than the cause ("you didn't ask for any of lines, words, or bytes") - I'd maybe rewrite this (But the code works fine as it is, too) |
||
parts = [str(len(lines)), str(len(words)), str(bytes_)] | ||
print(' '.join(parts), path) | ||
|
||
except FileNotFoundError: | ||
print(f"wc: {path}: No such file or directory") | ||
except IsADirectoryError: | ||
print(f"wc: {path}: Is a directory") | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
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('paths', nargs='+', help='Files to count') | ||
args = parser.parse_args() | ||
|
||
for path in args.paths: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I pass multiple files, the real |
||
wc(path, args.l, args.w, args.c) | ||
|
||
if __name__ == "__main__": | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
n
andb
are both:Can you think of a way of passing this information into the function which is easier to read, and makes more clear that only one of these should be set?