python工匠:案例、技巧合工程实践学习小结

python工匠学习小结

基于对python有一定的实践使用,缺乏编码/工程的规范性,在阅读python工匠书籍后进行部分的小结。

1、变量与注释

1.1 变量解包:

  1. 值语句左侧添加小括号(…),甚至可以一次展开多层嵌套数据;
  2. 用星号表达式(*variables)作为变量名,它便会贪婪地捕获多个值对象,并将捕获到的内容作为列表赋值给variables;
  3. 假如你想在解包赋值时忽略某些变量,就可以使用_作为变量名;python交互式命令行里,_变量还默认保存我们输入的上个表达式的返回值
# 解包案例 1
>>> attrs = [1, ['piglei', 100]]
>>> user_id, (username, score) = attrs
>>> user_id
1
>>> username
'piglei'#解包案例 2  ----动态解包
>>> data = ['piglei', 'apple', 'orange', 'banana', 100]
>>> username, *fruits, score = data
>>> username
'piglei'
>>> fruits
['apple', 'orange', 'banana']
>>> score
100#解包案例 3 ---切片赋值
# 切片赋值
>>> username, fruits, score = data[0], data[1:-1], data[-1]
# 两种变量赋值方式完全等价#解包案例 4 ---循环语句
>>> for username, score in [('piglei', 100), ('raymond', 60)]:
...     print(username)
...
piglei
raymond# 解包案例 5 
#忽略展开时的第二个变量
>>> author, _ = usernames
# 忽略第一个和最后一个变量之间的所有变量
>>> username, *_, score = data

以上解包操作也可用于循环语句,但是实际上并不太好使。

1.2 给变量注明类型

Python是动态类型语言,使用变量时不需要做任何类型声明,但是动态类型所带来的缺点是代码的可读性会因此大打折扣。使用类型注解,只需在变量后添加类型,并用冒号隔开即可,比如func(value:str)表示函数的value参数为字符串类型。

from typing import List
# List表示参数为列表类型,[int]表示里面的成员是整型
def remove_invalid(items: List[int]): """剔除 items 里面无效的元素"""... ...

“类型注解”只是一种有关类型的注释,不提供任何校验功能。要校验类型正确性,需要使用其他静态类型检查工具

类型注解带来的优势:
1.代码更易读,读代码时可以直接看到变量类型;
2.大部分的现代化IDE[插图]会读取类型注解信息,提供更智能的输入提示
3.类型注解配合mypy等静态类型检查工具,能提升代码正确性(13.1.5节)。

1.3 命名规则

1、遵循PEP 8原则:一是通过大小写界定单词的驼峰命名派CamelCase,二是通过下划线连接的蛇形命名派snake_case。
2、描述性强:体现出变量作用
3、尽可能短:为变量命名要结合代码情境和上下文
4、要匹配类型:体现出变量类型
5、超短命名:通常作为变量少用,目前做索引可以酌情用一下
在这里插入图片描述

1、在同一段代码内,不要出现多个相似的变量名,比如同时使用users、users1、users3这种序列;·
2、可以尝试换词来简化复合变量名,比如用is_special来代替is_not_normal;·
3、如果你苦思冥想都想不出一个合适的名字,请打开GitHub ( chatgpt 开源项目有太多可以学习的地方);

1.4 注释

文件、类、函数接口需要提供段落注释进行简要说明(接口注释),行注释采用 # 进行说明。
1、注释不是用来复述代码,而是描述该代码的作用,为什么要这么做,尽量提供那些读者无法从代码里读出来的信息

指引性注释并不提供代码里读不到的东西——假如没有注释,耐心读完所有代码,你也能知道代码做了什么事儿。指引性注释的主要作用是降低代码的认知成本,让我们能更容易理解代码的意图。无论代码写得多好,多么“自说明”,同读代码相比,读注释通常让人觉得更轻松。注释会让人们觉得亲切(尤其当注释是中文时),高质量的指引性注释确实会让代码更易读。有时抽象一个新函数,不见得就一定比一行注释加上几行代码更好。

2、接口文档主要是给函数(或类)的使用者看的,它最主要的存在价值,是让人们不用逐行阅读函数代码,也能很快通过文档知道该如何使用这个函数,以及在使用时有什么注意事项。在编写接口文档时,我们应该站在函数设计者的角度,着重描述函数的功能、参数说明等。而函数自身的实现细节,比如调用了哪个第三方模块、为何有性能问题等,无须放在接口文档里,放置于函数内部。

