Skip to content

London | 26-SDC-July | Alex Jamshidi | Sprint 4 | Implement shell tools in python - #676

Open
Alex-Jamshidi wants to merge 26 commits into
CodeYourFuture:mainfrom
Alex-Jamshidi:implement-shell-tools-in-python
Open

London | 26-SDC-July | Alex Jamshidi | Sprint 4 | Implement shell tools in python#676
Alex-Jamshidi wants to merge 26 commits into
CodeYourFuture:mainfrom
Alex-Jamshidi:implement-shell-tools-in-python

Conversation

@Alex-Jamshidi

Copy link
Copy Markdown

Learners, PR Template

Self checklist

  • I have titled my PR with Region | Cohort | FirstName LastName | Sprint | Assignment Title
  • My changes meet the requirements of the task
  • I have tested my changes
  • My changes follow the style guide

Task code

CYF-1152

Changelist

Implemented wc, ls, cat in python

@Alex-Jamshidi Alex-Jamshidi added 📅 Sprint 4 Assigned during Sprint 4 of this module Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. Module-Tools The name of the module. labels Aug 30, 2026
@LonMcGregor LonMcGregor added the Review in progress This review is currently being reviewed. This label will be replaced by "Reviewed" soon. label Sep 1, 2026

@LonMcGregor LonMcGregor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good start on this task. Reading through it, I can see you have put thought into these implementations, but they feel a little bit over-engineered, and at times are a bit difficult to see how the data is flowing through them. I've got a few questions for you to answer which might help me better understand your thinking.

# ===== Print Output =====
def print_lines(all_files_contents):
for file_content in all_files_contents:
for line in file_content:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason to use two loops here? Could your data structure be simplified?

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.

See above comment.

# ===== Flag Handling =====
def execute_flags(all_files_contents):
if args.b:
for file_content in all_files_contents:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here it looks like you loop over all the content twice.Once to add the line numbers, then once again to print. Is it possible to do this only looking at the data once?

@Alex-Jamshidi Alex-Jamshidi Sep 5, 2026

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.

There is a reason for this. The data in all_file_contents is stored as two lots of nested arrays.

For 3 files it might look like this:
[[line, line, line, line], [line, line, line], [line, line, line, line]]

For a single file it looks like this:
[[line, line, line]]

So the first loop essentially just unwraps that first array.

I could update the code in read_files() to unpack all lines into a single array, even if there are multiple files... that would be something like...

    file_content = read_file(file_name, cwd).splitlines())
    for line in file_content:
    all_files_contents.append(line)

(replacing lines 29 and 30).

This would then let me have a single loop in each of the two locations you flagged:
for line in all_file_contents:

But I chose to do it this way to preserve the information of which lines are from which files. The reason to do this was because, this version of cat implements only 2 flags, but was written with the view to be potentially expanded, so I wanted to maintain as much information about the input as possible, letting the print function unpack it all at the end.

This is also why there are two loops below.


# ===== Flag Handling =====
def execute_flags(flag_status):
if getattr(args, "1"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here, when you are doing things like if args.a …, then you set something to True. What benefit is there doing it this way over just referencing args.a when you need it?

flag_status = {"print_in_list": False, "show_all": False}
execute_flags(flag_status)

cwd = os.getcwd()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you use the cwd for in this program?

if not (Path(cwd) / p).is_dir()
]
if not flag_status["show_all"]:
file_args = remove_dot_files(file_args)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are multiple places where you use remove_dot_files in this program. Is there a reason for that?

return all_files_data

def read_file(file_name, cwd):
file_path = Path(cwd) / file_name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are you using the Path / expression here?

return len(text.splitlines())

def calculate_word_count(text):
return len(text.split())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason the word count method has a different structure to your line count method?

for file in output_data:
output_string = ""

for metric in metrics:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do you need to loop over metrics and then check if it is in displayed_metrics? Could you simplify this?

@LonMcGregor LonMcGregor added Reviewed Volunteer to add when completing a review with trainee action still to take. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. Review in progress This review is currently being reviewed. This label will be replaced by "Reviewed" soon. labels Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Module-Tools The name of the module. Reviewed Volunteer to add when completing a review with trainee action still to take. 📅 Sprint 4 Assigned during Sprint 4 of this module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants