今天的题目,加深了关于对象类型以及函数和对象方法的理解。
一.题目
You might know some pretty large perfect squares. But what about the NEXT one?
Complete the findNextSquare method that finds the next integral perfect square after the one passed as a parameter. Recall that an integral perfect square is an integer n such that sqrt(n) is also an integer.
If the parameter is itself not a perfect square, than -1 should be returned. You may assume the parameter is positive.
Examples:
findNextSquare(121) --> returns 144 findNextSquare(625) --> returns 676 findNextSquare(114) --> returns -1 since 114 is not a perfect
一些英语单词:
1.perfect square
完全平方数
完全平方数是指例如一个数能表示成某个整数的平方。例如
9=3×3
121=11×11
9和121就是完全平方数。
- parameter
/pəˈræmɪtə(r)/
n.参数
关于上面的翻译:
你也许知道一些很大的完全平方数,但是这个完全平方数下一个完全平方数你又知道吗?
完成这个名为findNextSquare的函数,这个函数当输入一个参数后,可以找到下一个完全平方数。回想一下,一个整数完全平方数是这个整数开根号后还是一个整数。
如果这个参数本身并不是一个完全平方数,那么就返回-1吧。假定输入的参数都是正数。
初始代码
举个栗子
Test.describe("find_next_square")
Test.it("should return the next square for perfect squares")
Test.assert_equals(find_next_square(121), 144, "Wrong output for 121")
Test.assert_equals(find_next_square(625), 676, "Wrong output for 625")
Test.assert_equals(find_next_square(319225), 320356, "Wrong output for 319225")
Test.assert_equals(find_next_square(15241383936), 15241630849, "Wrong output for 15241383936")
Test.it("should return -1 for numbers which aren't perfect squares")
Test.assert_equals(find_next_square(155), -1, "Wrong output for 155")
Test.assert_equals(find_next_square(342786627), -1, "Wrong output for 342786627")
二.代码和思路
思路
先想想函数大概的框架
输入:一个整数
操作:判断是否是完全平方数,然后按要求返回
输出:-1或完全平方数数
开始的思路是,121开根号是整数,120开根号不是整数。那就将121开根号然后判断是不是整型,这样就知道是不是完全平方数了
所以判断的语句是
if isinstance(math.sqrt(sq),int):
isinstance是python的内置函数,用来判断对象是不是某种类型。
当时的思路是:
如果sq是完全平方数。那么math.sqrt(sq)就是整型。
如果sq不是完全平方数,那么math.sqrt(sq)就是浮点数。
但是!!!
错误来了哦,无论sq是不是完全平方数,这条if语句都判定为错。
即使sq=121,isinstance(math.sqrt(sq),int)的结果是:False !!!
问题出在哪呢?
用type()函数后发现,原来math.sqrt()的返回结果,都是浮点数(float)。
这里就是我们判断整数和计算机判断整数的不同:
我们对121开根号结果是11,11是整数。对120开根号,10.954....不是整数。
但计算机不是,用math.sqrt()计算后,返回的结果都是float。math.sqrt(121)是等于11,但不是(int) 11 , 而是(float) 11.0
!!! 计算机并不会把(float)11.0自动变为(int)11
既然不能通过类型判断整数,接着可以通过值判断。
例如 11.0(float)=11(int) 结果为True
(PS:后面最优解会更简单的判断是不是整数的方法)
将if语句改成
if math.sqrt(sq) == math.trunc(math.sqrt(sq)):
math.trunc()方法即直接舍弃该数字的小数部分。
例如math.trunc(10.51) 会返回 10(int)
当时以这样值比较的方式,就写了下面的代码
代码
import math
def find_next_square(sq):
if math.sqrt(sq) == math.trunc(math.sqrt(sq)):
return (math.sqrt(sq) + 1) ** 2
else:
return -1
三.最优代码解
我们前面想用函数isinstance()来判断是不是整数行不通
但其实Python是有办法的,就是浮点数里面有个方法is_integer()
if root.is_integer():
是的,就这么简单。
另外一种用值来判断的话,也很简单的就是
if x%1 :
四.总结
1.对象类型
对象类型在做类型判断的时候是很关键。像本题中math.sqrt()返回值就是float,并不会和我们想的再自行判断是不是整数。
2.函数和方法
之前关于函数和方法就一直在困惑我。
该怎么区分函数和表达式?
一个数x开根号:
x**0.5 #表达式
pow(x,0.5) # 函数
math.sqrt(x) #方法
抛开表达式,我们来看看函数和方法。
其实方式就是一种特殊的函数。他写在了对象里面,所以要使用这个方法的时候,得先写出该对象的变量名,然后加个 ‘.’ 再写该方法名。
x='abcdefgh' #x是变量名字,x对象类型是字符串
x.replace(‘a’,'b') #字符串里面有replace()方法
如果想知道这个对象类型有什么方法的话,可以查阅文档或在python中用dir()函数
x='abc' #字符串
dir(a)
x=1.0 #浮点数
dir(x)
x=1 #整数
dir(x)
以浮点数为例输出结果(打印输出)
__abs__
__add__
__bool__
__class__
__delattr__
__dir__
__divmod__
__doc__
__eq__
__float__
__floordiv__
__format__
__ge__
__getattribute__
__getformat__
__getnewargs__
__gt__
__hash__
__init__
__init_subclass__
__int__
__le__
__lt__
__mod__
__mul__
__ne__
__neg__
__new__
__pos__
__pow__
__radd__
__rdivmod__
__reduce__
__reduce_ex__
__repr__
__rfloordiv__
__rmod__
__rmul__
__round__
__rpow__
__rsub__
__rtruediv__
__setattr__
__setformat__
__sizeof__
__str__
__sub__
__subclasshook__
__truediv__
__trunc__
as_integer_ratio
conjugate
fromhex
hex
imag
is_integer
real
双下划线开头和结尾的是函数,可以传入浮点数的一些函数。
而后面没有以双下划线开头的,就是浮点数里面的方法。
当然也不用刻意去记,方法和函数用的多了,自然就记住了。(就像这次记住了浮点数里面有个is_integer()方法 )