日期: 2021 年 4 月 19 日

搭建rtmp推流服务器

搭建基于rtmp协议的推流服务器。

环境Linux centos 7.6 + Nginx

1.安装Nginx

安装Nginx依赖库:

#安装Nginx的编译环境gcc
yum install gcc-c++

#nginx的http模块使用pcre解析正则表达式所以安装perl兼容的正则表达式库
yum install -y pcre pcre-devel

#nginx使用zlib对http包的内容进行gzip
yum install -y zlib zlib-devel

#nginx不仅支持http协议,还支持https(即在ssl协议上传输http),如果使用了https,需要安装OpenSSL库
yum install -y openssl openssl-devel
下载Nginx,下载地址: http://nginx.org/en/download.html 选择下载的版本,我这里选择 nginx-1.15.3,进入到下载路径,输入下载命令:

cd /usr/local/
wget http://nginx.org/download/nginx-1.15.3.tar.gz
tar -zxvf nginx-1.15.3.tar.gz
rm nginx-1.15.3.tar.gz
mv nginx-1.15.3 nginx
cd nginx
./configure –prefix=/usr/local/nginx
make
make install

#遇到make错误 /usr/local/nginx 路径不存在不管,继续 make install

#添加Nginx环境变量,可以在命令行直接输入Nginx命令
vim /etc/profile
#在*后添加Nginx的路径
export NGINX_HOME=/usr/local/nginx
export PATH=$PATH:$NGINX_HOME/sbin

#重新编译环境变量
source /etc/profile

#启动nginx
cd sbin
./nginx

#我这边启动时报错:
nginx: [alert] could not open error log file: open() “/usr/local/nginx/logs/error.log” failed (2: No such file or directory)
2018/09/25 13:59:56 [emerg] 15555#0: open() “/usr/local/nginx/logs/access.log” failed (2: No such file or directory)
#需要手动创建logs文件夹
mkdir /usr/local/nginx/logs
#再启动
./nginx

#重启命令:
nginx -s reload
Nginx安装完成,测试:打开浏览器输入IP地址显示欢迎界面则安装启动成功,如果显示访问超时,则可能是防火墙没有打开80端口。打开80端口:

iptables -I INPUT -p tcp –dport 80 -j ACCEPT
2.安装Nginx的rtmp拓展

nginx的rtmp拓展包github地址:https://github.com/arut/nginx-rtmp-module,可以使用git clone下拉或者直接下载,我这边下载解压放到:/opt/module/下。Nginx安装rtmp拓展:

cd /usr/local/nginx
./configure –add-module=/opt/module/nginx-rtmp-module
make
make install
配置Nginx的rtmp服务站点:

vim /usr/local/nginx/conf/nginx.conf

# 在文件底部添加下面内容:
rtmp {
server {
listen 1935; #监听的端口
chunk_size 4000;
application tv_file {
live on; #开启实时
hls on; #开启hls
hls_path /usr/local/nginx/html/tv_file; #rtmp推流请求路径,文件存放路径
hls_fragment 5s; #每个TS文件包含5秒的视频内容
}
}
}
重启Nginx:

nginx -s reload
测试:windows打开doc,输入:

telnet 你的ip地址 1935
如果失败,则开启1935端口:

iptables -I INPUT -p tcp –dport 1935 -j ACCEPT
3.推拉流测试

推流。下载OBS Studio,官网下载太慢了,其他下载地址:https://pc.qq.com/detail/4/detail_23604.html

安装完成,打开软件,在来源版块新建媒体源,本地文件选择一个视频视频,勾选循环,去除勾选播放结束隐藏源,在控件版块点击设置,左边的导航选择流,然后流类型选择自定义流媒体服务器,url输入rtmp://你的IP:1935/tv_file,流名称随便设置一个,这里设置zm:
%title插图%num

设置完成点击推流。

在服务器就看到m3u8文件的生成,推流成功。

%title插图%num

拉流。测试拉流的网站:https://www.wowza.com/testplayers

设置如下:

%title插图%num

 

python – 内置对象 之 保留字 & 关键字