1.5 小贴士tips

1.5.1 、保持变量的一致性:

<1>名字一致性是指在同一个项目(或者模块、函数)中,对一类事物的称呼不要变来变去。
<2>类型一致性则是指不要把同一个变量重复指向不同类型的值
mypy工具

1.5.2、变量定义尽量靠近使用

这一点和C语言有点不一样,总是把变量声明放在最前面。python变量本身可读性稍差。变量定义移动到每段“各司其职”的代码头部,大大缩短了变量从初始化到被使用的“距离”。当读者阅读代码时,可以更容易理解代码的逻辑,而不是来回翻阅代码。函数不宜过长,超过200行需要进行功能拆分/切割

1.5.3、定义临时变量提升可读性

将复杂的表达式赋值为一个临时变量,代码更易读。

1.5.4、同一作用域内不要有太多变量

对局部变量分组并建模, 增加数据类,函数内的变量被更有逻辑地组织了起来,数量变少了许多

# 增加两个数据类,函数内的变量被更有逻辑地组织了起来,数量变少了许多
class ImportedSummary:"""保存导入结果摘要的数据类"""def __init__(self):self.succeeded_count = 0self.failed_count = 0class ImportingUserGroup:"""用于暂存用户导入处理的数据类"""def __init__(self):self.duplicated = []self.banned = []self.normal = []def import_users_from_file(fp):"""尝试从文件对象读取用户,然后导入数据库  :param fp: 可读文件对象:return: 成功与失败的数量"""importing_user_group = ImportingUserGroup()for line in fp:parsed_user = parse_user(line)# …… 进行判断处理,修改上面定义的importing_user_group 变量summary = ImportedSummary()# …… 读取 importing_user_group,写入数据库并修改成功与失败的数量return summary.succeeded_count, summary.failed_count

函数内变量的数量太多,通常意味着函数过于复杂,承担了太多职责。只有把复杂函数拆分为多个小函数,代码的整体复杂度才可能实现根本性的降低。

1.5.5、空行注释

即对函数内功能进行分类–增加可读性。

1.5.6、不要使用locals()

locals()是Python的一个内置函数,调用它会返回当前作用域中的所有局部变量。locals()看似简洁,但其他人在阅读代码时,为了搞明白模板渲染到底用了哪些变量,必须记住当前作用域里的所有变量。假如函数非常复杂,“记住所有局部变量”简直是个不可能完成的任务。使用locals()还有一个缺点,那就是它会把一些并没有真正使用的变量也一并暴露。
显式优于隐式

1.5.7、能不定义变量就别定义

把不必要的东西赋值为临时变量,反而会让代码显得啰唆,删掉赘语的句子,变得更精练、更易读。

1.5.8、先写注释,后写代码

要在函数名和短短几行注释里,把函数内代码所做的事情,高度浓缩地表达清楚。正因如此,接口注释其实完全可以当成一种协助你设计函数的前置工具。这个工具的用法很简单:假如你没法通过几行注释把函数职责描述清楚,那么整个函数的合理性就应该打一个问号。在写出一句有说服力的接口注释前,别写任何函数代码。

先写伪代码,进行打桩。然后再写具体的实现过程。

2、数值与字符串

2.1 数值基础

  • 变量类型转换:int、float、str …

  • 进制转换

n=input()
#16进制转换成10进制
print((int(n,16)))

在这里插入图片描述

如果数字特别长,可以通过插入_分隔符来让它变得更易读:

  • 浮点数精度问题
    在这里插入图片描述
#0.1 + 0.2的最终结果多出来0.000…4
>>> 0.1 + 0.2
0.30000000000000004#在使用Decimal的过程中,大家需要注意:必须使用字符串来表示数字
>>> from decimal import Decimal
# 注意:这里的'0.1'和'0.2' 必须是字符串
>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')
  • 布尔值其实也是数字
>>> int(True), int(False)
(1, 0)
>>> True + 1
2# 把 False 当除数的效果和0 一样
>>> 1 / False
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
  • 字符串常用操作
    1、遍历一个字符串,将会逐个返回每个字符
    2、对字符串进行切片假如你想反转一个字符串,可以使用切片操作或者reversed内置方法
    3、切片最后一个字段使用-1,表示从后往前反序
    4、reversed会返回一个可迭代对象,通过字符串的.join方法可以将它转换为字符串
