Python - Return all cities of a.txt file in a percentage range

Asked

Viewed 169 times

0

I’m having trouble returning all cities with the percentage within a range that the user has gone through. My text file consists of these cities and their respective isolation rates:

São Paulo = 30
Guarujá = 47
Belo Horizonte = 38
Rio de Janeiro = 45
Curitiba = 44
Fortaleza = 47
Recife = 50

With this, I have to make a code that returns all cities in a percentage period passed by the user. Below my code:

taxa1 = input("Digite um intervalo de taxa de isolamento, sendo <50%, 50% <= x <= 60% e >60%")

arquivo1 = open('arquvio.txt','r')
y = 0
for linha1 in arquivo1:
    linha1 = linha1.rstrip()
    if taxa1 in linha1:
        y = y + 1
        print ("Cidade: ", linha1)
print("\nForam encontradas", y ,"Cidades")

If the user type 45 for example, the above code would only return to the city that has an isolation rate of 45%. However, I want it to return all cities below 50% once the user type "<50%". I want the code to return all cities that have the isolation rate between 50% and 60%, once the user type "50% <= x <= 60%", and so on.

4 answers

2

To compare whether the insulation is larger, smaller or equal to a certain value, you need to isolate it from the line and convert it to number. An alternative is to use split to separate the line into parts, and then convert the relevant part to int:

taxa = input("Digite um intervalo de taxa de isolamento, sendo <50%, 50% <= x <= 60% e >60%")
cont = 0
with open('arquivo.txt') as arquivo:
    for linha in arquivo:
        isolamento = int(linha.split('=')[1])
        if (taxa == '<50%' and isolamento < 50) or \
           (taxa == '50% <= x <= 60%' and 50 <= isolamento <= 60) or \
           (taxa == '>60%' and isolamento > 60):
            cont += 1

print(f'{cont} cidades com isolamento {taxa}')

I do the split by character =, separating the line into two parts: the first with the name of the city and the second with the isolation rate. Then I take the second part ([1] - because in lists the first index is zero) and convert to int.

Then I count according to the rate criterion. If the rate should take into account values less than 50, I check if the isolation is less than 50. If you should consider values between 50 and 60, I check this, and so on.


I did it because it looks like it’s only gonna count one criteria at a time. But if the idea is to count the 3 separately, then you need 3 counters:

faixa1 = faixa2 = faixa3 = 0
with open('arquivo.txt') as arquivo:
    for linha in arquivo:
        isolamento = int(linha.split('=')[1])
        if isolamento < 50:
            faixa1 += 1
        elif 50 <= isolamento <= 60:
            faixa2 += 1
        else:
            faixa3 += 1

if taxa == '<50%':
    # mostrar resultado da faixa1
elif taxa == '50% <= x <= 60%':
    # mostrar resultado da faixa2
elif taxa == '>60%':
    # mostrar resultado da faixa3

This code does not validate if the isolation rate is negative (if it is, it will enter track 1 count).


Note also that I used with, which ensures that the file is closed at the end.

Remembering that the code does not validate the format of the lines (if it is not in the correct format, the split will not return a list with 2 elements and will give error when trying to catch the second, or if the second element is not a number, will also give error, etc).

1

Try to parse symbols in a string like "<" or "%" is, in my opinion, more work than it is worth. The more you manage to limit user input, the better.

It is simpler to warn the user that the first input is the lower limit and the second is the upper. Consider the following approach:

1) Read the values of the txt file into a dictionary:

with open('file.txt', 'r') as f: 
    dados = {line.split(' = ')[0]: int(line.split(' = ')[1]) for line in f} 

2) Choose the upper and lower limit for the percentage:

limite_inf = int(input('Digite o limite inferior: '))
limite_sup = int(input('Digite o limite superior: '))

3) Find and return values and cities that are within limits:

dados_dentro = [(c, v) for c, v in dados.items() if limite_inf < v < limite_sup]

4) Show the results

print(f"Foram encontradas {len(dados_dentro)} Cidades:")
for cidade, valor in dados_dentro:
    print(cidade, '->', valor)

Complete code:

with open('file.txt', 'r') as f: 
    dados = {line.split(' = ')[0]: int(line.split(' = ')[1]) for line in f}

limite_inf = int(input('Digite o limite inferior: '))
limite_sup = int(input('Digite o limite superior: '))

