技能书答题——python

一、预备知识

1.python简介

Hello World

答案

if __name__ == '__main__':
    str1 = "Hello,"
    str2 = "World!"
    print('str1'+'str2')

解析
直接把str1和str2当成字符串而不是变量当然不可能输出hello world

注:

  1. eval的用法是把括号里面的代码用python执行一下
str1="Helo,"   
str2="World!"   
print(eval("str1+str2"))


#### Helo,World!
  1. join的用法
str_list = ["Hello,","World!"]
res = ''.join(str_list)

2.程序设计思想

2.1 编程语言简史

答案

if __name__ == '__main__':
    languages = ...
    years = ...
    for language in languages:
        for year in years:
            print(language, ':', year)

解析

错误选项:一个语言都和每个年份一起打印了出来,正确的应该是一个语言按顺序对应一个年份。

2.2 编程语言发明家

答案

def parse_creators(creators):
    profiles = []
    i = 0
    while i<len(creators):
        creator = creators[i]
        name, achievement = parse_parts(creator)
        profiles.append({ 'name_cn': name, 'name_en': name, 'achievement': achievement })
        i+=1
    return profiles

解析
缺少继续拆分中英文姓名的功能

2.3 Alice、Bob 和他们的朋友们

答案

class CryptographyCity:
    def __init__(self):
        self.peoples = []

    def add(self, text):
        parser = SimpleCryptographyPeopleParser(text)
        people = parser.parse(text)
        self.peoples.append(people)

    def introduce():
        for people in peoples:
            say(people)

    def say(people):
        info = f'{people.name_cn}({people.name_en}): 密码学家说我是一位{people.role}{people.desc}。'
        print(info)

解析
class中定义函数的正确写法,即类中定义函数必须要有一个self参数

3.安装python

Python 安装交互式查询程序

答案

while True:
    ret = input("请选择安装平台[w/c/u/m, 按q退出]:")
    platform = shortcut_keys.get(ret)

    if ret == 'q':
        break
    
    if platform is None:
        print("不支持的平台")
        break
    
    doc = install.get(platform)
    print(f"{platform}: {doc}")

解析
break退出循环,continue结束本次循环,进入下一轮循环。

4.运行方式

操作系统如何运行程序

答案

while True:
    ret = input("请选择你想了解的 Python 运行方式(输入:r/s选择,输入 q 退出):")
    if ret == 'r' or ret == 's':
        has_learn_repl = ret=='r'
        has_learn_source = ret=='s'
        desc = run.get(shoutcut_keys.get(ret))['desc']
        for i in range(0, len(desc)):
            print("{}. {}".format(i, desc[i]))
    elif ret != 'q':
        print("[错误] 不支持的运行方式")
        break
    else:
        pass

解析

  1. 因为ret只有在用户输入r或s时才有值,如果用户输入其他字符,那么ret就没有值,会导致程序出错。应该在判断用户输入是否合法后再进行has_learn_repl和has_learn_source的赋值操作.
  2. ret == ‘r’ or ret == 's’也符合elif的判断

5.常用开发工具

现代集成开发环境(IDE)

答案

find_records = {}
for top_ide in top_ides:
    for py_ide in py_ides:
        py_ide_name = py_ide['name']
        if not find_records.get(py_ide_name):
            if py_ide['name'].lower() == top_ide['IDE'].lower():
                find_records[py_ide['name']] = True
                dump_join_result(py_ide, top_ide)

解析
错误的打印是在满足两个都有同样IDE名称的时候打印共有的三个IDE信息,而其他的都是打印下面四个IDE信息。
可更改为

 
    find_records = {}
    find_records_names = []
    for top_ide in top_ides:
        for py_ide in py_ides:
            py_ide_name = py_ide['name']
            if not find_records.get(py_ide_name):   
                if py_ide['name'].lower() == top_ide['IDE'].lower():
                    find_records[py_ide['name']] = True
                    find_records_names.append(py_ide['name'].lower())
                    dump_join_result(py_ide, top_ide)
    for py_ide in py_ides:
        if py_ide['name'].lower() not in find_records_names:
            dump_join_result(py_ide, None)

6.编码规范

代码规范(风格)

答案

if not word in word_dict:
    word_info = {'word': word, 'count': 0}
    word_dict[word] = word_info

word_info['count'] += 1

解析
其他正确选项的第一句都是:word_info = word_dict.get(word)。作用是将word_info指向word_dict中对应的值上。缺少这一句的话,word_info会指向上一个while循环的位置。
举例说明:

guides = “a b c d a b ”  # 因为在分割符位置进行计数,所以最后要有一个空格,才能将最后一个数计入
 