username, score = 'piglei', 100
# 1. C 语言风格格式化
print('Welcome %s, your score is %d' % (username, score))
# 2. str.format
print('Welcome {}, your score is {:d}'.format(username, score))
# 3. f-string,最短最直观
print(f'Welcome {username}, your score is {score:d}')
# 输出:
# Welcome piglei, your score is 100
  • 不常用但特别好用的字符串方法
#1、str.translate(table)方法有时也非常有用。它可以按规则一次性替换多个字符,使用它比调用多次replace方法更快也更简单
>>> s = '明明是中文,却使用了英文标点.'
# 创建替换规则表:',' -> ',', '.' -> '。'
>>> table = s.maketrans(',.', ',。')
>>> s.translate(table)
'明明是中文,却使用了英文标点。'#2、str.partition(sep)的功能是按照分隔符sep切分字符串
#返回一个包含三个成员的元组:(part_before, sep, part_after),它们分别代表分隔符前的内容、分隔符以及分隔符后的内容
#而spilt 不带有 分割符 sep

2.2 其它

  • 枚举
from enum import Enum
# 在定义枚举类型时,如果同时继承一些基础类型,比如int、str,
# 枚举类型就能同时充当该基础类型使用。比如在这里,UserType 就可以当作int 使用
class UserType(int, Enum):# VIP 用户VIP = 3# 小黑屋用户BANNED = 13

1、使用SQLAlchemy模块改写代码
2、使用Jinja2模板处理字符串

2.3 小贴士tips

2.3.1、保留计算

Python是一门解释型语言,但在解释器真正运行Python代码前,其实仍然有一个类似“编译”的加速过程:将代码编译为二进制的字节码。我们没法直接读取字节码,但利用内置的dis模块,可以将它们反汇编成人类可读的内容——类似一行行的汇编代码。用到复杂计算的数字字面量时,请保留整个算式吧。这样做对性能没有任何影响,而且会让代码更容易阅读。

使用dis 模块反编译字节码

2.3.2、使用特殊数字:“无穷大”

float(“-inf”)<任意数值< float(“inf”)

2.3.3、改善超长字符串的可读性

除了用斜杠\和加号+将长字符串拆分为几段,还有一种更简单的办法,那就是拿括号将长字符串包起来,之后就可以随意折行了。

s = ("This is the first line of a long string, ""this is the second line")# 如果字符串出现在函数参数等位置,可以省略一层括号
def main():logger.info("There is something really bad happened during the process. ""Please contact your administrator.")

2.3.4、多级缩进里出现多行字符串

可以用标准库textwrap来解决这个问题。dedent方法会删除整段字符串左侧的空白缩进。使用它来处理多行字符串以后,整段代码的缩进视觉效果就能保持正常了。

from textwrap import dedentdef main():if user.is_active:message = dedent("""\Welcome, today's movie list:- Jaw (1975)- The Shining (1980)- Saw (2004)""")

2.3.5、别忘了以r开头的字符串内置方法

比如rsplit()就是split()的镜像“逆序”方法

2.3.6、不要害怕字符串拼接

以前Python里的字符串是不可变对象,因此每拼接一次字符串都会生成一个新对象,触发新的内存分配,效率非常低。但是,如今,使用+=拼接字符串基本已经和"".join(str_list)一样快了。

2.3.7、dis & timeit

如果需要验证某个“经验之谈”,dis和timeit两个优秀的工具可以帮到你:前者能让你直接查看编译后的字节码,后者则能让你方便地做性能测试

3、容器类型

1、元组(tuple)和列表非常类似,但跟列表不同,它不能被修改
2、每个类实例的所有属性,就都存放在一个名为dict的字典
3、集合(set)最大的特点是成员不能重复,所以经常用来去重(剔除重复元素)

class Foo:def __init__(self, value):self.value = valuefoo = Foo('bar')
print(foo.__dict__, type(foo.__dict__))
#{'value': 'bar'} <class 'dict'>

可变(mutable):列表、字典、集合。·
不可变(immutable):整数、浮点数、字符串、字节串、元组。(没法修改一个已经存在的字符串对象)

