Python Forum
How to Randomly Print a Quote From a Text File When User Types a Command on Main Menu
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to Randomly Print a Quote From a Text File When User Types a Command on Main Menu
#1
Hello. Just recently I put my BBS back online after nine years, and I am trying to write a python-based game -- for my BBS.

Before I continue, let me inform you that I am 70 years old, I am NOT a programmer, and I do not know any programming languages.

However, following the coding example of another open-source external that was written for my BBS, I have made some progress.

But, due my lack of expertise, I am stuck in several areas. Let me just discuss one of them in this current message.

I have a long list of quotes -- meaning several thousand of them -- in a text file, one quote per line. I have placed this text file in the "strings" folder for the python module that I am building for my BBS.

I have already imported both "random" and "string" at the top of my main.py file.

So, what I would like to do is create a function -- which I assume I must in some way declare at the top of my main.py file -- with an accompanying menu command, which I can add to the main menu in my python module.

I have done a lot of online research, and found a lot of different methods for doing what I want to do, which has left me rather confused.

Basically, once a user enters my game on my BBS -- meaning the python module -- I want them to be able to type a one-letter command that is shown on the main menu of the game module.

Typing this one-letter command will then have my game module randomly print one quote from the text file on the user's screen.

I don't know if this list of several thousand quotes would be referred to as a list, a dictionary, a set or what. As I said, I am very new to all of this, and being seventy, it is hard for my mind to grasp all of this stuff.

Being as this text file is one MB in size, I am assuming that it would not be wise to load it all into memory at once.

So, if anyone here has the patience to walk me through this step-by-step, explaining how to set this up, and how to link the command on the Main Menu, with clear examples of exactly what to type, and where to put it in my modules files, I would be most appreciative.

Thank you in advance.
Reply
#2
A basic random quote example using a text file

from random import choice 

with open('quote.txt', 'r') as quotes:
    quotes = quotes.readlines()



def get_quote():
    return choice(quotes)
    

while True:
    try:
        cmd = input('Type q for a random quote or e to exit\n>> ')
        if cmd.lower() == 'q':
            # print(choice(quotes)) - print it out
            print(get_quote()) # Call a function
        elif cmd.lower() == 'e':
            print('Goodbye!')
            break
        else:
            print('Print something else')
    except:
        print('Error! Not a valid input')
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
Hello Menator01. Thank you for your quick response. I just got back from the store, and it was already here waiting for me.

Okay, let me see if I understand your code correctly.

The first part -- "from random import choice" -- is actually another import, so I should probably put it right below "import random", right?

The "def get_Quote():" part is a function, right? So I should declare it in the top portion of my main.py file BEFORE my main entry point?

The "while True:" part and below looks like I should put it anywhere after the entry point. Is this correct? Or am I mistaken?

But what about the "with open('quote.txt', 'r')" part? Where exactly would that go?

But I am getting the impression that this code is more of an inline thing which I can place anywhere after my entry point. But how do I make it work from my mainmenu in my "Text" folder? In other words, as I said in my original post, I want to add a command to my Main Menu -- probably an R as the command -- which when typed by the user will print the random quote on their screen.

Basically, I am building a space game, and I want to have a "Retreat" option on the Main Menu -- meaning the letter R -- where users can kind of go into this special place on base where they can read inspiring quotes.

Sorry, if I seem confused and have misunderstood you. But as I said, it is a struggle for me to grasp all of this stuff.

My gosh, I can't even get a "quit" option to work on the main menu. :)

Also, in that code, do I HAVE to use "q" and "e", or can I use whatever letters I want? i want to reserve the "q" for "Quit", once I figure out why it is not working.
Reply
#4
The first part -- "from random import choice" -- is actually another import, so I should probably put it right below "import random", right? - This is just part of the random module you can
import random and use it like
random.choice(somelist or tuple) or the way I did it

from random import choice - I prefer to import only what I need from the modules

The "def get_Quote():" part is a function, right? - Yes this a function and are generally towards the top

The "while True:" part and below looks like I should put it anywhere after the entry point. Is this correct? Or am I mistaken? - I used it as a continuous loop. As for where to put it depends on your code.

But what about the "with open('quote.txt', 'r')" part? Where exactly would that go? - Again this depends on your code.

Also, in that code, do I HAVE to use "q" and "e", or can I use whatever letters I want? - It can be which ever letter you choose.

Without seeing how the code is setup it's difficult to help much.

My code was just an example of how it could be done.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#5
So, to be clear, being as I already imported random, you are saying that I really don't need to add "from random import choice", being as "choice" is a part of the "random" module. Although it also sounds like you are saying to use "from random import choice" being as that is the only part that I need. BUT, if I do that, will it still randomly pick a quote each time that the loop is run, or will it do them in order, or what?

Before writing to you, I actually did add the import string, and I did place the function near the top of my main.py file.

However, as far as the rest of the code is concerned, I assumed that where your code says "with open('quote.txt', 'r') as quotes:" I am supposed to replace "quote.txt" with the actual name of the text file where all of the quotes are stored in my"strings" folder.

