Python中面向对象的编程

时间:2015-06-24 02:24:19

标签: python

我正在定义一个名为'car'的类我将它与一个在我的课上运行一系列测试的文档进行比较。但是,我收到了错误,我不知道为什么。这是我的代码。 Drive方法应该将汽车移动并将其移动指定的里程数。如果汽车可以用给定量的燃料达到所有里程,那么汽车就行驶并输出里程。如果它不能,它会达到它可以达到的最大里程数。 addFuel方法应该为汽车添加燃料,但是如果它溢出则不会添加任何燃料,如果指定的参数不是整数,或者不是正值,那么它应该是抛出一个例外。并且tripRange模块应该被赋予汽车中的加仑数量,并确定您将行驶多少英里。下面我先发布了我的代码,然后是代码来测试它。你能帮助我吗?我很感激。

#Define the class


class Car(object):

    def __init__(self,fuelEfficiency=0,fuelCapacity=0,fuelLevel=0,odometer=0):
        self.setCar(fuelEfficiency,fuelCapacity,fuelLevel,odometer)

    def setFuelEfficiency(self,newFuelEfficiency):
        self.setCar(fuelEfficiency = newFuelEfficiency)

    def setFuelCapacity(self,newFuelCapacity):
        self.setCar(fuelCapactity = newFuelCapacity)

    def setFuelLevel(self,newFuelLevel):
        self.setCar(fuelLevel = newFuelLevel)

    def setOdometer(self,newOdometer):
        self.setCar(odometer = newOdometer)

    def setCar(self,fuelEfficiency = None,fuelCapacity = None,fuelLevel = None,odometer = None):
        if fuelEfficiency == None:
            fuelEfficiency = self.getFuelEfficiency

        if fuelCapacity == None:
            fuelCapacity = self.getFuelCapacity

        if fuelLevel == None:
            fuelLevel = self.getFuelLevel

        if odometer == None:
            odometer = self.getOdometer

        self.fuelEfficiency = fuelEfficiency
        self.fuelCapacity = fuelCapacity
        self.fuelLevel = fuelLevel
        self.odometer = odometer

    def drive(self,miles):
        if miles < 0:
            return ("The car is not driven")

        milesDriven = miles/self.fuelEfficiency

        if milesDriven < self.fuelLevel:
            print("The car drove {} miles".format(miles))
        else:
            if self.fuelLevel == 0:
                print("The car drove 0 miles")
            else:
                newMiles = milesDriven * miles
                print("The car drove {} miles".format(newMiles))

        self.fuelLevel = self.fuelLevel - milesDriven
        self.odometer += miles

    def getCar(self):
        #Returns a tuple that has (FE,FC,FL,OD)
        return (self.fuelEfficiency,self.fuelCapacity,self.fuelLevel,self.odometer)        


    def addFuel(self,num):
        if type(num) == str:
            raise KeyError("String valued enter, an integer was expected.")
        if num < 0:
            print("Sorry, you need to enter a postive number.")
        if num + self.fuelLevel > self.fuelCapacity:
            return self.fuelLevel
        else:
            return self.fuelLevel + num

    def getFuelEfficiency(self):
        return self.getCar()[0]

    def getFuelCapacity(self):
        return self.getCar()[1]

    def getFuelLevel(self):
        return self.getCar()[2]

    def getOdometer(self):
        return self.getCar()[3]

    def tripRange(self):
        numOfMiles = self.fuelEfficiency 
        return numOfMiles

    def __str__(self):
        FE = self.getFuelEfficiency()
        FC = self.getFuelCapacity()
        FL = self.getFuelLevel()
        OD = self.getOdometer()

        string = '{}:{}:{}:{}'.format(FE,FC,FL,OD)
        return string

这是测试代码:

from car import *

def checkCar(car, expected, message):
    global errorsFound
    mpg, cap, level, odo = expected
    if car.getFuelEfficiency() != mpg:
        errorsFound = True
        print(message + ': Error efficiency. Expected ' + str(mpg))
        print('\tCar:', car)
    if car.getFuelCapacity() != cap:
        errorsFound = True
        print(message + ': Error capacity. Expected ' + str(cap))
        print('\tCar:', car)
    if car.getFuelLevel() != level:
        errorsFound = True
        print(message + ': Error level. Expected ' + str(level))
        print('\tCar:', car)
    if car.getOdometer() != odo:
        errorsFound = True
        print(message + ': Error odometer. Expected ' + str(odo))
        print('\tCar:', car)

def checkNum(value, expected, message):
    global errorsFound
    if value != expected:
        errorsFound = True
        print(message + ': Error value. Expected {}. Got {}'.format(expected, value))

