Printing specific lines from a text file

3

Imagine that I have a text file called test.txt with the following content:

4 Março 2017- Sábado

    meu aniversario

    -prova de calculo



    6 Março 2017- Segunda

    aniversario do Salomao

    - fazer compras




    8 Março 2017- Quarta

    feriado

    -acordar tarde

The purpose is to check if a specific string, such as "6 March 2017" is in the file (its first occurrence, if there is more than one) and then print "all" until before the next date. >

For example, if I want to check if "March 6, 2017" is in the file, I should print:

 6 Março 2017- Segunda

    aniversario do Salomao

    - fazer compras

I've done the following:

f = open("teste.txt",'r')
search = "6 Março 2017"
for  line in f:
    if search in line:

        print(line)
        break

But I only print:

6 Março 2017- Segunda

How can I make the program print the other lines that interest me as well?

I tried to implement a simpler logic and it did not work:

after finding the date, with a simple:

if "6 March 2017" in f.readlines ():

Then I would like to do a while to go through the other lines, after all I have already reached the first line I want, which is the one containing "6 March 2017- Monday" and print everything until BEFORE other date:

6 March 2017- Second

aniversario do Salomao

- fazer compras

It stops printing, because the next line after the whitespace starts with 8.

Could someone show this code?

    
asked by anonymous 12.03.2017 / 02:46

2 answers

5

I do not know what your problem is all about (would it be a college exercise?), but if you're trying to build an agenda or something, I'd suggest using a more appropriate and easy-to-handle storage format. / p>

  

If it's something more amateur, using same text file storage,   I would suggest using a JSON , an XML or a YAML . Everyone has   packages in Python. If it's something more professional, maybe it's   best to use a database ( MySQL , for example, which also has   packages ready in Python).

In any case, there are several options to do what you want. To facilitate, I suggest using the datetime package to identify the dates. But for this you need to set the location in Portuguese before and, very importantly, use the name of the day of the week correctly ("Monday" instead of "Monday"). p>

The following code reads line by line, testing each line to see if it finds a date (it uses the datetime.strptime function, which throws an exception if it is not a valid date - when I consider it as content from the previously recognized date , stored in the date variable). If it's a date, it opens a new "key" in the info dictionary based on that date. If it is not, it considers it as a content of that entry in your calendar, and simply accumulates it in the current key (when doing info[date] += line + '\n' ).

Note that "logic" is essentially:

  • Read a line if it has not yet reached the end of the file.
  • Checks if it's a date.
  • If it's a date, open a new "record" for it, and go back to step 1.
  • If it is not a date, add the line as content in the current record. Go back to step 1.
  • You can implement this logic anyway, and the cat's jump is just in step 2 (check if it's a date). This code only tries to facilitate this identification using the locale and datetime packages. But nothing prevents you from using regular expressions or even manual comparison.

    Here is the code:

    import sys
    import locale
    from datetime import datetime
    
    # Define a localização para Português do Brasil
    locale.setlocale(locale.LC_ALL, 'ptg_bra') # No Windows!
    # Em outro OS provavelmente será:
    # locale.setlocale(locale.LC_ALL, 'pt_BR')
    
    date = ''
    info = {}
    with open('teste.txt', 'r') as f:
        for line in f.readlines():
    
            line = line.strip('\n ') # Remove quebras de linhas e espaços
    
            # Tenta converter a linha atual para uma data (no formato esperado!)
            # Se sucesso, abre uma nova "chave" de conteúdo
            try:
                key = datetime.strptime(line, '%d %B %Y- %A')
                date = key
                info[date] = ''
    
            # Se falhou, o conteúdo pertence à chave atual (se há uma)
            except ValueError:
                if date != '':
                    info[date] += line + '\n'
    
    
    date = input('Digite a data para consulta:')
    try:
        date = datetime.strptime(date, '%d %B %Y- %A')
    except ValueError:
        print('O valor [{}] não é uma data válida.'.format(date))
        sys.exit(-1)
    
    print(info[date])
    

    Remembering that the entry has to be (with "Monday ** - fair **" rather than just "Monday"):

    4 Março 2017- Sábado
    
        meu aniversario
    
        -prova de calculo
    
    
    
        6 Março 2017- Segunda-feira
    
        aniversario do Salomao
    
        - fazer compras
    
    [. . .]
    

    The output of the code is this:

    >teste
    Digite a data para consulta:6 Março 2017- Segunda-feira
    
    aniversario do Salomao
    
    - fazer compras
    
      

    Q.: Note that the date format is set to dia Mês ano- Dia_da_semana based on %d %B %Y- %A format. If you need   change the format (even adding or removing a space!),   you need to change the format! The list of formats can be consulted   in the documentation or in this quick guide .

        
    12.03.2017 / 04:42
    6

    Logic

    The logic implemented is simple:

  • The contents of the file are read and stored in content
  • Stores in% with% of desired date
  • With regular expressions, all the dates in the format are searched in the file, storing in date :
    • The date should start with one or two digits
    • Followed by a space
    • Followed by any character (to match non-ASCII characters) countless times
    • Followed by a space
    • Four-digit string
  • Verify that the desired date exists in the file
    • If not, throw an exception with an error message
  • Finds the desired date in the file and stores the position in dates
  • Checks the index of the desired date in the list of dates start
  • Checks if the desired date is not the last in the file
    • If it is, sets dates to the position of the last character of the file's contents
  • Search the next date in the file by accessing the index end of index+1 , storing in dates
  • Finds the next date in the file and stores the position in next_date
  • Displays the contents of the file between end and start
  • Code

      

    Removed white space from question content to improve presentation of response, but not necessary for code to work.

    # -*- coding: utf-8 -*-
    
    import re
    
    content = """4 Março 2017- Sábado
    meu aniversario
    -prova de calculo
    
    6 Março 2017- Segunda
    aniversario do Salomao
    - fazer compras
    
    8 Março 2017- Quarta
    feriado
    -acordar tarde"""
    
    # Data desejada:
    date = "8 Março 2017"
    
    # Localizando todas as datas no arquivo:
    dates = re.findall(r"[0-9]{1,2}\s.+\s[0-9]{4}", content)
    
    # Verifica se a data existe no arquivo:
    if date not in dates:
        raise Exception("Data não definida")
    
    # Localiza a data desejada no arquivo:
    start = content.find(date)
    
    # Verifica o índice da data na lista de datas:
    index = dates.index(date)
    
    # Verifica se não é a última data da lista:
    if index < len(dates) - 1:
    
        # Verifica qual é a data posterior à desejada:
        next_date = dates[index + 1]
    
        # Localiza a próxima data no arquivo:
        end = content.find(next_date)
    
    else:
    
        # É a última data da lista, então exibe até o final do arquivo:
        end = len(content)
    
    # Exibe o conteúdo:
    print(content[start:end])
    

    Outputs

    For end , the output is generated:

    4 Março 2017- Sábado
    meu aniversario
    -prova de calculo
    

    For date = "4 Março 2017" , the output is generated:

    6 Março 2017- Segunda
    aniversario do Salomao
    - fazer compras
    

    For date = "6 Março 2017" , the output is generated:

    8 Março 2017- Quarta
    feriado
    -acordar tarde
    

    For date = "8 Março 2017" , the output is generated:

    Traceback (most recent call last):
      File "python", line 25, in <module>
    Exception: Data não definida
    
      

    See the code working in Repl.it or Ideone .

        
    12.03.2017 / 04:47