how can i keep/ save the user input in dictionary? - python-3.x

import pandas as pd
from pandas import DataFrame
words = {}
def add_word():
ask = input("Do You Want To Add a New Word?(y/n): ")
if ask == 'y':
new_word = input("type the word you want to add: ")
word_meaning = input("type the word meaning: ")
words[new_word] = [word_meaning]
elif ask == 'n':
pass
add_word()
table = pd.DataFrame(data=words)
table_transposed = table.transpose()
print(table_transposed)
as you can see, i want to make a dictionary but i don't know how to save the user's input.
i want to take the user input and save it in the dictionary, so the next time he uses the program he can see everything he added before

When you make and populate (fill) a dictionary in a running Python program, that dictionary only exists as long as the program is running. When you close the program - that memory is wiped and any modifications that are made are not stored.
As Tomerikoo pointed out, this solution: shelving dictionaries will allow you to preserve your dictionary after the program is closed.
I copy the code from the link (jabaldonedo's solution) and annotate it for you for clarity.
import shelve # this is a Python library that allows you to store dictionaries after the program is closed
data = {'foo':'foo value'} # this is a mock-up dictionary. "words" in your case
d = shelve.open('myfile.db') # this creates a storage container in the program folder that can store multiple dictionaries. You can see this file appear when this code runs.
d['data'] = data # you make a section in that storage container, give it a name, e.g. "data" in this case, and store your dictionary in that section. You will store your "words" here.
d.close() # close the storage container if you do not intend to put anything else inside.
When you close and open up the program, the dictionary will not automatically pop into your running memory - you need to write code to access it. It can be made as an option in your game menu, e.g. "Load existing dictionary of words".
Back to jabaldonedo's solution:
import shelve # no need to import again, if you are writing in the same python program, this is for demonstration
d = shelve.open('myfile.db') # open the storage container where you put the dictionary
data = d['data'] # pull out the section, where you stored the dictionary and save it into a dictionary variable in the running program. You can now use it normally.
d.close() # close the storage container if you do not intend to use it for now.
EDIT: Here is how this could be used in the specific context provided in your answer. Note that I imported an additional library and changed the flags in your shelve access commands.
As I mentioned in my comment, you should first attempt to load the dictionary before writing new things into it:
import shelve
import dbm # this import is necessary to handle the custom exception when shelve tries to load a missing file as "read"
def save_dict(dict_to_be_saved): # your original function, parameter renamed to not shadow outer scope
with shelve.open('shelve2.db', 'c') as s: # Don't think you needed WriteBack, "c" flag used to create dictionary
s['Dict'] = dict_to_be_saved # just as you had it
def load_dict(): # loading dictionary
try: # file might not exist when we try to open it
with shelve.open('shelve2.db', 'r') as s: # the "r" flag used to only read the dictionary
my_saved_dict = s['Dict'] # load and assign to a variable
return my_saved_dict # give the contents of the dictionary back to the program
except dbm.error: # if the file is not there to load, this error happens, so we suppress it...
print("Could not find a saved dictionary, returning a blank one.")
return {} # ... and return an empty dictionary instead
words = load_dict() # first we attempt to load previous dictionary, or make a blank one
ask = input('Do you want to add a new word?(y/n): ')
if ask == 'y':
new_word = input('what is the new word?: ')
word_meaning = input('what does the word mean?: ')
words[new_word] = word_meaning
save_dict(words)
elif ask == 'n':
print(words) # You can see that the dictionary is preserved between runs
print("Oh well, nothing else to do here then.")

import shelve
words = {}
def save_dict(words):
s = shelve.open('shelve2.db', writeback=True)
s['Dict'] = words
s.sync()
s.close()
def load_dict():
s = shelve.open('shelve2.db', writeback=True)
dict = s['Dict']
print(dict)
s.close()
ask = input('Do you want to add a new word?(y/n): ')
if ask == 'y':
new_word = input('what is the new word?: ')
word_meaning = input('what does the word mean?: ')
words[new_word] = word_meaning
save_dict(words)
elif ask == 'n':
load_dict()
so this is my code after making the save_dict and load_dict functions, it works fine but when i run the program and write a new_word and word_meaning it overwrites the previous data, i believe i am missing something in the save_dict function, if you can point the problem to me i would be so grateful

Related

save a dictionary to a .db file

for the past couple of hours, I've been trying to find a solution to this issue. Any knowledge share is very helpful.
The objective is to save the dictionary created from the program. I am getting an error in line 3.
def save_dict(dictionary_to_be_saved):
with shelve.open('OperationNamesDictionary.db', 'c') as s: #create OperationNamesDictionary.db
s = dictionary_to_be_saved
What am I planning to achieve? : I have to pass the dictionary name to this function and it should create a (****.db) file, which I can use later.
Thanks in advance
Code used to save a dictionary:
def save_dict(dictionary_to_be_saved):
with shelve.open('OperationNamesDictionary.db', 'c') as s: # "c" flag used to create dictionary
s = dictionary_to_be_saved
Code used to retrieve a dictionary from created file:
def load_dict():
try:
with shelve.open('TOperationNamesDictionary.db', 'r') as s:
operation_names = s
return(operation_names)
except dbm.error:
print("Could not find a saved dictionary, using a pre-coded one.")
operation_names = load_dict()
print(operation_names)
output:<shelve.DbfilenameShelf object at 0x0000021970AD89A0>
Expected output: data inside the operation_names (A dictionary)
I think this is what you are after, more or less. This is untested code so I hope it works! What I have added to your attempts in the question is to provide a key value for the items you are shelving (I used the uninteresting identifier "mydictionary" as my key). So we put items in by that name, and take them out again by that same name.
def save_dict(dictionary_to_be_saved):
with shelve.open('OperationNamesDictionary.db', 'c') as s:
s['mydictionary'] = dictionary_to_be_saved
def load_dict():
try:
with shelve.open('TOperationNamesDictionary.db', 'r') as s:
return s['mydictionary']
except KeyError:
print("Could not find a saved dictionary")
For my specific case, creating a (.npy) file worked for me.
Again, the objective of my code is to use a dictionary that is available (the type of file that stores this dictionary doesn't matter) and at the end of the program save the updated dictionary to the same file.
import numpy as np
try:
operation_names = np.load("Operation_Dictionary.npy", allow_pickle = 'TRUE').item()
print("Using the Dictionary which is found in Path")
except FileNotFoundError:
print("Using Pre-coded Dictionary from the code")
operation_names = {"Asd-013we":"No Influence", "rdfhyZ1":"TRM"}# default dictionary
.....
.....
# the program will update the dictionary
np.save("Operation_Dictionary.npy",operation_names) #the updated dictionary is saved to same file.

Convert text to speech on mac when button pressed

I am trying to create a script which will read a text file and then speak one line of the file every time I press a button on my keyboard. I am using the system accessibility voice on my Mac as the voice sounds more human than some of the python modules I tried.
So far my script runs and speaks a line but the spoken lines are not in order but rather are just lines spoken at random, whereas I would like each line to be spoken once and in order.
Also, I would rather use another key (not alphanumeric) such as right arrow to invoke the function but not sure how to specify that in my script?
I am just learning to code so any help would be much appreciated.
I am using Python 3.9.1 on Mac OSX 10.15.5
filename = ('file.txt')
with open(filename) as f:
lines = f.readlines()
# for x in lines:
# pass
def say():
while True:
try: # used try so that if any key other than the specified key is pressed an error will not be shown
for x in lines:
if keyboard.is_pressed('l'): # if key 'l' is pressed
subprocess.call(['say', x])
print('You Pressed A Key!')
#break # finishing the loop
except:
break # this should break loop if user presses a key other than the given key but doesn't work
say()
Ok I have now managed to fix the issue of reading from a file and reading each line in sequence (see clode below).
And aparantly you can just specify the key with 'up' or 'right' which works. It does output random characters to the screen so if anyone has a better way of doing this, I'd love to hear it
import keyboard
import subprocess
filename = ('text.txt')
with open(filename) as f:
lines = f.readlines()
def say():
i=0
while i <len(lines):
try: # used try so that if any key other than the specified key is pressed an error will not be shown
if keyboard.is_pressed('up'): # if key 'up' is pressed
subprocess.call(['say', lines[i]])
i += 1
except:
break # this should break loop if user presses a key other than the given key but doesn't work
say()
import keyboard
import subprocess
CURRENT_LINE = 0 #records line to be read out, first line is 0.
def ttsLine(line): #TTS function, uses macs say as per you requested.
try:
k = subprocess.check_output(["say",line.strip()]) #using subprocess, line.strip() to clean each line.
return True #returns true so we know if say command was successful
except:
return False #returns false if exceptions occured.
filename = ('text.txt') #text file with lines to be read.
with open(filename) as f:
lines = f.readlines() #saving lines to array.
while True:
keyboard.wait("up") #Waits until up key is pressed.
if not ttsLine(lines[CURRENT_LINE]): #if ttsLine returned false, something went wrong and script halts.
print("Something went wrong while reading out", lines[CURRENT_LINE])
break
CURRENT_LINE += 1 #else we update line to next one
if CURRENT_LINE == len(lines): #if all lines have been read, script ends.
break

Python: command line, sys.argv, "if __name__ == '__main__' "

I have a moderate amount of experience using Python in Jupyter but am pretty clueless about how to use the command line. I have this prompt for a homework assignment -- I understand how the algorithms work, but I don't know how to format everything so it works from the command line in the way that is specified.
The prompt:
Question 1: 80 points
Input: a text file that specifies a travel problem (see travel-input.txt
for the format) and a search algorithm
(more details are below).
python map.py [file] [search] should read
the travel problem from “file” and run the “search” algorithm to find
a solution. It will print the solution and its cost.
search is one of
[DFTS, DFGS, BFTS, BFGS, UCTS, UCGS, GBFTS, GBFGS, ASTS, ASGS]
Here is the template I was given:
from search import ... # TODO import the necessary classes and methods
import sys
if __name__ == '__main__':
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
# TODO implement
goal_node = ... # TODO call the appropriate search function with appropriate parameters
# Do not change the code below.
if goal_node is not None:
print("Solution path", goal_node.solution())
print("Solution cost", goal_node.path_cost)
else:
print("No solution was found.")
So as far as python map.py [file] [search] goes, 'file' refers to travel-input.txt and 'search' refers to one of DFTS, DFGS, BFTS,... etc - a user-specified choice. My questions:
Where do I put my search functions? Should they all just be back-to-back in the same block of code?
How do I get the command line to recognize each function from its four or five-letter code? Is it just the name of the function? If I call it just using those letters, how can the functions receive input?
Do I need to reference the input file anywhere in my code?
Does it matter where I save my files in order for them to be accessible from the command line - .py files, travel-input.txt, etc? I've tried accessing them from the command line, with no success.
Thanks for the help!
The function definitions go before the if __name__ == "__main__" block. To select the correct function you can put them in a dict and use the four-letter abbreviations as keys, i.e.
def dfts_search(...):
...
def dfgs_search(...):
....
...
if __name__ == "__main__":
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
search_dict = {"DFTS": dfts_search, "DFGS": dfgs_search, ...}
try:
func = search_dict[search_algo_str]
result = func(...)
except KeyError:
print(f'{search_algo_str} is an unknown search algorithm')
Not sure what you mean by reference, but input_file already refers to the input file. You will need to write a function to read the file and process the contents.
The location of the files shouldn't matter too much. Putting everything in the same directory is probably easiest. In the command window, just cd to the directory where the files are located and run the script as described in the assignment.

Continues variable not triggering while loop

Apologies if this is a repost. I am trying to write a while loop with a continue variable and if/else statement. My issue is that my continue variable is being ignored I cannot find the problem thus far. So far I have moved the while continues == 'y' condition into the else block now I am a bit flummoxed on why this var is being overlooked.
code:
def add_to_existing_file(data):
# data[0]-api response
# data[1]-city
# infile-file object returned from openFile()
# file_name- file name string. check filetype & report version.
continues = 'y' # set up continue variable
while continues == 'y':
file_name = input("Enter File Path to file to be appended: ") # get file from user
if file_name is False:
print("Now Creating Excel File..") # create condition for no user response.
return # if empty response exit function
else:
infile = appends.openFile(file_name) # open file to work with. Returns file object.
added_data = appends.journal_report_1_to_df(infile, file_name, data[0], data[1]) # append selected file to existing df
continues = input("Do you want to append another file? Y or N").lower() # check if new file
return added_data # return new df w/appended data
The problem happens on the last line. You're returning at the end of the first iteration, which exits the loop. This can be fixed by moving the return to the outer scope.
def add_to_existing_file(data):
# data[0]-api response
# data[1]-city
# infile-file object returned from openFile()
# file_name- file name string. check filetype & report version.
continues = 'y' # set up continue variable
while continues == 'y':
file_name = input("Enter File Path to file to be appended: ") # get file from user
if file_name is False:
print("Now Creating Excel File..") # create condition for no user response.
return # if empty response exit function
else:
infile = appends.openFile(file_name) # open file to work with. Returns file object.
added_data = appends.journal_report_1_to_df(infile, file_name, data[0], data[1]) # append selected file to existing df
continues = input("Do you want to append another file? Y or N").lower() # check if new file
return added_data # return new df w/appended data
It should work if you get the second return line (return added_data # return new df w/appended data) to have the same indentation as your while line. As a basic outline for a continue loop:
def function
continues = 'y'
while
if :
elif :
else :
print
continue ?
return

Python: Printing data and receiving user input simultaneously

I want to be able to receive user input and print stuff simultaneously, without them interfering. Ideally, that would be printing regularly and having the user type input to the bottom of the terminal window, for example:
printed line
printed line
printed line
printed line
printed line
(this is where the next print would happen)
Enter Input: writing a new input...
This should look like a chat app or something of that sort.
If there is no good way to do that, any way to print above the input line would be amazing too.
Thanks!
Sadly it is not very feasible to both take input and give output in python, without importing modules to directly interact with the OS.
But you can can get pretty close to it with this code:
import curses
import random # for random messages
#this should be async
def get_message():
message = [str(random.randint(0,9)) for i in range(15)]
return "".join(message)
def handle_command(cmd): # handle commands
if cmd=="exit":
exit(0)
def handle_message(msg): # send a message
raise NotImplementedError
def draw_menu(stdscr):
stdscr.erase()
stdscr.refresh()
curses.raw()
k = 0
typed=""
while True:
# Initialization
stdscr.erase()
height, width = stdscr.getmaxyx()
stdscr.addstr(0, 0, "Welcome to chat app")
msg = get_message()
if msg: # add a message if it exists
stdscr.addstr(1, 0, msg)
if k==ord("\n"): # submit on enter
if typed.startswith("/"): # execute a command
typed = typed[1:]
handle_command(typed)
elif typed.startswith("./"): # bypass commands with a dot
typed = typed[1:]
handle_message(typed)
else:
handle_message(typed) # send the message
typed = ""
elif k==263: # Backspace
typed = typed[:-1] # erase last character
stdscr.addstr(height-1, 0, typed)
elif k==3: # Ctr+C
typed="" # Delete the whole string
stdscr.addstr(height-1, 0, typed)
elif k!=0:
typed += chr(k) # add the char to the string
stdscr.addstr(height-1, 0, typed)
stdscr.refresh() # refresh
# Wait for next input
k = stdscr.getch()
def main():
curses.wrapper(draw_menu)
if __name__ == "__main__": # dont import
main()
the only thing that is to do to update the messages is to type a new char.
And I do not recommend you to build a chat in the terminal for anything other then educational value (trust me I tried it).
It would be better if you tried it using a web platform (e.g. Tauri or Electron)
Also the code cannot:
insert automatic line breaks (it errors)
send any messages (must implement yourself)
show any user names (must implement yourself)

Resources