日期: 2021 年 4 月 21 日

笨阶乘

笨阶乘

[leecode] 1006. 笨阶乘
问题
试图解题
地板除法(floor division)
思路和代码
问题
通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。

相反,我们设计了一个笨阶乘 clumsy:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。

例如,clumsy(10) = 10 * 9 / 8 + 7 – 6 * 5 / 4 + 3 – 2 * 1。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。

另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8 等于 11。这保证结果是一个整数。

实现上面定义的笨函数:给定一个整数 N,它返回 N 的笨阶乘。

示例 1:

输入:4
输出:7
解释:7 = 4 * 3 / 2 + 1

示例 2:

输入:10
输出:12
解释:12 = 10 * 9 / 8 + 7 – 6 * 5 / 4 + 3 – 2 * 1

提示:

1 <= N <= 10000
-2^31 <= answer <= 2^31 – 1 (答案保证符合 32 位整数。)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/clumsy-factorial
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

试图解题
地板除法(floor division)
百科
python里的地板除

也就是截取商的整数位

思路和代码
俺寻思这应该就是写个计算器吧, 输入数值和运算规律固定的那种(掏出堆栈)
一开始把减号后面的那一个数也当成前一个入栈值的一部分了((N * (N – 1) / (N – 2)) – N + 3), 我是傻逼=。=
但是很申必, 放leecode上输入是4的时候能通过, 为什么输入10的时候就炸了, 明明在本地运行都没问题啊?
*稿代码:

class Solution {
public:
int clumsy(int N) {
int sum = 0;
int i = 0;
int* nums = new int[N % 4 ? N / 4 + 1 : N];
while (N / 4)
{
nums[i++] = (N * (N – 1) / (N – 2));
nums[i++] = N – 3;
N -= 4;
}
if (N)
{
switch (N)
{
case 3:
nums[i] = 6;
break;
case 2:
nums[i] = 2;
break;
case 1:
nums[i] = 1;
break;
default:
break;
}
i++;
}
i–;
while (i)
{
sum += i % 2 ? nums[i] : -nums[i];
i–;
}
return nums[0] + sum;
}
};

为啥运行了要炸啊?
嗯, i *大是N的2倍(取四舍五入),等会, 之前改i的逻辑的时候数组new的大小是不是忘记改了?!
草!果然! vs2019! 你算计我!!!
所以实际上数组大小是[N % 4 ? N / 2 + 1 : N * 2]
*终通过的代码如下:

class Solution {
public:
int clumsy(int N) {
int sum = 0;
int i = 0;
int* nums = new int[N % 4 ? N / 2 + 1 : N * 2];
while (N / 4)
{
nums[i++] = (N * (N – 1) / (N – 2));
nums[i++] = N – 3;
N -= 4;
}
if (N)
{
switch (N)
{
case 3:
nums[i] = 6;
break;
case 2:
nums[i] = 2;
break;
case 1:
nums[i] = 1;
break;
default:
break;
}
i++;
}
i–;
while (i)
{
sum += i % 2 ? nums[i] : -nums[i];
i–;
}
return nums[0] + sum;
}
};

爬虫网络请求模块和保存图片的方法

爬虫网络请求模块和保存图片的方法

urllib模块
一、什么是urllib模块
1、urllib模块是python中的内置模块
二、为什么要学习urllib模块
1、有一些比较老的爬虫项目用的就是这个技术。
2、有的时候我们去爬取一些数据需要request+urllib模块进行配合。
3、python内置的模块
二、保存图片的方法有以下3种

import requests
*种:需要自己写关闭
# url = ‘https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3566088443,3713209594&fm=26&gp=0.jpg’
# response = requests.get(url)
# fn = open(‘code.png’, ‘wb’)
#fn.write(response.content)
# fn.close()

第二种:用with方法不用写关闭
# url = ‘https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3566088443,3713209594&fm=26&gp=0.jpg’
# response = requests.get(url)
# fn = open(‘code.png’, ‘wb’)
# with open(‘code2.png’, ‘wb’) as file_obj:
# file_obj.write(response.content)

