Selecting an element of a list inside a list (python) - python-3.x

Im attempting to write a turn based, pokemon-esque, game to test my python skills & learn new things.
I'm having trouble selecting an element from a list inside of another list.
Punch = ["Punch!", 20]
Kick = ["Kick!", 40]
Moves = [Punch, Kick]
Player = ["Jamie", 100, Moves]
print ("Do you want to punch, or kick?")
attack = input(" ")
if attack == "punch":
atk = 0
if attack == "kick":
atk = 1
damage = Player[2[atk[1]]]
print (Player[0]," uses ", Player[2[atk[0]]])
but this results in error:
TypeError: 'int' object is not subscriptable
I understand why this error happens. But I'm wondering is there is another way to call up an element of a list inside of a list.
Thanks

What you want is probably something like this :
damage = Player[2][atk][1]
But beware because you only define atk in if statements so atk could potentially not be defined after those ifs.
Moreover you place either 1 or 2 in atk but you only have two moves which makes me think you want to put either 0 or 1 in it.
Note: You should not capitalise the name of your variables as it would imply they are classes instead of variables

from the way i understand
damage=Player[2][atk][1]
As has already been mentioned . The thing to understand is what is happening when you do this.
player[2] refers to Moves and when you further subscript it, it subscripts to the Moves, so player[2][atk] simply becomes Moves[atk].
A thing to keep in mind is that it is truly just a reference, if you were to change the list Moves, the value in player[2] will also change.
For example:
code:
Moves[1][2]=1000
print(player[2][1][2])
Will give output
1000

Related

How can i create a "run-loop" function that detects key-presses using Python?

