LazySloth13
LazySloth13

Reputation: 2487

TypeError - Classes in Python

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.

Upvotes: 4

Views: 10706

Answers (3)

Anthon
Anthon

Reputation: 76882

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.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1124748

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.

Upvotes: 7

SethMMorton
SethMMorton

Reputation: 48835

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.

Upvotes: 0

Related Questions