第三种:用urllib保存
# from urllib import request
# url = ‘https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3566088443,3713209594&fm=26&gp=0.jpg’
# request.urlretrieve(url, ‘code3.png’)

三、urllib模块的快速入门
一、urllib.request.urlopen(‘网址’)
1、 作用:向网站发起请求并获取响应

import urllib.request
# headers = {}
# # response 响应对象
# response = urllib.request.urlopen(‘https://www.baidu.com/’)
# # print(response.read()) # 1、字节流bytes 2、数据不对(反爬)
# html = response.read().decode(‘utf-8’)
# print(type(html))

二、urllib.request.Request(添加网站, user-agent)
1、 作用:创建请求对象

mport urllib.request

url = ‘https://www.baidu.com/’
headers = {
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36 Edg/90.0.818.39’
}
# 1、创建请求对象
req = urllib.request.Request(url, headers=headers)
# 2、获取请求对象
response = urllib.request.urlopen(req)
# 3、响应对象的内容
html = response.read().decode(‘utf-8’)
print(html)
print(response.getcode()) # 获取状态码
print(response.geturl()) # 反回请求的url地址
# encode str(字符串)–> bytes数据类型
# decode bytes数据类型 –> str(字符串)

urllib.pars的使用
一、如果我们通过urllib向一个携带有中文字样的url发起请求,
这个时候我们需要注意把中文转换成百分号+十六进制的这种数据类型 %E6%B5%B7%E8%B4%BC%E7%8E%8B

import urllib.request
# 如何编码 3个%是一个汉字
# %E6%B5%B7%E8%B4%BC%E7%8E%8B
# wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B
# url = ‘https://www.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B’
# url2 = ‘https://www.baidu.com/s?wd=海贼王’

# res = urllib.request.urlopen(url)
# 如果我们通过urllib向一个携带有中文字样的url发起请求,
# 这个时候我们需要注意把中文转换成百分号+十六进制的这种数据类型 %E6%B5%B7%E8%B4%BC%E7%8E%8B
# result = urllib.parse.urlencode(字典) # 在括号中传入字典类型
*种方法:
import urllib.parse
# wd = {‘wd’: ‘海贼王’}
# result = urllib.parse.urlencode(wd)
# print(result)
# base_url = ‘https://www.baidu.com/s?’ + result
# print(base_url)
第二种方法:
# urllib.parse.quote(字符串)
r = ‘海贼王’
result = urllib.parse.quote(r)
# print(result)
url3 = ‘https://www.baidu.com/s?’ + result
print(url3)
# 拓展
总结以后看到如下数据如何解决
# https%E6%B5%B7%E8%B4%BC%E7%8E%8B%E6%B5%B7%E8%B4%BC%E7%8E%8B
hreo_url = ‘http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735042015%2F1618905362%5F84828260%5F13100%5FsProdImgNo%5F1%2Ejpg%2F200 ‘ # 图片的url
img_url = urllib.parse.unquote(hreo_url)
print(img_url)

Python 中的断言( assert )

Python 中的断言( assert )

Python 中的断言( assert )

由Python 文档https://docs.python.org/3/reference/simple_stmts.html#assert 可知,assert 语句的语法如下所示:

assert_stmt ::= “assert” expression1 [“,” expression2]

此乃编译原理的定义格式,通俗说法为:

assert expression1 [, expression2]

其中expression1是需要测试的条件, expression2是错误消息是可选的,测试的条件为假时显示之。在执行时,Python 解释器将每条断言语句大致转换为以下这些语句:

if __debug__:

if not expression1:

raise AssertionError(expression2)

需要说明两点:

*,代码在检查断言条件之前,还会检查__debug__全局变量。这是一个内置的布尔标记,,内置变量 __debug__ 在正常情况下为 True。

