- 2024-09-12
-
回复了主题帖:
中秋芯积分兑换月饼、实用工具健身器材啦!
已兑换,存了好久的积分总算可以兑换了,期待收到礼物!
- 2024-09-06
-
回复了主题帖:
大家都用国产SoC落地AI吗?所以ST、瑞萨、Microchip推出的少有人用?
nmg 发表于 2024-9-6 11:10
你这没跟上时代
不过我上面说的是你有没有推荐zynq mp soc板卡的型号,我瞅着都上万了
米联客的也有啊!https://detail.tmall.com/item.htm?abbucket=10&id=658782788125&ns=1&priceTId=2100cfb417256059100272287e0bdf&spm=a21n57.sem.item.4.13f7390357jfM5&utparam=%7B%22aplus_abtest%22:%22b9b53c4e1637c7e25b264593b54f5907%22%7D&xxc=taobaoSearch&skuId=5044725742160
-
回复了主题帖:
大家都用国产SoC落地AI吗?所以ST、瑞萨、Microchip推出的少有人用?
本帖最后由 打破传统 于 2024-9-6 15:02 编辑
nmg 发表于 2024-9-6 11:10 你这没跟上时代 不过我上面说的是你有没有推荐zynq mp soc板卡的型号,我瞅着都上万了
这个有啊,官方的太贵了,正点原子的不都1两千的?淘宝上搜的到,链接如下:
https://detail.tmall.com/item.htm?abbucket=10&id=692450874670&ns=1&priceTId=2100cfb417256059100272287e0bdf&spm=a21n57.sem.item.3.13f7390357jfM5&utparam=%7B%22aplus_abtest%22:%2267afbeb9a291b9068b249625f0014b2d%22%7D&xxc=taobaoSearch
-
回复了主题帖:
大家都用国产SoC落地AI吗?所以ST、瑞萨、Microchip推出的少有人用?
nmg 发表于 2024-9-5 16:38
推荐啥型号,哪个板卡,瞅瞅价格合适不
哈哈,没有玩过国产的不知道那个合适呢
- 2024-09-05
-
回复了主题帖:
大家都用国产SoC落地AI吗?所以ST、瑞萨、Microchip推出的少有人用?
没有用过国产soc,都玩的zynq mp soc,测评整一个哇
- 2024-06-25
-
发表了主题帖:
趣味微项目,轻松学Python_16-22章读书心得
第十六章的内容是随机重排单词中部。作者通过举例我们阅读文字时不会因为单词的打乱而降低阅读速度从而引入本章内容-解扰。
本章中我们要实现一个程序。它对实参给出的文本中的每个单词进行扰码,该扰码只对4个或以上字符的单词作用,只扰乱单词中部的字母,首尾字母保存不变。
主要内容包括:编写scrambler.py、把文本分解成行和单词、捕获组,非捕获组和可选组、编译正则表达式、对一个单词进行扰码,对所有单词进行扰码、处理文本等内容。
通过本章学习我们将学会使用正则表达式把文本拆分成单词、使用random.shufile()函数将list打乱、创建单词的扰码版本,打乱除首尾字母的单词。程序实现如下:
#!/usr/bin/env python3
"""Scramble the letters of words"""
import argparse
import os
import re
import random
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Scramble the letters of words',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
splitter = re.compile("([a-zA-Z](?:[a-zA-Z']*[a-zA-Z])?)")
for line in args.text.splitlines():
print(''.join(map(scramble, splitter.split(line))))
# --------------------------------------------------
def scramble(word):
"""For words over 3 characters, shuffle the letters in the middle"""
if len(word) > 3 and re.match(r'\w+', word):
middle = list(word[1:-1])
random.shuffle(middle)
word = word[0] + ''.join(middle) + word[-1]
return word
# --------------------------------------------------
def test_scramble():
"""Test scramble"""
state = random.getstate()
random.seed(1)
assert scramble("a") == "a"
assert scramble("ab") == "ab"
assert scramble("abc") == "abc"
assert scramble("abcd") == "acbd"
assert scramble("abcde") == "acbde"
assert scramble("abcdef") == "aecbdf"
assert scramble("abcde'f") == "abcd'ef"
random.setstate(state)
# --------------------------------------------------
if __name__ == '__main__':
main()
第十七章内容是使用正则表达式。作者通过“疯狂”填词游戏引出本章的内容。
本章中我们要实现一个程序。它读取位置实参给出的文件,并且找到所有位于尖括号内的占位符,针对每个占位符,我们向用户提示所需词性,然后用户输入的每个值将替换文本中的占位符,当所有占位符都被用户的输入替换后,打印出新文本。
主要内容包括:编写mad.py、使用正则表达式找到尖括号、停止并打印错误、获取值、替换文本、用正则表达式进行替换、不用正则表达式找到占位符等内容。
通过本章学习我们将学会使用sys.exit()暂停程序并提升错误状态、学会使用正则表达式进行贪婪匹配、使用re.findall()为正则表达式找到所有匹配项、使用re.sub()把找到的模式替换成新文件、探索不使用正则表达式的解决方案。实现程序如下:
#!/usr/bin/env python3
"""Mad Libs"""
import argparse
import re
import sys
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Mad Libs',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('file',
metavar='FILE',
type=argparse.FileType('rt'),
help='Input file')
parser.add_argument('-i',
'--inputs',
help='Inputs (for testing)',
metavar='input',
type=str,
nargs='*')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
inputs = args.inputs
text = args.file.read().rstrip()
blanks = re.findall('(<([^<>]+)>)', text)
if not blanks:
sys.exit(f'"{args.file.name}" has no placeholders.')
tmpl = 'Give me {} {}: '
for placeholder, pos in blanks:
article = 'an' if pos.lower()[0] in 'aeiou' else 'a'
answer = inputs.pop(0) if inputs else input(tmpl.format(article, pos))
text = re.sub(placeholder, answer, text, count=1)
print(text)
# --------------------------------------------------
if __name__ == '__main__':
main()
第十八章内容是使用ASCII值对文本进行数字编码。作者通过希伯来数及《圣经教圣经启示录》引出本章的内容。
本章中我们要实现一个程序。把每个单词中的字符对应的数字相加,从而以数值方式对给定文本中的每个单词进行编码。
主要内容包括:编写gematria.py、清洁单词、序数字符值和范围、求和与归约、使用functools.reduce、对单词进行编码、拆解文本、编写word2num()、排序等内容。
通过本章学习我们将了解ord()和chr()函数、探索字符在ASCII表中的组织方式、理解正则表达式中使用的字符范围、使用re.sub()函数、学会如何在不用lambda的情况下写map()、
使用sum()函数,看它与reduce()的关系、学习如何执行不区分大小写的字符串排序。实现程序如下:
#!/usr/bin/env python3
"""Gematria"""
import argparse
import os
import re
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Gematria',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
for line in args.text.splitlines():
print(' '.join(map(word2num, line.split())))
# --------------------------------------------------
def word2num(word):
"""Sum the ordinal values of all the characters"""
return str(sum(map(ord, re.sub('[^A-Za-z0-9]', '', word))))
# --------------------------------------------------
def test_word2num():
"""Test word2num"""
assert word2num("a") == "97"
assert word2num("abc") == "294"
assert word2num("ab'c") == "294"
assert word2num("4a-b'c,") == "346"
# --------------------------------------------------
if __name__ == '__main__':
main()
第十九章的内容是解析 CSV文件,创建文本表输出。作者以自己参加健身俱乐部的例子引出本章的内容。“Workout of the Day”
在本章中我们将实现一个程序。它来帮助我们创建一个随机的每日健身活动清单,这些健身活动是我们必须做的不容反驳。
主要内容包括:编写wod.py、读取带分隔符的文本文件、手动读取CSV文件、用CSV模块进行解析、创建读取CSV文件的函数、选择健身项目、格式化输出、处理无效数据、读取CSV文件、潜在运行错误、使用Pandas.read_csv()解析文件、对表格进行格式化。
通过本章学习我们将学会使用CSV模块解析带分割符的文本文件、强制将文本转换为数字、使用tabulate模块打印表格数据、处理缺失的和格式错误的数据。实现程序如下:
#!/usr/bin/env python3
"""Create Workout Of (the) Day (WOD)"""
import argparse
import csv
import io
import random
from tabulate import tabulate
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Create Workout Of (the) Day (WOD)',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-f',
'--file',
help='CSV input file of exercises',
metavar='FILE',
type=argparse.FileType('rt'),
default='inputs/exercises.csv')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
parser.add_argument('-n',
'--num',
help='Number of exercises',
metavar='exercises',
type=int,
default=4)
parser.add_argument('-e',
'--easy',
help='Halve the reps',
action='store_true')
args = parser.parse_args()
if args.num < 1:
parser.error(f'--num "{args.num}" must be greater than 0')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
wod = []
exercises = read_csv(args.file)
for name, low, high in random.sample(exercises, k=args.num):
reps = random.randint(low, high)
if args.easy:
reps = int(reps / 2)
wod.append((name, reps))
print(tabulate(wod, headers=('Exercise', 'Reps')))
# --------------------------------------------------
def read_csv(fh):
"""Read the CSV input"""
exercises = []
for row in csv.DictReader(fh, delimiter=','):
low, high = map(int, row['reps'].split('-'))
exercises.append((row['exercise'], low, high))
return exercises
# --------------------------------------------------
def test_read_csv():
"""Test read_csv"""
text = io.StringIO('exercise,reps\nBurpees,20-50\nSitups,40-100')
assert read_csv(text) == [('Burpees', 20, 50), ('Situps', 40, 100)]
# --------------------------------------------------
if __name__ == '__main__':
main()
第二十章内容是生成安全且容易记忆的密码。作者通过一部XKCD漫画引出本章的内容易记忆性的密码算法。
本章中我们要使用一个程序。通过随机组合来自输入文件的单词来创建密码。
主要内容包括:编写password.py、创建唯一的单词列表、清洁文本、使用集合、对单词进行过滤、将单词首字母大写、采样和制作密码、l33t-ify、整体运行、ransom()函数、l33t()函数、处理文件、采样和创建密码等内容。
通过本章学习我们将学会把一个或多个输入文件的列表作为位置实参、使用正则表达式删除非单词字符、按照某个最小长度要求来过滤单词、使用单词集(set)来创建唯一表、组合给定数据量的随机选择单词,生成给定数量的密码、选择之前写过的算法的组合来对文本进行编码。实现程序如下:
#!/usr/bin/env python3
"""Password maker, https://xkcd.com/936/"""
import argparse
import random
import re
import string
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Password maker',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('file',
metavar='FILE',
type=argparse.FileType('rt'),
nargs='+',
help='Input file(s)')
parser.add_argument('-n',
'--num',
metavar='num_passwords',
type=int,
default=3,
help='Number of passwords to generate')
parser.add_argument('-w',
'--num_words',
metavar='num_words',
type=int,
default=4,
help='Number of words to use for password')
parser.add_argument('-m',
'--min_word_len',
metavar='minimum',
type=int,
default=3,
help='Minimum word length')
parser.add_argument('-x',
'--max_word_len',
metavar='maximum',
type=int,
default=6,
help='Maximum word length')
parser.add_argument('-s',
'--seed',
metavar='seed',
type=int,
help='Random seed')
parser.add_argument('-l',
'--l33t',
action='store_true',
help='Obfuscate letters')
return parser.parse_args()
# --------------------------------------------------
def main():
args = get_args()
random.seed(args.seed) # <1>
words = set()
def word_len(word):
return args.min_word_len <= len(word) <= args.max_word_len
for fh in args.file:
for line in fh:
for word in filter(word_len, map(clean, line.lower().split())):
words.add(word.title())
words = sorted(words)
passwords = [
''.join(random.sample(words, args.num_words)) for _ in range(args.num)
]
if args.l33t:
passwords = map(l33t, passwords)
print('\n'.join(passwords))
# --------------------------------------------------
def clean(word):
"""Remove non-word characters from word"""
return re.sub('[^a-zA-Z]', '', word)
# --------------------------------------------------
def l33t(text):
"""l33t"""
text = ransom(text)
xform = str.maketrans({
'a': '@', 'A': '4', 'O': '0', 't': '+', 'E': '3', 'I': '1', 'S': '5'
})
return text.translate(xform) + random.choice(string.punctuation)
# --------------------------------------------------
def ransom(text):
"""Randomly choose an upper or lowercase letter to return"""
return ''.join(
map(lambda c: c.upper() if random.choice([0, 1]) else c.lower(), text))
# --------------------------------------------------
if __name__ == '__main__':
main()
第二十一章的内容是探索状态。作者电源《战争游戏》中井字棋游戏引入本章内容。
本章中我们将实现一个程序。编写一个只玩单回合井字棋的程序。程序接收一个字符串,以代表游戏期间任意时刻的棋盘状态。默认状态是游戏开始,任意玩家行棋之前的空白棋盘。程序可以接收一次行棋添加到棋盘,将打印棋盘的一张图片,并报告本次行棋之后是否有赢家。
主要内容有:编写tictactoe.py、验证用户输入、更改棋盘、打印棋盘、确定赢家、验证实参和变更棋盘、对棋盘进行格式化、找到赢家等。
通过本章学习我们将学会考虑如何使用像字符串和列表这样的元素来表示程序状态的各个方面、在代码中强制实施游戏规则、使用正则表达式来确认初始棋盘、使用and和or将布尔值的组合归约到单个值、使用列表的列表来找获胜的棋盘、使用enumerate()函数来迭代list的索引和值。实现程序如下:
#!/usr/bin/env python3
"""Tic-Tac-Toe"""
import argparse
import re
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Tic-Tac-Toe',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-b',
'--board',
help='The state of the board',
metavar='board',
type=str,
default='.' * 9)
parser.add_argument('-p',
'--player',
help='Player',
choices='XO',
metavar='player',
type=str,
default=None)
parser.add_argument('-c',
'--cell',
help='Cell 1-9',
metavar='cell',
type=int,
choices=range(1, 10),
default=None)
args = parser.parse_args()
if any([args.player, args.cell]) and not all([args.player, args.cell]):
parser.error('Must provide both --player and --cell')
if not re.search('^[.XO]{9}$', args.board):
parser.error(f'--board "{args.board}" must be 9 characters of ., X, O')
if args.player and args.cell and args.board[args.cell - 1] in 'XO':
parser.error(f'--cell "{args.cell}" already taken')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
board = list(args.board)
if args.player and args.cell:
board[args.cell - 1] = args.player
print(format_board(board))
winner = find_winner(board)
print(f'{winner} has won!' if winner else 'No winner.')
# --------------------------------------------------
def format_board(board):
"""Format the board"""
cells = [str(i) if c == '.' else c for i, c in enumerate(board, start=1)]
bar = '-------------'
cells_tmpl = '| {} | {} | {} |'
return '\n'.join([
bar,
cells_tmpl.format(*cells[:3]), bar,
cells_tmpl.format(*cells[3:6]), bar,
cells_tmpl.format(*cells[6:]), bar
])
# --------------------------------------------------
def find_winner(board):
"""Return the winner"""
winning = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7],
[2, 5, 8], [0, 4, 8], [2, 4, 6]]
for player in ['X', 'O']:
for i, j, k in winning:
combo = [board[i], board[j], board[k]]
if combo == [player, player, player]:
return player
# --------------------------------------------------
if __name__ == '__main__':
main()
第二十二章的内容是带有类型提升的交互式版本的井字游戏。本章中作者接上一章的内容完善井字游戏。
主要内容有:编写itictactoe.py、元组对话、具名元组、添加类型提升、用Mypy进行类型验证、更新不可改的结构、向函数定义添加类型提示、使用TypedDict的版本等内容。
通过本章学习我们将学会使用和退出无限循环、向代码中添加类型提示、探索元组,具名元组和类型字典、使用mypy分析代码错误。实现程序如下:
#!/usr/bin/env python3
""" Interactive Tic-Tac-Toe using NamedTuple """
from typing import List, NamedTuple, Optional
class State(NamedTuple):
board: List[str] = list('.' * 9)
player: str = 'X'
quit: bool = False
draw: bool = False
error: Optional[str] = None
winner: Optional[str] = None
# --------------------------------------------------
def main() -> None:
"""Make a jazz noise here"""
state = State()
while True:
print("\033[H\033[J")
print(format_board(state.board))
if state.error:
print(state.error)
elif state.winner:
print(f'{state.winner} has won!')
break
elif state.quit:
print('You lose, loser!')
break
elif state.draw:
print("All right, we'll call it a draw.")
break
state = get_move(state)
# --------------------------------------------------
def get_move(state: State) -> State:
"""Get the player's move"""
player = state.player
cell = input(f'Player {player}, what is your move? [q to quit]: ')
if cell == 'q':
return state._replace(quit=True)
if not (cell.isdigit() and int(cell) in range(1, 10)):
return state._replace(error=f'Invalid cell "{cell}", please use 1-9')
cell_num = int(cell)
if state.board[cell_num - 1] in 'XO':
return state._replace(error=f'Cell "{cell}" already taken')
board = state.board
board[cell_num - 1] = player
return state._replace(board=board,
player='O' if player == 'X' else 'X',
winner=find_winner(board),
draw='.' not in board,
error=None)
# --------------------------------------------------
def format_board(board: List[str]) -> str:
"""Format the board"""
cells = [str(i) if c == '.' else c for i, c in enumerate(board, 1)]
bar = '-------------'
cells_tmpl = '| {} | {} | {} |'
return '\n'.join([
bar,
cells_tmpl.format(*cells[:3]), bar,
cells_tmpl.format(*cells[3:6]), bar,
cells_tmpl.format(*cells[6:]), bar
])
# --------------------------------------------------
def find_winner(board: List[str]) -> Optional[str]:
"""Return the winner"""
winning = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7],
[2, 5, 8], [0, 4, 8], [2, 4, 6]]
for player in ['X', 'O']:
for i, j, k in winning:
combo = [board[i], board[j], board[k]]
if combo == [player, player, player]:
return player
return None
# --------------------------------------------------
if __name__ == '__main__':
main()
分享中的代码并非全部代码,感兴趣小伙伴可以扫描下面的二维码下载完整的文件。
-
回复了主题帖:
AD9689使用心得
太爱学习了 发表于 2024-6-25 14:13
9689为啥有4个ddc,只需要2个就够了啊,芯片为啥这么设计,有谁懂
我也只用到两个DDC的时候,应该还是跟后端需求有关,多一个DDC相当于多了一路数据输出。这个问题你可以在ADI官网论坛去问问
- 2024-06-22
-
发表了主题帖:
趣味微项目,轻松学Python_8-15章读书心得
第八章内容是找到并替换,作者通过《苹果和香蕉》这个歌曲引出本章的内容。
本章中我们将实现一个程序,该程序选取某个文本并把该文本中的所有元音都替换成给定的-v或—vowel选项。
主要内容包括:更该字符串、使用str.replace()方法、使用str.translate()、其他变更字符串的方法、替换元音的6中方法、用测试进行重构等内容。
通过本章的学习,我们将进一步学习到文本的处理方法,学习多种替换文本的方法:包括迭代每个字符、使用str.replace()方法、使用str.translate()方法、使用列表推导式、使用带有函数的列表推导式、使用map()函数、使用带有具名函数的map()、使用正则表达式。程序一种方式实现如下:
#!/usr/bin/env python3
"""Apples and Bananas"""
import argparse
import os
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Apples and bananas',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-v',
'--vowel',
help='The vowel to substitute',
metavar='vowel',
type=str,
default='a',
choices=list('aeiou'))
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
text = args.text
vowel = args.vowel
new_text = []
for char in text:
if char in 'aeiou':
new_text.append(vowel)
elif char in 'AEIOU':
new_text.append(vowel.upper())
else:
new_text.append(char)
print(''.join(new_text))
# --------------------------------------------------
if __name__ == '__main__':
main()
第九章内容是用单词列表生成随机嘲讽话。作者通过拨号诅咒引出本章随机事件处理的内容。
本章中我们将实现一个程序。它将随机选择形容词和名词来创建诽谤绰号来嘲讽用户。
主要内容包括:编写abuse.py、验证实参、导入随机模块并生成种子、定义形容词和名词、采集随机样本并选择、对输出进行格式化、使用parser.error()、程序退出值和STDERR、使用random.seed()控制随机性、用range()进行迭代并使用抛弃变量、构建嘲讽语句等内容。
通过本章的学习,我们将学会使用来自argpars的parser.error(),抛出错误、用随机种子控制随机性、从python列表中随机选择和采样、用for循环把一个算法迭代特定次数、对输出字符串进行格式化。程序实现如下:
#!/usr/bin/env python3
"""Heap abuse"""
import argparse
import random
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Heap abuse',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-a',
'--adjectives',
help='Number of adjectives',
metavar='adjectives',
type=int,
default=2)
parser.add_argument('-n',
'--number',
help='Number of insults',
metavar='insults',
type=int,
default=3)
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
args = parser.parse_args()
if args.adjectives < 1:
parser.error(f'--adjectives "{args.adjectives}" must be > 0')
if args.number < 1:
parser.error(f'--number "{args.number}" must be > 0')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
adjectives = """
bankrupt base caterwauling corrupt cullionly detestable dishonest false
filthsome filthy foolish foul gross heedless indistinguishable infected
insatiate irksome lascivious lecherous loathsome lubbery old peevish
rascaly rotten ruinous scurilous scurvy slanderous sodden-witted
thin-faced toad-spotted unmannered vile wall-eyed
""".strip().split()
nouns = """
Judas Satan ape ass barbermonger beggar block boy braggart butt
carbuncle coward coxcomb cur dandy degenerate fiend fishmonger fool
gull harpy jack jolthead knave liar lunatic maw milksop minion
ratcatcher recreant rogue scold slave swine traitor varlet villain worm
""".strip().split()
for _ in range(args.number):
adjs = ', '.join(random.sample(adjectives, k=args.adjectives))
print(f'You {adjs} {random.choice(nouns)}!')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十章内容是随机变更字符串。作者通过电话游戏程序引出本章内容。
本章中我们将模拟这个电话游戏程序,该游戏中一排或一圈人以耳语的方式传播一个秘密消息,每次传播该消息都以一种不可预知的方式改变,最后一个接收到消息的人将他大声说出来。
主要内容包括:编写telephone.py、计算变更的数量、变更的空间、选择要变更的字符、变更字符串、使用list代替str等内容。
通过本章的学习,我们将学会数字取整、使用srting模块、修改字符串和列表,进行随机变更。程序实现如下:
#!/usr/bin/env python3
"""Telephone"""
import argparse
import os
import random
import string
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Telephone',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
parser.add_argument('-m',
'--mutations',
help='Percent mutations',
metavar='mutations',
type=float,
default=0.1)
args = parser.parse_args()
if not 0 <= args.mutations <= 1:
parser.error(f'--mutations "{args.mutations}" must be between 0 and 1')
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
text = args.text
random.seed(args.seed)
alpha = ''.join(sorted(string.ascii_letters + string.punctuation))
len_text = len(text)
num_mutations = round(args.mutations * len_text)
new_text = text
for i in random.sample(range(len_text), num_mutations):
new_char = random.choice(alpha.replace(new_text[i], ''))
new_text = new_text[:i] + new_char + new_text[i + 1:]
print(f'You said: "{text}"\nI heard : "{new_text}"')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十一章的内容是编写和测试函数。作者通过《墙上有九十九瓶啤酒》之歌引出本章内容。
本章中我们将实现一个歌曲生成程序。它采用一个选项-n或—num,必须是正的int,该程序打印从—num反向计数到1的所有小节。每个小节之间应该有两个新行。最后一个小节之后只能有一个新行,并打印“No more bottles of beer on the wall”。
主要内容包括:编写bottles.py、反向计数、函数的编写、为verse()编写测试、使用verse()函数、测试驱动开发、verse()函数、遍历歌曲小节等内容。
通过本章学习,我们将学会如何产生一个由递减数字构成的列表、编写一个函数来创建歌曲的一个小节,使用测试来验证该小节何时正确、探索如何把for循环写成列表推导式,进而写成map()。程序实现如下:
#!/usr/bin/env python3
"""Bottles of beer song"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Bottles of beer song',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-n',
'--num',
metavar='number',
type=int,
default=10,
help='How many bottles')
args = parser.parse_args()
if args.num < 1:
parser.error(f'--num "{args.num}" must be greater than 0')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
print('\n\n'.join(map(verse, range(args.num, 0, -1))))
# --------------------------------------------------
def verse(bottle):
"""Sing a verse"""
next_bottle = bottle - 1
s1 = '' if bottle == 1 else 's'
s2 = '' if next_bottle == 1 else 's'
num_next = 'No more' if next_bottle == 0 else next_bottle
return '\n'.join([
f'{bottle} bottle{s1} of beer on the wall,',
f'{bottle} bottle{s1} of beer,',
f'Take one down, pass it around,',
f'{num_next} bottle{s2} of beer on the wall!',
])
# --------------------------------------------------
def test_verse():
"""Test verse"""
last_verse = verse(1)
assert last_verse == '\n'.join([
'1 bottle of beer on the wall,', '1 bottle of beer,',
'Take one down, pass it around,',
'No more bottles of beer on the wall!'
])
two_bottles = verse(2)
assert two_bottles == '\n'.join([
'2 bottles of beer on the wall,', '2 bottles of beer,',
'Take one down, pass it around,', '1 bottle of beer on the wall!'
])
# --------------------------------------------------
if __name__ == '__main__':
main()
第十二章内容是随机大写文本。作者通过绑匪寄赎金条这个故事引入本章内容。
本章中我们要实现一个程序。它可以将文本替换为随机大写字母。
主要内容包括:编写ransom.py、修改文本、投掷硬币、创建新字符串、遍历序列中的元素、编写函数来选择字母、编写list.append()的另一种方法、使用str代替list、使用列表解析式、使用map()函数方法比较等内容。
通过本章学习我们将学会使用random模块来形象地“掷硬币”,在两个选择之间取舍、探索从现有字符串中生成新字符串的方法,并于随机决策相结合、研究for循环、列表推导和map()函数相似性。程序一种实现如下:
#!/usr/bin/env python3
"""Ransom note"""
import argparse
import os
import random
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Ransom Note',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='int',
type=int,
default=None)
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
# Method 1: Iterate each character, add to list
ransom = []
for char in args.text:
ransom.append(choose(char))
print(''.join(ransom))
# --------------------------------------------------
def choose(char):
"""Randomly choose an upper or lowercase letter to return"""
return char.upper() if random.choice([0, 1]) else char.lower()
# --------------------------------------------------
def test_choose():
"""Test choose"""
state = random.getstate()
random.seed(1)
assert choose('a') == 'a'
assert choose('b') == 'b'
assert choose('c') == 'C'
assert choose('d') == 'd'
random.setstate(state)
# --------------------------------------------------
if __name__ == '__main__':
main()
第十三章内容是算法设计。作者通过《圣诞节的十二天》这首歌曲引出本章的主题。
本章中我们就要实现这样一个算法。为给定的天数生成一首歌。它将生成直到给定的日期的《圣诞节的十二天》,这一天由-n或—num实参指定。
主要内容包括:编写twelve_days.py、计数、创建序数值、制作小节、使用verse()函数、生成小节、打印小节等内容。
通过本章学习我们将学会创建一个用1-12范围内给定天数生成歌曲的算法、逆序排列一个列表、使用range()函数、把文本写到一个文件或写到STDOUT。程序实现如下:
#!/usr/bin/env python3
"""Twelve Days of Christmas"""
import argparse
import sys
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Twelve Days of Christmas',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-n',
'--num',
help='Number of days to sing',
metavar='days',
type=int,
default=12)
parser.add_argument('-o',
'--outfile',
help='Outfile',
metavar='FILE',
type=argparse.FileType('wt'),
default=sys.stdout)
args = parser.parse_args()
if args.num not in range(1, 13):
parser.error(f'--num "{args.num}" must be between 1 and 12')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
verses = map(verse, range(1, args.num + 1))
print('\n\n'.join(verses), file=args.outfile)
# --------------------------------------------------
def verse(day):
"""Create a verse"""
ordinal = [
'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh',
'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'
]
gifts = [
'A partridge in a pear tree.',
'Two turtle doves,',
'Three French hens,',
'Four calling birds,',
'Five gold rings,',
'Six geese a laying,',
'Seven swans a swimming,',
'Eight maids a milking,',
'Nine ladies dancing,',
'Ten lords a leaping,',
'Eleven pipers piping,',
'Twelve drummers drumming,',
]
lines = [
f'On the {ordinal[day - 1]} day of Christmas,',
'My true love gave to me,'
]
lines.extend(reversed(gifts[:day]))
if day > 1:
lines[-1] = 'And ' + lines[-1].lower()
return '\n'.join(lines)
# --------------------------------------------------
def test_verse():
"""Test verse"""
assert verse(1) == '\n'.join([
'On the first day of Christmas,', 'My true love gave to me,',
'A partridge in a pear tree.'
])
assert verse(2) == '\n'.join([
'On the second day of Christmas,', 'My true love gave to me,',
'Two turtle doves,', 'And a partridge in a pear tree.'
])
# --------------------------------------------------
if __name__ == '__main__':
main()
第十四章的内容是使用正则表达式创建押韵单词。作者通过电影《公主新娘》中涉及到的一个押韵游戏引入本章内容。
本章中我们要实现一个程序,选取给定的单词,并创建与它押韵的单词,当然是使用正则表达式的方式。
主要内容包括:编写rhymer.py、分解单词、使用正则表达式、使用捕获组、真实性、取单词词干、对正则表达式进行格式化和注释、在程序之外使用stemmer()函数、创建押韵字符串、不带正则表达式的stemmer().
通过本章的学习我们将学会编写和使用正则表达式、把守卫语句(guard)用在列表推导式中、探索带有守卫语句的列表推导式与filter()函数的相似性、在布尔语境中评估python类型时,考虑“真实性”。程序实现如下:
#!/usr/bin/env python3
"""Make rhyming words"""
import argparse
import re
import string
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Make rhyming "words"',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('word', metavar='word', help='A word to rhyme')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
prefixes = list('bcdfghjklmnpqrstvwxyz') + (
'bl br ch cl cr dr fl fr gl gr pl pr sc '
'sh sk sl sm sn sp st sw th tr tw thw wh wr '
'sch scr shr sph spl spr squ str thr').split()
start, rest = stemmer(args.word)
if rest:
print('\n'.join(sorted([p + rest for p in prefixes if p != start])))
else:
print(f'Cannot rhyme "{args.word}"')
# --------------------------------------------------
def stemmer(word):
"""Return leading consonants (if any), and 'stem' of word"""
word = word.lower()
vowels = 'aeiou'
consonants = ''.join(
[c for c in string.ascii_lowercase if c not in vowels])
pattern = (
'([' + consonants + ']+)?' # capture one or more, optional
'([' + vowels + '])' # capture at least one vowel
'(.*)' # capture zero or more of anything
)
pattern = f'([{consonants}]+)?([{vowels}])(.*)'
match = re.match(pattern, word)
if match:
p1 = match.group(1) or ''
p2 = match.group(2) or ''
p3 = match.group(3) or ''
return (p1, p2 + p3)
else:
return (word, '')
# --------------------------------------------------
def test_stemmer():
"""test the stemmer"""
assert stemmer('') == ('', '')
assert stemmer('cake') == ('c', 'ake')
assert stemmer('chair') == ('ch', 'air')
assert stemmer('APPLE') == ('', 'apple')
assert stemmer('RDNZL') == ('rdnzl', '')
assert stemmer('123') == ('123', '')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十五章的内容是关于正则表达式的更多故事。作者通过当地人会省略以“ing”结尾的单词末尾的“g”引入本章内容。
本章中我们将实现一个程序。它接收某个输入作为单个位置实参,并把文本中以“ing”结尾的双音节词用(')替换,并将“you”改为“y’all”。
主要内容包括:编写friar.py、使用正则表达式拆解文本、简写类、否定简写类、使用带有已捕获的正则表达式的re.split()、编写fry()函数、使用fry()函数、编写带有正则表达式的fry()函数。
通过本章学习我们将学到更多关于正则表达式的知识、学会分别使用re.match()和re.search()查找锚定于字符串开头或字符串中任意位置的模式、了解正则表达式中$符号如何把模式锚定与字符的末尾、学会如何使用re.split()来拆解字符串、探索如何编写找到双音节“ing”或单词“you”手动解决方案。程序实现如下:
#!/usr/bin/env python3
"""Kentucky Friar"""
import argparse
import os
import re
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Southern fry text',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
for line in args.text.splitlines():
print(''.join(map(fry, re.split(r'(\W+)', line.rstrip()))))
# --------------------------------------------------
def fry(word):
"""Drop the `g` from `-ing` words, change `you` to `y'all`"""
ing_word = re.search('(.+)ing$', word)
you = re.match('([Yy])ou$', word)
if ing_word:
prefix = ing_word.group(1)
if re.search('[aeiouy]', prefix, re.IGNORECASE):
return prefix + "in'"
elif you:
return you.group(1) + "'all"
return word
# --------------------------------------------------
def test_fry():
"""Test fry"""
assert fry('you') == "y'all"
assert fry('You') == "Y'all"
assert fry('your') == 'your'
assert fry('fishing') == "fishin'"
assert fry('Aching') == "Achin'"
assert fry('swing') == "swing"
# --------------------------------------------------
if __name__ == '__main__':
main()
- 2024-06-17
-
回复了主题帖:
趣味微项目,轻松学Python_1-7章读书心得
秦天qintian0303 发表于 2024-6-17 08:53
一步一步循序渐进,楼主应该有一定的python开发经验吧
小白一枚,分享的都是书中的内容,这本书写的很好,章节调理很清晰,认真读非常好看懂!
-
发表了主题帖:
趣味微项目,轻松学Python_1-7章读书心得
从今天开始正式阅读本书的主要内容,开启Python编程之旅。接下来介绍本书1-7章的学习内容和心得。
由于我的环境是windows 下安装的Pycharm ,并且使用的是conda环境下,所以与书中的部分的内容是有出入的,例如书中用的是python3的命令,在我的环境中用的是python命令,书中需要添加释伴行,我的环境中不用添加,因为是在项目设置中已经指定Python解析器的。
本书第一章的内容是如何编写和测试Python程序。下面就从”hello world!”开始吧!
主要内容包括: 创建程序、添加注释、怎样写一个测试程序、添加#!释伴行、可执行程序、理解$PATH、添加参数和帮助、可选实参的介绍(argarse模块的使用)、运行测试、添加main()函数、添加get_args()函数、测试hello.py、用new.py开始新程序、使用template.py替代new.py等内容。通过本章学习基本的程序框架就大致理解了,下面就是template.py
#!/usr/bin/env python3
"""
Author : Me <me@foo.com>
Date : today
Purpose: Rock the Casbah
"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Rock the Casbah',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('positional',
metavar='str',
help='A positional argument')
parser.add_argument('-a',
'--arg',
help='A named string argument',
metavar='str',
type=str,
default='')
parser.add_argument('-i',
'--int',
help='A named integer argument',
metavar='int',
type=int,
default=0)
parser.add_argument('-f',
'--file',
help='A readable file',
metavar='FILE',
type=argparse.FileType('r'),
default=None)
parser.add_argument('-o',
'--on',
help='A boolean flag',
action='store_true')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
str_arg = args.arg
int_arg = args.int
file_arg = args.file
flag_arg = args.on
pos_arg = args.positional
print(f'str_arg = "{str_arg}"')
print(f'int_arg = "{int_arg}"')
print('file_arg = "{}"'.format(file_arg.name if file_arg else ''))
print(f'flag_arg = "{flag_arg}"')
print(f'positional = "{pos_arg}"')
# --------------------------------------------------
if __name__ == '__main__':
main()
第二章内容是使用字符串。作者通过一个荒诞滑稽的小对话引出本章的内容,本章的内容主要是使用字符串。
本章中我们要实现的程序是通过接收单个位置实参,把这个给定的实参连同单词“a”或“an”一起打印到“Ahoy”短语内。
主要内容包括:如何使用测试、用new.py创建程序、重复的编写然后测试、定义实参、串连字符串、变量类型、获取字符串的正确部分、在REPL中找到帮助、字符串方法、字符串比较、条件分支、字符串格式化等内容。
通过本章学习我们能创建一个能接收位置实参并生成使用文档的程序,通过程序的输入创建一个新的输出字符串,运行全套的测试集,最终实现如下:
#!/usr/bin/env python3
"""Crow's Nest"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description="Crow's Nest -- choose the correct article",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('word', metavar='word', help='A word')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
word = args.word
article = 'an' if word[0].lower() in 'aeiou' else 'a'
print(f'Ahoy, Captain, {article} {word} off the larboard bow!')
# --------------------------------------------------
if __name__ == '__main__':
main()
main()
第三章内容是使用列表。作者通过举例野餐清单的例子引出本章的内容,如何使用列表。
本章中我们要实现一个接收一个或多个要携带的物品对应的位置实参,还要接收-s或—sorted标志位来选择是否对这些条目进行排序,输出“You are bringing” 后跟条目。
主要内容包括:怎么样通过new.py或template.py开始程序的编写、编写picnic.py程序、列表的介绍、怎样向列表中添加一个元素、怎样添加多个元素、怎样对列表进行索引、怎样进行切片化、怎样在列表中查找元素、怎样删除列表中元素、对列表进行排序和反转、变更列表、连接列表、用if/elif/else进行条件分支。
通过本章的学习我们将实现能够接收多个位置实参的程序,使用if /elif/else来处理三个以上选项的条件分支,查找并更改列表中的条目,对列表中的条目进行排序和反转,实现格式化列表为一个新字符串。程序实现如下:
#!/usr/bin/env python3
"""Picnic game"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Picnic game',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('item',
metavar='str',
nargs='+',
help='Item(s) to bring')
parser.add_argument('-s',
'--sorted',
action='store_true',
help='Sort the items')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
items = args.item
num = len(items)
if args.sorted:
items.sort()
bringing = ''
if num == 1:
bringing = items[0]
elif num == 2:
bringing = ' and '.join(items)
else:
items[-1] = 'and ' + items[-1]
bringing = ', '.join(items)
print('You are bringing {}.'.format(bringing))
# --------------------------------------------------
if __name__ == '__main__':
main()
第四章内容是使用字典。作者通过电视剧中的情节引申出本章内容跳5编码算法的实现。
本章中我们要实现一个程序,这个程序接收一些文本作为实参。文本中的每个数字都将用跳5算法编码。其他非数字字符原封不动输出。
主要内容包括:字典的介绍、如何创建字典、如何访问字典的值、字典的方法、编写jump.py、使用dict进行编码、处理序列中条目的5中方法等内容。
通过本章学习我们将学会创建字典、使用for循环和列表推导式来逐个字符地处理文本,检查字典中是否有特定条目,从字典中检索特定值,打印一个新字符串,其中数字被替换成编码值。程序实现如下:
#!/usr/bin/env python3
"""Jump the Five"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Jump the Five',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='str', help='Input text')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
jumper = {'1': '9', '2': '8', '3': '7', '4': '6', '5': '0',
'6': '4', '7': '3', '8': '2', '9': '1', '0': '5'}
for char in args.text:
print(jumper.get(char, char), end='')
print()
# --------------------------------------------------
if __name__ == '__main__':
main()
第五章内容是使用文件和STDOUT。作者通过《哈利波特》中的“吼叫信”引出本章的内容文件实参的使用。
本章中我们要实现一个程序。当你向程序中输入“How dare you steal that car!”程序输出为“HOW DARE YOU STEAL THAT CAR!”。
主要内容包括:怎样读取文件、怎样写入文件、编写howler.py、从文件或命令行读取输入、选择输出文件句柄、低内存版本等内容。
通过本章学习我们将学会接收命令行或文件中的文本输入、将字符串改为大小、将输出打印到命令行或文件中、像处理文件句柄一样处理纯文本。程序实现如下:
#!/usr/bin/env python3
"""Howler"""
import argparse
import os
import sys
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Howler (upper-cases input)',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text',
metavar='text',
type=str,
help='Input string or file')
parser.add_argument('-o',
'--outfile',
help='Output filename',
metavar='str',
type=str,
default='')
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
out_fh = open(args.outfile, 'wt') if args.outfile else sys.stdout
out_fh.write(args.text.upper() + '\n')
out_fh.close()
# --------------------------------------------------
if __name__ == '__main__':
main()
第六章内容是读取文件和STDIN,迭代列表,格式化字符串。作者通过数数来引出本章内容。
本章中我们要实现一个WC程序。它将计算每个输入中的行数、单词数和字节数。
主要内容包括:编写wc.py、定义文件输入、迭代列表、数什么、格式化结果、使用for循环读入一个文件等内容。
通过本章学习,我们将学会如何处理零个或多个位置实参、验证输入文件、从文件或标准输入中读取数据、使用多层for循环、将文件分解为行、单词和字节、使用计数器变量、格式化字符串输出结果。程序实现如下:
#!/usr/bin/env python3
"""Emulate wc (word count)"""
import argparse
import sys
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Emulate wc (word count)',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('file',
metavar='FILE',
nargs='*',
default=[sys.stdin],
type=argparse.FileType('rt'),
help='Input file(s)')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
total_lines, total_bytes, total_words = 0, 0, 0
for fh in args.file:
num_lines, num_words, num_bytes = 0, 0, 0
for line in fh:
num_lines += 1
num_bytes += len(line)
num_words += len(line.split())
total_lines += num_lines
total_bytes += num_bytes
total_words += num_words
print(f'{num_lines:8}{num_words:8}{num_bytes:8} {fh.name}')
if len(args.file) > 1:
print(f'{total_lines:8}{total_words:8}{total_bytes:8} total')
# --------------------------------------------------
if __name__ == '__main__':
main()
第七章内容是在字典中查找条目。作者通过Edward Gorey的The Gashlycrumb Tinies 这本书引出本章内容。
本章我们要实现一个程序。这个程序将接收一个或多个字母作为位置实参,并从一个可选的输入文件中查找以该字母开头的文本行。
主要内容包括:编写gashlycrumb.py、读取输入文件、使用字典推导式、lookup字典等内容。通过本章学习,我们将学会接收一个或多个位置参数letter(字母)、接收一个可选的—file参数,它必须是一个可读文本文件,默认值是gashlycrumb.txt、读取文件找到每行的第一个字母,并建立一个数据结构与该字母对应的文本行相关联、对于用户提供的每个letter,如果存在该字母对应的文本行,则将其打印出来,如果不存在则打印一条消息、美观的打印数据结构代码。程序实现如下:
#!/usr/bin/env python3
"""Lookup tables"""
import argparse
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Gashlycrumb',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('letter',
help='Letter(s)',
metavar='letter',
nargs='+',
type=str)
parser.add_argument('-f',
'--file',
help='Input file',
metavar='FILE',
type=argparse.FileType('r'),
default='gashlycrumb.txt')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
lookup = {}
for line in args.file:
lookup[line[0].upper()] = line.rstrip()
for letter in args.letter:
if letter.upper() in lookup:
print(lookup[letter.upper()])
else:
print(f'I do not know "{letter}".')
# --------------------------------------------------
if __name__ == '__main__':
main()
- 2024-05-28
-
回复了主题帖:
【AI挑战营终点站】应用落地:部署手写数字识别应用到幸狐RV1106开发板
打卡完成
#AI挑战营终点站# rv1106数字识别模型部署 - 嵌入式系统 - 电子工程世界-论坛 (eeworld.com.cn)
- 2024-05-27
-
发表了主题帖:
#AI挑战营终点站# rv1106数字识别模型部署
本帖最后由 打破传统 于 2024-5-29 10:39 编辑
参考https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-SDK
进行了SDK环境的搭建,由于我的Ubuntu是20.04版本的所以需要安装Docker环境
先下载安装docker
添加当前用户到docker组中
更改使生效,查看当前是否添加成功
获取已经配置好的官方docker镜像,并查看本地镜像
获取最新SDK
将本地主机上的SDK目录映射到容器的/home目录下以Bash shell运行,注意这个目录要替换成自己电脑SDK所在的目录
然后安装交叉编译工具链 注意应该在运行docker环境的状态下安装
然后进入/home 目录,清除编译
Buildroot nand flash启动选8
编译全部 ./build.sh
Yolov5物体检测实例
如果下载不成功可以直接到github上下载,注意环境变量设置为本机SDK路径
下载后解压
解压后编译
可以看到生成的luckfox_rtsp_yolov5_demo文件夹
通过这个文件夹SFTP上传到开发板,按如下命令执行,注意权限和关掉开发板原来的推流rkip程序
然后就是参考网友luyism的工程,在Yolov5物体检测实例的基础上部署了第二关生成的MODE_NUM.rknn
编译的时候遇到如下错误
原因是windows 直接sftp工程文件会有部分文件传输不成功,直接在Ubuntu下载的工程上修改重新编译解决问题,还有个问题编译好后生成的文件夹中没有包含model文件夹不知道是怎么回事,于是手动将model文件拷贝到生成的文件夹下,上传开发板后运行如下:
下午找到没有生成model的原因是CMakeLists中的rknn模型名忘改了,改成自己的编译成功!
代码见附件,演示见视频。我在识别的过程中发现背景,光线,和数字的粗细等因素对识别影响都很大,目前只是算跑通,后续待优化。
对于数字粗细因素我觉得在预处理图像时可以加入放大图像像素的这步,先写了个python验证一下代码如下:
# 读取图像
image = cv2.imread('num_1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 边缘检测
edges = cv2.Canny(binary, 50, 150)
# 查找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 筛选和加粗轮廓
for contour in contours:
# 根据轮廓大小筛选数字
# if cv2.contourArea(contour) > some_threshold:
if cv2.contourArea(contour) > 1:
# 形态学操作加粗轮廓
dilated = cv2.dilate(np.uint8(edges), None, iterations=3)
# 在原图上绘制加粗后的轮廓
cv2.drawContours(image, [contour], -1, (0, 0, 0), 2)
# 显示图像
cv2.imshow('Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
刚做了个验证结果如下,后续优化后再加入试试。
[localvideo]6361d00de977d2422677d541b86e0800[/localvideo]
- 2024-05-22
-
回复了主题帖:
趣味微项目,轻松学Python之前沿导读
秦天qintian0303 发表于 2024-5-21 09:21
看看这个书的厚度?
357页
-
发表了主题帖:
#AI挑战营终点站#之Luckfox_Pico_ProMax_flash烧录及SSH登录
我收到的板卡是RV1106G3所以对应的板卡是LuckFox Pico Max M,然后参照官网wiki https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-prepare 下载板卡驱动,烧录工具和镜像。
首先打开烧录工具,选择下载好的镜像中\Luckfox Pico\镜像文件\buildroot(推荐)\luckfox_pico_pro_max_image这个镜像
然后按照https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-Login-ADB中安装ADB工具包,先以ADB的方式登录,下载好镜像后系统会启动
这样就是ADB方式登录系统了,然后再用ifconfig命令查看到usb网络IP地址为172.32.0.93
然后我们打开网络设置,可以看到NDIS网络,这个虚拟网络实际链接的是usb,此时板子可以不插入网线,修改网络的IP地址为172.32.0.100
这时候我们就能在window中打开命令行ping通172.32.0.93了。然后就可以采样ssh的方式登录
以上是采用设置虚拟IP地址的方式SSH登录。
然后我们在https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-Login-UART,中下载MobaXterm_Personal_22.0工具,打开后可以SSH登录板子也可以SFTP链接板子
然后就是设置静态IP地址,通过https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-Autostart 的说明我们可以用sftp在板子的/etc/init.d/目录中拷贝一个.sh脚本文件下载到本地后复制网站上设置静态网页的脚本代码,修改为本机所在网络段的IP地址,比如我的电脑是10.0.3.1,板子的ip设为10.0.3.2,不能设冲突了。然后sh 加载脚本就可以通过ifconfig命令看到修改过后的IP地址了。
然后就可以通过ssh root@10.0.3.2的方式登录板子的系统
以上就是设置静态以太网IP的方式SSH登录。
- 2024-05-21
-
发表了主题帖:
趣味微项目,轻松学Python之前沿导读
非常幸运可以得到这边书的测评机会,上周就拿到书了,先过目了一下整体的内容,主要是前沿部分的内容,废话不说下面分享给没有拿到书且一样想学习的小伙伴。
先来个封面特写:
其实刚看到这本书的时候就被它的封面吸引到了,一本编程的书为啥封面上画的是一个穿民族服装的女人?怪怪的?不着急稍后为大家解密!
本书虽然属于技术类书籍,作者作为一个技术大咖,不仅对编程有着极大的热诚更是对生活充满热爱的一个人。细度前沿部分的内容我们就可以很直观的感受到这位工程师的魅力,作者在前沿部分介绍了为什么使用python,以及为什么写这本书的问题,在致谢部分可以看出作者是个热爱家庭,非常有爱的人。
接下来是关于本书部分,介绍了这本书的受众,本书的组织结构,以及代码和硬件要求
然后是作者的自传,作者是一个高级程序员,还是音乐专业的本科生,然后计算机只是他的兴趣,后来才发展成职业生涯,可以说是一位跨界大咖了
再然后揭晓封面中的秘密“穿过街道的土耳其女人”。怎么说呢,作者可以说是有文艺范的程序员吧,不仅程序写的好,音乐,绘画方面的知识也极其丰富。能让艺术融入到编程这种枯燥的工作中想来是极有趣,也极有意义的事了。
最后是入门部分:介绍的是引言及安装指导,包括编写命令行程序,测试驱动的开发,设置开发环境,代码示例,获取代码,安装模块,代码格式化工具,代码检测器,如何开始编写新程序,为什么不用Notebooks,本书的主题范畴,为什么不进行面对对象的编程,行话注解,之类的内容,其中还偶尔有漫画类的插图,可见作者的艺术细胞了!
本书的前沿部分就介绍到这里,接下来我们就让我们跟作者去领略一番python编程的魅力吧!
- 2024-05-11
-
回复了主题帖:
【AI挑战营第二站】算法工程化部署打包成SDK
AI 挑战营第二站
1、ONNX模型是一种开放的深度学习模型交换格式,类似于JSON格式,可以实现不同深度学习框架之间的模型转换和共享;RKNN模型是Rockchip系列芯片专用的神经网络推理模型
2、#AI挑战营第二站#安装RKNN TOOlkit2工具转换ONNX模型 为RKNN的模型 - 嵌入式系统 - 电子工程世界-论坛 (eeworld.com.cn)
- 2024-05-10
-
发表了主题帖:
#AI挑战营第二站#安装RKNN TOOlkit2工具转换ONNX模型 为RKNN的模型
RV1120对应的工具是RKNN Toolkit2,先下载RKNN Toolkit2工具
RV1106对应的版本为:https://github.com/rockchip-linux/rknn-toolkit2
我的系统为Ubuntu20.04刚好支持此工具链
下载好RKNN-Toolkit2后在doc文件夹下可以找到快速上手指南
参考指南完首先下载rknn-toolkit2 工具链
下载rknn-model zoo ,下载速度有时候很慢,多试几次可以下载成功
下载 conda
安装conda
回车到此 ctrl-c退出
验证是否安装成功
使用conda 创建python环境
进入conda base 环境
开始安装python3.8 但在后面安装依赖库会报错后装了3.9
激活toolkit2环境
安装依赖库和RKNN-Toolkit2
cd到下载好的安装包目录
根据python版本选择不同的requirements文件
遇到下面的错误
参考网友安装tf-estimator-nightly
https://blog.csdn.net/weixin_51447731/article/details/137088316
再次安装requirements成功
安装对应的wheel文件
验证是否安装成功
退出后重新进入激活的toolkit2环境
cd 到下载的rknn_model_zoo,拷贝#AI挑战营第一站#生成好的MODE_NUM.onnx文件
参考example文件中的例子添加转换代码
import sys
from rknn.api import RKNN
# Create RKNN object
rknn = RKNN(verbose=True)
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[[28]], std_values=[
[28]], target_platform='rv1106')
print('done')
# Load model
print('--> Loading model')
ret = rknn.load_onnx(model='./MODE_NUM.onnx')
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export rknn model')
ret = rknn.export_rknn('./MODE_NUM.rknn')
if ret != 0:
print('Export rknn model failed!')
exit(ret)
print('done')
# Release
rknn.release()
添加量化dataset,并执行convert.py
如下转换成功
- 2024-05-09
-
回复了主题帖:
入围名单公布:嵌入式工程师AI挑战营(初阶),获RV1106 Linux 板+摄像头的名单
个人信息已确认,领取板卡,可继续完成&分享挑战营第二站和第三站任务
- 2024-05-08
-
回复了主题帖:
共读入围:《趣味微项目,轻松学Python》
个人信息确认,谢谢!
- 2024-04-26
-
回复了主题帖:
免费申请:幸狐 RV1106 Linux 开发板(带摄像头),助力AI挑战营应用落地
本帖最后由 打破传统 于 2024-4-26 15:28 编辑
AI挑战营第一站#pytorch训练MNIST数据集实现 - 嵌入式系统 - 电子工程世界-论坛 (eeworld.com.cn)
预期应用:实现手写数字识别并显示到屏幕上