4

I'm a beginner at Python just getting to grips with classes. I'm sure it's probably something very basic, but why does this code:

class Television():
    def __init__(self):
        print('Welcome your TV.')
        self.volume = 10
        self.channel = 1
    def channel(self, channel):
        self.channel = input('Pick a channel: ')
        print('You are on channel ' + self.channel)
    def volume_up(self, amount):
        self.amount = ('Increase the volume by: ')
        self.volume += self.amount
        print('The volume is now ' + self.volume)
    def volume_down(self, amount):
        self.amount = ('Decrease the volume by: ')
        self.volume -= self.amount
        print('The volume is now ' + self.volume)
myTele = Television()
myTele.channel()
myTele.volume_up()
myTele.volume_down()

Produce the following error:

TypeError: 'int' object is not callable, Line 18

EDIT: I changed the code to this:

class Television():
    def __init__(self, volume = 10, channel = 1):
        print('Welcome your TV.')
        self.volume = volume
        self.channel = channel
    def change(self, channel):
        self.channel = input('Pick a channel: ')
        print('You are on channel ' + self.channel)
    def volume_up(self, amount):
        self.amount = int(input('Increase the volume by: '))
        self.volume += self.amount
        print('The volume is now ' + str(self.volume))
    def volume_down(self, amount):
        self.amount = int(input('Decrease the volume by: '))
        self.volume -= self.amount
        print('The volume is now ' + str(self.volume))
myTele = Television()
myTele.change()
myTele.volume_up()
myTele.volume_down()

But it returns:

TypeError: change() missing 1 required positional argument: 'channel'

Again, this is coming from someone just starting with classes, so please don't be too harsh if I've done something glaringly obvious wrong. Thank you.

0

3 Answers 3

7

You assign a channel attribute in your __init__:

self.channel = 1

This shadows the channel() method on the class. Rename the attribute or the method.

Attributes on the instance trump those on the class (except for data descriptors; think propertys). From the Class definitions documentation:

Variables defined in the class definition are class attributes; they are shared by instances. Instance attributes can be set in a method with self.name = value. Both class and instance attributes are accessible through the notation “self.name”, and an instance attribute hides a class attribute with the same name when accessed in this way.

Your methods also expect a parameter that you are not passing in in your example, but I'm figuring you'll solve that yourself next.

Sign up to request clarification or add additional context in comments.

2 Comments

Martijn, how good are you? I mean every time I open up a Python question you're first to the punch :)
@MorganWilde: you are right .. i agree. .. !! indeed his answers are great source of learning :)
0

You have a method called channel and a variable called channel. The variable, which is an int, shadows the method (steals it's name so that you can't access it). Rename wither the method or the variable and this will solve your problem.

Comments

0

Actually your code after the Edit exposed the problem Martijn was already indicating at. Your self.change() expects a parameter which you don't provide in myTele.change(). Since you are not using the parameter in the method, you should define change as:

def change(self):
    self.channel = input('Pick a channel: ')
    print('You are on channel ' + self.channel)

volume_up and volume_down actually assign a string to self.amount instead of calling a function. You probably want to change those to

def volume_up(self, amount):
    self.amount = input('Increase the volume by: ')
    self.volume += self.amount
    print('The volume is now ' + self.volume)
def volume_down(self, amount):
    self.amount = input('Decrease the volume by: ')
    self.volume -= self.amount
    print('The volume is now ' + self.volume)

Since you are setting self.amount every time before using it, you can probably just make it a local variable to the method ( amount ). If you have future plans to have a method xyz() that uses self.amount without first setting it, you should make sure self.amount is set in __init__() to a reasonable value, in case xyz() is called before the volume changing methods.

2 Comments

Thanks, you cleared up what Martijn was saying about passing parameters in methods.
You were lucky I came in late to this question and noticed your edit, such a late change with additional things to be answered often gets unnoticed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.