Skip to content

London | Elhadj Abdoul Diallo | Module-Tools | WEEK4 - Implement-shell-tools-python #38

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

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
acf2628
Add initial implementation of ls tool to read and print file content
Mar 5, 2025
f8f1ca8
Refactor ls tool to encapsulate file reading and printing in a function
Mar 5, 2025
4b0c2dc
Remove ls tool implementation and related file reading logic
Mar 5, 2025
5050c26
Add initial implementation of cat tool to read and print file content
Mar 5, 2025
59fb74a
Refactor cat tool to return file content and print it in a loop
Mar 5, 2025
4fa86d0
Refactor cat tool to use argparse for command-line argument parsing
Mar 5, 2025
aa0ed1d
add option n for numbering lines for only one file passed as command …
Mar 6, 2025
946e244
Refactor cat tool to extract content lines into a separate function
Mar 6, 2025
2b59edd
Refactor cat tool to implement output_lines_with_numbers function for…
Mar 6, 2025
12ab72a
Refactor cat tool to support multiple file inputs and streamline line…
Mar 6, 2025
b61e4d1
Add option to number non-empty lines in cat tool
Mar 6, 2025
b908688
Implement basic ls command with directory listing functionality
Mar 6, 2025
2c493bf
Update ls command to print directory contents in a single line
Mar 6, 2025
f83037b
Enhance ls command to support listing files one per line with -1 option
Mar 6, 2025
8c55ba3
Filter out hidden files in ls command output
Mar 6, 2025
92ce714
Add option to list hidden files in ls command
Mar 6, 2025
3969905
Refactor ls command variable names for clarity and consistency
Mar 6, 2025
6e2cad2
Rename read_dir function to list_directory_contents for clarity and i…
Mar 6, 2025
80db8ec
Fix hidden files handling in ls command to prepend '.' and '..' when …
Mar 6, 2025
4b7afa0
Add wc command implementation to read and display file content
Mar 6, 2025
65c2653
Enhance wc command: trim empty lines from content and add line counti…
Mar 6, 2025
f9f4f1b
Add function to output line count and file path in wc command
Mar 6, 2025
c31cb36
Refactor read_file_content to return content directly and streamline …
Mar 6, 2025
3dd6a35
Add function to extract words and update output to include word count…
Mar 6, 2025
3fda7b2
Add function to extract characters and update output to include chara…
Mar 6, 2025
78aff81
Remove unused number_of_lines function to streamline wc command imple…
Mar 6, 2025
e6d6afe
Update wc command to accept multiple file paths and adjust output fun…
Mar 6, 2025
1be9fbe
Refactor wc command to return counts as a list and handle multiple fi…
Mar 6, 2025
5d7f354
Refactor output handling in wc command to improve readability and str…
Mar 6, 2025
716ab40
Enhance wc command output to display individual file counts and total…
Mar 6, 2025
af6a6a7
Add option to output only line counts in wc command
Mar 6, 2025
282e9cc
Add option to output word counts in wc command
Mar 6, 2025
6fcf115
Add option to output character counts in wc command
Mar 6, 2025
39b5783
Refactor wc command to streamline option handling and improve output …
Mar 6, 2025
d889bf4
Rename output functions in wc command for clarity and consistency
Mar 6, 2025
f2c55db
Encapsulate file statistics printing logic in a dedicated function
Mar 6, 2025
d6c6577
Simplify print statements in wc command for improved readability
Mar 6, 2025
b8d801b
Add .venv directory to .gitignore to prevent tracking of virtual envi…
Mar 15, 2025
b384884
Remove commented debug print statement in cat command
Mar 15, 2025
cafe718
Remove commented debug print statement in cat command
Mar 16, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
implement-cowsay/.venv.
45 changes: 45 additions & 0 deletions implement-shell-tools/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import argparse

parser = argparse.ArgumentParser(
prog="cat program implementation",
description="Implements the cat program",
)

parser.add_argument("-n", "--number", action="store_true", help="Number the output lines, starting at 1.")
parser.add_argument("-b", "--number2", action="store_true", help="Number the output of non-empty lines, starting at 1.")
parser.add_argument("paths", nargs='+', help="The files to search")

args = parser.parse_args()
def read_file_content(file_path):
with open(file_path, 'r') as f:
return f.read()

