how can i call one function inside of another? - python

I just want to make a separate function in the dice class which would allow me to store every 'roll' in the list_of_rolls list in the 'rolls' function. so when 'rolls' is called it would display a list of every 'roll' executed (if any).
I tried using global but it didn't work (maybe i did it wrong), i also heard using global is a bad habit so if there is another way i wouldn't mind. my indents are proper it is just not shown here.
import random
class Dice:
def roll(self):
x = random.randint(1, 6)
y = random.randint(1, 6)
roll_list = (x, y)
return roll_list
def rolls(self):
list_of_rolls = []
final = list_of_rolls.append()
return final

There are a few ways you can do this. However I am just going to suggest the most straight forward way which is to use text file to store your history of rolls within the Dice class itself.
Note that the con will be multiple instances of Dice will be accessing the same history file
However this implementation may not be optimized, as everytime you roll a dice you are opening the file and appending new rolls to it. It may not be ideal if you need millions of rolls. That say I will leave it to you to better/optimize the solution.
import random
class Dice:
list_of_rolls = []
filename = "./roll_history.txt" # a textfile to store history of rolls
def __init__(self):
try: # just to check if file exists if not create one for storing
file = open(self.filename, "r")
except FileNotFoundError:
print("File not found")
file = open(self.filename, "x") #creates file
finally:
file.close()
with open(self.filename, 'r') as opened_file_object:
self.list_of_rolls = opened_file_object.read().splitlines()
print(self.list_of_rolls)
def roll(self):
x = random.randint(1, 6)
y = random.randint(1, 6)
roll_list = (x, y)
self.list_of_rolls.append(roll_list) # updates the array with latest roll
file = open(self.filename, 'a') # 'a' for appending new rolls
# I append a newline so that the rolls are more readable in the text file
file.write('(' + str(x) + ',' + str(y) + ')\n') # appends a newline
return roll_list
def rolls(self):
return self.list_of_rolls
print(Dice().roll()) # append 2 dice rolls here
print(Dice().roll())
print(Dice().rolls()) # you should see 2 dice rolls here
try closing your python program and run it again,
Dice() # you should be able to see past rolls

Declare list_of_rolls as member variable of the class instead of defining it in the function. Create a constructor to initialize it. If you do it after class name than it becomes for the class and not at instance level.
import random
class Dice:
# list_of_rolls = [] # becomes class variable and dont use it
def __init__(self):
self.list_of_rolls = []
def roll(self):

Related

Dice roller - Python OOP

I need to make a program where the user should be able to define
How many sides are on the dice
How many times the dice is rolled
How many dice there are
I'm trying to build the basic structure. I have started with the properties sides and rolled which will be in my main class Dice. I'm assuming here that I will always have 1 dice. Then I created a subclass called Dices( trying to make it plural) which will inherit the Dice class members.
However, I'm trying to introduce a new property called number_of_dice which I haven't set up in my main class, and it will take more than 1 dice. When I try to print print(input_more_dice.number_dice()) I get the following error:
in __init__
self.number_of_dice = number_of_dice
NameError: name 'number_of_dice' is not defined
I'm sure I'm not setting this up correctly. Here is my (Updated) code:
import random
# One dice result
class Dice:
sides = 0
rolled = 0
def __init__(self, sides, rolled):
self.sides = sides
self.rolled = rolled
def rolling_output(self):
if self.rolled == 1:
rolled_once = random.randint(0, self.sides)
return rolled_once
else:
list_of_results = [];
for i in range(self.rolled):
rolled_more = random.randint(0,self.sides)
list_of_results.append(rolled_more)
return list_of_results
# More than one Dice
class Dices(Dice):
number_of_dice = 0
def __init__(self, number_of_dice):
self.number_of_dice = number_of_dice
super().__init__(sides= self.sides, rolled= self.rolled, number_of_dice= self.number_of_dice)
def number_dice(self):
return self.number_of_dice
# input_one_dice = Dice(3, 3)
# print(input_one_dice.rolling_output())
input_more_dice = Dices(number_of_dice= 2)
print(input_more_dice.number_dice())
Why is my subclass not accepting a new property?
The number of parameters in the "init" in Dice class is 2(excluding self). But you tried to call the class Dice in Dices using 3(excluding self) parameters. Is it because of That? I am not that much familiar with Object Oriented programming. Also return doesn't work very well under loops.

Declaring class methods in a function and accessing its values from another function