python – 内置对象 之 保留字 & 关键字

目录

1.python保留字

2.保留字分类介绍

3.保留字使用语法介绍

1.python保留字
and       用于表达式运算,逻辑与操作
as        用于类型转换
assert    断言,用于判断变量或条件表达式的值是否为真
break     中断循环语句的执行
class     用于定义类
continue  继续执行下一次循环
def       用于定义函数或方法
del       删除变量或序列的值
elif         条件语句,与if,else结合使用
else      条件语句,与if,elif结合使用,也可用于异常和循环语句
except    except包含捕获异常后的操作代码块,与try,finally结合使用
exec      用于执行python 语句
for       for循环语句
finally   try..except..finally..无论有否始终要执行finally
from      用于导入模块,与import结合使用
global    定义全局变量
if            条件语句,与else,elif结合使用
import    用于导入模块,与from结合使用
in           判断变量是否在序列中
is            判断变量是否为某个类的实例
lambda  定义匿名变量
not         用于表达式运算,逻辑非操作
or          用于表达式运算,逻辑或操作
pass      空的类,方法,函数的占位符
print      打印语句
raise     异常抛出操作
return    用于从函数返回计算结果
try         try包含可能会出现异常的语句,与except,finally结合使用
while     while的循环语句
with      上下文管理器
yield     定义生成器
nonlocal  非本地声明保留字,声明变量为当前与全局命名空间之间
false     布尔保留字
2.保留字分类介绍
1.逻辑运算保留字:and(与操作), not(非操作), or(或操作)
2.对象引用增加保留字,相当于绑定别名: as
# import 模块 as 别名(对象引用) # (try) except 异常 as 对象引用 # with … as 对象引用
3.assert:断言语句保留字,通过异常进行程序辅助调试
# assert 判断条件 # 如果条件为False,产生AssertiomError异常
4.循环控制保留字:break, continue
# break:退出当前层循环 # continue:退出当次循环
5.类定义保留字:class
# class 类名 # class 派生类名(基类名):
6.def:函数定义保留字
# def 函数名(参数列表): # async def 函数名(参数列表):
7.条件判断保留字:if , elif, else
8.异常处理保留字:try, except, finally
# try-except # try-except-else-finally
9.循环处理关键字:for, while
# 遍历循环: for…in # 无限循环:while
10.模块导入关键字: from import
# import 模块名 # from 模块名 import *
11.in : 成员关系操作保留字
# 成员关系判断 ..in.. # 成员关系提取 for…in
12.is :对象判断保留字
# 对象一致性判断,即比较id()函数结果 # 以内存对象为判断依据: x is y
13.lambda:匿名函数保留字
# 定义匿名函数,产生函数对象 # lambda 参数列表:表达式
14.pass:空操作保留字,代表空操作,占位符
15.raise:异常产生保留字
# 产生一个异常,辅助try-except程序功能 # raise 异常名称
16.return:函数返回保留字
# 结束当前函数,返回0个或多个结果
17.with:上下文管理保留字
# 构建并管理一个上下文区域 # with表达式as对象
18.生成器定义保留字:yield
# 定义一个同步或异步(协程)生成器
19.删除保留字:del
# 解除引用与对象的绑定关系,“删除”引用 # del 引用
20.全局声明保留字: global,全局变量声明,声明后可以赋值
21.nonlocal:非本地声明保留字,用来在函数或其他作用域中使用外层(非全局)变量。
22.布尔保留字:True, False
23.空无保留字:None
24.协程声明保留字:async
# 声明一段协程程序 # async def 协程函数名(函数参数): # async with …:
25.协程等待保留字: await
# 等待一段协程程序执行并返回结果 # await 协程函数调用()
3.保留字使用语法介绍
(1)assert断言

断言函数是对表达式布尔值的判断,要求表达式计算值必须为真。
如果表达式为假,触发异常;如果表达式为真,不执行任何操作。
作用:检查某条件是否符合,不符合就触发异常,终止程序.可以等价raise-if-not
语法:assert 表达式 [, 参数]
_age = input(“请输入您的年龄:”)
age = int(s_age)
#判断age是否在20至80之间,是则执行一步,否则发出异常
assert 20 < age < 80
print(“您输入的年龄在20和80之间”)
(2)nonlocal声明内外层同名变量为相同变量

