目录
第1关:数字时钟走字
本题细节知识点总结:(个人的一点小思考,可以看一下)
第2关:定义一个类描述平面上的点并提供移动点和计算到另一个点距离的方法
本题细节知识点总结:(个人的一点小思考,可以看一下)
from time import sleep
class Clock(object):
"""数字时钟"""
def __init__(self, hour=0, minute=0, second=0):
"""初始化方法
:param hour: 时
:param minute: 分
:param second: 秒
"""
self._hour = hour #self:引用对象3个属性
self._minute = minute
self._second = second
def run(self):
"""走字"""
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._minute = 0
self._hour += 1
if self._hour == 24:
self._hour = 0
def show(self):
"""显示时间"""
return '%02d:%02d:%02d' % \
(self._hour, self._minute, self._second)
def main():
#h为时,m为分,s为秒
h,m,s = input().split(',')
h = int(h)
m = int(m)
s = int(s)
# 请在此处添加代码 #
# *************begin************#
a = Clock(h,m,s)
for i in range(60): #输出60次走字,秒数为60,进位
print(a.show()) #返回字符串,表示当前时间为23:59:58
a.run() #走字:秒数+1 (是否进位)
# **************end*************#
if __name__ == '__main__':
main()
(一)self的作用:
在 Python 中,self 是一个特殊的参数,它代表类的实例对象。在类中定义的方法,需要以 self 作为第一个参数,用于引用该实例对象。
在这个时钟程序中,我们定义了一个 Clock 类,其中包含了 _hour、_minute、_second 这三个属性,用于表示时钟的小时、分钟、秒数。
当我们创建一个 Clock 对象时,需要指定小时、分钟、秒数的初始值,这些初始值需要传递给 Clock 类的构造函数,构造函数中会将它们保存到对象的 _hour、_minute、_second 属性中。
当我们调用 Clock 对象的方法时,比如 run() 方法,需要引用该对象的属性,以及对这些属性进行操作,这时就需要使用 self 这个参数,来引用这个对象的属性。
例如,在 run() 方法中,需要将秒数加 1,那么就需要使用 self._second 这个属性,来表示当前对象的秒数属性。代码 self._second += 1 就是将当前对象的秒数属性加 1。
因此,self 在这个程序中的作用,就是用来引用当前对象的属性,以及对这些属性进行操作。
(二) "——"(两个连续的短横线) VS 下划线(_)
1. 分割线,用于分隔不同部分的代码,增加代码的可读性。"——" 通常在函数、类、方法等定义的头部使用
2. 作为变量名的前缀,通常是一种命名约定,用于指示这个变量是一个“内部变量”,即该变量是类或对象的内部实现细节,不应该被直接访问或修改。
在这个时钟程序中,使用下划线作为变量名的前缀,例如 self._hour、self._minute、self._second,是为了表示这些变量是时钟对象的内部实现细节,不应该被直接访问或修改。
但是,在 Python 中,这种命名约定并不会强制限制变量的访问或修改,开发者仍然可以在类外部访问或修改这些变量。因此,在代码中使用下划线作为变量名的前缀,主要是为了约定俗成,提醒开发者不要直接访问或修改这些变量,以避免意外错误的发生。
from math import sqrt
#定义一个类描述平面上的点并提供移动点和计算到另一个点距离的方法
class Point(object):
def __init__(self, x=0, y=0):
"""初始化方法
:param x: 横坐标
:param y: 纵坐标
"""
self.x = x # x -> 类的属性 (共有)
self.y = y
def move_to(self, x, y): #移动时修改“对象属性” 不是“类属性”
"""移动到指定位置
:param x: 新的横坐标
"param y: 新的纵坐标
:return : 无返回值
"""
# 请在此处添加代码 #
# *************begin************#
self.x = x # x -> 对象的属性 (独有)
self.y = y
# **************end*************#
def move_by(self, dx, dy):
"""移动指定的增量
:param dx: 横坐标的增量
"param dy: 纵坐标的增量
:return : 无返回值
"""
# 请在此处添加代码 #
# *************begin************#
self.x += dx # self.x = self.x + dx
self.y += dy #横坐标的增量
# **************end*************#
def distance_to(self, other):
"""计算与另一个点的距离
:param other: 另一个点,坐标为(other.x,other.y)
:return :返回两点之间的距离
"""
# 请在此处添加代码 #
# *************begin************#
dx = self.x - other.x #两点距离
dy = self.y - other.y
return sqrt(dx ** 2 + dy ** 2)
# **************end*************#
def __str__(self):
return '(%s, %s)' % (str(self.x), str(self.y))
(一)为什么在初始化和定义移动方法时,要写两遍self.x = x 和self.y = y 呢?
在初始化方法中,self.x = x是将传入的x值赋值给类的属性x,而在move_to方法中,self.x = x是将传入的x值赋值给对象的属性x。在Python中,类属性和对象属性是不同的,类属性是所有对象共享的,而对象属性是每个对象独有的。因此,当我们想要移动一个点时,需要修改对象的属性值,而不是类的属性值。因此,在move_to方法中,需要重新给对象的属性x赋值,以实现移动点的功能。
(二)在方法move_by和方法distance_to中,的dx是同一个吗?
不是同一个。在方法move_by(self, dx, dy):中的dx是指横坐标的增量,而在方法distance_to(self, other):中的dx是指当前点与另一个点横坐标之间的差值。
(三) sqrt(dx ** 2 + dy ** 2) 关于平方和平方根:
**
是 Python 中的指数运算符,表示乘方。例如,2 ** 3
表示 2 的 3 次方,结果为 8。在
return sqrt(dx ** 2 + dy ** 2)
中,dx ** 2
表示横坐标差值的平方,dy ** 2
表示纵坐标差值的平方,两者相加得到两点之间的距离的平方,最后使用sqrt()
函数求出距离的实际值。
sqrt()
是 Python 中的数学库math
中的一个函数,用于计算数值的平方根。例如,sqrt(4)
返回 2.0,因为 2 的平方是 4。