dados_dentro = [(c, v) for c, v in dados.items() if limite_inf < v < limite_sup]

print(f"Foram encontradas {len(dados_dentro)} cidades:")
for cidade, valor in dados_dentro:
    print(cidade, '->', valor)

If you really want the flexibility to choose between a point rate or a crease fee, then manage these options in a previous menu, such as:

resposta = input('''
Qual opção você deseja? Digite o número correspondente:
1) taxa pontual
2) range de taxas
sua opção: ''')
if resposta == '1':
     # código da taxa pontual
elif resposta == '2':
     # código do range de taxas

0

You can create a function in your code to find all cities that have a rate within a certain range set by you or the user.

Within this function just go through the cities and check if the rate of the city in question is within the range set by the user with the conditional: start <= taxa <= stop.

To do this check we will need to get the city rate on type int, separating it from the city name using the method split and removing the line break at the end of the string.

# A variável cidades é um iterável com todas as linhas do arquivo.

for cidade in cidades:
    taxa = int(cidade.split(" = ")[-1].replace("\n", ""))
    if start <= taxa <= stop: cidades_encontradas.append(cidade)

For the function to become more dynamic, we can define None as default value for the range stop point. If the user does not pass a value for the parameter stop, this variable will later receive the value passed to the parameter start.

def encontrar_cidades(cidades, start, stop = None):
    cidades_encontradas = []
    stop = start if not stop else stop

This means that the user is not required to declare a range, and may search cities that have a specific fee. See the full function code below:

def encontrar_cidades(cidades, start, stop = None):

    cidades_encontradas = []
    stop = start if not stop else stop

    for cidade in cidades:
        taxa = int(cidade.split(" = ")[-1].replace("\n", ""))
        if start <= taxa <= stop: cidades_encontradas.append(cidade)

    return cidades_encontradas

Now that we’ve created the function responsible for finding cities based on the isolation rate, we’ll need to apply it to the program.

To do this, just create some conditionals for each type of input typed by the user, setting the arguments of start and stop based on user input:

taxa = input("Digite um intervalo de taxa de isolamento:")

if "<50%" == taxa: start, stop = 0, 50                # <50%             | (0, 50)
elif ">60%" == taxa: start, stop = 60, 100            # >60%             | (60, 100)
elif "50% <= x <= 60%" in taxa: start, stop = 50, 60  # 50% <= x <= 60%  | (50, 60)
else: start, stop = int(taxa), None                   # Taxa X           | (x, x)

cidades_encontradas = encontrar_cidades(conteudo, start, stop)               
print("\nCidades encontradas:", cidades_encontradas)

Since the function we create gives us the freedom to use the range we want, you can give the user more flexibility to search cities with the range he wants.

See the example below to understand what I mean:

if "<" == taxa[0]:
    taxa = int(taxa[1:].replace("%", ""))
    start, stop = 0, taxa

In this example, if the user type "<" before the rate, means that the user wants cities with the rate less than or equal to X. Thus, we do not need to limit ourselves to search for rates "<50%".


Remember that it is important to always close the file after you have made its use. To close the file, you can use the method close or the with to close the file automatically.

# Utilizando o método "close" para fechar o arquivo.

arquivo = open('arquivo.txt')
conteudo = arquivo.readlines()
arquivo.close()

# Utilizando a declaração "with" para fechar o arquivo.

with open('arquivo.txt') as arquivo:
    conteudo = arquivo.readlines()

-1

I thought of a possible solution, but that only works if there are no blank lines in the imported text file:

opcao = input('''
Escolha uma das opções de intervalo de isolamento (A, B ou C)
A) menor que 50%;
B) entre 50% e 60%;
C) maior que 60%
Opção escolhida:''').strip().lower()

arquivo = open('arquivo.txt','r')
y = 0
for linha in arquivo:
    isolamento = int(linha[-3:])
    if opcao == 'a':
        if isolamento < 50:
            y = y + 1
            print ("\nCidade: ", linha)
    elif opcao == 'b':
        if 50 <= isolamento <= 60:
            y = y + 1
            print("\nCidade: ", linha)
    elif opcao == 'c':
        if isolamento > 60:
            y = y + 1
            print("\nCidade: ", linha)

print("\nForam encontradas", y ,"Cidades")

Browser other questions tagged

You are not signed in. Login or sign up in order to post.