第二,当expression1为真时,程序继续往下执行,只是判断,不做任何处理;

当expression1为假时,中断程序,抛出AssertionError错误,并将expression2消息输出。

 

例1、

def foo(s):
n = int(s)
assert n != 0, ‘n is zero!’
return 10 / n

print(foo(‘2’)) #程序不报错,将该句改为print(foo(‘0’)) # 代码执行结果, AssertionError: n is zero!

例2、本例演示了用try语句捕获assert抛出异常,代码如下:

def testAssert():
for i in range(4):
try:
assert i<2
except AssertionError:
print(‘捕获assert抛出的异常!’)
print(i)
print(‘……end……’)

testAssert()

本例中定义了testAssert函数,当for循环变量i为2时,assert后的条件i<2为假,因此抛出AssertionError,因为这个异常被捕获处理,程序不会中断,直至for循环正常结束。

运行效果如下:

0
1
捕获assert抛出的异常!
2
捕获assert抛出的异常!
3
……end……

 

如何禁用Python中的断言?怎么做?

断言语句是可以被禁用的——需要满足__debug__ == flase,可以这样做:

若在命令行中使用-O 和-OO 标识,或修改Python 中的PYTHONOPTIMIZE环境变量,都会全局禁用断言。

如,,在命令行中使用-O标志(大写字母O)调用Python运行scriptName.py :

python -O scriptName.py

 

关于__debug__可参见https://docs.python.org/zh-cn/3/library/constants.html?highlight=__debug__#__debug__

 

 

python学习之http服务和类

python学习之http服务和类

发送http请求
import requests

# 生成url
def create_header():
header = {
“content-type”: “application/json”
}
return header

body = {“name”: “zhangsan”}
headers = create_header()
print(headers)
response = requests.post(“http://localhost:8085/test/length”, json=body, headers=headers)
if response.ok:
print(response.text)
else:
print(response.reason)

提供web接口
import flask
import time

server = flask.Flask(__name__)

@server.route(‘/time’)
def test():
return str(time.time())

server.run(‘127.0.0.1’, 9000)

类的定义
class people:
def __init__(self, name, city):
self.name, self.city = name, city

def __str__(self):
return “name=%s, city=%s” % (self.name, self.city)

def moveTo(self, new_city):
self.city = new_city

def __lt__(self, other):
return self.city < other.city

__repr__ = __str__

class teacher(people):
def __init__(self, name, city, school):
self.name, self.city, self.school = name, city, school

def __lt__(self, other):
return self.school < other.school

p1 = people(“张三”, “beijing”)
print(p1)
p1.moveTo(“shanghai”)
print(p1)
people_list = list()
people_list.append(p1)
people_list.append(people(“李四”, “chongqin”))
people_list.append(people(“王五”, “nanjin”))
print(people_list)
people_list.sort()
print(people_list)

teacher_list = list()
teacher_list.append(teacher(“蔡元培”, “北京”, “beida”))
teacher_list.append(teacher(“胡适”, “青岛”, “tsinghua”))
teacher_list.append(teacher(“陈独秀”, “厦门”, “fudan”))
print(teacher_list)
teacher_list.sort()
print(teacher_list)

 

时间戳问题汇总

时间戳问题汇总
用一个 VLC(流媒体客户端) 去请求流媒体服务器上的数据, 但是获得的数据播放速度明显快于1倍速,大概是 timestamp 不对, 不知道是服务器的错误,还是客户端解码时出错, 总感觉服务器那边有问题
TAG: 时间戳 PTS DTS

我刚接触流媒体不久, 现在遇到一个非常奇怪的问题,向各位大侠请假,请你们指点。
问题是这样的 用一个 VLC(流媒体客户端) 去请求流媒体服务器上的数据, 但是获得的数据播放速度明显快于1倍速,大概是 timestamp 不对, 不知道是服务器的错误,还是客户端解码时出错, 总感觉服务器那边有问题, 由于服务器端是客户端提供的,客户说是我们的问题, 我还不知道如何证明是谁的错。

A:RFC3984 规定采用 90000 Hz 的时钟,因此如果编码帧频是 30,那么时间戳间隔就该是 90000 / 30 = 3000,根据抓包来看,似乎时间戳间隔的确是 3000。

时间戳的 间隔不固定,比如有的时间戳间隔是 2990 有的是 3002,会导致解析出来的视频快播的效果么

Q:各位大侠好:
我现在正在开发视频实时流播放,简单的过程如下:
采集视频流 -> 视频流转换为Sorenson H.263编码格式 -> 把编码的实时流通过RTMP协议发送 -> flash客户端进行播放。
现在我的时间戳颗粒是这样生成的:
*帧的时间戳为0;
第二帧的时间戳的算法为:*个字符编码的当前时间 – 上一帧*个字符编码的当前时间
根据这个时间颗粒的算法,我在flash客户端播放就会产生延时。
请问各位大侠有什么好的建议或是文档之类的,以前firstime管管建议我看RFC4629文档,但是效果不太明显?
谢谢!

A;时间戳顺序累加就行了,每次加1

Q:*近做了一个捕捉摄像头并保存FLV的小东西,发现转换完毕后的FLV文件,用播放器播放的时候,速度特别快,大概是正常速度的4倍。请问这是怎么回事?网上搜了一下,说是时间戳的问题,可是PTS我跟了,AVPacket的PTS是每帧增长40,time_base为: 25/s.。DTS是个无效值。PTS的计算是根据ffmpeg的例子写的。

pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);