def add_str(in_func_obj):print(f'In add [before]: in_func_obj="{in_func_obj}"')in_func_obj += ' suffix'print(f'In add [after]: in_func_obj="{in_func_obj}"')orig_obj = 'foo'
print(f'Outside [before]: orig_obj="{orig_obj}"')
add_str(orig_obj)
print(f'Outside [after]: orig_obj="{orig_obj}"')'''
#同样的示例,如果参数是列表,函数内的+=操作居然可以修改原始变量的值
Outside [before]: orig_obj="foo"
In add [before]: in_func_obj="foo"
In add [after]: in_func_obj="foo suffix"# 重要:这里的orig_obj 变量还是原来的值
Outside [after]: orig_obj="foo"
'''

(1)值传递(pass-by-value):调用函数时,传过去的是变量所指向对象(值)的拷贝,因此对函数内变量的任何修改,都不会影响原始变量——对应orig_obj是字符串时的行为。
(2)引用传递(pass-by-reference):调用函数时,传过去的是变量自身的引用(内存地址),因此,修改函数内的变量会直接影响原始变量——对应orig_obj是列表时的行为。
Python在进行函数调用传参时,采用的既不是值传递,也不是引用传递,而是传递了“变量所指对象的引用”(pass-by-object-reference)。

3.1 列表

  • 内置函数list(iterable)则可以把任何一个可迭代对象转换为列表。删除列表中的某些内容,可以直接使用del语句
>>> list('foo')
['f', 'o', 'o']#通过索引获取内容,如果索引越界,会抛出 IndexError异常
>>> numbers[2]
3# 使用切片获取一段内容
>>> numbers[1:]
[2, 3, 4]#  删除列表中的一段内容
>>> del numbers[1:]
>>> numbers
[1]
  • 在遍历列表时获取下标,选择用内置函数enumerate()包裹列表对象。enumerate()适用于任何“可迭代对象”,因此它不光可以用于列表,还可以用于元组、字典、字符串等其他对象。
>>> names = ['foo', 'bar']
>>> for index, s in enumerate(names):
...     print(index, s)
...
0 foo
1 bar#enumerate()接收一个可选的start参数,用于指定循环下标的初始值(默认为0)
>>> for index, s in enumerate(names, start=10):
...     print(index, s)
...
10 foo
11 bar
  • 列表推导式
def remove_odd_mul_100(numbers):"""剔除奇数并乘以100"""results = []for number in numbers:if number % 2 == 1:continueresults.append(number * 100)return results#用一个表达式完成4件事情
#
# 1. 遍历旧列表:for n in numbers
# 2. 对成员进行条件过滤:if n % 2 == 0
# 3. 修改成员: n * 100
# 4. 组装新的结果列表
#
results = [n * 100 for n in numbers if n % 2 == 0]

3.2 元组

  • 函数可以一次返回多个结果,这其实是通过返回一个元组来实现的;函数返回值一次赋值给多个变量时,其实就是对元组做了一次解包操作:
def get_rectangle():"""返回长方形的宽和高"""width = 100height = 20return width, height# 获取函数的多个返回值
result = get_rectangle()
print(result, type(result))
# 输出:
# (100, 20) <class 'tuple'>width, height = get_rectangle()
# 可以理解为:width, height = (width, height)
  • 没有“元组推导式”
>>> results = (n * 100 for n in range(10) if n % 2 == 0)
>>> results
<generator object <genexpr> at 0x10e94e2e0>
#并没有生成元组,而是返回了一个生成器(generator)对象。生成器仍然是一种可迭代类型。
>>> results = tuple((n * 100 for n in range(10) if n % 2 == 0))
>>> results
(0, 200, 400, 600, 800)
  • 元组经常用来存放结构化数据–具名元组

1、初始化具名元组
2、指定字段名称来初始化
3、可以像普通元组一样,通过数字索引访问成员
4、具名元组也支持通过名称来访问成员
5、普通元组一样,具名元组是不可变的
用名字访问成员(rect.width)比用普通数字(rect[0])更易读、更好记

思考:对于列表/字典成员属性,是否也可以对成员“具名”,增强代码的可读性!

from collections import namedtuple
Rectangle = namedtuple('Rectangle', 'width,height') >>> rect = Rectangle(100, 20)>>> rect = Rectangle(width=100, height=20)>>> print(rect[0])100
>>> print(rect.width)100
>>> rect.width += 1...
AttributeError: can't set attribute#typing.NamedTuple和类型注解语法
class Rectangle(NamedTuple):width: intheight: intrect = Rectangle(100, 20)
#写法虽然给width和height加了类型注解,但Python在执行时并不会做真正的类型校验。也就是说,下面这段代码也能正常执行
#提供错误的类型来初始化
rect_wrong_type = Rectangle('string', 'not_a_number')

