My output is missing the last word "millennium". I'm not sure why.
Write a program that first reads in the name of an input file, followed by two strings representing the lower and upper bounds of a search range. The file should be read using the file.readlines() method. The input file contains a list of alphabetical, ten-letter strings, each on a separate line. Your program should output all strings from the list that are within that range (inclusive of the bounds).
Blockquote
input1.txt
ammoniated
millennium
and the contents of input1.txt are:
aspiration
classified
federation
graduation
millennium
philosophy
quadratics
transcript
wilderness
zoologists
the output is:
aspiration
classified
federation
graduation
millennium
Notes:
There is a newline at the end of the output. All input files are hosted in the zyLab and file names can be directly referred to. input1.txt is available to download so that the contents of the file can be seen. In the tests, the first word input always comes alphabetically before the second word input.
My code:
fileName = input()
lowerLimit = input()
upperLimit = input()
with open(fileName) as fileData:
lst = fileData.readlines()
for index, value in enumerate(lst):
if value >= lowerLimit and value <= upperLimit:
print(value.rstrip())
Program output displayed here:
aspiration
classified
federation
graduation
CodePudding user response:
To answer your question, I think it is probably because your upperLimit
should be upperLimit 1
since the end index for the list is exclusive.
In addition, it is probably a good idea to put your code into a class for reusability.
Here is how I will write this tiny project (for my version you will need to input both txt dir, but you can always change to read words list txt when input file name extracted).
class WordsFilter:
def __init__(self, index_txt_dir: str, allWords_txt_dir: str):
'''
:param index_txt_dir: the txt file contains a file name, lower bound word, and upper bound word
:param allWords_txt_dir: the txt file contains all words
'''
self._index_txt_dir = rf'{index_txt_dir}'
self._allWords_txt_dir = rf'{allWords_txt_dir}'
def _helper_read_file(self):
'''
:purpose: this function is used to read both txt files
'''
with open(self._index_txt_dir, 'r') as file:
self.file_name, self.lower_bound, self.upper_bound = [x.strip() for x in file.readlines()]
with open(self._allWords_txt_dir, 'r') as file:
self.words_list = [x.strip() for x in file.readlines()]
def _helper_cleaned_raw_output_index(self):
'''
: purpose: this function is used to handle the following situations
1: lower bound words can be found, but an upper bound cannot find.
solutions: return all words starting from the lower bound (inclusive)
2: the lower bound word comes after a higher bound word in the words list.
solutions: return switch lower index and upper index to return everything in between.
3: both lower bound and upper bound word cannot be found.
solutions: return all words in words list read
'''
lower_index, upper_index = self._helper_raw_output_index()
if lower_index > upper_index:
# lower bound word can be found, but upper bound cannot find. ie: raw index as (4,0)
# Solution: return all words starting from the lower bound (inclusive)
if upper_index == 0:
return (lower_index, None)
# lower bound word comes after higher bound word in the words list. ie: raw index as (4,3)
# Solution: return switch lower index and upper index to return everything in between.
else:
return (upper_index, lower_index 1)
# both lower bound and upper bound word cannot be found. ie: raw index as (0, 0)
# Solution: return all words in words list read
elif lower_index == upper_index:
return (None, None)
else:
return (lower_index, upper_index 1)
def get_filtered_words(self):
'''
:purpose: This is the function you will call directly
:return: filtered words list
'''
self._helper_read_file()
low, upper = self._helper_cleaned_raw_output_index()
return self.words_list[low:upper]
def _helper_raw_output_index(self):
'''
:purpose: this function is used to get the raw index for lower and upper bound words. If any of them can found, it will be set as 0
'''
lower_index, upper_index = [0, 0]
try:
lower_index = self.words_list.index(self.lower_bound)
except ValueError:
print('Lower Bound Not In Words List')
finally:
try:
upper_index = self.words_list.index(self.upper_bound)
except ValueError:
print('Upper Bound Not In Words List')
return lower_index, upper_index
words = WordsFilter(index_txt_dir= r'/index.txt', allWords_txt_dir= r'/input.txt')
words.get_filtered_words()
I hope this is helpful.
CodePudding user response:
This answer only uses readlines() because the question requires it. File objects can be iterated over so, in this case, readlines() isn't really necessary.
filename = input('Filename: ') # always nice to have a literal prompt
lowerLimit = input('Lower limit: ')
upperLimit = input('Upper limit: ')
with open(filename) as fileData:
for line in map(str.rstrip, fileData.readlines()):
if line >= lowerLimit and line <= upperLimit:
print(line)