1. dts到底需不需要自己计算?
2. 还有播放速度过快的可能原因?
3. 还有PTS和DTS的具体含义?
int64_t pts; ///< presentation time stamp in time_base units
int64_t dts; ///< decompression time stamp in time_base units

上面的意思是不是说,播放器根据PTS进行播放。然后DTS是在编码的时候自己设置?

刚用ffmpeg,好些东西不懂,还请大侠多多指教——刚才又试了一下,把time_base降为10帧每秒。播放速度和正常速度接近。但是不知道FLV文件的帧率该设置多少合适。有没有一个权威的说法。

A:我也做摄像头捕捉,跟你出现一样的问题,我自己分析的话,应该是捕捉摄像头的图像的速度只有10帧每秒,但是保存成视频25帧每秒的话播放看起来就非常快,但是我摄像头捕捉设定的是25帧每秒,难道是速度达不到?
反正我还没解决,LZ解决了的话告诉下,

谢谢。暂时认为是摄像头捕捉速率问题。换了一个高清无驱摄像头就好了

Q:在每个音视频数 据包中都含有PTS和DTS,一个数据包中应该含有多个数据帧以及音频数据,那么这里的PTS和DTS它是如何来标识数据帧的?PTS和DTS的单位是什 么?视频的*小单位是帧,可通过PTS来指定它何时播放,那音频的*小单位是什么?这里的PTS对音频而言它标识的是什么?是这个时间点采样点吗?

在网上找了很久关于音视频编解码的资料,都没有合适的

A:

audio_timebase = av_q2d(fmtctx->streams[audio_index]->time_base);
video_timebase = av_q2d(fmtctx->streams[video_index]->time_base);

last_video_pts = pts * video_timebase;
last_audio_pts = pts * audio_timebase;

timebase就是单位

以audio为基准同步video。只要设置好了 ao 的参数,如sample rate, channels, sample size等, audio驱动就能以正确的速度播放,所以只要程序里write不出大问题的话,这种同步是非常有效的。

在video out里如下做:

pre_time = av_gettime();
gl_vo->vo_display(pic);
after_time = av_gettime();
rest_time = 1000*1000/fps – (after_time – pre_time);

av_diff = last_audio_pts – last_video_pts;

