Python Forum
Still playing with text files (Jose Portilla on Udemy)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Still playing with text files (Jose Portilla on Udemy)
#1
In a previous thread titled, “Counting words in the last line of a file” that I was working on where I explored how to analyze text files, @DeaD_EyE graciously stepped in to help rewrite the script from scratch to make it more pythonic. @DeaD_EyE’s post can be found on page #2 (post #12) of my thread. See the bottom for the current script that I am working with now.

It runs well and as intended. The script:
  • presents the user with different books to analyze,
  • shows the user how many lines there,
  • asks the user which line they want to print,
  • prints the line number
  • asks the user if they want to play again

Now I am trying to add this feature to that list:
  • prints the single line chosen by the user

To achieve that, here are the changes that I made so far. I have:
  • initialized an empty request variable at the top of the script,
  • asked the user to choose the line (within the validate and choose function),
  • printed the line.

When I run the script it turns out that it is print the selected line number twice. What I really want is for Python to print the chosen line once and the line number once. I partially understand that the request variable when asked for input (inside validate_and_shoose()), it’s picking the integer value but it’s not clear to me how I can extract the actual line contents chosen by the user. What would you ppl recommend?

Here is the latest iteration of my script:

#!/usr/bin/env python3
"""
Description

This is my tenth iteration of this text reading script. This iteration is based on DeaD_EyE's. DeaD_EyE's script runs well. It prompts the user to choose a line, counts the number of words and characters but I noticed that it doesn't actually print the selected line when the instructions say it will. here I attempt to add this missing functionality
"""
import sys
 

BOOKS = {1: 'Tolstoy.txt', 2: 'Alice.txt', 3: 'Chesterton.txt'}
request = None


def read_all_books():
    """
    Read all books from global variable BOOKS
    The keys are the digits
    """
    result = {}
    for number, filename in BOOKS.items():
        with open(filename) as fd:
            book_lines = fd.read().splitlines()
        result[number] = book_lines
        # maybe adding some metadata to the book
    return result
 
 
def which_book():
    """
    This function presents the user with a selection
    of 3 potential books to examine.
    """
    print("\nChoose from this list of books: \n 1. Tolstoy \n 2. Alice \n 3. Chesterton")
    while True:
        try:
            pick = int(input("What is your pick (1, 2, 3)? "))
        except ValueError:
            print(f'{pick} is not in the list. Enter a valid number in the range of available books.')
        return pick
 
 
def showcase(book):
    """
    This function essentially prints the entire book,
    line by line (but also prints the associated line numbers)
    """
    max_num = len(str(len(book))) + 1 # i know it's silly
    # just want to know how long the last linenumber is
    for num, line in enumerate(book):
        print(f'{num:>{max_num}}: {line.rstrip()}')
    # we don't return anything
    # the books are already loaded
 
  
def validate_and_choose(allowed_range):
    """
    This function ensures the user input is an integer
    and within the range of number of lines.
    """
    global request
    request = input('\nWhich line do you want to count and print? >> ')    
    range_text = f'integer in range {min(allowed_range)} - {max(allowed_range)}'
    while True:
        answer = input(f'Enter {range_text}: ')
        try:
            answer = int(answer)
            if answer in allowed_range:
                return answer        
            if answer not in allowed_range:
                raise ValueError  
        except ValueError:
            print(f'Expected {range_text} but input was "{answer}". Try again! ')
    
  
def again():
    """
    This function gives the user the ability to
     
    (1) start from the very beginning at the top,
    (2) restart half way through
    (3) exit
    """
    replay = input(
        "\n------------------------------------------------------\n" 
        "\nWould you like to choose a new line in the same book?\n" 
        "Or would you prefer to pick a line from a different book?\n"
        "\n'A' for the same book, \n'B' for a different book, "
        "or \n'C' to exit this program \n Make your selection: ")
    return replay.lower()
 
 
def main_menu():
    """
    Main menu + Loop for this game
    """
    print('Welcome to my game.')
    print('Maybe some help..')
    print(f'All books together take {utf8_in_memory / 1024**2:.2f} MiB in memory')
    # it's not right. It consumes more memory because of
    # the overhead of the dict itself and the list as holder for
    # the lines of the books
    print()
    book_key = which_book()
    # just a number, which is the key of the dict book_data
    while True:
        book = book_data[book_key]
        print()
        showcase(book)
        print()
        line_index = validate_and_choose(range(0, len(book)))
        words = len(book[line_index].split())
        # characters = len(book[line_index])
        characters = len(book[line_index].replace(' ', ''))
        # only characters, no whitespaces
        print(f'Here is the line # that you picked: "{line_index}"\n'
              f'Here is the content of the line that you picked:"{request}"\n'
              f'The number of words: {words}\n'
              f'The number of characters: {characters}')
        replay = again()
        if replay == 'a':
            continue
        elif replay == 'b':
            book_key = which_book()
        elif replay == 'c':
            print("Goodbye!")
            return 0
        else:
            print(
                "I'll take that answer as a request"
                "to exit this program. Goodbye for now!"
                )
            return 1
  
  
if __name__ == "__main__":
    book_data = read_all_books()
    # book_data on module leve.
    # it could be in main()
    # but then you must pass this around
    utf8_in_memory = sum(sys.getsizeof(line) for book in book_data.values() for line in book)
    try:
        retval = main_menu()
    except KeyboardInterrupt:
        retval = 10
        print('\nGoodbye!')
    sys.exit(retval) # maybe as information for other shell citizens
Here is my script on GitHub on the master branch. For my future reference, this exercise is part of Jose Portilla's Udemy course at this specific module: Python-Narrative-Journey/02-Field-Readiness-Exam-1/01-Field-Readiness-Exam-One.ipynb
Reply


Messages In This Thread
Still playing with text files (Jose Portilla on Udemy) - by Drone4four - Oct-04-2019, 01:59 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  azure TTS from text files to mp3s mutantGOD 2 1,732 Jan-17-2023, 03:20 AM
Last Post: mutantGOD
  Writing into 2 text files from the same function paul18fr 4 1,710 Jul-28-2022, 04:34 AM
Last Post: ndc85430
  Delete empty text files [SOLVED] AlphaInc 5 1,601 Jul-09-2022, 02:15 PM
Last Post: DeaD_EyE
  select files such as text file RolanRoll 2 1,193 Jun-25-2022, 08:07 PM
Last Post: RolanRoll
  Two text files, want to add a column value zxcv101 8 1,966 Jun-20-2022, 03:06 PM
Last Post: deanhystad
  select Eof extension files based on text list of filenames with if condition RolanRoll 1 1,544 Apr-04-2022, 09:29 PM
Last Post: Larz60+
  Separate text files and convert into csv marfer 6 2,932 Dec-10-2021, 12:09 PM
Last Post: marfer
  Sorting and Merging text-files [SOLVED] AlphaInc 10 4,959 Aug-20-2021, 05:42 PM
Last Post: snippsat
  Replace String in multiple text-files [SOLVED] AlphaInc 5 8,216 Aug-08-2021, 04:59 PM
Last Post: Axel_Erfurt
  Several pdf files to text mfernandes 10 5,886 Jul-07-2021, 11:39 PM
Last Post: Pedroski55

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020