''' 输出结果 '''
单词排行榜
--------
1. 单词:d, 词频:3
2. 单词:a, 词频:1
3. 单词:b, 词频:1
4. 单词:c, 词频:1

7.模块管理

7.1 Python标准库模块导入

答案

import time.time

if __name__ == '__main__':
    print(time())

解析
没有time.time模块,所以无法导入。可以frome time import time 。time.time()返回的是时间戳。

7.2 从前有座山,山上有座庙,庙里有个老和尚说:使用Python 包(package)组织代码

答案

import sys

if __name__ == '__main__':
    while True:
        import parent
        import parent.one.one
        import parent.two

        del sys.modules['parent']
        del sys.modules['parent.one.one']
        del sys.modules['parent.two']

解析
注:导入子目录会自动导入父目录的module

import parent
缓存已有---无
输出---从前有座山,
缓存新增---parent
 
import parent.one.one
缓存已有---parent
输出---山上有座庙,庙里有个老和尚,
缓存新增---parent.one, parent.one.one
 
import parent.two
缓存已有---parent,parent.one, parent.one.one
输出---老和尚说
缓存新增---parent.two
 
del sys.modules['parent']
缓存还有---parent.one, parent.one.one, parent.two
 
del sys.modules['parent.one.one']
缓存还有---parent.one, parent.two
 
del sys.modules['parent.two']
缓存还有---parent.one  (这里没删干净!!!!!)
 
(下一次循环)
 
import parent
缓存已有---parent.one
输出---从前有座山,
缓存新增--- parent
 
import parent.one.one
缓存已有---parent.one, parent
输出--庙里有个老和尚,(这里因为parent.one缓存还在,不会执行“山上有座庙”)
 
...
 

7.3 使用相对路径导入包

答案

import ..subpackage2.moduleZ

解析
import module_name。即import后直接接模块名
from package_name import module_name。一般把模块组成的集合称为包(package)。与第一种写法类似,Python会在sys.path和运行文件目录这两个地方寻找包,然后导入包中名为module_name的模块。

二、基础语法

1.缩进规则

看不见的开始和结束

答案

if __name__ == '__main__':
    i = 0
    c = 5
    max = 10
    while i < max:
        d = max-i-i

      if abs(d) < 3:
        print(i, max-i)
      else:
        pass

        i += 1

解析
缩进问题

2.函数

2.1 使用函数组织代码

答案

circulate_print(str, count)

解析
没有count+1,会导致死循环

2.2 循环计算阶乘函数

答案

import math
z = n + 1
p = [1.000000000190015, 76.18009172947146, -86.50532032941677,
        24.01409824083091, -1.231739572450155, 1.208650973866179E-3, -5.395239384953E-6]

d1 = math.sqrt(2 * math.pi) / z

i = 1
d2 = p[0]
while i <= 6:
    d2 += p[i] / (z + i)
    i += 1

d3d4 = math.pow((z + 5.5), (z + 0.5))*math.exp(-(z + 5.5))
d = d1 * d2 * d3d4
r = int(d)

解析
计算的不是阶乘

2.3 Python 函数递归(1)

答案

def inner_fact(n, m, r):
    if m == n:
        return r
    return inner_fact(n, m+1, r*m)
 
 
def fact4(n):
    return inner_fact(n, 1, 1)

解析
m 等于 n 时, 阶乘 r 还只是乘到了 m - 1, 没有乘到 m, 计算 10 的阶乘, 实际只计算了 9 的阶乘
代码可以改为

def inner_fact(n, m, r):
    if m == n:
        return r
    return inner_fact(n, m+1, r*m)
 
 
def fact4(n):
    return inner_fact(n+1, 1, 1)

2.4 Python 斐波那契(fibonacci)(I)

答案

def fibonacci_inner(n, r):
    if n == 1 or n == 2:
        return r

    return fibonacci_inner(n-1, fibonacci_inner(n-2, r))


def fibonacci4(n):
    return fibonacci_inner(n, 0)

解析
r没有参与到迭代中
改为

def fibonacci_inner(n, r):
    if n == 1 or n == 2:
        return r

    return fibonacci_inner(n-1, fibonacci_inner(n-2, r+1))


def fibonacci4(n):
    return fibonacci_inner(n, 1)

2.5 Python 斐波那契(fibonacci)(II)

答案

if cache.get(n) is None:
    fibonacci_inner1(n-2, cache)
    fibonacci_inner1(n-1, cache)
    cache[n] = cache[n-1]+cache[n-2]
return cache[n]

解析
没有给cache[n-1]和cache[n-2]赋值