I'm new to python3 and I've been practicing by doing some basic programs but now I'm stuck with a little snake type game I wrote. The code I wrote so far have the following parts in order:
Imported modules
Classes to get a key from the user without the need to press "enter"
A function that is called by the module threading (named move_alt()).
t = threading.Thread(target=move_alt) # this is immediately after the portion of code
described in point 3)
4)A move_forward() function to create the map using a list of characters and to move a "position character" starting at the center of the map to the right till it crashes into a "wall caracter". This function is named move_forward().
t.setDaemon(True)
t.start()
move_forward()
The idea is to start a thread to run simultaneously with move_forward function, which targets the function described in 2) to take a key from the user and depending on what key was pressed make some action over move_forward function, for example (and to be more specific) move_up or move_down, etc.
I don't know how to use the threading module correctly so I'm not getting my code to work as expected. Instead what is happening is the program would run the thread without running simultaneously the move_forward function and until I don't press a key (which is what it's done inside the thread) it doesn't do anything. Actually, at the beginning when i just run the program it tries to draw the map (list of characters) but only draws some characters and then gets stuck.
Sorry if my explanation wasn't efficient but English is not my first language and I tend to write too much.
P.S= I didn't put the code above because it is too long due to comments and stuff I made to learn (and not forget)
After a lot of thinking I was finally able to make the program work as expected. First of all, the threading module wasn't the best option but for some reason I was confusing threading (which is used for concurrency purposes) with whatever I was trying to do. So after a little while I stopped using this idea.
The way I managed to make it work was actually using another module called "keyboard" (for linux users you have to use the module as root for some reason). Here is a little bit of a code to use that module:
def onkeypressw(event): this function is used as a condition in the "while loop" for the move_up condition
global stopw
if event.name == 's' or event.name == "a" or event.name == "d":
stopw = True
keyboard.on_press(onkeypressw)
def onkeypressw1(event): # this function is used as condition in the if sentence in the main function to call move_up() function
global runw1
if event.name == "w":
runw1 = True
else:
runw1 = False
keyboard.on_press(onkeypressw1)
Then in the main function i have a while True loop running, where i have some if sentences that run one of four possibles move function: move_up, move_down, move_left, move_right depending of which key i pressed (w-s-d-a). Inside these "move functions" there are while loops to draw the map and move the character position(let's say the snake head) using a list of characters, until I press another button. So for example if in the main function I pressed "w" the program is going to run move_up function and move the character position until either it crashes against "the wall character" or I press "s, d or a". The conditions I put for the "while loop" are: 1)one for the wall character and 2)"not stopw" so it draws the list until I crash against the wall or stopw = True.
I know you can make this code using others modules and get the same result with less work but i wanted to use as much basic code as possible to learn python3 faster because I had previous experience programming with C.
P.S: Here is one of the moves function, just in case someone is curious:
def move_up():
global c, f
global map1
global stopw
while f> 0 and not stopw:
map1[f, c] = " o " # f represents the rows and c the columns, I replaced the initial position character "_" for "o"
f = f - 1 # up one row
map1[f, c] = " _ " # I put the position character "_" at the new position
cls() # clear the screen
time.sleep(0.4) # add a little delay just to modify the snake speed
stopw = False # reset the boolean

Error in retainedges[dat$seg] : invalid subscript type 'list'

I am conducting linearK function for the observed point pattern on a linear network and I get the following error
Error in retainedges[dat$seg] : invalid subscript type 'list'
I do not understand what it means and how should I correct it.
On the traceback call, I get the following information
> traceback()
4: thinNetwork(x, retainvertices = subi)
3: countends(L, X[-j], D[-j, j], toler = toler)
2: linearKengine(X, r = r, ..., denom = denom, correction = correction,
ratio = ratio)
1: linearK(sl2)
Could someone help me on what this error means and how I can correct it.
Thank you.
Your network is a bit problematic since it is disconnected. It has one very big component with 3755 vertices and 5593 lines and then 5 small components with only 2 or 3 vertices and 1 or 2 lines that are not connected to anything else. In your example you have only two points in this big network (both occurring in the big component as far as I can tell). We might be able to handle this in future versions of spatstat, but for now I suggest you simply discard the small empty components. Then I think linearK works as expected for your example (although I doubt you find interesting information from a pattern of 2 points!).
To identify connected components of a linear network use connected.linnet with argument what = "components" then you get a list of connected components and you can use the big connected component to define a new lpp on a connected linnet. With your example you could do something like (noting that component number 1 is the main component):
comp <- connected(as.linnet(sl2), what = "comp")
sl2new <- lpp(as.ppp(sl2), comp[[1]])

Need help working with lists within lists

I'm taking a programming class and have our first assignment. I understand how it's supposed to work, but apparently I haven't hit upon the correct terms to search to get help (and the book is less than useless).
The assignment is to take a provided data set (names and numbers) and perform some manipulation and computation with it.
I'm able to get the names into a list, and know the general format of what commands I'm giving, but the specifics are evading me. I know that you refer to the numbers as names[0][1], names[1][1], etc, but not how to refer to just that record that is being changed. For example, we have to have the program check if a name begins with a letter that is Q or later; if it does, we double the number associated with that name.
This is what I have so far, with ??? indicating where I know something goes, but not sure what it's called to search for it.
It's homework, so I'm not really looking for answers, but guidance to figure out the right terms to search for my answers. I already found some stuff on the site (like the statistics functions), but just can't find everything the book doesn't even mention.
names = [("Jack",456),("Kayden",355),("Randy",765),("Lisa",635),("Devin",358),("LaWanda",452),("William",308),("Patrcia",256)]
length = len(names)
count = 0
while True
count < length:
if ??? > "Q" # checks if first letter of name is greater than Q
??? # doubles number associated with name
count += 1
print(names) # self-check
numberNames = names # creates new list
import statistics
mean = statistics.mean(???)
median = statistics.median(???)
print("Mean value: {0:.2f}".format(mean))
alphaNames = sorted(numberNames) # sorts names list by name and creates new list
print(alphaNames)
first of all you need to iter over your names list. To do so use for loop:
for person in names:
print(person)
But names are a list of tuples so you will need to get the person name by accessing the first item of the tuple. You do this just like you do with lists
name = person[0]
score = person[1]
Finally to get the ASCII code of a character, you use ord() function. That is going to be helpful to know if name starts with a Q or above.
print(ord('A'))
print(ord('Q'))
print(ord('R'))
This should be enough informations to get you started with.
I see a few parts to your question, so I'll try to separate them out in my response.
check if first letter of name is greater than Q
Hopefully this will help you with the syntax here. Like list, str also supports element access by index with the [] syntax.
$ names = [("Jack",456),("Kayden",355)]
$ names[0]
('Jack', 456)
$ names[0][0]
'Jack'
$ names[0][0][0]
'J'
$ names[0][0][0] < 'Q'
True
$ names[0][0][0] > 'Q'
False
double number associated with name
$ names[0][1]
456
$ names[0][1] * 2
912
"how to refer to just that record that is being changed"
We are trying to update the value associated with the name.
In theme with my previous code examples - that is, we want to update the value at index 1 of the tuple stored at index 0 in the list called names
However, tuples are immutable so we have to be a little tricky if we want to use the data structure you're using.
$ names = [("Jack",456), ("Kayden", 355)]
$ names[0]
('Jack', 456)
$ tpl = names[0]
$ tpl = (tpl[0], tpl[1] * 2)
$ tpl
('Jack', 912)
$ names[0] = tpl
$ names
[('Jack', 912), ('Kayden', 355)]
Do this for all tuples in the list
We need to do this for the whole list, it looks like you were onto that with your while loop. Your counter variable for indexing the list is named count so just use that to index a specific tuple, like: names[count][0] for the countth name or names[count][1] for the countth number.
using statistics for calculating mean and median
I recommend looking at the documentation for a module when you want to know how to use it. Here is an example for mean:
mean(data)
Return the sample arithmetic mean of data.
$ mean([1, 2, 3, 4, 4])
2.8
Hopefully these examples help you with the syntax for continuing your assignment, although this could turn into a long discussion.
The title of your post is "Need help working with lists within lists" ... well, your code example uses a list of tuples
$ names = [("Jack",456),("Kayden",355)]
$ type(names)
<class 'list'>
$ type(names[0])
<class 'tuple'>
$ names = [["Jack",456], ["Kayden", 355]]
$ type(names)
<class 'list'>
$ type(names[0])
<class 'list'>
notice the difference in the [] and ()
If you are free to structure the data however you like, then I would recommend using a dict (read: dictionary).
I know that you refer to the numbers as names[0][1], names[1][1], etc, but
not how to refer to just that record that is being changed. For
example, we have to have the program check if a name begins with a
letter that is Q or later; if it does, we double the number associated
with that name.
It's not entirely clear what else you have to do in this assignment, but regarding your concerns above, to reference the ith"record that is being changed" in your names list, simply use names[i]. So, if you want to access the first record in names, simply use names[0], since indexing in Python begins at zero.
Since each element in your list is a tuple (which can also be indexed), using constructs like names[0][0] and names[0][1] are ways to index the values within the tuple, as you pointed out.
I'm unsure why you're using while True if you're trying to iterate through each name and check whether it begins with "Q". It seems like a for loop would be better, unless your class hasn't gotten there yet.
As for checking whether the first letter is 'Q', str (string) objects are indexed similarly to lists and tuples. To access the first letter in a string, for example, see the following:
>>> my_string = 'Hello'
>>> my_string[0]
'H'
If you give more information, we can help guide you with the statistics piece, as well. But I would first suggest you get some background around mean and median (if you're unfamiliar).

Creating a function that creates two lists in Python 3

I am trying to create a function, getStocks, that gets from the user two lists, one containing the list of stock names and the second containing the list of stock prices. This should be done in a loop such that it keeps on getting a stock name and price until the user enters the string 'done' as a stock name. The function should return both lists. My main issues are figuring out what my parameters are, how to continuously take in the name and price, and what type of loop I should be using. I am very new to programming so any help would be appreciated. I believe I'm close but I am unsure where my errors are.
def getStocks(name,price):
stockNames = []
stockPrices = []
i = 0
name = str(input("What is the name of the stock?"))
price = int(input("what is the price of that stock?"))
while i < len(stockNames):
stockNames.append(name)
stockPrices.append(price)
i += 1
else:
if name = done
return stockNames
return stockPrices
Your question is a bit unclear but some things off the bat, you cant have two return lines, once you hit the first, it leaves the function. Instead you'do write something like
return (stockNames, stockPrices)
Secondly while loops dont have an else, so you'd actually set up your while loop, then setup an if statement at the beginning to check if the string is 'done', then act accordingly. Break will get you out of your last while loop, even though it looks like it's associated with the if. So something like this:
while i < len(stockNames):
if name.upper() == 'DONE':
break
else:
stockNames.append(name)
stockPrices.append(price)
i += 1
Also you have to use == (comparison) instead of = (assignment) when you check your name = done. And dont forget done is a string, so it needs to be in quotations, and I used .upper() to make the input all caps to cover if its lower case or uppercase.
If you can clear up your question a little bit, I can update this answer to include everything put together. I'm not quite understanding why you want to input a list and then also take user input, unless you're appending to that list, at which point you'd want to put the whole thing in a while loop maybe.
Update:
Based on your comment, you could do something like this and enclose the whole thing in a while loop. This takes the incoming two lists (assuming you made a master list somewhere) and sends them both into the getStocks function, where someone can keep appending to the pre-existing list, and then when they type done or DONE or DoNe (doesn't matter since you use .upper() to make the input capitalized) you break out of your while loop and return the updated lists:
def getStocks(name, price):
stockNames = name
stockPrices = price
while 1:
inputName = str(input("What is the name of the stock?"))
inputPrice = int(input("what is the price of that stock?"))
if name.upper() != 'DONE':
stockNames.append(inputName)
stockPrices.append(inputPrice)
else:
break
return (stockNames, stockPrices)
But really, depending on the rest of the structure, you might want to make a dictionary instead of having 2 separate lists, that way everything stays in key:value pairs, so instead of having to check index 0 on both and hoping they didn't get shifted by some rogue function, you'd have the key:value pair of "stock_x":48 always together.

Python3 access previously created object

Im new to programming in general and I need some help for accessing a previously created instance of Class. I did some search on SO but I could not find anything... Maybe it's just because I should not try to do that.
for s in servers:
c = rconprotocol.Rcon(s[0], s[2],s[1])
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)
Now, what can I do if I want to call a function on "c" ?
Thanks, Hugo
You're creating several different objects that you briefly name c as you go through the loop. If you want to be able to access more than the last of them, you'll need to save them somewhere that won't be overwritten. Probably the best approach is to use a list to hold the successive values, but depending on your specific needs another data structure might make sense too (for instance, using a dictionary you could look up each value by a specific key).
Here's a trivial adjustment to your current code that will save the c values in a list:
c_list = []
for s in servers:
c = rconprotocol.Rcon(s[0], s[2],s[1])
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)
c_list.append(c)
Later you can access any of the c values with c_list[index], or by iterating with for c in c_list.
A slightly more Pythonic version might use a list comprehension rather than append to create the list (this also shows what a loop over c_list later one might look like):
c_list = [rconprotocol.Rcon(s[0], s[2],s[1]) for s in servers]
for c in c_list:
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)

Resources