Drkdeibs
Drkdeibs

Reputation: 103

printing lines from a file within an inclusive alphabetical range not including desired limits

The trouble I'm having with this program is that it is not including the bounds even though I use the >= <= operators. Also for some reason the words that are output are each separated by a newline rather than printing one after another.

For example, if the chosen .txt file contains:

Aladdin
Batman
Dinosaurs
Edgar
Fruitloop
Mongoose

and the chosen upper and lower bounds are:

Batman
Fruitloop

The program prints:

Batman

Dinosaurs

Edgar


Here is what I'm working with. Any help is greatly appreciated!

import os

user_file = input() #reads name of user chosen .txt file containing alphabetized one word per line lists
lo_limit = input() #reads a user chosen word as the inclusive lower alphabetical limit
up_limit = input() #reads a user chosen word as the inclusive upper alphabetical limit

file_handle = open(user_file) #opens user chosen file

lines = file_handle.readlines() #creates by-line string of file contents


#if user chosen file contains words equal to or between bounds, prints words
for ln in lines:
    if ln >= lo_limit \
        and ln <= up_limit:
        print(ln)

Upvotes: 2

Views: 80

Answers (4)

thekid77777
thekid77777

Reputation: 391

Ok starting with how your opening the file, its easier to open it with a context manager like this, then it handles the opening/closing for you.

with open('input.txt') as f:
    lines = f.readlines()

On to why your code isn't working, you have to consider what file_handle.readlines() is doing and storing. I believe you are under the impression that lines contains:

['Aladdin', 'Batman', 'Dinosaurs', 'Edgar', 'Fruitloop', 'Mongoose']

when in reality it contains:

['Aladdin\n', 'Batman\n', 'Dinosaurs\n', 'Edgar\n', 'Fruitloop\n', 'Mongoose']

You can use a list comprehension like so to peel that newline escape character off:

lines = [l.replace('\n', '') for l in lines]

Then your logic should work fine. In summary, try something like this:

with open('input.txt') as f:
    lines = f.readlines()

lines = [l.replace('\n', '') for l in lines]

print(lines)

lo_limit = 'Batman'
up_limit = 'Fruitloop'

for ln in lines:
    if ln >= lo_limit and ln <= up_limit:
        print(ln)

which gives output:

['Aladdin', 'Batman', 'Dinosaurs', 'Edgar', 'Fruitloop', 'Mongoose']
Batman
Dinosaurs
Edgar
Fruitloop

Upvotes: 1

MrNobody33
MrNobody33

Reputation: 6483

That happens because when you do f.readlines() this will return a list like this:

f.readlines()
>>>['Aladdin\n', 'Batman\n', 'Dinosaurs\n', 'Edgar\n', 'Fruitloop\n', 'Mongoose']

And when you enter up_limit=Edgar, you will be comparing each of the list f.readlines() with the word Edgar like this:

'Aladdin\n'>=lo_limit and 'Aladdin\n'<='Edgar'
>>>True
'Batman\n'>=lo_limit and ''Batman\n''<='Edgar'
>>>True
....
....
....

And when becomes the iteration of 'Edgar\n' you can check that:

'Edgar'>='Edgar\n'
Out[6]: False

And that's why 'Edgar' is not printed. You could try:

import os

user_file = input() #reads name of user chosen .txt file containing alphabetized one word per line lists
lo_limit = input() #reads a user chosen word as the inclusive lower alphabetical limit
up_limit = input() #reads a user chosen word as the inclusive upper alphabetical limit

with open(str(user_file)) as file_handle:#opens user chosen file
    lines = file_handle.readlines()
    #if user chosen file contains words equal to or between bounds, prints words
    for ln in lines:
        if (ln > lo_limit) or (ln == lo_limit) or (ln < up_limit):
            print(ln)
            if (ln == up_limit+'\n'):
                break

Or you can select by index:

user_file = input() #reads name of user chosen .txt file containing alphabetized one word per line lists
lo_limit = str(input()) #reads a user chosen word as the inclusive lower alphabetical limit
up_limit = str(input()) #reads a user chosen word as the inclusive upper alphabetical limit

with open(str(user_file)) as file_handle:#opens user chosen file
    lines = file_handle.readlines() #creates by-line string of file contents    
    linesselected=lines[lines.index(lo_limit+'\n'):(lines.index(up_limit+'\n')+1)]
    for i in linesselected:
        print(i.replace('\n',''))

Upvotes: 1

Jailton Silva
Jailton Silva

Reputation: 370

You need to replace ">=" and "<=" with ">" and "<". Also remove "\n" from each line.

To leave the result on the same line you need to use the end attribute of the print function.

Stays like this:

user_file = input() #reads name of user chosen .txt file containing alphabetized one word per line lists
lo_limit = input() #reads a user chosen word as the inclusive lower alphabetical limit
up_limit = input() #reads a user chosen word as the inclusive upper alphabetical limit

file_handle = open(user_file) #opens user chosen file

lines = file_handle.readlines() #creates by-line string of file contents

#if user chosen file contains words equal to or between bounds, prints words
for ln in lines:
    ln = ln.replace('\n', '')
    if ln > lo_limit \
        and ln < up_limit:
        print(ln, end=' ')

output:

$ python file.py 
arquivo.txt
Aladdin
Mongoose
Batman Dinosaurs Edgar Fruitloop

Upvotes: 0

Harshal Parekh
Harshal Parekh

Reputation: 6017

This is not how to select a range of lines. This case is working because the input is ascending order. Give it a random input and you'll not get what you expect.

lines = """Aladdin
Batman
Dinosaurs
Edgar
Axe # input to break the ascending order
Fruitloop
Mongoose"""

lines = lines.split("\n")

for i in range(len(lines)):
    if "Batman" == lines[i]:
        for j in range(i, len(lines)):
            print(lines[j])
            if "Fruitloop" == lines[j]:
                break

To get a range of lines, you first need to loop on the lines, find the starting line, then start looping from that line until you find the ending line.


Also: Always use a with clause to open a file:

with open(file, "r") as file:
    for line in file:
        # read line by line here

Upvotes: 1

Related Questions