if ( av_diff > 0.2 )
{
if( av_diff < 0.5 ) rest_time -= rest_time / 4;
else rest_time -= rest_time / 2;
}
else if ( av_diff < -0.2)
{
if( av_diff > -0.5 ) rest_time += rest_time / 4;
else rest_time += rest_time / 2;
}

if ( rest_time > 0 )
usleep(rest_time);
Q:谢谢kf701的回复,看后明白了不少
这种同步是音频抽样一次就与一帧图像去同步的吗?

A:上面的代码是每display一个picture,就与audio的PTS比较一下,
如果没有audio,只有video,那么video就会以fps显示, 靠的就是那个 usleep(rest_time)

Q:如何利用AVPacket包里的pts,dts实现音视频同步?声频播放是只管自己播放,视频有一个初始化播放帧率,如何根据AVPacket里的pts,dts还实现两者的同步?
现在我的视频播放一直按原始播放帧率播放,声音有点卡!哪位知道,尽快告知小弟!

A:DTS:decoding time stamp
PTS:presentation time stamp

Generally the PTS and DTS will only differ when the stream we are playing has B frames in it.

Q:关于b帧和时间戳的问题

我从mpeg2视频中用av_read_frame()读取视频帧并解码,顺序是IPBBPBB…
它们的pts顺序是1423756…现在我要把这个视频再用mpeg2编码,*大b帧数还是2.那么我在编码时是否要将视频数据调整为按显示时间先后的顺序,再交给avcodec_encode_video()编码?即把第2帧放在3、4帧之后,第7帧放在5、6帧之后?

A:你不能这么做,编码器会给你这么做的。如果你有B帧,那么所有的B帧都会被放在缓冲区里直到下一个I/P帧到来

例如:你的输入序列是IBBPBBPBBI

那么输出的序列是

输入I,编码I,输出I

输入B

输入B

输入P,编码P,输出P

编码B,输出B

编码B,输出B

输入P,编码P,输出P

。。。。。。

在解码端所有的P帧都会被放在缓冲力直到下一个I/P真的到来

如:解码I,输出I

解码P,放入缓冲P

解码B,输出B

解码B,输出B

解码P,输出上一次P帧

Q:解码出来的图片的时间戳问题 MPEG一个包中包含有时间戳, 而可能几个包才能解码出一张图象, 也可能一个包能解码出几张图, 请问包中的时间戳与解码出来的图象如何对应上?

A: 在ffmpeg中通过parser部件把从avformat部件取下来的原始包重新“合成”为有仅包含一个完整帧的包。从MPEG2部份的代码中看出,如 果“几个包才能解码出一张图象”的话,会取*个包的PTS和DTS,如果“也可能一个包能解码出几张图”,则会跟据这个包的PTS和DTS通过帧频推算 出其它帧的DTS。

Q: ffmpeg的avcodec_decode_video 函数解码时间戳问题?在 VLC 中调用 avcodec_decode_video() 函数进行解码时,AVFrame->pts 时间戳不对,导致我的图像不能够显示? 请问有谁知道它的解码原理,这个 PTS 怎么得出的吗?还是外部传入的?

A: /* NOTE: ipts is the PTS of the _first_ picture beginning in
this packet, if any */
is->video_st->codec->reordered_opaque= pkt->pts;
len1 = avcodec_decode_video(is->video_st->codec,
frame, &got_picture,
pkt->data, pkt->size);

if( (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
&& frame->reordered_opaque != AV_NOPTS_VALUE)
pts= frame->reordered_opaque;
else if(pkt->dts != AV_NOPTS_VALUE)
pts= pkt->dts;
else
pts= 0;
pts *= av_q2d(is->video_st->time_base);

Q:我贴下 VLC 的代码,(vlc-0.9.8a/modules/codec/avcodec/video.c 文件中)

i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
&b_gotpicture,
p_sys->i_buffer <= 0 && p_sys->b_flush ? NULL : (uint8_t*)p_sys->p_buffer, p_sys- >i_buffer );

中间省略

取得 PTS ,

