Setting up a counter to know in which number to start - python

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.

Related

having issues affecting the value of an initialized class through methods in python. it keeps overriding the value

class SmarJug:
""""smart jug class needs to be initially set contents to the value of 100"""
def __init__(self, contents=100):
self._contents = contents
def pour(self):
if self._contents == 0:
print(f'Sorry this jug is empty!')
else:
print(f'Pouring...')
self._contents = int(self._contents) - 25
print(self._contents)
issue is that when i run test1.pour() logic happens but the initial value is set to 100 again
tes1 = SmarJug()
tes1.pour()
Nothing you've shown resets the value. Sounds like you are expecting the variable to be stored across multiple executions of the code. This is not true. Every time you define tes1 = SmarJug(), the initial contents=100. Therefore each run "resets" the value...
If you want to persist the object state across runs, then you'll need to save/load the contents into a file, for example
import json
with open('jug.json') as f:
contents = json.load(f).get("contents")
if contents is None:
tes1 = SmarJug()
else:
tes1 = SmarJug(int(contents))
tes1.pour()
jug = {"contents" : tes1._contents}
with open('jug.json') as f:
contents = json.dump(jug, f)

saving a input value in a dictionary in Python

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)

List iterate inside class method causing infinite loop in python

Hello Friends I'm a newbie to Python and trying to implement some sample code using Classes in Python. I could implement using individual functions but when I'm trying to integrate via class I'm ending up in infinite loop.
Here is the snippet of code and logic I'm reading a file where contents are like as follows:
File input.txt contents
fruit apple
animal cat
vehicle car
My final aim is to get output as dictionary of contents with key and value like below dict and later I want to search with keys and do processing.
{'fruit': 'apple', 'animal': 'cat', 'vehicle':'car'}
class FileHandler:
def __init__(self, dbf):
self.logger = logging.getLogger('fileHandler')
self.thefile = open(dbf, 'r')
print(self.thefile)
def __enter__(self):
return self
def __exit__(self,type,value,traceback):
self.thefile.close()
with FileHandler(dbf='input.txt') as fh:
config = [line.strip() for line in (fh.thefile.readlines())]
Here is the class definition:
class GetExtract:
def __init__(self, config_list=None, config_dict=None):
if (config_list, config_dict) is None:
config_list = []
config_dict = {}
self.config_list = config_list
self.config_dict = config_dict
def assign_sig(self, listin):
self.config_list = listin
#for item in listin:
# self.config_list = listin.extend(item.split())
#print("final dict is \n", self.config_list) ## break items into list
## Map adjacent items as key and value
#for index, kvalue in enumerate(self.config_list):
# if index %2 == 0:
# self.config_dict[kvalue] = self.config_list[index+1]
# return self.config_dict ## create a mapping inside dict
xtemp = GetExtract()
xtemp.assign_sig(config)
When I try to iterate using the for loop inside the class it goes into an infinite loop which I have commented in the above code for.
Please advise me how to achieve my aim using classes.
for item in listin:
self.config_list = listin.extend(item.split())
The object you are looping over (in this case listin) is being modified whithin the loop. Never do that.

Run condition in GAE datastore

class ModelCount(db.Model):
type = db.StringProperty(required=True,default='Default-type')
count = db.IntegerProperty(required=True, default=0) #Current counter
def to_dict(self):
d = dict([(p, unicode(getattr(self, p))) for p in self.properties()])
d["id"] = self.key().id()
return d
#Increments counter
#staticmethod
def increment_counter(en_name):
modelCount = ModelCount.all().filter('type',en_name).get()
if modelCount:
modelCount.count += 1
modelCount.put()
else:
modelCount = ModelCount(type=en_name, count=1)
modelCount.put()
In the above code (increment_counter), I am reading the count from ModelCount and incrementing it by one. I face run condition in increment_counter method when the server receives multiple requests. So I want to make increment_counter atomic. If I use #db.transactional on increment_counter, I get "Only ancestor queries are allowed inside transactions" error.
How can I fix this and make it atomic?
you could try to use sharding https://developers.google.com/appengine/articles/sharding_counters
full source available at https://github.com/GoogleCloudPlatform/appengine-sharded-counters-python

