Sc4r
Sc4r

Reputation: 700

Calling a method from a another class

class Switch():

    def __init__(self, mode):
        self._mode = mode
        if self._mode == '1':
            self._mode = True
        if self._mode == '0':
            self._mode = False

    def flip(self):
        if self._mode is True:
            self._mode = False
        if self._mode is False:
            self._mode = True


class Flip():

    def __init__(self, lst):
        self._lst = []
        for i in range(lst):
            self._lst.append(False)

    def flip(self, n):
        self._lst[n] = Switch.flip(self) #problem here

The problem with what I have so far is when I call a function from another class it throws an error.

what Switch class does:

if you pass '1' as the parameter, it will change it to True, and if you pass '0' as the parameter it will change it to False. The flip method in Switch changes the mode, so if it's True it will change it to False, etc.

what Flip class does:

If you pass a number as the parameter, it will create a list with that many elements but instead of numbers it will put False in place. ex. if you pass 10, instead of [0,1,2,3,4,5,6,7,8,9] you get [False, False, False, False, ... ]. The flip method in Flip will call the flip method from Switch and change it's state at the given index. Ex. [False, False, False] you call flip with 2 as n, then you'll get [False, False, True]

However, when I .flip(2) it throws an error:

f1 = Flip(10)
f1.flip(2)
Traceback (most recent call last):
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 1, in <module>
    # Used internally for debug sandbox under external interpreter
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 25, in flip
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 11, in flip
builtins.AttributeError: 'Flip' object has no attribute '_mode'

Not sure what exactly to change in order to resolve this. Classes are new for me so not quite sure :/

Upvotes: 0

Views: 132

Answers (4)

cod3monk3y
cod3monk3y

Reputation: 9843

To call the flip() method, you need to have an instance of the class Switch as most answers have already said. Reading through the Python documentation on Class Objects should give you a good start.

You have several other opportunities for confusion with this code though. Here's an implementation that solves a few things that might be issues for you in the future.

class Switch():

    # mode should be a boolean True/False
    def __init__(self, mode):
        self._mode = mode

    # since mode is boolean you can invert it with 'not'
    def flip(self):
        self._mode = not self._mode

    def __str__(self, ):
        return '1' if self._mode else '-'

class Flip():
    def __init__(self, switch_count ):
        # creates N Switch instances to store in the flip array
        # Switch() creates an instance
        # [ ... for x in ... ] is a list comprehension, you could just
        #    as easily leave your for loop, but this seems more like
        #    what you're trying to accomplish
        self._lst = [Switch(False) for i in range(switch_count)]

    def flip(self, n):
        # _list[n] access the Switch() instance, and flips it
        self._lst[n].flip()

    def __str__(self):
        return "Switches:" + ''.join([str(x) for x in self._lst])

Changes

  • representing all True/False values as booleans inside your switch class
  • boolean values can be inverted using not instead of using conditionals
  • added a __str__ which returns a string representation of the instance, which is useful for debugging
  • (advanced) Using a list comprehension in the Flip constructor instead of a loop. All pythonic and such and soforth.

And the usage:

f = Flip(5)
print f
#outputs
#Switches:-----

f.flip(1)
f.flip(3)
f.flip(4)
print f
#outputs
#Switches:-1-11

f.flip(3)
f.flip(4)
print f
#outputs
#Switches:-1---

Upvotes: 0

Kevin
Kevin

Reputation: 2182

I think you should re-think your class design. This may just be an example to help teach yourself classes. One way to determine what should become a class is called "Noun Extraction". Begin by creating a narrative of how a system works (e.g. "When a person flips a switch, a light turns on or off") Then extract the list of nouns: person, switch, light. Your classes will be a subset of those nouns. The verbs (flips, turns on, turns off) become the methods in those classes.

I think that your Switch class answers most of the problem you need. The Flip class can probably be deleted. You can just create a Switch object with the code that you have and run methods on it:

myswitch = Switch(1)
print myswitch._mode
myswitch.flip()
print myswitch._mode

Upvotes: 1

Gerrat
Gerrat

Reputation: 29690

You have two issues (look your modified code below, along with my two comments - where I made changes).

class Switch():

    def __init__(self, mode):
        self._mode = mode
        if self._mode == '1':
            self._mode = True
        if self._mode == '0':
            self._mode = False

    def flip(self):
        if self._mode is True:
            self._mode = False
        if self._mode is False:
            self._mode = True
        return self._mode  # need to return this for Flip class's method

class Flip():

    def __init__(self, lst):
        self._lst = []
        for i in range(lst):
            self._lst.append(False)

    def flip(self, n):
        # need to initialize Switch with the current mode
        self._lst[n] = Switch(self._lst[n]).flip()  

Also, all python classes should inherit from object or a descendent (but that has nothing to do with your issue).

Upvotes: 1

You need to create a Switch object with a mode variable passed in and remove the self variable being passed to:

self._lst[n] = Switch.flip(self) #problem here

So it should look like:

sw = Switch(mode)
self._lst[n] = sw.flip()

Upvotes: 0

Related Questions