[英]Object Oriented programming in Python
I am defining a class called 'car' I am comparing it to a document that runs a series of tests on my class. 我正在定义一个名为“汽车”的类,并将其与对我的类进行一系列测试的文档进行比较。 However, I am getting errors, and I am not sure why.
但是,我遇到了错误,并且不确定为什么。 Here's my code.
这是我的代码。 The
Drive
method is supposed to take the car and move it a specified amount of miles. 应采用
Drive
方法将汽车移至指定的距离。 If the car can achieve all the miles with the given amount of fuel, then the car makes the trip and outputs the miles. 如果汽车可以在给定的燃油量下达到所有里程,则汽车进行行驶并输出里程。 If it can't, it goes the maximum amount of miles it can.
如果不能,它将达到最大里程数。 The
addFuel
method is supposed to add fuel to the car, but if it overflows it doesn't add any fuel, and if the parameter specified isn't an integer, or isn't a positive value, it's supposed to throw an exception. addFuel
方法应该为汽车添加燃料,但是如果它溢出,则不会添加任何燃料,并且如果指定的参数不是整数或不是正值,则应该引发异常。 And the tripRange
module is supposed to be given the amount of gallons in the car, and determine how many miles you will travel. 并且应该给
tripRange
模块提供汽车中的加仑量,并确定您将行驶多少英里。 Below I have posted my code first, and then the code to test it out. 在下面,我先发布了我的代码,然后发布了代码进行测试。 Can you help me?
你能帮助我吗? I appreciate it.
我很感激。
#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
And here's the test code: 这是测试代码:
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()
Your code works as expected. 您的代码按预期工作。 Altough I found a number of indentation errors in the car.py file So that may be why.
虽然如此,我在car.py文件中发现了许多缩进错误,所以这可能就是原因。 specifically the
__init__
method for the Car
object you have def__init__(..)
, theres no space. 特别是您拥有
def__init__(..)
的Car
对象的__init__
方法,没有空间。
If your talking about the exception that get thrown at you in the terminal output: 如果您在终端输出中谈论抛出的异常:
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]
That's to be expected. 这是意料之中的。 As for the reason in the
main()
function in your test.py
on line 42, your trying to do c.addFuel('doctor')
, where inside the Car.addFuel()
method you raise KeyError("String valued enter, an integer was expected.")
when the type of input is a string. 至于第42行
test.py
main()
函数中的原因,您尝试执行c.addFuel('doctor')
,在Car.addFuel()
方法内部,您引发Car.addFuel()
KeyError("String valued enter, an integer was expected.")
如果输入的类型是字符串,则应为KeyError("String valued enter, an integer was expected.")
By the way you should use proper exceptions when raising errors, in this case you should use a TypeError("String valued enter, an integer was expected.")
to express that the variable type was wrong. 顺便说一下,在引发错误时应使用适当的异常,在这种情况下,应使用
TypeError("String valued enter, an integer was expected.")
表示变量类型错误。
https://docs.python.org/2/tutorial/errors.html https://docs.python.org/2/tutorial/errors.html
Python is not Java, so don't write like it is. Python不是Java,所以不要这样写。
Getters and Setters are often not needed, so don't add them, you can always do it easily later if needed. 通常不需要使用Getter和Setter,因此不要添加它们,如果需要的话,以后随时可以轻松进行。 There is no enforced instance member protection either, but the underscore in self._odometer signals to the reader that _odometer is private.
也没有强制的实例成员保护,但是self._odometer中的下划线向读者表明_odometer是私有的。
Abandon type declaration and embrace duck-typing. 放弃类型声明并接受鸭子输入。 In
addFuel()
you check to see if the argument is of type str
and proceed if it isn't. 在
addFuel()
您检查参数是否为str
类型,如果不是,则继续。 However, the argument could be of type file, module, dict, list, and so on. 但是,参数可以是文件,模块,字典,列表等类型。 You can't check them all, so it is best not to try.
您无法全部检查所有内容,因此最好不要尝试。
Of what remains, drive()
is broken, but now obviously so because so much junk has been removed and tripRange()
was redundant. 剩下的东西,
drive()
坏了,但是现在很明显是因为删除了那么多垃圾,并且tripRange()
是多余的。 This leaves one working method addFuel
and it is hard to make the case for testing two simple lines of code. 这样就留下了一个工作方法
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)
You are getting errors in your tests probably because 2/3 of your methods were broken, not even considering the peculiar getCar()
and all the trivial setters and getters. 您可能在测试中出现错误,可能是因为您的方法有2/3被破坏了,甚至没有考虑到特殊的
getCar()
以及所有琐碎的setter和getter。 You need to write much less code than you have. 您需要编写的代码比以前少得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.