So I have a dictionary, that translates english to swedish, and would like to let the user add new words to it. However, despite my attempts at updating the dictionary with the input, the values of the dictionary always reset to the base case when re-running Python. Check out the code:
dictionary = {"merry": "god", #base dictionary
"christmas": "jul",
"and": "och",
"happy": "gott",
"new": "nytt",
"year": "ar"
}
def add(): #Prompting user to add words to the dictionary, by asking how many he wants to add ( 0 is an option)
while True:
try:
a = int(input("How many words do you want to add to the dictionary? "))
if a >= 0:
break
else: #don't want negative values
raise ValueError
except ValueError:
print("Not valid ")
return a
for i in range (add()):
key_i = input(f"Enter english word {i + 1}: ")
value_i = input("Enter translation: ")
dictionary[key_i] = value_i
print(dictionary)
Try using this class:
import pickle
class Logger:
def save(self, obj, path):
with open(path, 'wb') as logfile:
pickle.dump(obj, logfile)
def load(self, path):
with open(path, 'rb') as logfile:
new_instance = pickle.load(logfile)
return new_instance
Then, at the beginning of your code create a new instance of the Logger and load (if already existing) the saved dictionary:
path = "./path/to/your/local/directory/" #change this with the path where you have previously saved your dictionary logs
logger = Logger()
dictionary = logger.load(path)
Then, at the end of your code, create a new instance of the logs and save them:
logger.save(dictionary, path)
Related
I am trying to do a dictionary database, like actual dictionary. User input key word and meaning and program saves it in database. Like input word: rain , input meaning of the word: water droplets falling from the clouds then program makes it a dictionary. So far I can manage do this but it doesn't work the way I want.
class Mydictionary:
def __init__(self):
self.key=input("Please input word: ")
self.value=input("Please input meaning of the word: ")
def mydictionary(self):
self.dic={self.key:self.value}
Mydic=Mydictionary()
Mydic.mydictionary()
It works for only one time. I want to save keywords and values as much as I want. I want to create a dictionary database.
As far as I could see, it is working perfectly as you explained...
If you were thinking that you want to insert many values in a single object, this won't work as you are getting the only one input while calling the constructor.
You have to implement it like,
import json
class Mydictionary:
def __inint__(self):
self.dic = {}
def mydictionary(self):
self.key=input("Please input word: ")
self.value=input("Please input meaning of the word: ")
self.dic[self.key] = self.value
def save(self, json_file):
with open(json_file, "w") as f:
json.dump(self.dic, f)
Mydic=Mydictionary()
Mydic.mydictionary()
Mydic.mydictionary()
# to save it in a JSON file
Mydic.save("mydict.json")
Now you can call the method n times to add n entries...
You can look at the answer by #arsho below which I would consider as a good practice. Naming the function appropriately wrt the actual function they are doing is important.
To insert new key - value pair to your dictionary, you need to create a method to get data from the user.
In __init__ you can declare an empty dictionary and then in insert method you can get a new entry from the user.
Moreover, to display the current elements of the dictionary you can create a separate method with name display.
json built-in can directly write and read dictionary type data from an to a json file. You can read about json from official documentation on json.
import json
import os
class Mydictionary:
def __init__(self, file_name):
self.json_file = file_name
if os.path.exists(file_name):
with open(self.json_file, "r") as json_output:
self.data = json.load(json_output)
else:
self.data = {}
def insert(self):
user_key = input("Please input word: ")
user_value = input("Please input meaning of the word: ")
self.data[user_key] = user_value
with open(self.json_file, "w") as json_output:
json.dump(self.data, json_output)
def display(self):
if os.path.exists(self.json_file):
with open(self.json_file, "r") as json_output:
print(json.load(json_output))
else:
print("{} is not created yet".format(self.json_file))
Mydic=Mydictionary("data.json")
Mydic.display()
Mydic.insert()
Mydic.insert()
Mydic.display()
Output:
data.json is not created yet
Please input word: rain
Please input meaning of the word: water droplets falling from the clouds
Please input word: fire
Please input meaning of the word: Fire is a chemical reaction that releases light and heat
{'rain': 'water droplets falling from the clouds', 'fire': 'Fire is a chemical reaction that releases light and heat'}
Disclaimer: This is just a concept of class and method declaration and usage. You can improvise this approach.
Try:
import json
class MyDictionary:
__slots__ = "dic",
def __init__(self):
self.dic = {}
def addvalue(self):
"""Adds a value into the dictionary."""
key=input("Please input word: ")
value=input("Please input meaning of the word: ")
self.dic[key] = value
def save(self, json_file):
"""Saves the dictionary into a json file."""
with open(json_file, "w") as f:
json.dump(self.dic, f)
# Testing
MyDic = MyDictionary()
MyDic.addvalue()
MyDic.addvalue()
print(MyDic.dic) # Two elements
MyDic.save("json_file.json") # Save the file
class dictionary():
def __init__(self):
self.dictionary={}
def insert_word(self,word):
self.dictionary.update(word)
def get_word(self):
word=input("enter a word or enter nothing to exit: ")
if word=="":
return None
meaning=input("enter the meaning: ")
return {word:meaning}
def get_dict(self):
return self.dictionary
if __name__ == "__main__":
mydict=dictionary()
word=mydict.get_word()
while word:
mydict.insert_word(word)
word=mydict.get_word()
print(mydict.get_dict())
this will keep taking inputs until you give it a null value and then print out the dictionary when u stop.
I have been using this basic code for a simple inventory system. I need to expand this to keep track of another list of parts that are leaving the inventory. I thought I might be able to do this by creating another namedtuple for the data structure . I have some problems because the two namedtuples would need to exist and be accessed at the same time. How can I do this in python?
import sys
from collections import namedtuple
class Part(namedtuple("Part", "name part_number quantity")):
def __str__(self):
return ", ".join(self)
class Parts(dict):
def display (self):
if not self:
print('No Parts Found in List')
return
print()
print('Name, Part Number, Quantity')
for part in self.values():
print(part)
print()
def add(self, *args):
try:
name, part_number, quantity = args
except ValueError:
name = input("Enter Name of Part:\n ")
part_number = input("Enter Part Number:\n ")
quantity = input("Enter Quantity:\n ")
self[name] = Part(name, part_number, quantity)
def remove(self, part=""):
if not part:
part = input("Enter Part Name to Remove\n")
try:
del self[part]
except Keyerror:
print("Part {} not found.".format(part))
def edit(self, part=""):
if not part:
part = input("Enter Part Name to Edit\n")
try:
new_name = input("Enter new part name\n")
number = input("Enter new part number\n ")
quantity = input("Enter new quantity\n ")
self[part] = Part(new_name, number, quantity)
except KeyError:
print("No such Part exists: {}".format(part))
def save(self, filename=""):
if not filename:
filename = input("Filename to save: ")
with open(filename, "wt") as out_file:
for part in self.values():
out_file.write("{}\n".format(part))
print("File saved")
def load(self, filename=""):
if not filename:
filename = input("Filename to load: ")
try:
with open(filename, "rt") as in_file:
for line in in_file:
if not line:
break
part, part_number, quantity = line.strip().split(",")
self.add(part, part_number, quantity)
except FileNotFoundError:
print("File Not Found.")
def menu(inventory):
menu_list = [("Parts", inventory.display),
("Add Part", inventory.add),
("Remove Part", inventory.remove),
("Edit Part", inventory.edit),
("Save Part List", inventory.save),
("Load Part List", inventory.load),
("Exit", sys.exit)]
while True:
for i, (name, _) in enumerate(menu_list, 1):
print("{}. {}".format(i, name))
try:
user = int(input("Selection> "))
menu_list[user-1][1]()
except (ValueError, IndexError):
print("Selection Not Valid.")
def main():
print("Welcome to Sticks&Stones Inventory System")
inventory = Parts()
while True:
menu(inventory)
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, SystemExit):
print("Exiting Program...")`enter code here
`
Your two tuples (or more) can exist and be accessed at the same time, with no problem!
class Parts(namedtuple("Parts", "name part_number quantity")):
def __str__(self):
return ", ".join(self)
class RemovedParts(namedtuple("RemovedParts", "name quantity")):
pass
# etc.
With that said, let me make some suggestions:
As #juanpa.arrivillaga has already suggested, your current Parts class should not extend dict. Ask yourself, "does my system have a dictionary because it's convenient to the implementation, or is my system a dictionary because of some fundamental property?"
I think you'll see that the has-a/is-a question in this case is a pretty good way to see that you should use composition (has-a) rather than inheritance (is-a) in your design.
Consider renaming your Parts class to something different. What you're modeling is really a thing that contains information about the parts, and how many you have on hand. Perhaps PartsInfo or even Inventory would be a better class name.
Consider separating the actual management object from the user interface. Perhaps you have an Inventory object and an InventoryUI object? Move pretty much all of the functions that interact with the user into the UI class.
Write some helper functions (methods) to do things like read in part numbers or part names and confirm that they are valid. Maybe you need a pair of dictionaries, one for part-number -> part-info and the other for part-name -> part-info?
Consider using the json library to serialize your data for load/save operations.
I want the following counter to check the order num class inside a dictionary thats inside a list.
...code...
self.counter = count(1)
def submit(self):
if Database.xoomDatabase[0]["Num Orden"] == next(self.counter):
self.counter = Database.xoomDatabase["Num Orden"]
Database.xoomDatabase.append(ordenOrganiz)
The reason I'm doing this type of counter is because I'm dumping a pickle file everytime the app closes, that contains Database.xoomDatabase. When the app is executed, the pickle dump gets loaded and all the dictionaries inside of it get pushed back into Database.xoomDatabase. This is the dictionary that's saved on Database.xoomDatabase:
global ordenOrganiz
ordenOrganiz = {"Num Order": nicenum,
"Nombre": nombre,
"Email": email,
"Num Tel/Cel": num,
"Orden Creada:": fechacreacion1,
"Fecha de Entrega": fechaentrega}
print(ordenOrganiz["Nombre"])
return dict(ordenOrganiz)
My questions is: How can I start the counter in exactly the last "Order Num" the is loaded from the pickle dump file?
EDIT:
This is how, with the help of Anand S Kumar, I got it it to work:
if len(Database.xoomDatabase) == 0:
newCount = 0
else:
newCount = max(Database.xoomDatabase, key = lambda x:x['Num Orden'])["Num Orden"]
nombre = contents1
nicenum = int(newCount) + 1
This loop checks if there are any saved dictionaries on the list. If there ar no dics., the count starts at 1. If there are already saved dics., the count will start from the last "Orden Num"(Order Number) saved into the pickle dump.
xoomDatabase = []
if path.isfile(file_path) == False:
open(file_path, "w").close()
else:
loadLis = open(file_path, "rb")
dalis = pickle.load(loadLis)
loadLis.close()
xoomDatabase.extend(dalis)
This loops check if there is any file to load, if there isn't, it cretes one. If there's already a saved pickle dump, then it will load the list with previously saved dicts.
You can create a class variable directly inside the class, and then access it using Class.<variable> and also in __init__() function use this Class.<variable> to initialize the counter for each variable and increment the counter.
Example -
class TempClass
counterInit = 0
def __init__(self):
self.counter = TempClass.counterInit
TempClass.counterInit += 1
...
And then at the start of the program, read back the data from the pickle dump and then take the largest counter and set it to counter as given in below example.
Example -
TempClass.counterInit = max(Database.xoomDatabase, key = lambda x:x['Num Orden'])
The above max() gives the largest Num Orden from the list of dictionaries.
As part of a beginners' university Python project, I am currently creating a database of words, be it Nouns, Verbs, Determiners, Adjectives.
Now the problem I am having is that the words being read into the program via the lexicon.readfromfile method are being put into the dictionary via an instance of a class ( be it noun, verb or adjective ). This created the problem that I have absolutely no idea how to call these objects from the dictionary since they do not have variables as keys, but rather memory locations (see the following):
{<__main__.Verb object at 0x02F4F110>, <__main__.Noun object at 0x02F4F130>, <__main__.Adjective object at 0x02F4F1D0>, <__main__.Noun object at 0x02F4F170>}
Does anyone have any idea how I can call these keys in such a way that I can make them usable in my code?
Here is the part I'm stuck on:
Add a method getPast() to the Verb class, which returns the past tense of the Verb. Your getPast() method can simple work by retrieving the value of ‘past’ from the attributes.
Here is a the majority of the code, leaving out the Noun and Adjective classes:
class Lexicon(object):
'A container clas for word objects'
def __init__(self):
self.words = {}
def addword(self, word):
self.words[word.stringrep] = word
def removeword(self, word):
if word in self.words:
del(word)
print('Word has been deleted from the Lexicon' )
else:
print('That word is not in the Lexicon')
def getword(self,wordstring):
if wordstring in self.words:
return self.words[wordstring]
else:
return None
def containsword(self,string):
if string in self.words:
return True
else:
return False
def getallwords(self):
allwordslist = []
for w in self.words:
allwordslist.append(self.words[w])
return set(allwordslist)
def readfromfile(self, x):
filehandle = open(x, 'r')
while True:
line = filehandle.readline()
if line == '':
break
line = line.strip()
info = line.split(',')
if info[1] == 'CN' or info[1] == 'PN':
noun=Noun(info[0],info[1])
noun.setattribute('regular',bool(info[2]))
self.addword(noun)
elif info[1] == 'A':
adjective=Adjective(info[0],info[1])
adjective.setattribute('comparative', bool(info[2]))
self.addword(adjective)
elif info[1] == 'V':
verb=Verb(info[0],info[1])
verb.setattribute('transitive', bool(info[2]))
verb.setattribute('past', info[3])
self.addword(verb)
def writetofile(self, x):
filehandle = open(x, 'w')
for t in self.words.values():
filehandle.write(t.getFormattedString() + '\n')
filehandle.close()
#---------------------------------------------------------------------------#
class Word(object):
'A word of any category'
def __init__(self,stringrep,category):
self.wordattribute = {}
self.stringrep = stringrep
self.category = category
def setattribute(self, attributename, attributevalue):
self.wordattribute[attributename] = attributevalue
def getvalue(self,name):
if name in self.wordattribute:
return self.wordattribute[name]
else:
return none
def __str__(self):
return self.stringrep + ':' + self.category
def __lt__(self,otherword):
return self.stringrep < otherword.stringrep
class Verb(Word):
'"Represents a Verb."'
def __init__(self, stringrep, category):
super().__init__(stringrep,category)
def istransitive(self):
return self.transitive
def getFormattedString(self):
n = '{stringrep},{category}'
n = n.format(stringrep=self.stringrep, category=self.category)
for i in range(1,2):
for v,b in self.wordattribute.items():
n = n+','+str(b)
return n
You have a set there, not a dictionary. A set will let you check to see whether a given instance is in the set quickly and easily, but, as you have found, you can't easily get a specific value back out unless you already know what it is. That's OK because that's not what the set is for.
With a dictionary, you associate a key with a value when you add it to the dictionary. Then you use the key to get the value back out. So make a dictionary rather than a set, and use meaningful keys so you can easily get the value back.
Or, since I see you are already making a list before converting it to a set, just return that; you can easily access the items in the list by index. In other words, don't create the problem in the first place, and you won't have it.
Sorry about the long title but I can't think of a better way to word this. I'm creating a basic sort of A.I. program, and one thing I want it to do is be able to define words, like a dictionary. Now I would use a python dictionary, but I want the database to stay intact after the program is finished, hence the reason I'm using a module. I also want the program to add to the module if the word isn't already defined.
Here's the part of the program I was using, but I'm stuck at this point:
from nouns import *
def search():
try:
print(nouns.(eval(definer)))
#This gives me a syntax error
except NameError:
define = input("I do not know what this is. Define it for me please: ")
n = open("nouns.py","a")
n.write("\n")
n.write(definer)
n.write("=")
n.write("\"")
n.write(define)
n.write("\"")
n.close()
print("You will have to restart the program before it recognizes the new definition.")
asking()
def asking():
global words
thewords = input("What do you want to talk about next?\n")
words = thewords.lower()
main()
def main():
global definer
defining = ("what is a ")
if defining in words and ("?") in words:
definerr = str(words[10:-1])
definer = definerr.lower()
search()
defining = ("what is ")
if defining in words and ("?") in words:
definerr = str(words[8:-1])
definer = definerr.lower()
search()
defining = ("what is a ")
if defining in words:
definerr = str(words[10:])
definer = definerr.lower()
search()
defining = ("what is ")
if defining in words:
definerr = str(words[8:])
definer = definerr.lower()
search()
asking()
So, how do I type a word into an input, then have python search for a word named that variable, and finally have python print that variable in the original program?
You need to store your objects in file or something similar. If you want you dictionary to be editable from outside the application I'd recommend json, if you want it to only be editable from with your application, use pickle. I'll give a json example:
words.json:
{
'thing': 'some object'
}
python:
import json
with open('words.json') as f:
words = json.load(f)
print words['thing']
... # Your program here, then as a final act before finishing
with open('words.json', 'w') as f:
json.dump(words, f)
Some code to get you started using the json module and in-memory dict editing:
#!/usr/bin/env python
import json
import os
FILE = "defs.json"
# load file (if exists...)
if not os.path.exists(FILE):
defs = {}
else:
with open(FILE) as defs_file:
try:
defs = json.load(defs_file)
except ValueError:
# invalid file - replace it with valid empty file
defs = {}
# do stuff...
defs['new definition'] = 'new value'
# save dict to the file
with open(FILE, 'w') as defs_file:
json.dump(defs, defs_file)