Python百日百行代码挑战-day1
最近在复现论文,做实验等等的过程中,深深感觉到自己的代码水平太差了,所以才有了这么一个想法,准备坚持一百天,每天看懂or写出来100行代码,尽量做到不重复,以此来增进一下python水平和编码思维习惯,每天的素材都是自己随机找到的,今天第一天,代码素材来源于csdn的python技能树的联系。
练习题
练习题一
本次练习一为Python入门技能树-基础语法-类-第二题。先看一下题目要求:
继承第一问的要求,完成你说我猜的小游戏,以下是示例输出:
猜一猜下半句是什么? hello -> :world
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? monkey -> :king
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? tomorrow -> :is another day
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? good -> :a
哈哈,肯定猜不到得啦:good->bye,扣除2分!
游戏结束,你本次游戏得分: 28
以下是题目所给出的代码部分
from key_value_set import KeyValueSet
class HashKeyValueSet(KeyValueSet):
def __init__(self) -> None:
super().__init__()
def hset(self, hash_key, key, value):
# TODO(You): 请在此实现 hset 方法
def hget(self, hash_key, key):
hash_set = self.get(hash_key)
if hash_set is None:
return None
else:
return hash_set.get(key)
def hkeys(self, hash_key):
hash_set = self.get(hash_key)
if hash_set is None:
return []
else:
return hash_set.keys()
if __name__ == '__main__':
hashset = HashKeyValueSet()
hashset.hset('puzzle', 'hello', 'world!')
hashset.hset('puzzle', 'monkey', 'king!')
hashset.hset('puzzle', 'tomorrow', 'is another day')
hashset.hset('puzzle', 'good', 'bye!')
keys = hashset.hkeys('puzzle')
for key in keys:
ret = input("猜一猜下半句是什么? {} -> :".format(key))
value = hashset.hget('puzzle', key)
if ret == value:
print('你太厉害了,这都能猜得到!')
else:
print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))
其中import的是这部分:
class KeyValueSet:
def __init__(self) -> None:
self.dict = {}
def set(self, key, value):
self.dict[key] = value
def get(self, key):
return self.dict.get(key)
def keys(self):
return self.dict.keys()
选项为:
A:
hash_set = self.get(hash_key,{key:value})
self.set(hash_key,hash_set)
B:
hash_set = self.get(hash_key)
if hash_set is None:
hash_set = {key:value}
self.set(hash_key,hash_set)
else:
hash_set[key] = value
self.set(hash_key,hash_set)
C:
self.set(hash_key,{key:value})
D:
hash_set = self.get(hash_key)
if hash_set is None:
hash_set = {key:value}
else:
hash_set[key] = value
self.set(hash_key,hash_set)
好,通过题目要求可以看到,本题要求实现HashKeyValueSet类当中的hset函数。首先对程序进行分析,该方法实现了什么功能。通过if name == ‘main’:部分,可以看到实例化过后的对象调用了四次该方法,通过后面的输入可以判断得到,该方法实现的功能为初始化题库,因此在解题过程中,重点要看ABCD四个选项中是否实现这一功能。
对A选项的分析
A选项就是错的,这个错的相当明显,就是在get函数里面,传入了太多的值。get函数出现在KeyValueSet的定义部分里面,很显然这里只允许传入一个值,但是A选项给了三个,完了程序就会报错,这么报的:
get() takes 2 positional arguments but 3 were given
对B选项的分析
相当正确的一个选项,看后面D的分析吧,这俩一样的,就是把一个句子写了两遍而已
对C选项的分析
这个代码可以说是相当的风骚啊,只写了一行,本来我以为这是个对的,运行完了才发现这玩意居然是错的(emmmm,难道说csdn当时选题的时候不怎么严谨?)。乍一看没什么问题,实际运行的时候才发现,字典中只剩下最后一个good bye!的键值对了。
我一开始想错了,我想的是,既然使得每一个key都等于了value(KeyValueSet中set这么说的),那么理应出现所有的组合,为什么值会被冲掉,后来发现每一个hash_key都是puzzle,所以在python看来,只是单纯修改了一下字典里面的值而已,所以最后只剩下了最后一次赋值的结果。
对D选项的分析
首先,该方法初始化了一个字典(在KeyValueSet部分),后面又定义了一个get函数,第一句话就用到 了这个函数,一开始,在该字典中没有任何值在里面,因此get出来的结果是一个None,返回为None,之后通过if语句,使得hash_set具有了初值,也就是一个字典,内容为第一次调用hset函数的hello和world。赋值结束以后,使用KeyValueSet类中的set方法,将hash_key和hash_set的内容结合起来,形成一个新的字典,此时大字典的value是一个小的字典。第二次调用hset方法的时候,里面已经有了初值,hast_set的内部存在值,跳转到else语句下面。(一开始我想着为啥不直接让hash_set等于一个键值对算了,后来发现这样的话会冲掉原来的值,这小破问题居然我都没想到,老了老了)。最终成功将题库加进来,perfect!
练习题二
本次练习二为Python入门技能树-基础语法-类-第三题。
本题要求与上一题一致,代码部分如下:
class KeyValueSet:
def __init__(self) -> None:
self.dict = {}
def set(self, key, value):
self.dict[key] = value
def get(self, key):
return self.dict.get(key)
def keys(self):
return self.dict.keys()
class HashKeyValueSet:
def __init__(self, kvset) -> None:
super().__init__()
self.kvset = kvset
def hset(self, hash_key, key, value):
# TODO(You): 请在此添加代码
def hget(self, hash_key, key):
hash_set = self.kvset.get(hash_key)
if hash_set is None:
return None
else:
return hash_set.get(key)
def hkeys(self, hash_key):
hash_set = self.kvset.get(hash_key)
if hash_set is None:
return []
else:
return hash_set.keys()
def test():
hashset = HashKeyValueSet(KeyValueSet())
hashset.hset('puzzle', 'hello', 'world!')
hashset.hset('puzzle', 'monkey', 'king!')
hashset.hset('puzzle', 'tomorrow', 'is another day')
hashset.hset('puzzle', 'good', 'bye!')
keys = hashset.hkeys('puzzle')
for key in keys:
ret = input("猜一猜下半句是什么? {} -> :".format(key))
value = hashset.hget('puzzle', key)
if ret == value:
print('你太厉害了,这都能猜得到!')
else:
print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))
if __name__ == '__main__':
test()
选项为:
A:
self.set(hash_key,{key,value})
B:
hash_set = self.kvset.get(hash_key)
if hash_set is None:
hash_set = {}
hash_set[key] = value
self.kvset.set(hash_key,hash_set)
else:
hash_set[key] = value
self.kvset.set(hash_key,hash_set)
C:
self.kvset.set(hash_key, {key: value})
D:
hash_set = self.kvset.get(hash_key)
if hash_set is None:
hash_set = {key:value}
else:
hash_set[key] = value
self.kvset.set(hash_key,hash_set)
对A选项的分析
该选项为错误选项,一开始我还没看出来有啥不对劲的,后来我才发现啊!在__init__函数里面,HashKeyValueSet定义了一个参数,叫做kvset,在test函数中,很显然可以看到这个参数就是KeyValueSet这个类啊!!而A选项,这玩意调动了KeyValueSet这个类当中的方法,但是!必须要写kvset.,来表示是从另一个类中调用的,不然python很蒙圈的,就跟血小板似的,一脸懵逼地看着你,你说谁尴尬啊。
但是在这里补充一下,在学习过程中,官方给出了这样一个资料代码:
class School:
def __init__(self,name):
self.teach_list = []
self.name = name
def zhaopin(self,teach):
self.teach_list.append(teach)
def shangke(self):
for t in self.teach_list:
t.work()
class Teacher:
def __init__(self,name):
self.name = name
def work(self):
print(f'{self.name}在上课')
lnh = School('老男孩')
t1 = Teacher('武Sir')
t2 = Teacher('太白')
t3 = Teacher('哪吒')
lnh.zhaopin(t1)
lnh.zhaopin(t2)
lnh.zhaopin(t3)
lnh.shangke()
通过实际测试,发现其确实可以运行,但是这里类之间却没有采用什么方法互相调用,这个原因是当你在创建t1等等的时候,t1本身就具有work这个工作的属性,因此才不需要额外的语句来说明,直接work()就行,但是本题中不一样,必须要表明这个方法是从另一个类中过来的才行。
对B选项的分析
这个和第二问其实没有什么差别,就是get了一下hash_key的值,和上一问的D分析逻辑上分析差不多,return的也没问题。和上一问的B有异曲同工之妙啊。需要强调的一点就是,当hash_set取到None的时候,必须在语句后面表明hash_set = {},这个作用是让python知道这玩意得是个字典,不然python看不懂后面那句话。
对C选项的分析
它甚至和上一问的C一模一样,就是因为类中调用了类多了一个kvset而已,还是一样的问题,把值给冲掉了。
对D选项的分析
和上一题的D一致,没啥好分析的了啊,同理也就是多了一个kvset。
本次训练收获总结
python中的get函数
这个函数就是为了取得字典中的某一个key对应的value,例子如下:
a = {'game1':'7 days to die','game2':'ARK','game3':'cfhd'}
print(a.get('game1'))
# 运行结果如下:
# 7 days to die
python中的format函数
识别输出语句中的大括号{},例子如下:
print('{} will improve {} skills'.format('I','python'))
# 输出结果
# I will improve python skills
python中神奇的符号->
这东西我复现论文的时候也没少见,一直很蒙圈,今天把这个例子静下心来写完才搞明白,这东西能够限定返回值的类型啊,本题中没有返回值,所以强行设置成了None。有的话设置成int啥的就行
对python中类的__init__()的理解
正经一点的话来说,他叫做构造函数。在Python语言中,所有以双下划线“__”包起来的方法,都统称为“魔术方法”。他就是其中的构造函数,用来初始化内部状态和参数,不过我肯定要用我自己的理解去解释这东西了,你创建这个类,你肯定得用,你要用你就得实际搞一个东西来用它,完了你想给这东西安排一下,你想咋安排就在这init里面设定,你要是不想安排,人万一不开心了不给你干活了咋整。大概就这样吧,表达能力不够,解释的不好
对python类中self的理解
self,就是你的实例对象,这两可以直接划等号了,比如你创建了一个动物的类,完了你让dog = Animal(),那程序里面的self就是dog,你给实例化的对象起个啥名,你的self就是啥意思。
其他总结
类和类有很多关系,除了熟知的子类用父类的东西以外,类和类之间的方法也可以互通。
- 要不就是实例化一个对象,在另一个类中调用这个对象,因为实例化过了,所以这个对象就有了另一个类的方法,随便用。
- 要不就是这个类直接调用另一个类,在__init__函数里面设定一个参数,用另一个类的方法的时候,把这个参数调用一下,也能用别的类的方法。
大概看了一下,这次的代码算上空格有109行,但是包括看教程举得那个例子,还有自己敲得一些东西,差不多下来有100行了,本次收获尚可吧。
防火防盗防诈骗