3.3 字典

字典在底层使用了哈希表(hashtable)数据结构

  • items() 函数以列表返回可遍历的(键, 值) 元组数组
#遍历获取字典所有的key
>>> for key in movie:
...     print(key, movie[key])
# 一次获取字典的所有 key: value 键值对
>>> for key, value in movie.items():
...     print(key, value)
  • 直接操作,但是捕获KeyError异常。
>>> try:
...     rating = movie['rating']
... except KeyError:
...     rating = 0
...
  • 使用setdefault取值并修改
>>> d = {'title': 'foobar'}
>>> d.setdefault('items', []).append('foo')>>> d
{'title': 'foobar', 'items': ['foo']}
>>> d.setdefault('items', []).append('bar')>>> d
{'title': 'foobar', 'items': ['foo', 'bar']}
  • 使用pop方法删除不存在的键
try:del d[key]
except KeyError:# 忽略 key 不存在的情况pass# 调用pop方法时传入默认值None,在键不存在的情况下也不会产生任何异常
d.pop(key, None)
  • 字典推导式
>>> d1 = {'foo': 3, 'bar': 4}
>>> {key: value * 10 for key, value in d1.items() if key == 'foo'}
{'foo': 30}

3.4 集合

集合是一种无序的可变容器类型,它最大的特点就是成员不能重复。集合里装的是一维的值{value, …},而不是键值对{key: value, …}。集合最重要的两个特征——去重与无序初始化一个空集合,只能调用set()方法,因为{}表示的是一个空字典,而不是一个空集合。

#正确初始化一个空集合
>>> empty_set = set()#集合也有自己的推导式语法
>>> nums = [1, 2, 2, 4, 1]
>>> {n for n in nums if n < 3}
{1, 2}
  • 不可变的集合frozenset
    集合是一种可变类型,使用.add()方法可以向集合追加新成员。你想要一个不可变的集合,可使用内置类型frozenset,它和普通set非常像,只是少了所有的修改类方法。
>>> f_set = frozenset(['foo', 'bar'])
>>> f_set.add('apple')
# 报错:没有 add/remove 那些修改集合的方法
AttributeError: 'frozenset' object has no attribute 'add'
  • 集合运算
    集合的最大独特之处在于:你可以对其进行真正的集合运算,比如求交集、并集、差集,等等。所有操作都可以用两种方式来进行:方法和运算符。
>>> fruits_1 = {'apple', 'orange', 'pineapple'}
>>> fruits_2 = {'tomato', 'orange', 'grapes', 'mango'}#使用& 运算符(求交集)
>>> fruits_1 & fruits_2
{'orange'}
# 使用intersection 方法完成同样的功能
>>> fruits_1.intersection(fruits_2)#使用| 运算符(求并集)
>>> fruits_1 | fruits_2
{'mango', 'orange', 'grapes', 'pineapple', 'apple', 'tomato'}
# 使用union 方法完成同样的功能
>>> fruits_1.union(fruits_2)#使用- 运算符(求差集)
>>> fruits_1 - fruits_2
{'apple', 'pineapple'}
# 使用difference 方法完成同样的功能
>>> fruits_1.difference(fruits_2)
  • 集合只能存放可哈希对象
    集合里只能存放“可哈希”(hashable)的对象。假如把不可哈希的对象(比如上面的列表)放入集合,程序就会抛出TypeError异常。字典的键也只能是可哈希的对象。

1、不可变的内置类型都是可哈希的,如str、int、tuple、frozenset
2、可变的内置类型都无法正常计算哈希值。如列表/字典
3、用户定义的所有对象默认都是可哈希的
4、对于不可变容器类型(tuple, frozenset),仅当它的所有成员都不可变时,它自身才是可哈希的;

3.5 深拷贝与浅拷贝

>>> nums = [1, 2, 3, 4]
>>> nums_copy = nums
>>> nums[2] = 30
#完成修改-。-
>>> nums_copy 
[1, 2, 30, 4]
  • 浅拷贝