if( p_sys->p_ff_pic->pts )
{
printf(” p_sys->p_ff_pic->pts = %Lx\n”, p_sys->p_ff_pic->pts);
p_sys->i_pts = p_sys->p_ff_pic->pts;
}

从 AVFrame 结构中取得 这个 PTS ,但是这个 AVFrame 结构中取得 这个 PTS 从哪里取得的呢?

A:时间戳一般是在编码的时候加入到媒体文件中的,所以在解码时可以从中分析出PTS。

discover执行多个用例

discover执行多个用例

前面我们说了,对于不同文件用例,我们可以通过addTest()把用例加载到一个测试套件(TestSuite)来统一执行,对于少量的文件这样做没问题,但是如果有几十上百个用例文件,这样做就太浪费时间了。

unittest中的discover()方法可以批量加载用例

discover(start_dir, pattern=‘test*.py’, top_level_dir=None)
start_dir:测试模块名或测试用例所在目录
pattern=‘test*.py’:表示用例文件名的匹配方式,此处匹配的是以test开头的.py类型的文件,*表示匹配任意字符
top_level_dir:测试模块的顶层目录
代码:
import unittest

import unittest
import os
import test_Suite

if __name__ == “__main__”:
# 测试用例目录
case_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), ‘test_Suite’)
print(case_dir)
case_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__))))
print(case_path)

# 尤其注意该目录两个参数,start_dir是相对路径精确到./ pattern是./下的.py文件 (用例文件昵称)
discover = unittest.defaultTestLoader.discover(start_dir=case_path, pattern=’test_Suite.py’)
runner = unittest.TextTestRunner(verbosity=2)
runner.run(discover)

命令队列

命令队列

命令队列

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
“””
参考命令模式实现的命令队列例子,已封装好顺序执行、同步执行命令,顺序/同步执行命令可相互嵌套。
撤销(undo)可参考执行(execute)的方式实现。
“””

class Command:
“””
所有命令的基类
“””

def __init__(self):
self.m_executedCallbackDict = {}
self.m_undidCallbackDict = {}

def execute(self):
“””
统一执行接口
“””
# print(“[execute]”)
self.executedCallback()

def undo(self):
“””
统一撤销接口
“””
# print(“[undo]”)
self.undidCallback()

def setExecutedCallback(self, k, func):
self.m_executedCallbackDict[k] = func

def setUndidCallback(self, k, func):
self.m_undidCallbackDict[k] = func

def executedCallback(self):
self.callback(self.m_executedCallbackDict)

def undidCallback(self):
self.callback(self.m_undidCallbackDict)

def callback(self, callbackDict):
for k, func in callbackDict.items():
if callable(func):

func(self)

def getCommandUUID(self):
return id(self)

class SequenceQueueCommand(Command):
“””
容器命令-顺序执行
“””

def __init__(self, cmds=None):
Command.__init__(self)
self.m_commands = [] if cmds is None else cmds
self.m_executingCommands = []
self.m_executedCommands = []

def appendCommand(self, cmd):
self.m_commands.append(cmd)

def insertCommand(self, index, cmd):
self.m_commands.insert(index, cmd)

def execute(self):
if self.m_executingCommands:
return
if self.m_commands:
cmd = self.m_commands.pop(0)
cmd.setExecutedCallback(
k=self.getCommandUUID(), func=self.executedOneCommand)
self.m_executingCommands = [cmd]
cmd.execute()
else:
self.executedAllCommand()

def executedOneCommand(self, cmd):
self.m_executedCommands.append(cmd)
if cmd in self.m_executingCommands:
self.m_executingCommands.remove(cmd)
self.execute()

def executedAllCommand(self):
self.executedCallback()

def undo(self):
pass

class ParallelQueueCommand(Command):
“””
容器命令-同步执行
“””

def __init__(self, cmds=None):
Command.__init__(self)
self.m_commands = [] if cmds is None else cmds
self.m_executingCommands = []
self.m_executedCommands = []

