Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Object-Oriented Python Dice Roller RPG Roller

andrew falcone
andrew falcone
8,651 Points

Roll Function Works on My computer, not on workspace.

It's very frustrating that the only error message given is 'Bummer: Try again!'

dice.py
import random


class Die:
    def __init__(self, sides = 2, value = 0):
        if not sides >=2:
            raise ValueError("Must have at least 2 sides!")
        if not isinstance(sides, int):
            raise ValueError("Must have an integer number of sides")
        if not value <= sides:
            raise ValueError("Value cannot be greater than sides!")
        self.value = value or random.randint(1, sides)
    def __int__(self):
        return self.value


    #comparison operators
    def __eq__(self, other):
        return int(self) == other
    def __ne__(self, other):
        return int(self) != other
    def __gt__(self, other):
        return int(self) > other
    def __lt__(self, other):
        return int(self) < other
    def __ge__(self, other):
        return int(self) >= other
    def __le__(self, other):
        return int(self) <= other
    def __add__(self, other):
        return int(self) + other
    def __radd__(self, other):
        return self + other 
    def __repr__(self):
        return str(self.value)


class D6(Die):
    def __init__(self, value = 0):
        super().__init__(sides = 6, value = value)
class D20(Die):
    def __init__(self, value = 0):
        super().__init__(sides = 20)
hands.py
from dice import D6
from dice import D20



class Hand(list):
    def __init__(self, size=0, die_class = None, *args, **kwargs):
        if not die_class:
            raise ValueError("You must provide a die_class!")
        super().__init__()

        for _ in range(size):
            self.append(die_class())
        self.sort()




    @property
    def total(self):
        return sum(self)
    def roll(rolls):
        return Hand(size = rolls, die_class = D20)

class YatzyHand(Hand):
    def __init__(self, *args, **kwargs):
        super().__init__(size = 5, die_class = D6, *args, **kwargs)

3 Answers

Steven Parker
Steven Parker
230,995 Points

You've done a lot of things the challenge didn't ask for, like several additional comparison methods, a "D6" class, and a "YatzyHand" class. For best results with all challenges, do only what the instructions ask for. Doing other things (even if the code is good) can confuse the validator.

And for this task, the instructions gave an example of how it might call the new method. In the example, it was called on "Hand" itself and not using an instance. So with that in mind, you may want to refactor "roll" as a class method.

andrew falcone
andrew falcone
8,651 Points

Good point about the extra stuff, but I don't know why that should affect the grading (I just copied it from my editor since it was working fine there).

I tried doing it as a class method, and for my first attempt I continued to copy over the init method and removed the rest of the extra stuff. This also worked in my editor, but not in the workspace.

@classmethod
def roll(cls, rolls):
    return cls(size = rolls, die_class = D20)

I then removed the init method and tried to basically rewrite the init method part that I needed inside of the roll method, this also worked in my editor, but not in the workspace.

@classmethod
def roll(cls, rolls):
    x = []
    for _ in range(rolls):
        x.append(D20())
    x.sort
    return x

I'm guessing the returned value of x looks like a Hand, but isn't really a Hand class since it doesn't have the 'total' property. I then tried returning my list of rolls as a class.

@classmethod
def roll(cls, rolls):
    x = []
    for _ in range(rolls):
        x.append(D20())
    x.sort
    return cls(x)

The die rolls are unsorted, but the total method works. However, the code still doesn't pass.

Any clarifications would be appreciated! Thanks!

Steven Parker
Steven Parker
230,995 Points

That final version looks good. Sorting isn't necessary, but it shouldn't hurt. I'd guess that something that isn't shown is affecting the outcome.

Can you post the entire "hands.py" with Markdown formatting?

andrew falcone
andrew falcone
8,651 Points
class Hand(list):
    @property
    def total(self):
        return sum(self)

    @classmethod
    def roll(cls, rolls):
    x = []
    for _ in range(rolls):
        x.append(D20())
    x.sort
    return cls(x)

Do you know if there is a good way to fix indentation (I'm using sublime text). It's frustrating getting indent errors and having to manually remove spaces and replace with tabs!

Thanks!

Steven Parker
Steven Parker
230,995 Points

In the code shown here, the lines below the definition of "roll" all need to be indented further to be considered part of the method. And you can remove the "sort".

And I'm not familiar with sublime, but many editors use the same convention as the workspaces of the keystroke combination Ctrl-] for indenting anything currently highlighted.

andrew falcone
andrew falcone
8,651 Points

I think that indent was just a copy paste error.

andrew falcone
andrew falcone
8,651 Points

LOL, I found my error-I didn't import D20.

Thanks for your all your help, I appreciate it!

Steven Parker
Steven Parker
230,995 Points

andrew falcone — Glad to help. You can mark a question solved by choosing a "best answer".
And happy coding!