How to save a function with python (3.2) - python

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'])

Related

How to use variable from constructor inside of methode?

Hi guys hope u are doing well, i'm new with python :)
so i have two issues the first how can i use the variable name from the init to my function game() which it use two args (those args whose make it realy difficult for me !) as u can see in code bellow:
# FUNCTION.py
class penGame():
def __init__(self):
print("Welcome to Pendu Game")
self.name = input("Enter your name: ") # IMPORT THIS VARIABLE FROM HERE
def game(self, letter, rword):
letter = letter.lower()
if letter in rword:
for Id, Value in enumerate(rword):
if Value == letter:
donnee.default_liste[Id] = letter
else:
name2 = self.name # it deosn't work i got 1 missing arg when i run the code from MAIN.py
print(f"try again {name} it's wrong ")
print("-".join(donnee.default_liste))
The second issue is i need to use the same variable (name) from init in another module which is my main module and i couldn't use it cause i tried to create an object from class penGame() like:
myObject = penGame()
name2 = myObject.name
then use the name2 inside of the if condition as u can see bellow but it doesn't work properly cause it run the init again which is not what i want actualy !
any idea how can i did it plz?
#MAIN.py
import donnee
from fonctions import penGame
random_word = random.choice(donnee.liste_words) # creation of random word from liste_words
penGame() #call the constructor
while donnee.counter < donnee.score:
letter = input("Enter the letter: ")
if penGame.check(letter):
print("You cant use more one letter or numbers, try again !")
else:
penGame.game(letter, random_word) # as u can see that's the reason cause i supposed to send 3 args instead of two ! but i only need those two !!?
if penGame.check_liste():
myObject = penGame() # that's cause runing the init everytime !!
name2 = myObject.name
print(f"congratulation {name2} you've guessed the word, your score is: {donnee.choice-donnee.counter} point.")
break
if penGame.loser():
print(f"the word was {random_word.upper()} you have done your chances good luck next time.")
donnee.counter += 1
Thank u in advance hope u help me with that and excuse my english if it wasn't that good :) :)
1.Error
You're calling the methods on the class penGame, not on a instance of penGame.
This causes your missing argument error because the method needs an instance of the class (the self parameter) but don't get one.
Instead use your variable (from the second solution):
if mygame.check(letter):
print("You cant use more one letter or numbers, try again !")
else:
mygame.game(letter, random_word)
...
Replace penGame with mygame also in the other calls.
Error
Save the result of the call in a variable and you won't need to recreate it.
mygame = penGame() # call the constructor
This line can then be removed:
myObject = penGame() # that causes the init to run again because it creates a new instance!

Variable within an instance of a class does not take a new value when it is assigned.

So, I'm working on a command line RPG for the sake of filling time, and re-stretching my Python muscles as I've been out of practice for a couple of years. I used to code in a really functional manner but I'm trying to get my head around object-orientated programming.
Preamble aside, I have an issue where after creating an instance of a class, my class variable is no longer being defined. I've made 2 versions of this which I'll use to demonstrate since I'm finding it hard to articulate.
Below I created a "character" class which I intended to use as a basis for both player characters and npcs. In the first draft I was updating this class, before realising it was going to affect subclasses, when I really just wanted it as a template. Either way, this particular code block worked; it adds the values of 2 dictionaries together, then assigns them to character.characterStats. It then prints them as per displayStats().
from collections import Counter
class character:
def __init__(self, *args, **kwargs):
pass
def __setattr__(self, name, value):
pass
characterRace = ''
characterStats = {}
charLocation = ''
charName = ''
class race:
def __init__(self):
pass
baseStatsDict = {
'Strength' : 5,
'Agility' : 5,
'Toughness' : 5,
'Intelligence' : 5 }
humanStatsDict = {
'Strength' : 1,
'Agility' : 1,
'Toughness' : 1,
'Intelligence' : 1 }
def displayRace():
print("Race: ", character.characterRace, "\n")
def displayStats():
for stat, value in character.characterStats.items():
print(stat, "=", value)
print("\n")
def raceSelection():
playerInput = input("I am a ")
playerInput
playerLower = playerInput.lower()
while "human" not in playerLower:
if "human" in playerLower:
character.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
character.characterRace = 'Human'
break
playerInput = input()
playerInput
playerLower = playerInput.lower()
playerChar = character()
raceSelection()
displayRace()
displayStats()
And this was the output:
Race: Human
Strength = 6
Agility = 6
Toughness = 6
Intelligence = 6
This however is the new code when I tried to tidy it up and turn the class into the template it was meant to be, and started using the class instance playerChar which for whatever reason can't assign the new value to playerChar.characterStats. playerChar.displayStats() prints the characterRace and characterStats variables as empty, even though they are assigned when the player enters the value human.
from collections import Counter
class character:
characterRace = ''
characterStats = {}
def __init__(self):
pass
def displayRace(self):
print("Race: ", self.characterRace, "\n")
def displayStats(self):
for stat, value in self.characterStats.items():
print(stat, "=", value)
print("\n")
class race:
def __init__(self):
pass
baseStatsDict = {
'Strength' : 5,
'Agility' : 5,
'Toughness' : 5,
'Intelligence' : 5 }
humanStatsDict = {
'Strength' : 1,
'Agility' : 1,
'Toughness' : 1,
'Intelligence' : 1 }
def raceSelection():
playerInput = input("I am a ")
playerInput
playerLower = playerInput.lower()
while "human" not in playerLower:
if "human" in playerLower:
playerChar.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
playerChar.characterRace = 'Human'
break
playerInput = input()
playerInput
playerLower = playerInput.lower()
playerChar = character()
raceSelection()
playerChar.displayRace()
playerChar.displayStats()
So this will output:
Race:
\n
\n
\n
So I know it's able to draw from the class race dictionaries and add their contents together as from the previous code. If I try and print the player.x characteristics it won't throw any errors so it recognises they exist. If anyone could explain to me what's going wrong and why in this new iteration, I'd be very grateful.
EDIT: So a friend and I have tried passing the class as an argument of raceSelection(), we've tried printing a string after each call/update of a variable and we've tried entering a string into the variable, printing it, then redefining the variable with a new string.
Input:
class character:
charRace = ''
charStats = {}
charLocation = ''
charName = ''
charString = "Cole said define a string."
Within the if statements:
if "human" in playerLower:
print("Oh, you're just a really ugly human.")
playerChar.charStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
playerChar.charRace = 'Ugly Human'
print("playerChar.charString = ", playerChar.charString)
playerChar.charString = "Redefine."
print("playerChar.charString = ", playerChar.charString)
break
Output:
Oh, you're just a really ugly human.
playerChar.charString = Cole said define a string.
playerChar.charString = Cole said define a string.
Race:
It should not be character.characterStats.items(), but self.characterStats.items(). Similarly for all other values that belong to one, specific character.
Using the name of the class assigns a value that belongs to the class, and is the same for all objects you create. Lookup instance vs class attributes.
So, after trying to move the variables in and out of __init__, trying setattr(), trying to pass any sort of argument through the class just so it had some data, trying to run the instance of the class through a function, none of those solutions came to work in the end.
The solution turned out to be to create a subclass of character and manipulate that instead. I figured this would be alright as well since the player character will mutate throughout gameplay, and will never see further subclasses of itself.