1)用于在内层函数中改变外层函数变量
a = 10 # a1 当前模块全局变量

def outer():

a = 9 # a2 outer局部变量

def inner():

nonlocal a

a = 8 # a既是inner局部变量,又是外层outer局部变量

print(a) # a3 8,在inner的局部作用域中找到了a3

inner() # inner()函数结束,a3作为外层变量(outer局部变量)被保留成为a2

print(a) # a2 8,在outer局部作用域中找到a2(在inner中被改变)

outer() # outer()函数结束,a2作为outer局部变量被释放

print(a) # a1 10,在当前模块全局作用域中找到了a1

结果:

8

8

10
2)如果在外层没有找到变量a,则会继续在再外层寻找,直到全局作用域的下一层为止
a = 10 # a1 当前模块全局变量

def outer2():

a = 9 # a2 outer2作用域局部变量

print(a) # a2 9,还未被a3改变

def outer1():

print(a) # a2 9,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(还未被a3改变)

def inner():

nonlocal a

a = 0 # a3 既是inner局部变量,又是再外层outer2作用域变量

print(a) # a3 0, 找到inner局部变量a3

inner() # inner()函数结束,a3作为外层变量(outer2局部变量)被保留成为a2

print(a) # a2 0,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(被a3改变)

outer1()

print(a) # a2 0, 在outer1中找到outer1局部变量a2(被a3改变)

outer2()

print(a) # a1 10,在当前模块全局作用域中找到了a1

结果:

9

9

0

0

0

10
3)全局变量不是外层变量,不被nonlocal寻找
a = 10 #a为全局变量

def outer():

def inner():

nonlocal a #在当前作用域外层即outer局部作用域中没找到outer局部变量a,outer外层为全局作用域,nonlocal不继续寻找,报错

a = 8

print(a)

inner()

print(a)

outer()

print(a) # a1 10,在当前模块全局作用域中找到了a1

结果:

SyntaxError: no binding for nonlocal ‘a’ found

python生成华氏度-摄氏度转换表

python生成华氏度-摄氏度转换表

## python生成华氏度-摄氏度转换表

#输入2个正整数lower和upper(lower≤upper≤100),请输出一张取值范围为[lower,upper]、且每次增加2华氏度的华氏-摄氏温度转换表。
#温度转换的计算公式:C=5×(F−32)/9,其中:C表示摄氏温度,F表示华氏温度。
upper=input()
lower=input()
upper=eval(upper);lower=eval(lower)
if upper<lower:
print(“输入有误,请重新输入”)
else:
print(“下面是温度转换表”);i=lower
while i<upper:
print(“{:d}–{:>6.1f}”.format(i,5*(i-32)/9))
i=i+2

思路:首先判断输入数据是否有误(例如大小关系等)
若输入无误则进入转换表的打印,首先打印如下是“温度转换表”使得程序更加贴切人意,再使用占位符以及while循环对输入的温度区间遍历并且运用算法转换。

python之有参装饰器

python之有参装饰器

装饰器
装饰器补充
有参装饰器
迭代器
生成器
装饰器补充
#偷梁换柱:即将原函数名指向的内存地址偷梁换柱成了wrapper函数,所以应该将wrapper做的跟原函数一样才行

from functools import wraps
def outer(func):
@wraps(func)
def wrapper(*args,**kwargs):
res = func(*args,**kwargs) #res=index(1,2)
return res
#将原函数的属性赋值给wrapper函数
#函数wrapper.__name__=原函数.__name__
#函数wrapper.__doc__=原函数.__doc__
#wrapper.__name__ =func.__name__
#wrapper.__doc__=func.__doc__
return wrapper
@outer #index=outer(index)
def index(x,y):
”’这个是主页功能”’
print(x,y)
print(index.__name__)
print(index.__doc__)

index(1,2) #wrapper(1,2)