How to save a function with python (3.2)

Just started learning python (3.2) and have a question. I have created a some code that creates some stats (as in health, magic etc etc) and the numbers are randomly generated. Here is the code...
def stats ():
print ()
print ('Some text.')
done = False
while not done :
charname = input(str('What is the name of the character? '))
hp = random.randint(5,20)
mp = random.randint(4,20)
stre = random.randint(3,20)
agi = random.randint(3,20)
spd = random.randint(3,20)
wis = random.randint(3,20)
intel = random.randint(3,20)
cha = random.randint(3,20)
print (charname)
print ('HP:',hp)
print ('Mana:',mp)
print ('Strength:',stre)
print ('Agility:',agi)
print ('Speed:',spd)
print ('Wisdom:',wis)
print ('Intelligence:',intel)
print ('Charisma:',cha)
print ()
done = input('All done? yes/no ')
if( done == 'yes' ):
done = True
elif(done == 'no'):
done = False
while done :
print ()
print ('Now that your stats are done, you can go on your adventure!')
done = False
Now this works fine, but how could I call on this function again in case I wanted to view the stats again with it keeping the same stats it randomly generated before?
Sorry if the question is bit off. Still all new to programming.
Thank you.
Since you're new to programming, here's some advice on a different way to store your data (without actually coding it for you).
First, define a Character class, with attributes for HP, mana, etc. I don't know if you know about classes yet, but here's an intro. There are various tricks you can do to get around having to explicitly write in the names for HP, mana, etc, but for learning's sake, it's probably better to do them all manually for now.
Then def a random_character() function that creates a Character object with random attributes, defined like how you're doing now, but instead of saving them in different variables that Python doesn't know have anything to do with one another, puts them in a single Character.
Add a __str__ method to the Character class, so that if char is a Character, print(char) prints out the attributes.
If you want to be able to keep track of characters, use pickle to store it in files.
If you have questions about any part of this, just ask. :)
Your function now uses local variables to record the stats you've generated. You'll need to bundle them together into either a dictionary or an object so that you can pass them around as a value.
For example:
def get_stats():
stats = {}
stats['charname'] = input(str('What is the name of the character? '))
stats['hp'] = random.randint(5,20)
stats['mp'] = random.randint(4,20)
stats['stre'] = random.randint(3,20)
stats['agi'] = random.randint(3,20)
stats['spd'] = random.randint(3,20)
stats['wis'] = random.randint(3,20)
stats['intel'] = random.randint(3,20)
stats['cha'] = random.randint(3,20)
return stats
def print_stats(stats):
print (stats['charname'])
print ('HP:',stats['hp'])
print ('Mana:',stats['mp'])
print ('Strength:',stats['stre'])
print ('Agility:',stats['agi'])
print ('Speed:',stats['spd'])
print ('Wisdom:',stats['wis'])
print ('Intelligence:',stats['intel'])
print ('Charisma:',stats['cha'])
print ()
you can use def keyword to declare functions . Def
def stat():
you can call the function like this in your desired location. stat()
If you want easy storage in an external file, you can use the pickle module, and a dictionary of the values you wish to store.
for example:
import pickle
stats={}
stats['hp'] = random.randint(5,20)
stats['mp'] = random.randint(4,20)
stats['stre'] = random.randint(3,20)
stats['agi'] = random.randint(3,20)
stats['spd'] = random.randint(3,20)
stats['wis'] = random.randint(3,20)
stats['intel'] = random.randint(3,20)
stats['cha'] = random.randint(3,20)
#save the stats into the file by using:
pickle.dump(stats,yourstatfile.pkl)
#then to load it again from any program just use:
stats=pickle.load(yourstatfile.pkl) #you assign it to a variable, so if i used the variable 'lol' i would use it as lol['hp'] not stats['hp'] like it was originally used when saving.
#then you can use it just like any other dictionary:
print "your hp: "+str(stats['hp'])

Categories