def main():
    c = Car(25, 15)
    checkNum(c.tripRange(), 0, 'Test 1')    

    expected = (25, 15, 0, 0)
    checkCar(c, expected, 'Test 2')

    c.addFuel(-1)
    checkCar(c, expected, 'Test 3')

    c.addFuel(1000)
    checkCar(c, expected, 'Test 4')

    c.addFuel('doctor')
    checkCar(c, expected, 'Test 5')

    c.addFuel(0)
    checkCar(c, expected, 'Test 6')

    c.addFuel(15)
    expected = (25, 15, 15, 0)
    checkCar(c, expected, 'Test 7')

    c.drive(50)
    expected = (25, 15, 13, 50)
    checkCar(c, expected, 'Test 8')

    c.drive(100000)
    expected = (25, 15, 0, 375)
    checkCar(c, expected, 'Test 9')

    c.drive(5)
    expected = (25, 15, 0, 375)
    checkCar(c, expected, 'Test 10')

    c.addFuel(10)
    expected = (25, 15, 10, 375)
    checkCar(c, expected, 'Test 11')

    c.drive(-1)
    expected = (25, 15, 10, 375)
    checkCar(c, expected, 'Test 12')

    c.drive(0)
    expected = (25, 15, 10, 375)
    checkCar(c, expected, 'Test 13')

    checkNum(c.tripRange(), 250, 'Test 14')

    if not errorsFound:
        print('No Errors Found')



errorsFound = False
main()

2 个答案:

答案 0 :(得分:1)

您的代码按预期工作。 尽管我在car.py文件中发现了一些缩进错误,这可能就是原因。特别是__init__对象的Car方法def__init__(..),没有空格。

如果你在终端输出中讨论被抛出的异常:

Test 1: Error value. Expected 0. Got 25
Sorry, you need to enter a postive number.
Traceback (most recent call last):
  File "/home/crispycret/Desktop/testcase.py", line 89, in <module>
    main()
  File "/home/crispycret/Desktop/testcase.py", line 42, in main
    c.addFuel('doctor')
  File "/home/crispycret/Desktop/car.py", line 64, in addFuel
    raise KeyError("String valued enter, an integer was expected.")
KeyError: 'String valued enter, an integer was expected.'
[Finished in 0.1s with exit code 1]

这是可以预料的。至于第42行main() test.py函数中的原因,您尝试执行c.addFuel('doctor')Car.addFuel()方法内部KeyError("String valued enter, an integer was expected.")输入的类型是一个字符串。

顺便提一下,在引发错误时应该使用适当的异常,在这种情况下,你应该使用TypeError("String valued enter, an integer was expected.")来表示变量类型是错误的。

https://docs.python.org/2/tutorial/errors.html

答案 1 :(得分:1)

Python不是Java,所以不要像这样写。

通常不需要Getters和Setter,因此不要添加它们,如果需要,您可以随时轻松完成。也没有强制实例成员保护,但self._odometer中的下划线向读者发出_odometer是私有的信号。

放弃类型声明并接受鸭子打字。在addFuel()中,您检查参数是否为str类型,如果不是,则继续。但是,参数可以是file,module,dict,list等类型。你无法全部检查,所以最好不要尝试。

剩下的就是drive()被打破了,但现在显然是这样,因为已经删除了很多垃圾而且tripRange()是多余的。这留下了一种工作方法addFuel,很难用于测试两行简单的代码。

class Car(object):
    def __init__(self, efficiency=0, capacity=0, fuel=0, odometer=0):
        self.efficiency = efficiency
        self.capacity = capacity
        self.fuel = fuel
        self.odometer = odometer

    # four useless setters removed

def drive(self, miles):
    # argument test removed

    # miles / (miles / 1 gallon) = miles * (1 gallon / miles) = 1 gallon
    # so this expression and thus method are broken
    one_gallon = miles / self.efficiency

    if one_gallon < self.fuel:
        print("The car drove {} miles".format(miles))
    elif self.fuel == 0:
            print("The car drove 0 miles")
    else:
       newMiles = milesDriven * miles
       print("The car drove {} miles".format(newMiles))

    self.fuel -= one_gallon
    self.odometer += miles      

def addFuel(self, volume):
    # Even more argument tests removed.
    if volume + self.fuel <= self.capacity:
        self.fuel += volume

# The method "tripRange()" is equivalent to "car.efficiency" so is removed

def __str__(self):
    # trivial getters don't exist; the format template is now conventional
    return '<Car {}, {}, {}, {}>'.format(self.efficiency, self.capacity,
        self.fuel, self.odometer)

你的测试中出现错误可能是因为2/3的方法被破坏了,甚至没有考虑到特殊的getCar()和所有琐碎的制定者和吸气剂。你需要编写的代码少于你的代码。