有参装饰器
一、知识储备
由于语法糖@的限制,outer函数只能有一个参数,并且该参数只用来接收被装饰对象的内存地址

def outer(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper

@outer #index = outer(index) #index==>wrapper
def index(x,y):
print(x,y)

#偷梁换柱之后
#index的参数是什么样子,wrapper的参数就应该是什么样
#index的返回值什么样子,wrapper的返回值就应该是什么样子
#index的属性什么样子,wrapper的属性就应该是什么样子==>from functools import wraps

傻瓜1:

def auth(func,db_type):
def wrapper(*args,**kwargs):
name = input(‘your name:>>’).strip()
pwd = input(your password:>>’).strip()
if db_type == ‘file’:
#从文件中取账号密码进行验证
if name ==’egon’ and pwd == ‘123’:
print(‘基于文件的验证’)
res = func(*args,**kwargs)
return res
else:
print(‘user or password error’)
elif db_type == ‘mysql’:
print(‘基于mysql的验证’)
elif db_type == ‘ldap’:
print(‘基于ldap的验证’)
else:
print(‘不支持db_type’)
return wrapper

@auth #账号密码来源是文件
def index(x,y):
print(‘index->>%s:%s’ %(x,y))

@auth #账号密码的来源是数据库
def home(name):
print(‘home->>%s’ % name)

@auth #账号密码的来源是ldap
def transfer():
print(‘transfer’)

index = auth(index,’file’)
home = auth(home,’mysql’)
transfer = auth(transfer,’ldap’)

傻瓜2:

def auth(db_type):
def deco(func):
def wrapper(*args,**kwargs):
name = input(‘your name:>>’).strip()
pwd = input(‘your password:>>’).strip()
if db_type == ‘file’:
#从文件中取账号密码进行验证
if name == ‘egon’ and pwd == ‘123’:
print(‘基于文件的验证’)
res = func(*args,**kwargs)
return res
else:
print(‘user or password error’)
elif db_type == ‘mysql’:
print(‘基于mysql的验证’)
elif db_type == ‘ldap’:
print(‘基于ldap的验证’)
else:
print(‘不支持db_type’)
return wrapper
return deco

deco = auth(db_type = ‘file’)
@deco #账号密码来源是文件
def index(x,y):
print(‘index->>%s:%s’ %(x,y))

deco = auth(db_type = ‘mysql’)
@deco #账号密码的来源是数据库
def home(name):
print(home–>%s’ %name)

deco = auth(db_type = ‘ldap’)
@deco #账号密码的来源是ldap
def transfer():
print(‘transfer’)

index(1,2)
home(‘egon’)
transfer()

语法糖

def auth(db_type):
def deco(func):
def wrapper(*args,**kwargs):
name = input(‘your name>>:’).strip()
pwd = input(‘your password>>:’).strip()
if db_type == ‘file’:
#从文件中取账号密码进行验证
if name == ‘egon’ and pwd ==’123′:
print(‘基于文件的验证’)
res = func(*args,**kwargs)
return res
else:
print(‘user or password error’)
elif db_type == ‘mysql’:
print(‘基于mysql的验证’)
elif db_type == ‘ldap’:
print(‘基于ldap的验证’)
else:
print(‘不支持db_type’)
return wrapper
return deco

@auth(db_type = ‘file’) #@dec0 #index = deco(index) #index=wrapper
def index(x,y):
print(‘index->>%s:%s’ %s (x,y))

@auth(db_type = ‘mysql’) #账号密码的来源是数据库
def home(name):
print(‘home–> %s’ %name)

@auth(db_type = ‘ldap’) #账号密码的来源是ldap
def transfer():
print(‘transfer’)

index(1,2)
home(‘egon’)
transfer()

有参装饰器模板

def 有参装饰器(x,y,z):
def outer(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
return outer

@有参装饰器(1, y =2 , z= 3)
def 被装饰对象():
pass

迭代器
什么是迭代求
迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代。
2.为何要有迭代
迭代器是用来取值的工具,而涉及到把多个值循环取出来的类型有:
列表、字符串、元组、自ID以、集合、打开文件
l = [‘egon’,’liu’,’alex’]
i = 0
while i < len(l):
print(l[i])
i+=1

上述迭代取值的方式只适用于有索引的数据类型:列表、字符串
为了解决基于索引迭代器取值的局限性,python必须提供一种能够不依赖索引的取值方式,这就是迭代器
1
2
3.如何用迭代器

可迭代对象:但凡内置有__iter__方法的都称之为可迭代的对象
s1 = ”
s1.__iter__()
l =[]
l.__iter__()
d = {‘a’:1}
d.__iter__()
set1 ={1,2,3}
set1.__iter__()
with open(‘a.txt’,mode = ‘w’,encoding=’utf-8′) as f:
f.__iter__()
f.__next__()

调用可迭代对象下的__iter__方法会将其转换成迭代器对象

d = {‘a’:1,’b’:2,’c’:3}
d_iterator = d.__iter__()
print(d_iterator)
print(d_iterator.__next__())
print(d_iterator.__next__())
print(d_iterator.__next__())
print(d_iterator.__next__()) # 抛出异常StopIteration 迭代器取值取干净了

l = [1,2,3,4,5]
l_iterator = l.__iter__()
while True:
try:
print(l_iterator.__next__())
except StopIteration:
break

4.可迭代对象与迭代器对象详解
可迭代对象(‘可以转换成迭代器的对象’):内置有__iter__方法对象
可迭代对象.iter():得到迭代器对象

可迭代对象:字符串、列表、元组、字典、集合、文件列表

迭代器对象:文件对象

s1 = ”
s1.__iter__()
l =[]
l.__iter__()
d = {‘a’:1}
d.__iter__()
set1 ={1,2,3}
set1.__iter__()
with open(‘a.txt’,mode = ‘w’,encoding=’utf-8′) as f:
f.__iter__()
f.__next__()

迭代器:内置有__next__方法并且内置有__iter__方法的对象
迭代器对象.next():得到迭代器的下一个值
迭代器对象.iter():得到迭代器本身,说白了掉跟没调一样

dic = {‘a’:1,’b’:2}
dic_iterator = dic.__iter__()
print(dic_iterator is dic_iterator.__iter__())

for 循环的工作原理:for循环可以称之为迭代器循环

for x in 迭代器对象.__iter__():
1
d = {‘a’:1,’b’:2,’c’:3}
d_iterator = d.__iter__()
while True:
try:
print(d_iterator.__next__())
except StopIteration:
break

d.iter() 得到一个迭代器对象
迭代器对象.next()拿到一个返回值,然后将该返回值赋值给k
循环往复上一步骤,直到抛出StopIteration异常 for循环会捕捉异常然后结束循环

for k in d:
print(k)
with open(‘笔记’,mode = ‘rt’,encoding=’utf-8′) as fp:
for line in fp:
print(line)

list(‘hello’) #原理同for循环
1
生成器
如何得到自定义的迭代器:
在函数内一旦存在yield关键字,调用函数并不会以执行函数体代码,会返回一个生成器对象,生成器即自定义的迭代器

def func():
print(‘first’)
yield 1
print(‘second’)
yield 2
print(‘third’)
yield 3
print(‘fourth’)

g = func()
print(g)

生成器就是迭代器
g.__iter__()
g.__next__()

会触发函数体代码的运行,然后遇到yield停下来,将yield后的值当做本次调用的结果返回

res1 = g.__next__()
print(res1)

res2 = g.__next__()
print(res2)

res3 = g.__next__()
print(res3)

res4 = g.__next__()

应用案例

def my_range(start,stop,step=1):
print(‘start…’)
while start < stop:
start+=step
yield start
print(‘end…’)

g = my_range(1,5,2)
print(next(g))
print(next(g))
print(next(g))

简单的背包问题

简单的背包问题

关于递归的一个例子2 简单的背包问题
关于递归的一个例子2 简单背包问题
题目
输入格式
输出格式
输入样例
输出样例
思路
代码如下
关于递归的一个例子2 简单背包问题
题目
一个背包里可放入重量为weight的物品,现有n件物品的集合S,其中物品的重量分别为w0,w1,···,wn-1。问题是能否从中选出若干件物品,其重量之和正好等于weight。如果存在就说明这一背包有解,否则就是无解。

输入格式
在一行中输入weight,物件*大数量n,物品集合S(是一个数组,Python中是列表)

输出格式
具体的实现方式(采用贪心算法,仅求一个解法即可)和对与错。

输入样例
30 7 list(range(20,0,-1))
1
输出样例
9 6 5 4 3 2 1 True
1
思路
题目给定背包,物件个数,物件质量。
先取出列表中的*个,判断它是否能达成所需要的效果。若不能达成条件,则返回错误,能达成条件则返回正确。这里用递归实现。
所以判断达成条件的方式是定义一些出口。

代码如下
def bags(weight,n,S):
if weight == 0: # 判断达成的条件
return True
elif weight < 0: # 跳出函数的条件,超重,出口1
return False
elif n <= 0: # 跳出函数的条件,*大个数被取完,出口2
return False
elif len(S)<= 0: # 列表被取完,出口3
return False
tw = S.pop() # 取出*个数
a = S[:] # 记录列表(易错点)
if bags(weight-tw,n-1,S): # 递归调用
print(tw,end = ‘ ‘)
return True
elif bags(weight,n,a): # 递归调用
return True
return False
print(bags(30,7,list(range(20,0,-1))))
”’
输出的数据排序是和输入的数组有关系,如果想统一可以自行对数组数据进行排序,再调用函数。
”’

剑指 Offer 20. 表示数值的字符串

剑指 Offer 20. 表示数值的字符串

题目链接:
https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/

题意:
实现一个函数用来判断字符串是否表示数值(包括整数和小数)

题解:
由于没给正确格式的正则表达式,所以写起来比较麻烦,需要试错。
首先将字符串的前缀空格以及后缀空格去掉。
然后通过“e” or “E”将字符串分割成数字部分以及指数部分。
数字部分:

长度为0,False
正负号在除首位的其他位置出现,False
小数点出现多次,False
只有小数点或者正负号,没有数字,False
指数部分:

原串包含“e”or“E”,但不包含任何数字,False
正负号在除首位的其他位置出现,False
出现小数点,False
只有小数点或者正负号,没有数字,False
代码:
class Solution:
def isNumber(self, s: str) -> bool:
#处理多余空格
t = ”
for i in range(len(s)):
if s[i]!=’ ‘:
s=s[i:]
break
for i in range(len(s)-1,-1,-1):
if s[i]!=’ ‘:
s=s[:i+1]
break
#分隔字符
pre,pst=”,”
for i in range(len(s)):
if s[i].upper() == ‘E’:
pre = s[:i]
pst = s[i+1:]
break
if i ==len(s)-1:
pre = s
# 数字部分
if len(pre) == 0:
return False
havedot ,havenum=False,False
for i in range(len(pre)):
if pre[i]==’+’ or pre[i]== ‘-‘:
if i!=0:
return False
elif pre[i]==’.’ :
if not havedot:
havedot =True
else :
return False
elif ‘0’<=pre[i]<=’9′:
havenum =True
else :
return False
if not havenum :
return False
# 指数部分
if pre != s and len(pst)==0:
return False
havenum = False
for i in range(len(pst)):
if pst[i] == ‘-‘ or pst[i] == ‘+’:
if i != 0:
return False
elif pst[i]==’.’:
return False
elif ‘0’<=pst[i]<=’9′:
havenum = True
else :
return False
if not havenum and len(pst)>0:
return False
return True

妙解:
利用python的异常处理机制。(虽取巧,但也是一种能力)
代码:

class Solution:
def isNumber(self, s: str) -> bool:
try:
float(s)
return True
except:
return False

浅谈Python基本数据类型

浅谈Python基本数据类型

PYTHON基础数据类型
整数
和我们生活中使用的整数一样1,2,3,4···100···

都是整数,PYthon可以处理任意大小的整数。由于计算机使用的是二进制,所以在计算机中也常用二进制或者十六进制表示整数。相比十进制,python使用0b表示,比如0b0110,0b1100等来表示

十六进制除了0~9个是个数字以外,还使用了a,b,c,d,e,f在python中,十六进制使用前缀0x,比如:0x12ef,0x2365a4fa

十进制数,二进制数,十六进制数是可以互相转换的。

浮点数
浮点数也可以理解为我们日常生活中所谓的小数,例如3.1415926,13.14,5.20等等,都是所谓的浮点数。浮点数之所以被称之为小数,是因为按照科学计数法来表达的时候,浮点数和小数点位置是可变的(浮动的),比如:31415.926*10^-4和3141.5926 *10^-3是一样的,因此称之为浮点数.

浮点数可以用数学发写入,例如3.14,5.2,13.14等。但是对于很大或者很小的浮点数,就必须用科学技术法表示,把10用e替代,比如3.14e-5=0.0000314.

浮点数和整数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。例如在python环境中输入0.1+0.2
然而输出的结果并不是0.3,但是0.01+0.02却可以精确的得到0.03

字符串
字符串对应生活中的就是非数字型的内容,例如,一段话或者一个句子,在python中就是字符串,在python中字符串的定义就是被””或者’‘括起来的内容,比如’rxxy’,“ysfx”等等。’’,””本身知识一种表达方式,并不是字符串的一部分,因此’rxxy’中只有r,x,x,y这四个字符,并没有’,’

例如print (‘hello python’)其中的字符串只是hello python。

布尔值
布尔值对应于生活中的就是’对’和’错’在计算机的世界里,大部分判断都是非错则对的,布尔值和布尔代数的表示完全一致,一个布尔值只有TRUE,FALSE两种值,不是TRUE就是FALSE,在Python也可以直接用TURE或者FALSE表示布尔值,请注意大小写,不要使用字符串括号括起来,也可以通过布尔运算计算出来。

布尔值可以用and,or,和not运送(注意and,or,not都是用Python语言本身的关键字)

**and**运算是与运算,只有所有都为 True,and运算结果才是 True。

**or**运算是或运算,只要其中有一个为 True,or 运算结果就是 True。

**not**运算是非运算,它是一个单目运算符,把 True 变成 False,False 变成 True。

空值
空值是Python里一个特殊的值,用None表示。

注意,None和0是不一样的,None不能理解为0,因为0是有意义的,比如我有0个苹果表示我没有苹果,0表达的是数值0的意思,而不能表示为我有None个苹果,None是一个特殊的空值。

iOS-十六进制转bytes数组(nsdata)

– (NSData *) stringToHexData
{
int len = [self length] / 2;    // Target length
unsigned char *buf = (unsigned char *)malloc(len);
unsigned char *whole_byte = buf;
char byte_chars[3] = {‘\0′,’\0′,’\0’};

int i;
for (i=0; i < [self length] / 2; i++) {
byte_chars[0] = [self characterAtIndex:i*2];
byte_chars[1] = [self characterAtIndex:i*2+1];
*whole_byte = strtol(byte_chars, NULL, 16);
whole_byte++;
}

NSData *data = [NSData dataWithBytes:buf length:len];
free( buf );
return data;
}

iOS-删除相册照片

#import <Photos/Photos.h>

 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(takeScreenSheetAction:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];

 

-(void)takeScreenSheetAction:(NSNotification *)notification{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
PHFetchOptions *options = [[PHFetchOptions alloc] init];

options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@”creationDate” ascending:NO]];

PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];

 

PHAsset *asset = [assetsFetchResults firstObject];

if (asset) {
NSArray *delAssets = [[NSArray alloc] initWithObjects:asset, nil];

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets:delAssets];

} completionHandler:^(BOOL success, NSError * _Nullable error) {
}];

}

});

}

iOS判断NSDictionary中含有某个key

NSDictonary *dict = @{@”123″:@”a”;@”234″:@:”b”};

判断字典中是否含有某个key

一:

if ([dict.allKeys containsObject:@”a”]) {

 

}

二:

[dict.allKeys enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

if ([obj isEqualToString:@”rightTitle”]) {

 

}

else//没有righttitle

{

 

}

}];

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速