2.6 基于函数的API设计,理解接口与实现分离

答案

def init():
    return {"pre": None, "key": None, "value": None, "next": None}

def set(dict, key, value):
    node = dict
    while node is not None:
        if node['key'] == key:
            return
        node = node['next']
    node['next'] = {"pre": node, "key": key, "value": value, "next": None}

def get(dict, key):
    node = dict
    while node is not None:
        if node['key'] == key:
            return node['value']
        node = node['next']

def exist(dict, key):
    node = dict
    while node is not None:
        if node['key'] == key:
            return True
        node = node['next']
    return False

解析
在初始化时把所有的值都赋值成了None.在node = node[‘next’]之后,这个node就变成了None,所以后面再去使用node[‘next’]就提示不存在了。

def init():
    return {"pre": None, "key": None, "value": None, "next": None}

def set(dict, key, value):
    node = dict
    while node["next"] is not None:
        if node['key'] == key:
            return
        node = node['next']
    node["next"] = {"pre":node, "key": key, "value": value, "next": None}

def get(dict, key):
    node = dict
    while node is not None:
        if node['key'] == key:
            return node['value']
        node = node['next']

def exist(dict, key):
    node = dict
    while node is not None:
        if node['key'] == key:
            return True
        node = node['next']
    return False

3 类

3.1 Python 类的基本使用(1)

答案

class GuessSentenceGame:
    ...

    def setup(sentences):
        for sentence in sentences:
            cut_pos = sentence.find(' ')
            self.kv.set(sentence[0:cut_pos], sentence[cut_pos+1:].strip())
        
    def guess(first_word):
        self.kv.get(first_word)
        return 0, value if value else 1, None

解析
这道题的错误有点像找茬问题,问题选项的guess方法中没有赋值给value,所以出错
但是从题目逻辑性出发,可以进一步增强代码的健壮性,比如guess方法中加入self.ret和self.value的比较

 
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 GuessSentenceGame:
    def __init__(self):
        self.kv = KeyValueSet()
        self.score = 0
 
    def setup(self, sentences):
        for i in sentences:
            key = i.split(' ', 1)[0]
            value = i.split(' ', 1)[1]
            self.kv.set(key, value)
 
    def guess(self, first_word):
        err = 0
        if self.kv.get(first_word) == self.ret:
            err = 0
            value = self.kv.get(first_word)
            return err, value
        else:
            err = 1
            value = self.kv.get(first_word)
            return err, value
 
    def run(self):
        self.score = 0
        for first_word in self.kv.keys():
            self.ret = input("猜一猜下半句是什么? {} -> :".format(first_word))
            err, value = self.guess(first_word)
            if err == 0:
                print('你太厉害了,这都能猜得到!+10分!')
                self.score += 10
            else:
                self.score -= 2
                print('哈哈,肯定猜不到得啦:{}->{},扣除2分!'.format(first_word, value))
        print('游戏结束,你本次游戏得分:', self.score)
 
 
if __name__ == '__main__':
    sentences = [
        "hello world",
        'monkey king',
        'tomorrow is another day',
        "good bye"
    ]
 
    game = GuessSentenceGame()
    game.setup(sentences)
    game.run()

3.2 Python 类的基本使用(2)

通过类的集成,可以扩展原有的类。例如继承KeyValueSet容器类,扩展功能,支持类似redis的 hset/hget/hkeys 扩展接口
答案

hash_set = self.get(hash_key,{key:value})
self.set(hash_key, hash_set)

解析
hashset的主key只有一个,后面的dict是值
注:

  1. 本题使用的是KeyValueSet作为基类,其中每个key对应的是一个value列表。因此,对于相同的hash_key,我们可以在value列表中添加多个key-value对。对于hget方法,可以通过value列表来获取指定的key值。对于hset方法,我们需要在value列表中添加新的key-value对,而不是直接覆盖原有的key-value对。
  2. hash_set = {key:value} 和 hash_set[key]=value的区别是,前者hash_set是空,是赋值操作;后者是添加值操作

3.3 Python 类的基本使用(3)

答案

self.set(hash_key, {key: value})

解析
类HashKeyValueSet没有定义set函数,无法调用,所以是错误的。self.kvset是一个KeyValueSet类,定义了set函数,可以调用。
此外,这两个选项没有对{key:value}进行扩展,而是直接覆盖了,所以都是错的。运行结果只有一个{“good”:“bye”}。

4.顺序语句结构

python顺序语句

答案

x = 10
y = 20
s = x * y

解析
python的运行顺序是,哪怕是你调用方法,只要方法内部,不存在其他方法,他就是自上向下运行代码,必须先有数据,才能对数据做运算,如果还没有数据,或者只有一部分数据,都会报错
注:

