#đź”’ Help with lists

88 messages · Page 1 of 1 (latest)

regal jungle
#

Hey there, people!

I was playing Pokemon and got frustrated about always having to look on Google about types weaknessess (my memory is horrible these days) so I decided to try to create a little program to help me with it.

I have two different files, one where the program actually is and the other is just each typing is with it's weaknessess and subsequent damage multiplier.

I'll give an example, on the Type_effect file, one of tthe entries is as follows:

ice = {("Fire", 2), ("Ice", 0.5), ("Rock", 2), ("Steel", 2)}

Now my question.

On my main file, I created a function that request the user to fill the desired type it wants to look up and matches it with the correct list on the Type_Effect file.

Using the example above, how could I print 2 different lines saying that "ice" is resistant to "Ice" due to the 0.5 parameter and another line printing that it weak against the other three due to the 2 parameter?

I'll send the current function too!

Thanks!

def defending_single(defending_type, multiplier):
# Calculates the best attacks against single defending type
defender_type = str(input("What is the defender type? \n"))
if defender_type.lower in Type_Effect:

craggy marshBOT
#

@regal jungle

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

noble pumice
#

You don't need to str() the result of input() - it is always a str.

.lower does not produce the lowercase version of a string; it's just a reference to the method. You want .lower() to actually call it and get the result.

Personally I'd do this:

defender_type = input("What is the defender type? \n").lower()

so that defender_type is always the lowercase version, avoiding tedium later.

#

I think you might need to show us the full content of Type_Effect.

regal jungle
proper wyvern
#

I would organize the information differently. For ice for example I would have something like ice = {"weak": ["Fire", "Rock", "Steel"], "resistant": ["Ice"]}. The damage multipliers are implied by the category

#

Seems easier to fetch information that way

noble pumice
regal jungle
#

Yeah, it does seem way easier than what I did. I was so focused on trying to put on text the type chart image that I didn't thought about it

proper wyvern
#

Alternatively you can do ice = {"Fire": 2, "Rock": 2} etc.

noble pumice
#

I'd be inclined to reform it along the lines suggested by Zig. Is the damage multiplier always the same per attack? i.e. is it always eg ('Water',2) or might the 2 be something else in another attack?

regal jungle
proper wyvern
proper wyvern
regal jungle
proper wyvern
noble pumice
regal jungle
#

Awesome! That fixes my problem on the single typing. How would I multiply to get the resulting effects from 2 of those?

proper wyvern
#

you get the value for each type separately and multiply

noble pumice
#

Something like:

water_damage = hit * effects[attack_type].get('Water',0)

This looks up the effects for attack_type (whatever that might be) and gets the Water entry - it gets 0 if there is no Water entry, thus no damage.

regal jungle
#

If I make two variables to get the effects as per Cameron's image and multiply them, would it only affect the same parts? Like if one has a 'Fire": 2 and another 'Fire": 0.5, would it end in 1?

noble pumice
#

Maybe you'd have a weakness_type variable containing 'Water' or one of the other ones.

#

effects[attack_type] is suppsed to get just the damage multipliers for attack_type.

regal jungle
#

On the single type situation what you sent is perfect, I just don't know how to mix the variables to get a total multiplier

noble pumice
#

damage = 0

proper wyvern
noble pumice
#
attack_effects = effects[attack_type]
damage = 0
for weakness, multiplier in attack_effects.items():
    damage += attack_strenght * multiplier

Something like that.

#

Maybe you have distinct collections of damage per weakness type.

#

A mapping's .items() method yields (key,value) pairs from the mapping (eg a dict in your case).
So You'd get ("Ground",2) and so on, and that would assign weakness="Ground" and multipler=2 for that iteration of the loop.

regal jungle
#

Perfect! I'll make the adjustments here to try it!

proper wyvern
regal jungle
#

Oh, yeah, I need to find a way to get the total multiplier, the damage isn't important because it would way more info than is visibly shown on the game interface. All I want is a way to get the 1 on that function.

#

just to get a message like "Water/Grass takes 1x damage from Fire"

noble pumice
#

Just stick a 1 in instead of attack_strength maybe. Remove attack_strenght * altogether, since it's 1? Of course at that point I'm not sure calling it a multiplier is quite right... 🙂

noble pumice
proper wyvern
#

Something along the lines of

attack_effects = effects[attack_type]
mult = 1
for type_ in defender_types:
    mult *= attack_effects[type_]