Sp I did that. Then I placed all of it -- minus the import call and the function -- together in the main entry part of my main.py file.

In other words, the "while True:" part is right below the "with open('quote.txt', 'r')" with the same indentation.

However, this jython installation that my BBS has does NOT like its placement, and keeps saying "Syntax Error: Invalid Syntax" with the little arrow right underneath the letter "o" in the word "open".

Quite often when I get that syntax error, it is because I have my indention wrong somewhere, or I forgot a comma, or a parenthesis. However, no matter how much, or how little, indentation I do, I still keep getting the syntax error.

Are you saying that instead of all of that other code you gave me, I can simplify things by using "random.choice(somelist or tuple)" instead, where I would replace "somelist or tuple" with the actual name of my text file? Do I need to put a print command below or above it?

I believe I may have tried something like that earlier today before I posted here, and I was unable to get it working properly.
Reply
#6
These are the same and either is fine to use.
from random import choice
import random

alist = [1,2,3,4,5,6,7,8,9]
atuple = ['a','b','c','d','e']

print(f'import random module as whole -> {random.choice(alist)}')
print(f'import just the choice function - > {choice(atuple)}')
I looked at the jython website and it only supports python 2. Most python users will have python 3. The code I provided may not work.

output
Output:
import random module as whole -> 8 import just the choice function - > e
I have not used jython so, I probably will not be much help with your code.

I assumed that where your code says "with open('quote.txt', 'r') as quotes:" I am supposed to replace "quote.txt" with the actual name of the text file Yes you will need to replace with the actual text file you are using

In other words, the "while True:" part is right below the "with open('quote.txt', 'r')" with the same indentation.

Again without seeing relevant code it's hard to help. You may not even need the while loop.
The jython website says it only supports python2. Most use python3. The code I provided may not work.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#7
Hello Menator01 and all. I apologize for being away from this thread, but I have been rather busy. In fact, I have been rather busy trying to overcome some of the problems I have been having with my python/jython based module.

Since last posting here, I have made significant progress with my module. However, I am currently having one basic problem which neither I, nor ChatGPT, have figured out how to rectify, despite many hours working on it.

As I may have mentioned earlier, basically, the Hermes II software that I use has its own Jython 2-based runtime environment. Within the file and folder structure of Hermes II, there is in fact a Jython folder, which among other things contains various packages, including a Hermes API package, a Jython package, a QT Java package, an MRJClasses package, as well as a few other things.

The python module I am creating is heavily based on the code of another BBS game which was quite popular within the BBS world quite a few years ago. That game is called Leech. Some of you older folks will no doubt be familiar with one flavor or another of this game.

At any rate, back around 2015 — or a little earlier — the last developer of my BBS software -- Michael Alyn Miller -- made a huge departure from the Pascal-based framework which was used to make games -- meaning externals -- for Hermes II, when he created a development system for externals -- called External Development System -- which is based on Jython, and not on Pascal. He then released a new version of Hermes II, which utilizes this then-new Jython framework.

The primary reason why he did this was to simplify the process of creating externals, so that SysOps who use his BBS software, can more easily create externals themselves for their own Hermes II BBSes, without all of the heavy coding and compilation work involved when using Pascal.

To show and teach SysOps how to create their own BBS externals with Python/Jython, he created an open source version of the Leech game, so that SysOps could learn from his code, which uses a lot of different functions and methods from the Jython development environment.

His Jython version of Leech in fact includes a number of class files, which after some online research, I figured out how to open with an app I found on the web. Upon opening these class files, I can see all of the imports he has made from python.org, all of the strings he has made, function names he has created, etc.

For those of you here who may have experience with this stuff, you will probably find all of this very easy to understand. However, I am not a programmer of Pascal, Python, Jython, C or anything else. Thus, I have struggled since my journey began about a week ago, and a lot of it is still Greek to me.

But, trying my best to understand Michael's coding examples, and more recently getting some help from ChatGPT — which is blowing my mind — as I said earlier, I have made considerable progress for a 70-year-old n00b such as myself.

I now have the entry point for my game module set up in the main.py file, which consists of six ANSI screens which serve as the welcome and backstory for my game.

I also have the framework for the main menu set up now, which currently has 5 or 6 working menu commands. I haven’t even begun working on the real meat of the game yet.

This leads us to my current problem. In the storyline for my game, I am including an option on the main menu where the game’s users can go to a spiritual retreat to relax from work. It is a place for spiritual inspiration.

If the game user types in the key command for the retreat, they will be able to randomly display, as many times as they want, quotes taken from the Bible, which are all stored in a text file in the “strings” folder, which is inside of the “resources” folder. This text file contains over 3,000 verses and verse sets from the KJV Bible, which I have personally compiled since 2002.

The coding structure for all of this has already been added to the main.py module, thanks to the Leech coding example, and to a lot of help from ChatGPT.

Now here is the problem — and I have seen through online research, that others have encountered this same problem too.

With all of this code in place, my game module is unable to load within my BBS environment, because the Java/Jython components are unable to open and read the text file which contains the aforementioned 3,000+ strings,.

