In: Computer Science
Python is a great tool for automating a number of tasks, including scanning and summarizing the files in a file system.
Write a Python class, FileAnalyzer that given a directory name, searches that directory for Python files (i.e. files ending with .py). For each .py file, open each file and calculate a summary of the file including:
Generate a summary report with the directory name, followed by a tabular output that looks similar to the following:
The class FileAnalyzer should have at least these attributes and these methods listed below:
{ 'filename_0.py': { 'class': # number of classes in the file 'function': # number of functions in the file 'line': # number of lines in the file 'char': # number of characters in the file }, ... }
Note: Your should execute the self.analyze_files in the self.__init__ but you MUST NOTexecute the self.pretty_print in the self.__init__, you will get 10 points deducted if you do so.
Keep in mind that you may see a file, but you may not be able to read it. In that case, raise a FileNotFound exception if the specified file can’t be opened for reading
Your program should use exceptions to protect the program against unexpected events.
The PrettyTable module (Links to an external site.) provides an easy way to create tables for output. You should use PrettyTable to format your table. See the lecture notes for an example.
You’ll need to think about how to test this program with unittest. You do not need to automatically verify the output from the table but you should validate the various numeric values, e.g. number of classes, functions, lines, and characters. Your automated test should validate the counts for each file in the test directory.
Hints:
Pre-requisites:
1) Python 3.x is used to execute the code
2) Python modules os, re and prettytable are installed in the python version been used.
CODE:
OUTPUT:
# ./fileanalyze.py
CODE to copy:
import os
import re
from prettytable import PrettyTable
class FileAnalyzer:
def __init__(self):
# declare the global dictionary to store the values
self.files_summary = {}
# directory to scan files for
self.directory = "/home/vsaurabh/analyzer"
# call the method to start scanning the files
self.analyze_files()
def analyze_files(self):
# walk through the given directory
for root, dir, files in os.walk(self.directory):
# check for each file
for file in files:
# check if the given file ends wiht .py extension
if file.endswith(".py"):
# get the absolute path for the file
myfile = root + "/" + file
# declare required variables
characters = 0
lines = 0
classes = 0
definition = 0
try:
# read the file for requried data
with open(myfile, 'r') as frb:
for line in frb:
# increment the no of line count
lines = lines + 1
# increment the no of characters count
characters = characters + len(line)
# check if given line is a class directive
if line.startswith("class"):
# if yes, increment the counter
classes = classes + 1
# check if given line is a function directive
if re.match('\s.*def|def', line):
# if yes, increment the counter
definition = definition + 1
# if the file scanned is not found as a key in dictionary
# add the filename as a key into the dictionary if file not in self.files_summary:
# declare a nested dictionary for the respective key
self.files_summary[file] = {}
# add values for the other paramters required to be stored
self.files_summary[file]['class'] = classes
self.files_summary[file]['function'] = definition
self.files_summary[file]['line'] = lines
self.files_summary[file]['char'] = characters
except (FileNotFoundError):
# Error is a filename is not found
print("Wrong file or file path: %s" %myfile)
except PermissionError:
# Raise in case the file is not accessible
print("Cannot open file : %s" %myfile)
# call the function to print the dictionary
self.pretty_print()
def pretty_print(self):
# declare a pretty table object
x = PrettyTable()
# add headers to the table
x.field_names = ["Filename", "classes", "definition", "lines", "characters"]
# for each key, value pair in dictionary add a row in the table
for key,value in self.files_summary.items():
data = []
data.extend([key,value["class"],value["function"],value["line"],value["char"]])
x.add_row(data)
# print the final table
print(x)
if __name__ == "__main__":
# instantiate the class to trigger _init_
obj = FileAnalyzer()