dynamic instances of a class object overwriting each other

I have a simple class that stores simple data. The class is as follows.
class DataFormater:
def __init__(self, N, P, K, price):
self.N = N
self.P = P
self.K = K
self.price = price
The code that calls this class is
from DataFormater import DataFormater
#global variables
ObjectList = [0,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]
ObjectListCounter = 0
# main
print "enter you N-P-K values, followed by a coma, then the price"
print "example ----> 5 5 5 %50 "
print "return as many values as you want to sort, then enter, 'done!' when done."
while True:
RawData = raw_input()
if RawData == 'done!':
break
else:
ObjectList[ObjectListCounter] = DataFormater
ObjectList[ObjectListCounter].N = int(RawData[0])
# very simple test way of putting first indice in ObjectList[ObjectListCounter].N
ObjectListCounter += 1
print ObjectList[0].N
print ObjectList[1].N
My idea is that ObjectList[0] would create that object '1' that I could call with 1.N
But, when I call these, it seems that I have overwritten the previous instances.
this is what prints...
return as many values as you want to sort, then enter, 'done!' when done.
12
1
done!
1
1
Thanks so much! And I know that my post is messy, I don't exactly know how to make it more "pretty"
So, it looks like you are assigning the actual class (instead of an instance of the class) in your loop. Where you do this:
ObjectList[ObjectListCounter] = DataFormater
I think what you actually want is this
ObjectList[ObjectListCounter] = DataFormater(...insert args here....)
EDIT to address the comments:
Your class init method looks like this:
def __init__(self, N, P, K, price):
That means that to create an instance of your class, it would look like this:
my_formater = DataFormater(1, 2, 3, 4)
You would then be able to access my_formater.N which would have a value of 1.
What you are trying to do instead is access a CLASS level attribute, DataFormater.N. This is generally used in situations where you have a constant variable that does not change between instances of the class. For example:
class DataFormater():
CONSTANT_THING = 'my thing that is always the same for every instance'
You would then be able to access that variable directly from the class, like this:
DataFormater.CONSTANT_THING
I hope that clears things up.

How to Type a Word Into an Input, and Then Have Python Search for a Variable Named That in a Module?

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)

Quality Centre, TestSetFactory [PYTHON]

I have a problem with dumping testsets list from HP QC. I'm using TestSetFactory object and simple SQL query and I receive > object (I'd love to receive dictionary filled base dump. What is wrong with this code? If you have a questions about implementation some function, write.
def create(self):
self._report_connector.connect()
self.qc_test_set_factory = self._report_connector._get_factory(self._path)
test_sets = self.qc_test_set_factory.NewList("SELECT * FROM CYCLE ")
if test_sets == None:
print " no results"
for test in test_sets:
pprint.pprint(test) #<---- it print me <COMOBject <unknow>>
print len(test_sets) #<---- it print me 1
Not certain about the accuracy of the rest of the code, but you do not pass a SQL query to the TestSetFactory.NewList method. If you want everything, pass an empty string.
test_sets = self.qc_test_set_factory.NewList("")

Categories