The error output is stating the following. I have obfuscated the actual path for reasons of security:

Traceback (innermost last):
File "/Macintosh HD/Applications/BBS Soft/BBS Files/Doors/MyGame/main.py", line 305, in ?
File "/Macintosh HD/Applications/BBS Soft/BBS Files/Doors/MyGame//main.py", line 264, in main
File "/Macintosh HD/Applications/BBS Soft/BBS Files/Doors/MyGame//main.py", line 96, in read_quotes

java.lang.SecurityException: java.lang.SecurityException: not allowed to read resources/strings/QuotesFile.txt

A runtimeException occurred.

So the problem is that I have absolutely no idea how to give — I assume main.py — the permissions it needs to read the “QuotesFile.txt” file. It knows exactly where to find the file, and sees it, but it doesn't have permission to open it, or Java doesn't have permission, or Jython. I am really not sure which is trying to open the file. If someone can explain to me exactly how to do this -- that is, provide the needed permissions -- then hopefully, my game module will load again, and I will be able to continue working on it.

Please note that this is all happening in a Mac OS 9.2.2 environment, which is made possible by running the Qemu PPC emulator, which runs inside of macOS Sonoma 14.4.1, on my 2019 5K iMac.

So, if anyone knows the solution to this problem, and can explain it to me in layman’s terms, I wold be most appreciative.

So there you have it.
Kind regards,

Bill Kochman
Reply
#8
Well, it has been six days since someone last responded here, so I am going to assume that no one knows how I can get past this SecurityException that Jython throws me everytime my module tries to open the text file containing the Bible quotes. I am really out of ideas myself. I don't even know where the rules regarding security are stored in the Jython installation that is included with my BBS software. And even if I did know, I have no idea how to edit them, in order to get rid of this SecurityException.
Reply
#9
If you can't open a text file, convert the text file to a python module. This is how you can convert your bible verse text file to a python module.

bible_verse.py
from random import choice


# This is your bible verse text file converted into a multi-line string.
# All you have to do is put the text=""" before the first verse and """
# after the last verse.
text = """
This is a verse.
This is the second verse.

Here's another verse.
This is the last verse
"""

# This splits the multi-line string into a list of strings, one string per
# line (\n).  It throws away empty strings.
verses = [quote for quote in text.split("\n") if quote]


# This is a function you can use to get a random verse.
def random_verse():
    return choice(verses)
Use the module like this:

test.py
from bible_verse import random_verse


for i in range(10):
    print(random_verse())
I'm not surprised that nobody had an answer for how to fix a java security access problem for jython code running in a BBS. That is a small expert pool. I don't know how to fix that problem. Luckily the problem you need to fix was not that problem
Reply
#10
Hello Dean. Thank you for your response. I appreciate it. You are the first person to a straightforward-sounding, what appears to be a simple way to bypass the Java SecurityException.

So, if I understand you correctly, you are saying to convert the text file which my module is unable to open due to the SecurityException and simply transform it into a module. The Bible quote text file is huge, at 1.1 MB, so I imagine that I really need to whittle it down in size.

Is there any limitation to how many characters can occupy a single line in the module. For example, do I need to follow standard Python practice and keep it below 80 characters. The reason why I ask is because a lot of single verses alone are much more than that, and many quotes are multiple verses.

So, if I got this write, I give this quote module a name, and then I import it into the module where I want to use it. In this case, into my "Space Race" module.

In my "Space Race" module, after importing the quote module, I have to define it near the top of the "Space Race" module, correct?

After that, I can use the function you gave me to use it wherever I want in the "Space Race" module -- in this case, as a command on the "Space Race" Main Menu -- to have it randomly quote a verse for a visitor to the "Retreat".

Have I got it all right?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Cannot get cmd to print Python file Schauster 11 553 May-16-2024, 04:40 PM
Last Post: xMaxrayx
  problem with print command in super() akbarza 5 718 Feb-01-2024, 12:25 PM
Last Post: deanhystad
  pyaudio seems to randomly halt input. elpidiovaldez5 2 463 Jan-22-2024, 09:07 AM
Last Post: elpidiovaldez5
  Problem with code / audio is playing randomly, not matching csv requirements Daniel_kcr 2 711 Sep-07-2023, 05:09 PM
Last Post: deanhystad
  Start print a text after open an async task via button Nietzsche 0 756 May-15-2023, 06:52 AM
Last Post: Nietzsche
  Python VS Code: using print command twice but not getting output from terminal kdx264 4 1,202 Jan-16-2023, 07:38 PM
Last Post: Skaperen
Thumbs Up Need to compare the Excel file name with a directory text file. veeran1991 1 1,192 Dec-15-2022, 04:32 PM
Last Post: Larz60+
  python sql query single quote in a string mg24 1 1,148 Nov-18-2022, 08:01 PM
Last Post: deanhystad
  python run all py files from main py file mg24 6 1,480 Oct-12-2022, 04:41 AM
Last Post: mg24
  Saving the print result in a text file Calli 8 1,945 Sep-25-2022, 06:38 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

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