raven quiver
# noble pumice I'd be inclined to reform it along the lines suggested by Zig. _Is_ the damage m...

well you gotta know your data.
in Pokémon, there are only 3 categories.
• Weak - which is 2 dmg
• Resistant - which is ½ dmg
• Immune - which is 0 dmg
There's no in between, at least for "vanilla" fights/games.

Other offshoot games & mods. Pixelmon, as one example, do have stuff like Âľ dmg. though that comes with unusual additional complexities that the mod offers.

#

anyhow, any approach that works is a good approach. 👍

regal jungle
#

So, I managed to make the single typing work but I cant seem to be able to add two different variables from Type_Effect to a single list on the main file.

#

def defending_dual():
# Calculates the best attacks against dual defending type
type1 = input("What is the defender's first typing? \n").lower()
defender_type1 = Type_Effect.typings.get(type1)
type2 = input("What is the defender's second typing? \n").lower()
defender_type2 = Type_Effect.typings.get(type2)
defender_types = defender_type1 + defender_type2
print (defender_types)

craggy marshBOT
#

Hey @regal jungle!

Please edit your message to use a code block

```py
print('Hello, world!')
```

This will result in the following:

print('Hello, world!')```
regal jungle
#

That's the function I tried using and I'll send the error message

#

Traceback (most recent call last):
File "C:\Users\Matt TP\PycharmProjects\PythonProject\a.py", line 49, in <module>
main()
~~~~^^
File "C:\Users\Matt TP\PycharmProjects\PythonProject\a.py", line 40, in main
defending_dual()
~~~~~~~~~~~~~~^^
File "C:\Users\Matt TP\PycharmProjects\PythonProject\a.py", line 17, in defending_dual
defender_types = defender_type1 + defender_type2
~^~
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'

Process finished with exit code 1

regal jungle
#

I understood my error, I was trying to add two dicts as lists and of course it wouldn't work but I'm still trying to match keys, multiply their values and add them with the symmetrical difference on a separate dict

unborn saffron
white flame
unborn saffron
#

it doesn't do the multiplying part tho

white flame
#

true

regal jungle
unborn saffron
white flame
#

it's the same as merging but you multiply overlapping keys instead of adding them both, right ?

unborn saffron
#
A | B == (A & B) | (A ^ B)
#

(for the keys)

regal jungle
unborn saffron
#

the only tricky part is with the values

#

but from "keys are sets" standpoint, the same

#

it may be useful to use the .keys() or .items() methods to open up more set-like possiblities

#

for example, you can use - with those, but not with dicts (not that you need to use - in this scenario, idk)

#

especiall useful with items, because you can do dict(some_dict.items())

#

a good test would be to see which item is kept when doing & on a dict_items object

#

if it's from the first dict only, or second dict only, that may be helpful

#

ah items will not be useful

#

because it messes with the equality when doing set operations

#

so you need to do the operations on the .keys(), then construct a new dict from that

regal jungle
#

Awesome! That's what I was looking up! I'll try it for the next few hours and see if I can get it to work

unborn saffron
#

I can give you a solution in about 2 minutes (or at least an example I mean)

#

as I just started writing one

#

!e

d0 = {i:i for i in [0, 1, 2, 4, 5, 6, 8, 9]}
d1 = {i:i-1 for i in [0, 1, 3, 4, 6, 7, 8, 10]}

d2 = d0 | d1

shared_keys = d0.keys() & d1.keys()
for k in shared_keys:
    d2[k] = d0[k] * d1[k]


print(d2)
craggy marshBOT
unborn saffron
#

I thought it was easier to just overwrite the keys after a union for shared keys, instead of trying to fandangle the symdiff manually

regal jungle
#

I'll try it with my dicts in 10 minutes and update you! Thanks a bunch

#

should I sort the dicts before running this code?

unborn saffron
#

that would be making two new dicts for (IMO) no reason at all

#
dict(sorted(your_dict.items()))

this is how you sort a dict

raven quiver
#

if you're already sorting, then a list structure would suit better.

unborn saffron
#

except maybe for output

#

I think the json module provides kwargs for doing so

regal jungle
#

IT'S ALIVE!

#

Thanks a ton everyone for the help

#

almost 8 hours with minimal knowledge and you helped me fix it very quickly

unborn saffron
#

all experience from helping people and chatting in this server :)

craggy marshBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.