Oct-04-2019, 01:59 PM
(This post was last modified: Oct-04-2019, 02:01 PM by Drone4four.)
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:
Now I am trying to add this feature to that list:
To achieve that, here are the changes that I made so far. I have:
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
Here is the latest iteration of my script:
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
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
#!/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 |