1、最通用的办法是使用copy模块下的copy()方法
>>> import copy
>>> nums_copy = copy.copy(nums)
>>> nums[2] = 30
# 修改不再相互影响
>>> nums, nums_copy
([1, 2, 30, 4], [1, 2, 3, 4])2、推导式也可以产生一个浅拷贝对象
>>> d = {'foo': 1}
>>> d2 = {key: value for key, value in d.items()}
>>> d['foo'] = 2
>>> d, d2
({'foo': 2}, {'foo': 1})3、各容器类型的内置构造函数
>>> d2 = dict(d.items())>>> nums_copy = list(nums)4、支持切片操作的容器类型——比如列表、元组,对其进行全切片
#nums_copy会变成 nums的浅拷贝
>>> nums_copy = nums[:]5、类型自身就提供了浅拷贝方法
#列表有 copy方法
>>> num = [1, 2, 3, 4]
>>> nums.copy()
[1, 2, 3, 4]
# 字典也有 copy 方法
>>> d = {'foo': 'bar'}
>>> d.copy()
{'foo': 'bar'}
  • 深拷贝

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/65571.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BTC涨这么多,还能买吗?要卖吗?| 量化定投策略告诉你答案【附代码】

引言: 邢不行的系列帖子“量化小讲堂”&#xff0c;通过实际案例教初学者使用python进行量化投资&#xff0c;了解行业研究方向&#xff0c;希望能对大家有帮助。 最近比特币行情很好&#xff0c;突破前期2万美金历史高点后&#xff0c;短短22天又再次突破4万大…

【程序员如何买基金 三】场内场外交易的区别

先搞明白一个普通概念&#xff0c;场外交易和场内交易的区别&#xff1a;场外交易&#xff08;一级市场交易&#xff09;就是直接向基金公司申购(通过之前讲过的直销人和代销人)&#xff0c;而场内交易&#xff08;二级市场交易&#xff09;就是消费者在证券市场内相互交易。 在…

【GPT4结对编程】word文档导出功能GPT4来实现

需求背景 最近产品增加了一个导出word文档的需求&#xff0c;之前有导出过pdf格式、excel格式、csv格式&#xff0c;但还没导出过word文档。 开源框架调研 我们的后端服务主要是用golang&#xff0c;因此首先想到的是golang相关的开源工具&#xff0c;找到2个。 unioffice …

基于GEC6818的智能家居管理系统

基于GEC6818的智能家居管理系统 使用步骤&#xff1a; 1、首先通过交叉编译make&#xff0c;生成可执行文件main 2、然后拷贝到开发板上&#xff0c;在开发板上对安装led和beep的驱动 3、加权限 然后执行 然后就可以在开发板上显示系统了(密码默认1234) 功能简介 本系统主…

智能家居服务发现实现

服务设备软件架构设计 代码复用 将网络通信框架移植到开发板&#xff0c;之后&#xff0c;可以使用框架中的组件实现 Response Task 和 Service Task。 框架移植注意事项 LWIP 是微型 TCP/IP 协议栈 (并非完整 TCP/IP 协议栈) 支持 socket 接口&#xff0c;但一些功能未实现…

基于MQTT的智能家居程序框架

小白能懂&#xff1a;嵌入式进阶&#xff1a;RTOS嵌入式系统框架 第一章 嵌入式常用裸机编程框架 第二章 面向对象编程基础 第三章 ESP8622物联网基础 第四章 STM32与ESP8266物联网编程 第五章 物联网编程优化 第六章 以OLED为例介绍RTOS面向对象编程 第七章 基于MQTT的智能家…

智能家居 —— 串口通信(语音识别)线程控制

文章目录 串口通信线程控制代码mianPro.cinputCommand.hvoiceControl.c测试结果 语音控制部分语言控制模块YS-LDV7 若要完成串口之间的通信&#xff0c;需要再树莓派上完成配置文件的修改&#xff0c;利用测试代码验证串口收发功能是否正常&#xff0c;详情可以参考博文&#x…

智能家居(3) —— 串口通信(语音识别)线程控制

目录 一、串口通信线程控制代码 mianPro.c inputCommand.h voiceControl.c 测试结果 二、语音控制部分 一、串口通信线程控制代码 mianPro.c #include <pthread.h> #include "controlDevice.h" #include "inputCommand.h"struct InputCommand…

[第一步]homekit智能家居,homebridge与homebridge-aqara通信协议

根据这个就可以使用iphone控制灯与开关. 折腾了3个晚上,终于将homebridge安装好,安装之前需要安装一堆的库,比如node.js运行环境等,因为网上资料大部分都是在树莓派上面运行,我是直接在ubuntu上面进行的测试,因为安装会有所区别,但是安装好之后就一样了,安装方法在此我就不写了…