def execute(self):
if self.m_executingCommands:
return
for cmd in self.m_commands:
cmd.setExecutedCallback(
k=self.getCommandUUID(), func=self.executedOneCommand)
self.m_executingCommands.append(cmd)
cmd.execute()

def executedOneCommand(self, cmd):
self.m_executedCommands.append(cmd)
if cmd in self.m_executingCommands:
self.m_executingCommands.remove(cmd)
if not self.m_executingCommands:
self.executedAllCommand()

def executedAllCommand(self):
self.executedCallback()

def undo(self):
pass

# —————- test —————-

class MoveByCommand(Command):
def __init__(self, pWalker, x, y):
Command.__init__(self)
self.m_Walker = pWalker
self.m_X = x
self.m_Y = y

def execute(self):
print(“[%s] MoveBy (%s, %s)” % (self.m_Walker, self.m_X, self.m_Y))
self.m_Walker.moveBy(self.m_X, self.m_Y)
Command.execute(self)

class JumpByCommand(Command):
def __init__(self, pWalker, y):
Command.__init__(self)
self.m_Walker = pWalker
self.m_Y = y

def execute(self):
print(“[%s] JumpBy (%s)” % (self.m_Walker, self.m_Y))
self.m_Walker.jumpBy(self.m_Y)
Command.execute(self)

class ScaleByCommand(Command):
def __init__(self, pWalker, fScaleX, fScaleY):
Command.__init__(self)
self.m_Walker = pWalker
self.m_ScaleX = fScaleX
self.m_ScaleY = fScaleY

def execute(self):
print(“[%s] ScaleBy (%s, %s)” %
(self.m_Walker, self.m_ScaleX, self.m_ScaleY))
self.m_Walker.scaleBy(self.m_ScaleX, self.m_ScaleY)
Command.execute(self)

class Walker:
def __init__(self, sName):
self.m_Name = sName

self.m_X = 0
self.m_Y = 0
self.m_ScaleX = 1.0
self.m_ScaleY = 1.0

def __repr__(self):
return self.m_Name

def moveBy(self, x, y):
self.m_X += x
self.m_Y += y

def jumpBy(self, y):
self.m_Y += y

def scaleBy(self, fScaleX, fScaleY):
self.m_ScaleX += fScaleX
self.m_ScaleY += fScaleY

if __name__ == ‘__main__’:
pWalker = Walker(“jack”)
print(“start:”, pWalker.m_X, pWalker.m_Y, pWalker.m_ScaleX, pWalker.m_ScaleY)

moveByCommand = MoveByCommand(pWalker, 10, 20)
jumpByCommand = JumpByCommand(pWalker, 3)
scaleByCommand = ScaleByCommand(pWalker, 0.5, -0.5)
parallelQueueCommand = ParallelQueueCommand([moveByCommand, jumpByCommand])

sequenceQueueCommand = SequenceQueueCommand([parallelQueueCommand, scaleByCommand])
sequenceQueueCommand.execute()

print(“end:”, pWalker.m_X, pWalker.m_Y, pWalker.m_ScaleX, pWalker.m_ScaleY)

# 输出:
#(‘start:’, 0, 0, 1.0, 1.0)
#[jack] MoveBy (10, 20)
#[jack] ScaleBy (0.5, -0.5)
#[jack] JumpBy (3)
#(‘end:’, 10, 23, 1.5, 0.5)

 

服务端统一时间戳 boost::date_time UTC

多服务器在多时区部署时, 需要按utc时间统一计算。

可以使用boost::date_time

#include <boost/date_time.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
using namespace boost::gregorian;
using namespace boost::posix_time;

int main(int, char *[])
{
ptime ct2(second_clock::universal_time()); //输出的就是UTC时间。 如果是使用second_clock::local_time()构造, 得到的就是localtime
cout << to_simple_string(ct2) << endl;

return 0;
}

无需其他库、或者自己写的程序, 太易出错了