if __name__ == '__main__':

含义是:表示如果程序直接被python 启动,例如 python test.py 的时候。一个python文件也可能被其他python文件通过 import 导入,加了这句则被导入的时候不会执行这行代码下缩进的代码。如果不加这句,直接放全局,无论是被 python命令启动还是被其他文件import,全局代码都会执行。

5.条件和分支

5.1 Python 条件和分支(1)

答案

if ret == "{}".format(test):
    print("哎,这么简单都答不对,回去重修吧!")
else:
    print("恭喜你答对了!")

解析
逻辑问题

5.2 Python 条件和分支(2)

答案

if database.get(key) is None:
    print("* 无法检索到该信息!")
else:
    print("* 返回:{}".format(database[key]))

解析
考察if not value/ if value/ if value is None的用法

6.循环

6.1 Python 循环1

答案

for i, item in list:
    print('')
    print("## 第{}条信息".format(i))
    print("* id: {}".format(item['id']))
    print("* number: {}".format(item['number']))
    print("* title: {}".format(item['title']))
    print("* body: {}".format(item['body']))

解析
enumerate的用法,输出是list的index 和value

6.2 Python 循环2

答案

while i in list:
    item = list[i]
    print('')
    print("## 第{}条信息".format(i))
    print("* id: {}".format(item['id']))
    print("* number: {}".format(item['number']))
    print("* title: {}".format(item['title']))
    print("* body: {}".format(item['body']))

循环

i是index not inlist
注:

  1. python iter()函数用于生成迭代器;
  2. python next()函数和iter()函数组合使用,返回迭代器的下一个项目。如果是next(a,b),那么获取a的最后一个元素之后, 下一次next返回设置的默认值b, 而不会抛出 StopIteration。

7. 数据类型

python六大数据类型包括:数字型(整型、浮点型、布尔型和复数类型)、字符串、列表、元组、集合和字典

7.1 字符串

答案

print("双引号字符串里的双引号: "hello world!"")
print('单引号字符串里的单引号: 'hello world!'')

triple2 = '''
    三引号字符串里的三引号:
    * "双引号" 
    * '单引号'
    * '''三引号'''
    '''

解析
引号嵌套问题:同种引号嵌套要注意转义,修改后的正确实现如下

print("双引号字符串里的双引号: \"hello world!\"")
print('单引号字符串里的单引号: \'hello world!\'')

triple2 = '''
    三引号字符串里的三引号:
    * "双引号" 
    * '单引号'
    * \'''三引号\'''
    '''

7.2 列表

答案
[30, 40]

解析
1.首先array = []是一个空列表
2. append了一个10和20,这个时候列表里面就多了两个数,不再是空列表 而是变成了array=[10,20]
3.pop默认是删除最后一个的,但是它给了一个索引位置0,那么就把array中索引为 0 的元素删除了,这个时候array=[20]
4.然后又append添加了 30和40两个数 ,这个时候array=[20,30,40]
5.pop把索引为0的删除,这个时候array=[30,40]
insert和pop方法写反了==

7.3元组

答案

tuple1 = ('红色')
for element in tuple1:
    print(element)

解析
只有一个元素的元组,需要在最后面添加一个逗号,不然系统会误判
不带括号的一系列逗号组成的序列也是元组

7.4字典

答案

['程序员', '户外达人']
None

解析

  1. python 对于dict 字典 key value 类型, key 值必须唯一, 当对一个字段进行add key 时, 如果key 存在 则更新key 的value内容。不存在则新增
  2. 字典get方法不会报错,没有的话返回None

8.内置类

答案

def filter_element(items, bound):
    res = [item for item in items if item < bound]
    return res

解析
要求是要过滤掉小于3的数字,逻辑错误

9.内置函数

9.1 Python 常用内置方法(1)

答案

解析
round()函数表示用于四舍五入

9.2 Python 常用内置方法(2)

列表相关
答案

seasons = ['Spring', 'Summer', 'Fall', 'Winter']
assert len(seasons) == 4

shortcut = list(map(lambda s: s[0], seasons))
assert shortcut == ['S', 'S', 'F', 'W']

9.3 python基本输入

答案

while True:
    n = input("请输入0-100之间的一个数字:")
    try:
        n = int(n)
    except:
        print("无效的数字")
        continue

    if n == v:
        print("你猜对了!")
        break
    elif n < v:
        print("你猜错了,我想到的数字比{}大".format(n))
    elif n > v:
        print("你猜错了,我想到的数字比{}小".format(n))