def extract_content_lines(content):
lines = content.split('\n')
if lines and lines[-1] == '':
lines = lines[:-1]
return lines

def output_lines_with_numbers(lines):
count = 0

Choose a reason for hiding this comment

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

possibly rename 'number1' and 'number2 ' to 'line_number_on' and filter_empty_lines'

number_lines = args.number
number_non_empty_lines = args.number2
for line in lines:
if number_lines:
count += 1
print(count, line)
elif(number_non_empty_lines) and line != '':
count += 1
print(count, line)
else:
print(line)

# Read contents of all files into a list
all_lines = []
for path in args.paths:
content = read_file_content(path)
lines = extract_content_lines(content)
all_lines.extend(lines)

# Output lines with or without numbering
output_lines_with_numbers(all_lines)
35 changes: 35 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import argparse
import os


parser = argparse.ArgumentParser(
prog="The ls program",
description="Implements the ls program"
)
parser.add_argument('dir', nargs='?', type=str, help="Path to the directory to list", default='.')
parser.add_argument("-1", "--one", action="store_true", help="list the directory files one per line")

parser.add_argument("-a", "--hidden_files", action="store_true", help="list the directory files one per line")

args = parser.parse_args()


def list_directory_contents():
is_file_per_line_option = args.one
is_hidden_option = args.hidden_files
dir = args.dir
files = os.listdir(dir)

if is_hidden_option:
files = ['.', '..'] + files

for file in files:
if is_hidden_option or not file.startswith('.'):
if is_file_per_line_option:
print(file)
else:
print(file, end=' ')
if not is_file_per_line_option:
print()

Choose a reason for hiding this comment

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

would good be a good idea, rather than printing directly to console, to add console lines to an in memory list, this would make it easier to direct the output whereever you want it, and to test.
For example, 'print' could be replaced by your own output function, like 'outputline', which either printed to console, or an in memory list. Then in python, you could monkey patch the 'outputline' function.

list_directory_contents()
79 changes: 79 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

import argparse


parser = argparse.ArgumentParser(
prog="wc program",
description="Implements the cat program"
)

parser.add_argument("paths", nargs='+', type=str, help="The path to process")
parser.add_argument('-l', '--lines', action="store_true", help='Ouput number of lines')
parser.add_argument('-w', '--words', action="store_true", help='Ouput number of words')
parser.add_argument('-c', '--chars', action="store_true", help='Ouput number of characters')

args = parser.parse_args()
is_lines_option = args.lines
is_words_option = args.words
is_chars_option = args.chars


def extract_lines(content):
lines = content.split('\n')
if lines and lines[-1] == '':
lines = lines[:-1]
return lines

def extract_words(content):
return content.split(' ')

def extract_chars(content):
return list(content)

def read_file_content(file_path):
with open(file_path, 'r') as file:
return file.read()


def get_lines_words_chars_count(file_path):
content = read_file_content(file_path)
lines = extract_lines(content)
words = extract_words(content)
chars = extract_chars(content)
return [len(lines), len(words), len(chars)]


def print_selected_counts(file_path):
lines_words_chars_count = get_lines_words_chars_count(file_path)

lines_count = lines_words_chars_count[0]
words_count = lines_words_chars_count[1]
chars_count = lines_words_chars_count[2]

if is_lines_option: print(lines_count, file_path)
elif is_words_option: print(words_count, file_path)
elif is_chars_option: print(chars_count, file_path)
else: print(lines_count, words_count, chars_count, file_path)

Choose a reason for hiding this comment

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

have a look at tuples rather than a plain array for the count results

def print_total_lines(lines_words_chars_count, total):
total_lines = sum(count[0] for count in lines_words_chars_count)
total_words = sum(count[1] for count in lines_words_chars_count)
total_chars = sum(count[2] for count in lines_words_chars_count)

if is_lines_option: print(total_lines, total)
elif is_words_option: print(total_words, total)
elif is_chars_option: print(total_chars, total)
else: print(total_lines, total_words, total_chars, total)

def print_file_statistics():
lines_words_chars_count = []
if len(args.paths) == 1:
print_selected_counts(args.paths[0])
else:
for file_path in args.paths:
result = get_lines_words_chars_count(file_path)
lines_words_chars_count.append(result)
print_selected_counts(file_path)
print_total_lines(lines_words_chars_count, 'total')

print_file_statistics()