继承父类方法时,父类方法的参数怎么传?

继承父类方法时,父类方法的参数怎么传?

考虑到父类方法传参的两种可能,一是用默认参数,二是用位置参数;

用默认参数的时候,子类确实可以直接调用不传参的父类方法,起码不会报错,但是父类方法的传参固定了,返回值也就固定了,不可取;

用位置参数的时候,子类调用的父类方法必须传参,否则会报错,但是定义子类方法,调用父类方法时直接传参,也会导致父类方法的传参固定,不可取;

*后发现,可以在定义方法时传入所有要用的参数,然后在继承父类方法时传入就好,如下:

感觉super().func()的使用很像内嵌函数的使用,将外部函数的局部变量,用到内嵌函数的局部作用域中,这是可以的

class A:
def call(self):
print(‘call’)
class B(A):
def record(self):
print(‘record’)
def call(self,record=False):
if record:
self.record()
super().call()
B().call(True)

class C(B):
def facetime(self):
print(‘facetime’)
def call(self,facetime=True,record=1):
if facetime:
self.facetime()
super().call(record=record)
C().call()

时间戳引起的网站访问不了的问题

针对有些用户能ping通我们的网站,但是连接时超时服务器没有任何响应,怀疑问题处在了了http的三次握手环节,这是决定通过抓包进行分析:

1、有问题机器的截图:

2、正常机器的截图:

3、发现问题

从抓包数据发现,web服务器对出问题机器和正常机器系统的tcp syn包都返回ACK包,但存在问题发出的tcp syn包有时候响应,有时候不响应。不响应时,终端与web服务器之间的tcp连接无法正常建立,导致页面不能打开。对比这两种数据包,就在时间戳上有差异,存在问题的机器发出的tcp syn包带有时间戳,因此怀疑时间戳问题导致的故障。

4、解决问题

既然怀疑是时间戳导致的,那我们就着手分析如果将出现问题的机器的时间戳去掉会不会解决问题。针对带有时间戳的tcp syn包不响应的问题,查阅了相关资料得知产生问题的原因是出问题系统中的注册表中有Tcp1323opts这个选项,会导致其在发包时加入时间戳,经过nat之后,如果前面相同的端口被使用过,且时间戳大于这个链接发出的syn中的时间戳,服务器上就会忽略掉这个syn,不返会syn-ack消息,表现为用户无法正常完成tcp3次握手,从而不能打开web页面。在业务闲时,如果用户nat的端口没有被使用过时,就可以正常打开;业务忙时,nat端口重复使用的频率高,很难分到没有被使用的端口,从而产生这种问题。

目前看有两种方法解决:

(1)    是在服务器上修改变量

首先我们先查看一下我们服务器net.ipv4.tcp_timestamps的默认值,如果该值为0测说名不是该问题导致,如果是1我们需要将该值设置为1。

查看默认值的方法:[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_timestamps

修改该值的方法:vim /etc/sysctl.conf  添加 net.ipv4.tcp_timestamps=0

(2)修改客户端的注册表Tcp1323Opts设置为0。

 

备注:

Tcp1323Opts

说明:该参数控制 RFC 1323 时间戳与窗口缩放选项。默认情况下,启用时间戳与

窗口缩放,但是可以使用标志位进行控制。0 位控制窗口缩放,1 位控制时间戳。

值为0(禁用 RFC 1323 选项)

值为1(仅启用窗口缩放)

值为2(仅启用时间戳)

值为3(两个选项均启用)

 

net.ipv4.tcp_timestamps=0

说明:时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

值为0(禁用时间戳)

值为1(启用时间戳)

 

只有客户端和服务端都开启时间戳的情况下,才会出现能ping通不能建立tcp三次握手的情况,所以做为提供服务的公司,不可能保证所有的用户都关闭时间戳,这个功能,所以我们必须关闭时间戳,这样才能给所用用户提供正常的服务。

使用该命令使其立马生效:/sbin/sysctl-p

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