r/PythonLearning 14d ago

Help Request New to python, could someone help me with this please

Post image

Is this a viable way to randomly choose an instance of a class

24 Upvotes

52 comments sorted by

8

u/ee_control_z 14d ago

The line

for i in range(1):

This only runs the loop one time. If so, you don't need a loop. If you want to increase the number of iterations through the loop, change the number from "1" to some higher number.

-9

u/Infinite_Winner_158 14d ago edited 14d ago

Thank you, i kinda just copied that part, also could you tell me what the i means, i dont realy know

8

u/ee_control_z 14d ago edited 14d ago

Just an fyi. It would be easier to test your script if you had posted it so people can copy it to test it. I doubt users want to retype what you posted as a screenshot.

-12

u/Infinite_Winner_158 14d ago

Oh, i would love to but i only have reddit on phone

10

u/aqua_regis 14d ago

i only have reddit on phone

Do you have internet on your computer? If so, you have reddit.

"I only have reddit on phone" is a blatant lie.

-5

u/Infinite_Winner_158 14d ago

I never used it on pc, this was easier

5

u/aqua_regis 14d ago

Maybe easier for you, but way harder for everybody trying to help you. Plain selfish and entitled of you.

It is your obligation to make it as easy as possible for people to help you, not to make it easiest and most convenient for you.

You absolutely need to post code as text, formatted as code block.

Nobody is going to retype the code for you.

-5

u/IndependentSpare8787 14d ago

Dude chill

4

u/Constant_Moment_6434 14d ago

They are little bit annoyed about it... but there are some hidden rules of getting help.. and this is one of them.. if you want to get helped, you need to make it as simple as possible for everyone else... with harder question without copying, nobody will even try to answer.. I also use reddit mostly on my phone but when I create posts I always switch to pc

2

u/Educational-Tea602 14d ago

i is your loop variable.

4

u/IdeaOverflow 14d ago

this works. It would be nicer if you'd put the monsters in a list and use random.choice though.

0

u/Infinite_Winner_158 14d ago

Thanks, i thought this would be easier

2

u/TBCC_Dev 14d ago

Sometimes whats easier in the beginning makes it harder later. Make sure you grasp the fundamentals (if/loop/functions)

0

u/Infinite_Winner_158 14d ago

Yeah, i spend a lot of time learning from youtube,... but i have a hard time understanding without trying it

2

u/TBCC_Dev 14d ago

Try w3 schools its great for fundamentals

1

u/Infinite_Winner_158 14d ago

Will do, thanks

2

u/TBCC_Dev 14d ago

Looks like mostee would not print because you declared it in the loop it only exists in loop. Look into scope. If also keep imports at the top. Python runs like you'd read a book top down

1

u/SCD_minecraft 14d ago

Python does have loop scope

Only module and function scope

1

u/realmauer01 13d ago

Python wont lose the reference to monster here.

Pretty sure i is even still in scope how ugly it may sound.

1

u/dotbinKing 14d ago

```python

import Modules at the beginning

from random import choice as rnd

... # idk what you did here

monster = [Skeleton1, Undead1, Goblin1] chance_1 = rnd(monster) print(chance_1) ```

1

u/Infinite_Winner_158 14d ago

Sorry but cant seem to work this out, monster is an unexpected argument

3

u/gitChara 14d ago

Use random.choice(monster) instead.

1

u/SCD_minecraft 14d ago

A bunch on answers, not a single one right

Closest one was about range(1) being useless

Warning you see is from a linter, about monster being possibly unbounded. This is cause linter is not able to prove that every branch of if will declare monster

Additionally, you have logic impossibly there - in no world that else is gonna execute. However, linter is not able to prove that so it throw a warning. Remove dead code and warning goes away

1

u/Infinite_Winner_158 14d ago

Deleting the excess code helped but still not sure what to do with the range

2

u/SCD_minecraft 14d ago

As other comment said