智能家居系统 QT

一 环境范围设置 &#xff08;1&#xff09;界面添加新控件 在mainwindow.ui 添加控件&#xff1a; 控件的类型 文本内容 对象名&#xff08;唯一&#xff09; 是否有槽函数 QLabel <温度< lable_随意 否 QLabel <湿度< lable_随意 否 QLabel <光…

Home Assistant 智能家居自动化

一、Home Assistant 自动化中的一个重要概念——模式 引入模式&#xff0c;用于解决正在执行过程中的同一规则又一次被触发的问题 二、Home Assistant 自动化规则的组成部分 2.1 触发条件Trigger&#xff1a;表示智能家居中事件或状态的转换 可选持续时间(特有) trigger有…

qt实现智能家居系统

一、项目介绍 通过TCP/IP协议实现客户端和和服务端的链接&#xff0c;服务端和下位机通过串口通信的方式链接&#xff0c;传递信息&#xff0c;客户端通过账号登录进入进入智能家居服务系统&#xff0c;账号登录和QQ登录类似&#xff0c;我采用的是数据库的方式实现数据的存储和…

语音识别智能家居控制设计

目录 一、方案流程及技术规格书设计 二、系统硬件电路设计 三、软件编写及调试 四、系统调试测试与分析 前言 随着科学技术的快速发展&#xff0c;人们对生活品质的要求也不断提高&#xff0c;开始追求更好更方便的生活方式。因此&#xff0c;智能家居系统应运而生。智能家…

智能家居之网关

网关诞生的背景 很多物联网终端设备在设计之初就考虑了低功耗、低成本的需求&#xff0c;因此大量的物联网终端设备是靠电池来工作并且需要运行相当长的一段时间&#xff0c;比如油田、农业相关的传感器&#xff0c;且这些终端设备不需要实时与物联网平台通讯&#xff0c;甚至…

智能家居是否可与ChatGPT深度融合?

​ ChatGPT自2022年面世以来&#xff0c;已为亿万网民提供智能问答服务。然而我们是否曾想到&#xff0c;这一人工智能驱动的聊天机器人&#xff0c;是否可为智能家居赋能? 要实现ChatGPT与智能家居设备之间的无缝对话&#xff0c;单单依靠一台终端是远远不够的。ChatGPT必须…

调查报告数据分析怎么做?

调查报告数据分析怎么做&#xff1f;拿到一份调查报告看选题、选题内容、调查的目的&#xff0c;然后清洗数据&#xff0c;分析数据提炼观点&#xff0c;过数据变化规律&#xff0c;揭示事物内在发展变化和趋势&#xff0c;抓住问题的本质和关键。 一、分析数据提炼观点 数据分…

pyqt5制作翻译软件+爬虫

VSCpythonmysql&#xff0c; 文章目录 目录 文章目录 前言 一、详细代码 第一个文件Ui_untitled.py 第二个fy_main.py文件&#xff1a; 第三个 &#xff1a;bd_pachong.py 二、登录界面&#xff1a; 总结 前言 通过pyqt5实现了翻译界面的可视化&#xff0c;利用python爬虫实现了…

给 30 岁左右的你三个职场跃迁/改变命运的建议!

见字如面&#xff0c;我是军哥&#xff01; 通过公众号的后台用户画像数据&#xff0c;我发现我的读者在 26 到 32 岁的年龄阶段的人数最多&#xff0c;所以今天来聊一聊这个话题&#xff0c;你一定要看到最后&#xff0c;会让你少走很多弯路&#xff01; 核心观点主要包括三个…

38岁程序员和你分享4个人生经验!

蓝色关注&#xff0c;回复“1”获取知名公司程序员和产品经理职级 这是我的第「123」篇原创文章 见字如面&#xff0c;我是军哥。 我最近一直想写一篇稍微长点的文章&#xff0c;毕竟内容篇幅有时候决定内容广度和深度。 距离我之前写的那篇文章《一位互联网老兵的五次认知升级…

【我命由我不由天】30多岁的大龄程序员,应该如何保持职场竞争力?

公众号后台回复“学习”&#xff0c;获取作者独家秘制精品资料 扫描下方海报二维码&#xff0c;试听课程&#xff1a; &#xff08;课程详细大纲&#xff0c;请参见文末&#xff09; 目录 回首往事&#xff1a;自己竟没有任何核心优势&#xff01;公司遇到危机时&#xff0c;大…