解析
input 返回str,需要int
注:

  1. try和except的使用
    运行一段代码,能运行继续运行,不能运行的话,输出except后的语句,也可以设置错误类型,最后加个finally的话try最后总会运行finally
  2. read函数是读取文件输入,input接收用户从键盘上输入,返回的结果是字符串,如果判断需要进行强制转换一下。

三、进阶语法

1. Python 列表推导式

1.1 Python 列表推导式(1)

答案

even = [n for n in list if n % 2 == 0]

解析
列表推导式
https://www.runoob.com/python3/python-comprehensions.html
https://zhuanlan.zhihu.com/p/90558097

1.3 Python 生成器推导式

答案

reading = (book for book in books if len(book) <= 4)

解析
元组的推导式,同list
元组可以理解为特殊的list,即不能更改元素的list

1.4 Python 元组推导式

答案

def test():
    books = ('程序员修炼之道', '构建之法', '代码大全', 'TCP/IP协议详解')

    reading = (book for book in books if len(book) <= 4)

    print("太长的书就不看了,只读短的:")
    for book in reading:
        print(" ->《{}》".format(book))

    print("可是发现书的名字短,内容也可能很长啊!")


if __name__ == '__main__':
    test()

1.5 Python 字典推导式

答案

non_windows = {key: install[key] for key in install if key != 'w'}

解析
字典的推导式

2.三元表达式

2.1 Python 三元表达式(1)

答案

even_count += 1 if i % 2 == 0 else 0

解析
三元推导式

2.2 Python 三元表达式(2)

答案

even_count += 2 if i % 4 == 0 else 1 if i % 2 == 0 else 0

解析
先判断是否是4的倍数,再判断是否是2的倍数
如果先判断2,轮不到判断4,明显让2就一锅端了。反之,先判断4,2的也不会被一锅端进4里边

3. 断言

Python 断言

答案

def check_param(key_value_map, key):
    assert key_value_map
    assert type(key_value_map) == dict
    assert key
    assert type(key) == str

解析
所谓断言,就是证明,使用 assert 对输入函数输入参数和函数返回结果分别做前校验和后校验

正确的是

def check_param(key_value_map, key):
    assert key_value_map is not None
    assert type(key_value_map) == dict
    assert key is not None
    assert type(key) == str

4. with as

4.1 Python with-as 语句(1)

答案

def load_json(file):
    with open(file, 'r') as f:
        return json.loads(f.read())

def dump_json(file, obj):
    with open(file, 'w') as f:
        f.write(json.dumps(obj, indent=2, ensure_ascii=False))

解析

  1. r表示read w表示write
  2. json.loads 转为json json.dumps json转为其他

4.2 Python with-as 语句(1)

答案

class TimeSpan:
    def __enter__(self):
        return time.time()

    def __exit__(self, exc_type, exc_val, exc_tb):
        end = time.time()
        print('耗时:{}毫秒'.format((end-exc_val)))

注:

  1. 参数传给slef这种写法值得学习
class TimeSpan:
    def __enter__(self):
        self.end = None
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        print('耗时:{}毫秒'.format((self.end-self.start)))

5. 异常捕获预处理

Python 异常处理

# -*- coding: UTF-8 -*-
import json
import traceback
import logging
logger = logging.getLogger(__name__)
 
def load_json(file):
    with open(file, 'r') as f:
        return json.loads(f.read())
 
def test():
    try:
    ret = load_json('a.json')
    return {'err': 'success', 'result': ret}
	except Exception as e:
	    logger.error(f"load json exception:{str(e)}")
	    logger.error(traceback.format_exc())
	    return {'err': 'exception'}
    ret = load_json('a.json')
    
if __name__ == '__main__':
    test()

解析

  1. except Exception as e:固定写法
  2. logging的用法

6. 字符串方法

Python 字符串方法

答案

def naive_calc(code):
    code_lines = [l for l in code.split('\n') if l.strip() != '']
    for line in code_lines:
        ret = re.match("\s*(\d+)([\+\-\*\/])(\d+)\s*", line)
        left = ret.group(1)
        op = ret.group(2)
        right = ret.group(3)
        if op == '+':
            print('{}+{}={}'.format(left, right, int(left)+int(right)))
        elif op == '-':
            print('{}-{}={}'.format(left, right, int(left)-int(right)))
        elif op == '*':
            print('{}*{}={}'.format(left, right, int(left)*int(right)))
        elif op == '/' and right != '0':
            print('{}/{}={}'.format(left, right, int(left)/int(right)))

解析

  1. re.match(rule,target)
  2. str转换为int 直接int()

7. lambda函数

Python 匿名表达式

答案

解析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值