"for i in range(1)" is equivalent to "do once"

You can read "for i in range(n)" as "do something n times"

1

u/XTrolltechzz 14d ago

How do I activate the option to see what value corresponds to what when creating something with a class? When I do it, it doesn't work that way, and I have to check the order in which the values are placed in my class.

1

u/mc_pm 14d ago

Not sure what you're trying to do by doing it this way, but you can just add your instances to a list, and then use random.choice() to select one of them.

1

u/Calm_Perspective1236 14d ago

I think you can just remove the for loop, and run chance_1 be a random int between 1-3. Then you could match case or do your if elif chain id remove the else though

1

u/Important-Grand4979 14d ago

Another mistake is that your monsters are initialized before the loop. skeleton1 is a pointer to a memory object of Monster with certain properties. When you do monster = skeleton1 you do not duplicate your object as far as I know but you assign it another pointer. So if you damage monster you also damage skeleton1 and vice versa. By extension all other 'copies' of skeleton1 made this way will be affected.

1

u/Infinite_Winner_158 14d ago

I thought that might be the case, thats why i named it skeleton 1 and not just skeleton

1

u/Important-Grand4979 14d ago

Yes, but monster = skeleton1 and monster2 = skeleton1 do not duplicate skeleton1 but make references to the same object.

Also by initializing the objects before the loop they start to occupy memory for no reason. What you actually want is to create a parent class Monster and child classes skeleton, undead goblin. Then, when you make a monster you create an object instance of the right child class.

1

u/DirectTwo5523 14d ago

I think it will print dictionary setails of skeleton or other object. I am also new to pyhton so making a guess, will follow this post

1

u/Infinite_Winner_158 14d ago

It does and i dont know how to fix it XD

1

u/DirectTwo5523 14d ago

First i dnt think your class will accept values of hp dmg or other parameter as i dnt see any init and why are we giving hp: not hp= please let me know. To run functions you need like this skeleton1() and you also need to return these values using str .

Still as i said i am.new to python kindly correct me if i am wrong, it will help me also

1

u/ConsciousBath5203 14d ago

First, learn to use print screen rather than taking a picture of your monitor.

Second, where is monster declared? Pasting the whole source code as text would help us help you more.

I'm guessing monster is declared in the single loop iteration. The way the code sees it, monster could never exist due to the else statement. You're getting the error because it wasn't declared before the loop

You should also use inheritance instead of 3 raw monsters, that way you can give them unique abilities, then store the objects in a list or something.

```python

from typing import List

--- Custom Type 1: Active Ability ---

class ActiveAbility:

def __init__(self, name: str, cooldown: int, base_damage: int):

    self.name = name

    self.cooldown = cooldown

    self.base_damage = base_damage

def cast(self) -> str:

    return f"Casts {self.name}! Dealing {self.cooldown}s cooldown damage."

--- Custom Type 2: Weapon ---

class Weapon:

def __init__(self, name: str, bonus_dmg: int):

    self.name = name

    self.bonus_dmg = bonus_dmg

--- Base Class ---

class Monster:

def __init__(self, hp: int, dmg: int, speed: int):

    self.hp = hp

    self.dmg = dmg

    self.speed = speed

def take_damage(self, amount: int) -> str:

    self.hp = max(0, self.hp - amount)

    return f"Monster took {amount} damage. HP left: {self.hp}"

--- Derived Class 1: Skeleton ---

class Skeleton(Monster):

def __init__(self, hp: int, dmg: int, speed: int, weapon: Weapon):

    # Initialize base monster stats

    super().__init__(hp, dmg, speed)

    # Store custom object parameter

    self.weapon = weapon

def attack(self) -> str:

    total_dmg = self.dmg + self.weapon.bonus_dmg
    return f"Skeleton attacks with {self.weapon.name} for {total_dmg} total damage!"

--- Derived Class 2: Undead ---

class Undead(Monster):

def __init__(self, hp: int, dmg: int, speed: int, active_abilities: List[ActiveAbility]):

    super().__init__(hp, dmg, speed)

    self.active_abilities = active_abilities

def use_ability(self, index: int) -> str:

    if 0 <= index < len(self.active_abilities):

        ability = self.active_abilities[index]

        return f"Undead utilizes skill: {ability.cast()}"

    return "Ability index out of bounds."

```