I've never really used classes before, I just simply went the easy way (global variables), and now I would like to make my code right to avoid future complications.
This is my code:
from dearpygui.core import *
class Engine:
def __init__(self,serial,type,profile):
self.serial = serial
self.type = type
self.profile = profile
def apply_selected_file():
res = []
html_name= "example.html"
path= "C:/"
#Function that reads data from a file and saves selected data in a list
res = html_imp(path + '/' + html_name)
#I would like to remove the code below and use a class for each file instead
setvalue(sn1,es[0]) #shows a label with this value
setvalue(type1,res[1]) #shows a label with this value
setvalue(profile1,res[2]) #shows a label with this value
return res
def button():
#This was my initial idea but it doesn't seem to work.
# res = apply_selected_file()
# E = Engine(res[0],res[1],res[2])
I have in mind reading multiple HTML files so using a class would be much easier than declaring variables for each file:
1- Use apply_selected_file to read a file and assign values (s/n,type,profile) to a new class (E1,E2,E3,...,E20,...)
2- Use another function button() to access those stored class values.

pickle not saving (or loading?) object list variable outside __init__

Python beginner question here. I'm trying to save and load objects using pickle in a text based game I'm making, and list variables are not loading as expected. This is the code I wrote to test the problem:
import pickle
class my_class(object):
def __init__(self, x):
self.x = x
self.y = [1,2,3]
a = [4,5,6]
b = 8
def save(object1):
print("Game saved")
pickle_out = open("saveobject1","wb")
pickle.dump(object1, pickle_out)
pickle_out.close()
def load():
print("Loading......")
pickle_in = open("saveobject1","rb")
object1 = pickle.load(pickle_in)
return object1
object1 = my_class(10)
print ("object1.x = " + str(object1.x))
print ("object1.y = " + str(object1.y))
print ("object1.a = " + str(object1.a))
print ("object1.b = " + str(object1.b))
print ("\n")
answer = input("Would you like to save (s) or load (l)?: ")
if answer == "s":
save(object1)
object1.x = 20
object1.y[2] = 6
object1.a[2] = 12
object1.b = 16
if answer == "l":
object1 = load()
print ("object1.x = " + str(object1.x))
print ("object1.y = " + str(object1.y))
print ("object1.a = " + str(object1.a))
print ("object1.b = " + str(object1.b))
print ("\n")
List variables within init save and load OK (y in this example) but list variables outside init do not (a in this example). However, non-list variables outside init do save and load. Thanks in advance for advice.
All variables within __init__ are instance variables, and so will be saved. Both the list and non-list variables outside __init__ are class variables, so won't be saved.
However, when you change object1.b that creates the instance variable b instead of setting the class variable, so it will be saved. However, when you modify object1.a, you are not reassigning it, just an element of it, so it is still an (unsaved) class variable.
If you want to save it, make it an instance variable or save the class variables separately.

Python Referencing Object Inside Object Incorrectly

I have 2 python classes: Player, and Board. The board contains a dict with "A1" reference style for spaces.
player.py's Player class:
from board import Board
class Player:
def __init__(self):
self.name = input("Name: ")
self.board = Board(3, ["A", "B", "C"])
board.py's Board class:
class Board:
EMPTY = "0"
spaces = {}
def __init__(self, size, letters):
for let in letters:
for num in range(1, size + 1):
self.spaces["{}{}".format(let, num)] = self.EMPTY
def place_piece(self, spot):
self.spaces[spot] = "X"
def display_board(self):
for let in letters:
for num in range(1, size + 1):
print("\n" + self.spaces["{}{}".format(let, num)]
When Player is instantiated, it creates a Board object inside.
2 players are created, and each is added to the list players[]. Each player's turn is selected with a simple 1/0 variable called current_player.
from player import *
from board import *
current_player = 1
players = []
player_1 = Player()
player_2 = Player()
players.append(player_1)
players.append(player_2)
while True:
# Switches players
current_player = abs(current_player - 1)
# Prints the current player's name
print(players[current_player].name)
# Calls some method which should alter the current player's board
players[current_player].board.place_piece(input("> "))
# Calls some method which should show the current player's board
players[current_player].board.show_board()
Obviously, very simplified. The name prints out correctly every single time. The board, however, only uses the first player's board for both players. I know it's working because the players' name prints correctly.
The issue persists even if the boards are created separately and placed in their own list.
What am I doing wrong?
As it is written now the code posted shouldn't be working. The two methods in Board, place_piece and display_board, need to accept 'self' as a first argument.
Assuming this is a typo here's what's happening. The class Board is created with a class member spaces. Each time you're referencing self.spaces in an object, it is not found in the object is instead looked up in the class. Meaning you're using the same dict for all object of the class Board. Instead, to create a regular member place the declaration in the init method as you do in the Player class:
class Board:
EMPTY = "0"
# Remove spaces = {}
def __init__(self, size, letters):
self.spaces = {}
...
Finally, since you're using Python 2x please let me encourage you to always use new style classes (i.e. write class Board(object)). See What is the difference between old style and new style classes in 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