Good morning,
I am wondering if someone can point me in the right direction.
I am trying to have a loop go through a list and add them to a printable list.
let's say the user inputs the number two:
Then it should print go pull out two random class-names of the list.
if the user inputs 4 it should pull out 4 random class-names from the list.
this is so i can print out attributes from the classes afterwards depending on the class-names above. with utskrift1=(vars(plane))
i have tried normal loops but it seem to print out the list in it's entirety, and if i ie go print out x=2 then it prints the entire list two times.
#The classes:
import random
class plane:
def __init__(self, dyr, dyrefamilie, antallbein):
self.dyr = 'Hund'
self.dyrefamilie = 'Hundefamilien'
self.antallbein = '4'
def __str__(self):
return f'undulat(={self.dyr},{self.dyrefamilie},{self.antallbein})'
plane2 = plane(dyr='something', dyrefamilie="something", antallbein='4')
class rocket:
def __init__(self, dyr, dyrefamilie, antallbein):
self.dyr = 'something'
self.dyrefamilie = 'something2'
self.antallbein = '4'
def __str__(self):
return f'katt(={self.dyr},{self.dyrefamilie},{self.antallbein})'
rocket2 = rocket(dyr='something', dyrefamilie="something", antallbein='4')
class boat:
def __init__(self, dyr, dyrefamilie, antallbein):
self.dyr = 'something'
self.dyrefamilie = 'something2'
self.antallbein = '5'
def __str__(self):
return f'undulat(={self.dyr},{self.dyrefamilie},{self.antallbein})'
boat2 = boat(dyr='something', dyrefamilie="something", antallbein='2')
Is it possible to randomise a selectetion and have the list.append(selected random name)
instead of preselecting it like i have done below?
x2=list = []
x1=list = []
# appending instances to list
list.append(plane(1,2,3))
list.append(rocket(1,2,3))
list.append(boat(1,2,3))
random.shuffle(x1) #roterer litt rundt på listen
for i, x1 in enumerate(x1): #kode fra canvas
print('Dyret er en', x1.dyr,'med',x1.antallbein+'-bein'+'.','denne er er en del av', x1.dyrefamilie)
Use the random std package, just put your instantiated objects in a list and you can choose a random one like such:
from random
values = [1,2,3,4,5,6]
rand_val = random.choice(values)
You can do a ranged for, which means that the for will execute x times (range(x)). By this way now you have a for executing X times, and you can index in the list, for example, the current iteration 'i' and print its object properties.
You have to take care about the range(x) and the range of the list/array you are indexing, if the range(x) > range(list) then you will have out of bound errors.
x2=list = []
x1=list = []
# appending instances to list
list.append(plane(1,2,3))
list.append(rocket(1,2,3))
list.append(boat(1,2,3))
random.shuffle(x1) #roterer litt rundt på listen
for i in range(2):
print('Dyret er en', x1[i].dyr,'med',x1[i].antallbein+'-bein'+'.','denne er er en del av', x1[i].dyrefamilie)
Thanks, got i working now :)
used both the solutions explained to me and made this code:
num = int(input("Skriv inn antallet du vil generere"))
x1=list = []
# appending instances to list
values = [plane,rocket,boat]
for i in range(num):
list.append(random.choice(values)(1,2,3))
Related
I am trying to create a new list performing element-wise substruction of two python lists as follows:
from operator import add
number_villains_players = 0
villain_strength = []
player_strength = []
resulten_strength = []
def get_villain_strength(size):
villain_strength = [int(x) for x in input("Enter {} numbers of space separated strength of Villains:".format(size)).split()]
print(villain_strength)
def get_player_strength(size):
player_strength = [int(x) for x in input("Enter {} numbers of space separated energy of Players:".format(size)).split()]
print(player_strength)
def compare_strength():
#resulten_strength = [m-n for (m,n) in zip(player_strength,villain_strength)] #doesn't work
#resulten_strength = [sum(x) for x in zip(player_strength, villain_strength)] #doesn't work
#resulten_strength = [list( map(add, player_strength, villain_strength) )] #doesn't work
resulten_strength = [a*b for a,b in zip(player_strength,villain_strength)] #doesn't work
print(resulten_strength)
def main():
number_villains_players = input("How many Players/Villains?:")
get_villain_strength(number_villains_players)
get_player_strength(number_villains_players)
compare_strength()
if (i > 0 for i in resulten_strength):
print("WIN")
else:
print("LOSE")
main()
But print(resulten_strength) is always empty as [] or [[]]
I have followed all the possible solutions from:
Element-wise addition of 2 lists?
How to mathematically subtract two lists in python? [duplicate]
How to perform element-wise multiplication of two lists in Python?
Can anyone point me where I am going wrong?
You are assigning local lists in methods and they are not global. Thus the top lines defined are always empty. This should fix your problem:
def get_villain_strength(size):
global villain_strength
villain_strength = [int(x) for x in input("Enter {} numbers of space separated strength of Villains:".format(size)).split()]
print(villain_strength)
However it's bad to use globals anywhere. You may want a function with something return.
When you are assigning the same name variable inside a function it will override the global variable's name, until you return from the function. Or to say if you lookup a variable, it first looks up the name in locals(), if nothing found, it'll go globals(). If still nothing found, an exception will be raised.
I'm not sure this is what you're looking for. I made a small modification to your code. I remove your variables declaration and modify your function.
def get_villain_strength(size):
villain_strength = [int(x) for x in input("Enter {} numbers of space separated strength of Villains:".format(size)).split()]
print (villain_strength)
return(villain_strength)
def get_player_strength(size):
player_strength = [int(x) for x in input("Enter {} numbers of space separated energy of Players:".format(size)).split()]
print (player_strength)
return(player_strength)
def compare_strength(x,y):
resulten_strength = [a*b for a,b in zip(x,y)]
return(resulten_strength)
def main():
number_villains_players = input("How many Players/Villains?:")
x = get_villain_strength(number_villains_players)
y = get_player_strength(number_villains_players)
print (compare_strength(x,y))
I am trying to find the max of the "rollList" and everything I have tried isn't working.I'm not very good with coding and the instruction my teacher gave me isn't very clear. I also have to reset "rollList" back to empty for each player and I am very confused.Please someone help.
import random
class Player:
def __init__(self,name ):
self.name = name
self.dice = []
def __str__(self):
return self.name
def roll_Dice(self):
rollDice = random.randint(1, 6)
return rollDice
rounds = 1
rollList = []
newplayer = []
newplayer.append(Player("CAT:"))
newplayer.append(Player("DOG:"))
newplayer.append(Player("LIZARD:"))
newplayer.append(Player("FISH:"))
for rounds in range(1,4):
print("-----------------")
print("Round" + str(rounds))
for p in newplayer:
print(p)
for x in range (4-rounds):
rollDice = random.randint(1, 6)
rollList.append(rollDice)
print(rollList)
max.pop(rollList)
print(rollList)
rollList.clear()
len(rollList)
The line max.pop(rollList) is fairly meaningless. It attempts to call the pop method of the built-in max function, which doesn't exist.
You can get the maximum by just calling max itself:
maxRoll = max(rollList)
If you want to remove that roll, you can (although it doesn't seem necessary, since you'll be clearing the list):
rollList.remove(maxRoll)
If you want to append the maximum to another list:
anotherList.append(maxRoll)
You can find the maximum of a list using max() function:
mylist = [1,2,4,5,6,7,-2,3]
max_value = max(mylist)
Now max_value is equal to 7. You can add this to a new list using append() method:
new_list = []
new_list.append(max_value)
then new_list will be [7]
I report some suggestions to resolve the error I suppose you have: AttributeError: 'builtin_function_or_method' object has no attribute 'pop'
Just change max.pop(rollList) to max(rollList).
Then you have a list of only one element because you are calling methods inside the for rounds in range(1,4): loop, without letting the list populate with other elements. You are calling also clear at each loop.
Also, the for x in range (4-rounds): it is not required, it's a nested loop.
You are printing the list of names without assign to each person the value of roll dice, so who's the winner?
Finally, you defined roll_Dice() as instance method of Person, so why not use it?
So, why not rollList.append(p.roll_Dice()) instead of:
rollDice = random.randint(1, 6)
rollList.append(rollDice)
Hope this can help.
I am working on a game where I need to randomly generate classes for a list. I use a self-made function randList to do this. The code for that function looks like this:
def randList(options, num): #RANDOMLY SELECTS NUM ITEMS FROM LIST OPTIONS
returnVal = [] #CREATE A LIST THAT IT RETURNS
for i in range(num - 1): #FOR DESIRED NUMBER OF RETURN ITEMS
val = r.choice(options) #RANDOMLY SELECT ITEM FROM OPTIONS
returnVal.append(val) #ADD THAT TO RETURNVAL
options.remove(val) #REMOVE IT FROM OPTIONS.
return returnVal #RETURN GENERATED LIST
I am using that to randomly generate monsters and items in a room like so:
class roomParent: #ROOM CHARACTER FINDS
def __init__(self, entities, floor): #INIT WITH ENEMIES IN ROOM, ITEMS ON FLOOR
self.entities = entities #ENEMIES THERE ARE
self.floor = floor #ON FLOOR THERE IS
def generate(self):
global enemiesBeat
if enemiesBeat >= 500:
self.entities = [dragon]
else:
self.entities = randList([goblin, dwarf, slime, naga, troll, beholder], 1)
self.floor = randList([scrap, scrap, scrap, fireJar, ambrosia, sword, spearhead, armor, potion, slimeball], r.randint(0, 3))
room = roomParent([], [])
Just so you know, goblin, dwarf, slimeball, etc. are defined earlier in the code. I don't think they have anything to do with the problem. I generate the room later like this:
def main():
room.generate()
print("Enemies: " + str(room.entities))
main()
I want it to print out a list with two random monsters in it from room.generate(), but it always prints Enemies: []. There are no errors in the code, and after trying to troubleshoot for 10 minutes, I decided to consult he web with no fruits in result of that labor. Thank you in advance for any help you give.
As Oliver points out, the reason you get always get an empty entities array is because self.entities is set to randList([goblin, dwarf, slime, naga, troll, beholder], 1) within generate (I assume the global variable enemiesBeat is less than 500 in your tests).
In your randList function you have an off-by-one error that I mention in the comments which means that the generated list will contain one fewer items than specified by num. As you try to generate a singleton list for self.entities (num = 1), you'll actually have it assigned to an empty list.
You can correct this issue by changing for i in range(num - 1) to for i in range(num) in your randList function.
As an aside, I don't think you need to pass entities and floor as parameters to the roomParent constructor, since it doesn't seem to have any effect. Instead, you could modify the class definition:
class roomParent(object):
def __init__(self):
self.entities = []
self.floor = []
...
And instantiate it like this:
room = roomParent()
Use the random.sample library function.
Also, you might want to rethink your capitalization...snake_case is preferred over inCaps for function names.
possibleRequests = ['test', 'test1']
def inboxReader():
global inbox
tempInbox = []
tempInbox = inbox.inboxMessage #inboxMesage remains filled?
print(inbox.inboxMessage, 'inboxReader')
i = 0
while (i < len(tempInbox)):
if (tempInbox[i] in possibleRequests):
print('THIS IS WORKING')
#print(i)
i+=1
I want to be able to have possible requests point towards a method to run rather than have a long list of if statments. What am I able to do in order to have a variable point towards and run a method.
Cheers,
Marc
You can first create a dictionary of functions then refer to it with tempInbox[i]. Example code below:
def func_a(x):
return x
def func_b(x):
return x*10
tempInbox = (2,3)
fn_dict = {"a":func_a,"b":func_b}
print fn_dict["a"](tempInbox[0]) # returns 2
print fn_dict["b"](tempInbox[1]) # returns 30
so I have a class with a list, and I would like to add a number to all the elements of that list, but not to every list in the class. I tried this:
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
data = [0]*len(list1)
for i,(l1,l2) in enumerate(zip(list1,list2)):
data[i] = class_name(l1,l2)
[(x + 5.0).list_name for x in data]
and it gives me the error:
TypeError: unsupported operand type(s) for +: 'instance' and 'float'
edit: people seem to not understand what I want. In the real code I have, the lists have been added to a class (in this case data) which I've been working with, but one of the lists in the class (specifically referring to magnitudes) needs to be calibrated. I do this by adding a number to every element in that list to calibrate it. This has to be done to the list connected to the class it's in, so I can't edit the list before putting it into the class.
I already have this class created much earlier in my code, and I needed it to be the way it was before so that I could work with all the elements. Now, later in the code, I want to calibrate this magnitude list within the class. Is there a way to do that?
maybe this attempt better illustrates what I'm trying to do:
[x.list_name for x in data] = [x.list_name+5 for x in data]
this also doesn't work, I get this error:
SyntaxError: can't assign to list comprehension
I just feel like it makes people understand what I need.
Check out the Map function for python.
https://docs.python.org/2/tutorial/datastructures.html#functional-programming-tools
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
def add_five(x): return x+5
list1 = map(add_five, list1)
#or instead you can use a lambda
list1 = map(lambda x: x+5 , list1)
EDIT: maybe try this.
for class_name in class_names:
class_name.list_name = map(lambda x: x+5 , class_name.list_name)
If you want to increment one of two lists stored as a list of pairs, this should work:
[x.list_name+5.0 for x in class_names]
x isn't a number, it's the class_name object. You want to retrieve the thing you want to increment from x (x.list_name) and then add 5.0.
You are adding the value to the instance first then accessing the attribute.
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
class_names = [0]*len(list1)
for i,(l1,l2) in enumerate(zip(list1,list2)):
class_names[i] = class_name(l1,l2)
print [x.list_name+5.0 for x in class_names]
I am not sure what you mean, but I have created a simple example:
class class_name(object):
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
self.list1 = []
self.list2 = []
self.list1.append(self.list_name)
self.list2.append(self.other_list)
print "My List1: ", self.list1
print "My List2: ", self.list2
def input_data():
list_one = raw_input("Data for list 1: ")
list_two = raw_input("Data for list 2: ")
class_name(list_one, list_two)
if __name__ == '__main__':
input_data()
Is that what you want to?