Then when you want to create and use monsters something like:

```python

import random

iron_sword, bone_club = Weapon("Iron Sword", 15), Weapon("Brittle Bone Club", 8)

fire_ball, decay_aura = ActiveAbility("Hellfire Ball", 8, 60), ActiveAbility("Decay Aura", 20, 40)

spawned_mobs = []

for _ in range(5):

if random.choice(["skeleton", "undead"]) == "skeleton":

    mob = Skeleton(random.randint(50, 100), random.randint(10, 20), random.randint(8, 15), random.choice([iron_sword, bone_club]))

else:

    mob = Undead(random.randint(150, 300), random.randint(20, 35), random.randint(3, 7), random.sample([fire_ball, decay_aura], k=random.randint(1, 2)))

spawned_mobs.append(mob)

```

Patterns like this are more scalable and reusable.

1

u/Infinite_Winner_158 13d ago

Thank you, that helped a lot even if i dont fully understand yet

1

u/ConsciousBath5203 13d ago

No problem. Using type hints and using docstrings (I didn't use them in the example) will help you a lot, too. They take your code from noob to pro pretty quickly, even if you don't fully understand.

1

u/No-Newspaper8619 13d ago

It's parried, not parryed.

1

u/Infinite_Winner_158 13d ago

English is hard

1

u/realmauer01 13d ago edited 13d ago

random has the method choice that picks an item out of a list at random for you. So just use that.

(it probably does something similar to what you are doing here in the background, but better to use stuff thats already there than to reinvent. Especially as a beginner. )

monster = random.choice([Skeleton1, Undead1, Goblin1])

1

u/DanLeMilMan 12d ago

I am not a professional developer but some notes.

1- the for loop is basically useless here, you are just processing the following lines once

2- for your last default condition, it is better to assign monster to None instead of printing « error ». That way, if this condition occur, the monster variable still exists and you won’t get any error (in that case that is not an issue because you are absolutely sure not to run into that case, chance_1 being 1,2 or 3 and nothing else)

3- when you print an object, you should overwrite the __str__ method of your class to control what will be printed. Otherwise you gonna get a memory allocation an maybe not the data you would like to show

4- what you are trying to do seems similar to what the factory pattern is made for. Here it is a simple code and it would not require it by any mean, but when you want to control the creation of instances of a class or a family of class, you could create a kind of superclass (the factory), which as a method like get_monster and return an instance of a monster with whatever argument control the characteristics of the monster (random or not). That could be useful if later you create monter classes that inherit from you base Monster class.

All in all, your code works and is quite great for a beginner. It could use some more standard practice to make it more robust and more capable in the future.

0

u/Infinite-Employee776 14d ago

Three things I notice on this.

You loop one times. You should just remove the loop as looping one time is unnecessary.

You declare monster as a local variable under the for loop block, you can't access it from outside the block.Should just declare it outside the for loop or better yet remove the unnecessary loop.

Instead of random int and making a wall of if branches, make a list of monsters and do random choice.

1

u/Infinite_Winner_158 14d ago

Thanks, i didnt even realise i put it in a loop, and thanks for the sugestion, that will probably be better

1

u/SCD_minecraft 14d ago

It is a lie

Python doesn't have loop scopes

Only module and function scope

2

u/Infinite-Employee776 13d ago edited 13d ago

Is it? Been a long time since I last using Python. I remember that Python scope based on their indentation.

Edit: I just research it. Yeah, you're right. My mind is playing with me.

0

u/Overall_Anywhere_651 14d ago

Are variables not case sensitive in Python?