python简单实现计算过期时间的方法

2024-08-30

python简单实现计算过期时间的方法(通用9篇)

篇1:python简单实现计算过期时间的方法

作者:chongq 字体:[增加 减小] 类型:

这里使用Python实现一个简单的状态框架,代码需要在python3.2环境下运行

代码如下:

from time import sleep

from random import randint, shuffle

class StateMachine(object):

‘‘‘ Usage:Create an instance of StateMachine, use set_starting_state(state) to give it an

initial state to work with, then call tick on each second (or whatever your desired

time interval might be. ‘‘‘

def set_starting_state(self, state):

‘‘‘ The entry state for the state machine. ‘‘‘

state.enter()

self.state = state

def tick(self):

‘‘‘ Calls the current state‘s do_work() and checks for a transition ‘‘‘

next_state = self.state.check_transitions()

if next_state is None:

# Stick with this state

self.state.do_work()

else:

# Next state found, transition to it

self.state.exit()

next_state.enter()

self.state = next_state

class BaseState(object):

‘‘‘ Usage: Subclass BaseState and override the enter(), do_work(), and exit() methods.

enter()-- Setup for your state should occur here.This likely includes adding

transitions or initializing member variables.

do_work()-- Meat and potatoes of your state.There may be some logic here that will

cause a transition to trigger.

exit()-- Any cleanup or final actions should occur here.This is called just

before transition to the next state.

‘‘‘

def add_transition(self, condition, next_state):

‘‘‘ Adds a new transition to the state.The “condition” param must contain a callable

object.When the “condition” evaluates to True, the “next_state” param is set as

the active state. ‘‘‘

# Enforce transition validity

assert(callable(condition))

assert(hasattr(next_state, “enter”))

assert(callable(next_state.enter))

assert(hasattr(next_state, “do_work”))

assert(callable(next_state.do_work))

assert(hasattr(next_state, “exit”))

assert(callable(next_state.exit))

# Add transition

if not hasattr(self, “transitions”):

self.transitions = []

self.transitions.append((condition, next_state))

def check_transitions(self):

‘‘‘ Returns the first State thats condition evaluates true (condition order is randomized) ‘‘‘

if hasattr(self, “transitions”):

shuffle(self.transitions)

for transition in self.transitions:

condition, state = transition

if condition():

return state

def enter(self):

pass

def do_work(self):

pass

def exit(self):

pass

##################################################################################################

############################### EXAMPLE USAGE OF STATE MACHINE ###################################

##################################################################################################

class WalkingState(BaseState):

def enter(self):

print(“WalkingState: enter()”)

def condition(): return randint(1, 5) == 5

self.add_transition(condition, JoggingState())

self.add_transition(condition, RunningState())

def do_work(self):

print(“Walking...”)

def exit(self):

print(“WalkingState: exit()”)

class JoggingState(BaseState):

def enter(self):

print(“JoggingState: enter()”)

self.stamina = randint(5, 15)

def condition(): return self.stamina <= 0

self.add_transition(condition, WalkingState())

def do_work(self):

self.stamina -= 1

print(“Jogging ({0})...”.format(self.stamina))

def exit(self):

print(“JoggingState: exit()”)

class RunningState(BaseState):

def enter(self):

print(“RunningState: enter()”)

self.stamina = randint(5, 15)

def walk_condition(): return self.stamina <= 0

self.add_transition(walk_condition, WalkingState())

def trip_condition(): return randint(1, 10) == 10

self.add_transition(trip_condition, TrippingState())

def do_work(self):

self.stamina -= 2

print(“Running ({0})...”.format(self.stamina))

def exit(self):

print(“RunningState: exit()”)

class TrippingState(BaseState):

def enter(self):

print(“TrippingState: enter()”)

self.tripped = False

def condition(): return self.tripped

self.add_transition(condition, WalkingState())

def do_work(self):

print(“Tripped!”)

self.tripped = True

def exit(self):

print(“TrippingState: exit()”)

if __name__ == “__main__”:

state = WalkingState()

state_machine = StateMachine()

state_machine.set_starting_state(state)

while True:

state_machine.tick()

sleep(1)

希望本文所述对大家的Python程序设计有所帮助,

篇2:python简单实现计算过期时间的方法

本文实例讲述了Python实现简单拆分PDF文件的方法,分享给大家供大家参考。具体如下:

依赖pyPdf处理PDF文件

切分pdf文件

使用方法:

1)将要切分的文件放在input_dir目录下

2)在configure.txt文件中设置要切分的份数(如要切分4份,则设置part_num=4)

3)执行程序

4)切分后的文件保存在output_dir目录下

5)运行日志写在pp_log.txt中

P.S. 本程序可以批量切割多个pdf文件

from pyPdf import PdfFileWriter, PdfFileReaderimport osimport timeimport sysdef part_pdf(input_file, output_file, config_count, f_w, now, file_name): file1 = file(input_file, ‘rb‘) pdf = PdfFileReader(file1) pdf_pages_len = len(pdf.pages) if config_count <= pdf_pages_len: ye = pdf_pages_len / config_count lst_ye = pdf_pages_len % config_count part_count = 0 part_count_ye = 0 for fen in range(config_count):part_count += 1if part_count == config_count: part_ye = ye + lst_yeelse: part_ye = yewrite_pdf(pdf, part_count_ye, part_count_ye+part_ye, fen, output_file)part_count_ye += ye else: f_w.writelines(‘time: ‘+now+‘ file name: ‘+file_name+‘ status: part_num > pdf pages [error]n‘) sys.exit(1)def write_pdf(pdf, part_count_ye, part_count_ye_end, fen, output_file): ut = PdfFileWriter for pp in range(part_count_ye, part_count_ye_end): out.addPage(pdf.getPage(pp)) us = file(output_file+‘_‘+str(fen+1)+‘.pdf‘, ‘wb‘) out.write(ous) ous.close()def pdf_main(): f = open(‘configure.txt‘, ‘r‘) f_w = open(‘pp_log.txt‘, ‘a‘) now = time.strftime(‘%Y-%m-%d %H:%M:%S‘) for i in f: i_ = i.strip() aa = i_.split(‘=‘)[1] if i_.find(‘part_num=‘) != -1 and aa.isdigit():config_count = int(aa) else:f_w.writelines(‘time: ‘+now+‘ status: part_num in configure.txt is error [error]n‘)sys.exit(1) files = os.listdir(‘input_dir/‘) for each in files: input_file = ‘input_dir/‘+each file_name = input_file[input_file.index(‘/‘):input_file.index(‘.‘)] output_file = ‘output_dir/‘+file_name part_pdf(input_file, output_file, config_count, f_w, now, file_name) f_w.writelines(‘time: ‘+now+‘ file name: ‘+file_name+‘ status: successn‘)pdf_main()

篇3:python简单实现计算过期时间的方法

在现代计算机应用的发展过程中,C语言[1]无疑扮演了一个很重要的角色。作为一种通用的、过程式的编程语言,C语言广泛用于应用软件与系统的开发。具有高效、灵活、功能丰富、表达力强和较高的可移植性等特点,在程序员中备受青睐,是使用最广泛的编程语言。

现有的C程序代码或者算法,对于其代码分析多是在开发环境下进行的,同时对于其的编译分析多用于检测C程序代码编码过程的正确性以保证其可正常执行,而对于其代码的时间效率优良度没有一个便捷、直接的判定方法,且在对相似功能程序的代码分析与比较过程中,更多的是靠人力去分析、计算。例如对于嵌入式C代码的检测,大多通过运行评测[2],没有一个可以实时对嵌入式代码进行效率评测的方式方法。从而在实际运行之前,没有对代码质量和效率进行充分测试,对于代码的优良性无法得到保证且造成极大人力浪费。

理论上,对于每一个C程序函数,它的效率可以从运行时间、空间来判定。一段程序或算法的优劣也主要从时间复杂度和空间复杂度来考虑。而随着计算机硬件的发展,特别是储存结构和CPU运算结构的发展,空间复杂度的影响已经越来越小。人们更加直观地从一个程序或者项目运行时间的长短去判定程序的优劣。同时,相关组织也制定了一系列的编码准则来进行规范和约束,例如ANSI-C标准以及嵌入式编码常用的MI-SRA-C。一段C代码的优劣性也可以从其是否符合规范的角度进行定性分析。

本文对C程序代码文件进行扫描编译,输出程序中函数调用关系、循环控制关系等信息,完成对指定函数在常见级别范围内时间复杂度的自动计算方法模型的构建和实现,并根据计算结果进行函数优良性的比较判定,同时在MISRA-C标准下对C代码函数循环控制体部分进行相关判定,进而实现对其代码时间复杂度分析,为代码的实时高效分析、评价、选取提供有效支持。

1 基本概念

1.1 时间复杂度简述

一段程序或算法中的语句执行次数称为语句频度或时间频度,记为T(n)。n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。程序执行所耗费的时间,理论上是不能算出来的,必须实际运行测试才能得出,但不可能也没有必要对每段代码都运行测试。一般情况下,程序中基本操作重复执行的次数,是问题规模n的某个函数,即T(n)。若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为非零常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))为程序的渐进时间复杂度[3]。通常意义下的时间复杂度均指渐进时间复杂度。

常见的时间复杂度,按数量级递增排列依次为:P类问题范围内的常数阶O(1)、对数阶O(logn)、线性阶O(n)、线性对数阶O(n×logn)、平方阶O(n2)、立方阶O(n3)、k次方阶O(nk)和NP类问题范围内的指数阶O(2n)、阶乘阶O(n!)。计算机科学家普遍认为P类多项式问题,即有效算法,而把NP问题判定为非多项式问题,即非有效算法。本文中的扫描分析程序对于NP问题只进行扫描,不进行分析。

1.2 常见时间复杂度代码形态

不同数量级的时间复杂度是通过不同的循环控制体产生的,首先需要对常见数量级的函数复杂度[4]在C程序中可能的出现形式进行分析说明。

C程序函数中的循环控制体分别通过for/while/do-while进行编码,其出现形式分类如图1所示。

1)常数阶O(1)

基本语句的执行频度是一个常数,一般来说,只要C函数中不存在循环控制或循环控制的循环变量与不定项n无关,如上图中(1),无论循环次数再大,依旧为常数定项,基本语句执行频度为常数,其复杂度均为O(1)。

2)线性阶O(n)

基本语句的最大执行频度为不定项n,在C函数中主要体现在for/while/do-while的循环控制语句中。如图1中(2)出现的三种循环控制体,其循环条件变化上限均为不定项n级别,在单步变化为1或常数项时,便称其复杂度为O(n)。

3)平方阶O(n2)、立方阶O(n3)、k次方阶O(nk)

三者均可统称为k次方阶(k≥2,k∈N+),在C函数中,高次方阶的出现是由不同循环控制体之间的嵌套产生的。如图1中分支(3)所示为两层for循环的嵌套,其各自均符合O(n)的复杂度,嵌套后相乘即为复杂度O(n2)。同理,对于while和dowhile循环嵌套关系也是一样。进而对于更高次方阶,便是通过更多的循环控制体嵌套产生。

4)对数阶O(logn)

对于对数阶的复杂度,在C函数中的体现主要集中在对于循环控制条件中循环变量的非线性操作,所以对于对数阶的判定主要体现在对于函数体中循环变量改变方式的判定,如图1中分支(4)所示,于循环变量i,程序中循环体内进行了乘2的变化,又因其上限为n,则x=log2n。所以,循环复杂度即为O(log2n),这种变化致使程序中对数阶复杂度的出现。当然,对数阶的底数不一定是2,如i=i×k,则底数为k。由此便可推广到O(logn)。

5)线性对数阶O(n×logn)

对于线性对数阶,在C函数中的体现即为循环控制嵌套时,不同层次分别采用了线性阶和对数阶,那么内层基本语句的频度很有可能成为二者相乘形式,即为线性对数阶,线性阶和对数阶上面已经进行介绍,不再赘述。

特别说明,对于指数阶O(2n),如求n个元素的集合的所有子集;阶乘阶O(n!),如求n个元素的全排列问题,均属于NP类级别复杂度,实际应用中复杂度过高,时间效率太低,本文不做讨论。

以上分别对各种常见复杂度在C函数体中的可能出现形式进行说明,以便根据其代码特点对自动计算过程进行设计实现。

1.3 MISRA-C编码准则

MISRA-C作为工业标准的C编程规范,其对于C代码运行安全的保证性是毋庸置疑的,本文在时间复杂度自动计算的基础上,对于代码内部循环控制相关部分进行了MISRA-C的标准检查,涉及的准则如下:

规则1 for语句的控制表达式不能包含任何浮点类型的对象:控制表达式可能会包含一个循环计数器,检测其值以决定循环的终止。浮点变量不能用于此目的。舍入误差和截取误差会通过循环的迭代过程传播,导致循环变量的显著误差。

规则2 for循环中用于迭代计数的数值变量不应在循环体中修改。

规则3组成循环结构体的语句应该是复合语句:即每一个循环控制体内部语句必须在大括号内部,即使该复合语句只包含一条语句。

以上准则为MISRA-C内部涉及循环控制部分的准则,依次对应MISRA-C标准的规则13.4、规则13.6、规则14.8。

2 自动计算方法的模型设计

2.1 复杂度计算的理论前提

通过对几种常见级别时间复杂度的分析发现,要实现对C函数复杂度的计算和相关规则判定,首先要完成对函数的以下关键信息的判定:

1)函数之间调用关系的判定

在C语言函数中,是否存在函数调用对函数复杂度的影响是显而易见的,如果被调用函数复杂度高于所分析函数,则所分析函数的复杂度则很大程度上取决于被调用函数,所以需要扫描分析目标函数内部各调用函数及其调用关系。

2)循环控制体[5]信息判定

主要是for/while/do-while循环控制结构的确定以及不同循环控制体之间嵌套或平等关系的判定。

鉴于在C函数中,n级别及以上的语句执行频度基本是通过循环控制产生,因此对于C函数中循环控制块以及其控制变量操作以及不同控制块之间关系的判定也是必不可少的,同时对于控制体进行1.3节的规则判定也需要首先完成对基本信息的确定。

2.2 编译模块简介

使用Windows环境下集成lex[6]和yacc[6]功能的分析程序生成器parser generator[7]。要实现对于现有C程序函数的分析,必须在底层对其进行良好的编译支持。因此,则需用到lex和yacc。而现在大多数的开发者选用Windows平台,考虑到广泛适用性,需要用到在Windows环境下对两者集成性优良的parser generator平台。

parser generator是一个指定某种语法格式的编程语言作为它的输入,并为该种语言产生分析过程以作为它的输出的程序。平台会根据词法和语法文件生成对应C的专用编译器[8],在此基础上根据自主需要编写输入、输出函数即可。

2.3 自动计算框架设计

C函数时间复杂度自动计算方法的基本思路是:通过parser generator平台对于C程序一系列输入文件的自定义编译,得到程序中函数调用关系[9],从而产生所分析函数的调用有向图。然后,从图中原子函数入手,进行函数内部各循环控制体循环次数以及嵌套关系的计算判定[5],计算得出各循环体的复杂度。可以得到循环体内各基本语句的执行频度,经过嵌套关系的相乘操作和平等关系的比较操作得到原子函数的复杂度。在此基础上,通过函数调用图的调用关系回溯分析上级函数,逐级回溯到所分析函数,得出复杂度结论。自动计算框架如图2所示。

3 自动计算方法的实现

3.1 符号说明

为了更直观、方便地对时间复杂度的自动计算方法及其过程进行说明,特做以下声明和定义。

1)vn:表示C函数vn,n∈N+;

2)cm:表示C函数体内某一for/while/do-while循环控制块cm,m∈N+;

3)L:表示C函数中的基本执行语句;

4)O(vn):表示C函数vn的时间复杂度;

5)O(cm):表示循环控制块cm的时间复杂度;

6)Fre(L):表示基本语句L的执行频度;

7)vn*:表示C函数vn内部中排除被调用函数后的函数体部分。

3.2 算法实现

C函数的时间复杂度计算主要包括以下5个步骤,如图3所示。

1)程序编译预处理

首先,提取C函数中函数调用关系、函数定义范围等关键信息,该部分是通过对程序的自定义编译实现的。将所分析的C程序文件(.c/.h文件)以文件流模式输入底层编译模块,编译模块以正则匹配的词法分析和上下文无关文法的自定义C语法分析为编译依据,经过编译的自定义输出后,得到程序内部函数调用关系、各函数定义起止位置等信息并进行存储。

2)生成函数调用图

选定一个具体的目标函数v开始对其复杂度进行计算。对于目标函数v,根据上一步的整体调用关系,生成以该函数为起始点的调用有向图[10]G=(V,{A})存入邻接链表,其中,V为函数名集合,起点v1为所选定的函数v;{A}为调用关系集合,若〈vm,vn〉∈A,即表示函数vm定义中调用了函数vn(m,n∈N+,且m≠n)。在接下来的自动化计算中,可以根据此有向图查询和分析相关函数之间的调用关系。

3)原子函数复杂度分析

该步骤是自动计算方法实现中的关键。在调用有向图G中出度为0的顶点函数即为原子函数,表示此函数的定义中没有调用任何其他函数。而在C函数的时间复杂度计算过程中,很多情况下,其复杂度都是和被调用函数息息相关的。所以,在自动计算的过程中,先计算无函数调用的原子函数就显得尤为重要,通过对原子函数的计算,可以统一定义和实现C函数中无调用函数部分函数体的自动计算,从而实现计算的统一化和算法的高效化。对于函数v1,设其调用有向图中共有t个原子函数vu,vu+1,…,vu+t-1(u∈N+),对单个原子函数时间复杂度的具体分析计算如下:

(1)C函数体内循环控制体的确定。在C函数中,n阶及以上的语句执行频度是通过for/while/do-while循环体产生的,计算时,通过调用底层自定义的定向编译方法函数中的语法分析进行循环控制的分析扫描,输出并存储v1中循环控制体的位置信息及其对应循环变量的相关信息,然后通过对循环变量类型匹配和在循环体中的匹配完成对1.3节中规则1和规则2的判定,通过循环体位置信息和对于“{}”的匹配完成对于规则3的判定;

(2)循环控制体之间关系的确定。在常见复杂度的分析中可以看到,不同阶时间复杂度之间的相乘关系和k次方阶都是通过循环控制之间的嵌套关系产生,循环控制体之间的关系和程序内不同函数的调用关系分析类似,所以依旧调用底层编译进行定向分析即可,得到不同循环控制体之间的平等或者嵌套关系;

(3)循环控制体复杂度阶数的确定。循环体的循环次数的不同就体现在通过对于循环变量的操作而造成的执行频度的不同,所以需要监控各循环体内循环变量的变化情况并结合循环体嵌套关系得到其执行频度。结合已经讨论过的常见复杂度,得出下计算准则:

(1)若循环体cm中循环变量的改变次数上限是常数项或可表示为常数项的,则O(cm)=O(1);

(2)若cm中循环变量循环改变次数的上限为不定输入规模,记为不定项n,且变量单步变化为线性变化,则O(cm)=O(n);

(3)若cm中循环变量的上限为不定输入规模,记为不定项n,且变量单步变化为乘2,则O(cm)=O(log2n)。

在完成对循环变量的判定后,进行循环体嵌套关系的处理,处理过程和函数复杂度分析一致,从最内层循环开始向外层处理。即若循环体cm和cp之间为嵌套关系,且cm为外层循环,则利用式(1)进行O(cm)的赋值更新,以便后期确定语句执行频度时使用,同时舍去O(cp)。

若循环体之间是平等关系,则不进行相乘,保留互为平等关系循环体之间的最大复杂度即可,其余舍去;

(4)基本语句L执行频度的确定。C函数的复杂度归根结底是通过语句执行频度体现出来的。所以,在确定各循环体复杂度后,完成对循环体内最大语句频度的赋值计算,若基本语句L位于cm内部最内部,则Fre(L)=O(cm);

(5)复杂度判定。若原子函数vu中w个基本语句L,分别记为L1,L2,…,Lw(w∈N+)。以上四步得到了其各自的执行频度。则原子函数复杂度计算公式为:

同样的,可以得到其他原子函数的复杂度。

4)整体回溯分析

完成对原子函数的计算之后,进行回溯计算[12],根据函数调用图沿着原子函数的调用路线进行回溯计算,路线上每个函数v,分析计算时,v*部分的分析递归调用第3)步的计算方式,遇到被调用函数时,将其按照循环体对待处理,同时因为是回溯思想,所以其复杂度已被判定,直接代入即可。一直回溯至所分析函数v1,即可得到其复杂度。算法终止。

3.3 算法补充说明

需要说明的是,计算过程专注于对于多项式可计算范畴的常见复杂度度量,本文对于NP类级别的时间复杂度只进行了说明,而没有进行编译分析。同时为了计算简便,对于程序中可能出现的系统函数调用、函数自身递归调用以及成环调用,若在语法编译过程中出现,进行提示即可,不做进一步分析计算。

4 实验验证及数据分析

4.1 实验设计原理

C函数时间复杂度自动计算主要意义在于对于未知复杂度C函数进行复杂度计算,进而通过复杂度对不同C程序进行时间效率判定及比较。所以,一方面,我们需要设计实验对于其时间复杂度的计算能力和准确度进行验证;另一方面,我们需要设计实验对不同的可比程序组进行复杂度判定比较并通过实际运行效果来证明判定的实用性,从而充分说明本文实现的自动计算方法的可行性及实用性。

4.2 复杂度计算可行性实验

C程序函数时间复杂度的计算能力和准确性是本文所需实现的主要功能,对其的验证需要选取通用且具有代表性的代码数据[11]进行计算分析。考虑到大多数C程序的运行和编辑环境,本文选取具有代表意义的常见算法,通过对其复杂度的计算来进行准确性验证;同时选取标准Linux内核代码(版本号:2.6.27.28)进行复杂度的计算能力验证[13]。

首先,选取一系列典型的经典算法C语言实现形式进行分析计算,来对于本文提出的自动计算方法的准确性进行验证。

1)直接插入排序算法的分析验证

理论上可以计算得出,在输入规模为n的前提下,最坏情况算法时间复杂度为O(n2)。下面,将算法C文件输入编译模块,用本文提出的计算方法进行计算:

(1)编译可得文件含主函数main()、输入函数scanf()、输出函数printf()和插入函数insert Sort(),输入输出函数为系统函数不进行分析。即分析的调用关系为main调用insert Sort。其中后者为原子函数。

(2)分析main函数时间复杂度。从原子函数insert Sort入手分析。

(3)扫描得insert Sort内部共有两个循环控制,记为c1和c2,且其循环变量均为线性变化,则O(c1)=O(n)=O(c2)。c1和c2之间为嵌套关系,c1为外层循环,则利用式(1)更新O(c1)=O(c1)×O(c2)=O(n2)。则循环体c1最内层基本语句L1的执行频度Fre(L1)=O(n2)。又因该原子函数内部只有c1和c2,且其嵌套,所以O(insert Sort)=O(n2)。

(4)回溯分析,即回溯到main函数进行分析。扫描其得三个循环控制,记为c3、c4和c5。对其用(3)思想进行分析。c3循环变量上限为人为常数,即O(c3)=O(1),O(c4)=O(n)=O(c5)。将已分析的调用函数复杂度带入,其与c4和c5地位平等,则三者取最大值为O(n2)。又因c3为最外层循环,所以利用式(1)更新O(c3)=O(1)×O(n2)=O(n2)。同理,便可得O(main)=O(n2),分析完毕,算法终止。

可得本文算法思想计算所得结果与理论结果一致。

2)堆排序算法的分析验证

众所周知,对于堆排序算法,主要是建堆函数Heap Adjust()和排序函数Heap_sort(),其余均是常数阶函数或对其的调用。堆排序算法理论时间复杂度为O(n×log2n),这里运用本文自动计算思想进行计算验证。

(1)编译可得基本函数调用关系如下:

(2)从原子函数Heap Adjust入手分析。

(3)扫描得Heap Adjust函数内部有一个循环控制c3,其循环变量改变方式为乘2,上限不定项m,所以O(c3)=O(log2n),因为就这一个循环控制,所以内部基本语句的执行频度Fre(L)=O(log2n)。推知,O(Heap Adjust)=O(log2n)。

(4)回溯分析,即回溯到Heap_sort函数进行分析。扫描其得三个循环控制c1和c2。对其用(3)思想进行分析,可得O(c1)=O(n)=O(c2)。二者为平等关系,且相当,均保留。又因内部有被调用函数Heap Adjust,当作循环控制处理,其与c1和c2均为嵌套关系,且c1和c2为外层循环,则更新c1和c2为O(c1)=O(n)×O(log2n)=O(c2)=O(n×log2n)。同理,推知可得O(Heap_sort)=O(n×log2n)),分析完毕,算法终止。

可得本文算法思想计算所得结果与理论结果一致。

经过以上两种典型经典算法的分析可以看出,本文提出的时间复杂度自动计算方法对于常见数量级的时间复杂度可以进行良好的准确识别。

准确性得到保证的基础上,本文继续对其计算能力进行测试验证,选取的Linux内核代码数据标本参数如表1所示。

依次进行各标本数据的分析,将路径下各C文件输入编译模块进行计算,完成对每个路径下各文件中C函数及其之间关系的扫描判定、对于1.3节规则的扫描判定以及对于各C函数复杂度的计算判定,并进行相关信息的输出统计。经计算,4个标本内涉及函数上万个,本文分析了整体所有函数,此处列出典型的函数计算结果如表2所示。

根据表2可以很清晰地看到,本文所提出的自动计算方法可以对标准C函数进行相关分析,对于其复杂度的判定计算可顺利进行并得出相应输出,操作人员可以根据自主需求完成对相应具体C函数的分析计算,对C函数时间复杂度加以判定。

表2中的复杂度为自动计算结果,作者使用代码走读方式[14],确认了自动计算结果的正确性。通过以上实验,证明本文提出的时间复杂度自动计算方法是可行的。

4.3 复杂度计算实用性实验

在完成复杂度计算可行性的验证之后,更进一步,需要证明计算方法的实用性。因为需要对代码进行分析,为了保证实验数据的可参考性和可计算性,本文选取了三款开源视频格式转换软件Miro Video Converter、Hand Break和StaxRips,获取其源代码,经过4.2节的计算分析,获取其复杂度不为O(1)的函数并进行统计,得到以下输出数据,如表3所示。

从表3中,可以直观看出,StaxRips中存在复杂度为O(n3)的处理函数且其复杂度为非常数级别的函数数量大于其余二者,所以整体时间复杂度要高于Miro Video Converter和HandBreak,理论上得出在同等硬件环境下,StaxRips处理速度最慢。同理,Hand Break的处理速度快于Miro Video Converter。

以上为理论分析结果,下面我们通过实际运行不同软件来进行性能测试(这里选取的被处理视频对象相同),得到结果如图4所示,其中横坐标表示视频处理对象大小,单位为M,纵坐标为视频处理时间,单位为秒。

可以看出,同等条件下,Handbreak的处理时间要依次快于Miro Video Converter和StaxRips,即实际运行所的结果与理论分析一致。

由此可以证明本文所提出计算方法有一定的实用性,可以帮助开发或测试人员对相似功能C程序进行时间效率评测。

5 结语

本文对C语言函数的时间复杂度计算问题进行了详细讨论,提出了对C函数时间复杂度自动计算的方法并加以实现。同时对本文提出的计算方法进行了可行性和实用性的实验验证,得出以下结论:

1)大多数C语言函数运行的时间效率高低和其程序时间复杂度的繁简程度有很大负相关性。

2)本文给出了计算常见复杂度阶数下,C函数时间复杂度的计算方法和实现方式,所得计算值与实验值良好吻合,可供工程设计参考。

3)运用本文所给方法进行不同C程序之间函数时间复杂度的比较计算是可行的,比较的理论结果与实际运行后得到的比较数据相符,具有实际参考价值[15]。

综上所述,可以得出结论:C程序效率的优良性与时间复杂度的相关性很高。时间复杂度越低,其C程序实际运行效率越高。且不同程序之间的时间效率差异主要跟程序的时间复杂度相关。通过本文提出并实现的计算方法可以进行良好判定。

本文完成了对于C函数代码时间复杂度的自动计算,并在此基础上,利用MISRA-C中少许规则进行了对于C函数语义分析的初步研究。结合实际应用价值,接下来的研究将偏重于语义分析方面,完成对于MISRA-C标准全面的规则验证功能,从而增强研究应用的实用性,进而与嵌入式实时系统相结合,更加有效地为工业生产服务。

摘要:现有的C语言编译或代码分析软件大多集中于检测C程序代码编码过程的正确性,而对于其代码的时间效率高低无法判定。针对这种情况,通过对标准C语言程序代码语法形式的分析,提出对于C语言函数时间复杂度自动计算的算法原型并加以实现和验证。实验结果表明,C程序代码时间效率的高低很大程度上取决于程序内部函数的时间复杂度。程序中函数整体时间复杂度越高,运行时间效率越低。相比于传统意义上的C代码分析方法,时间复杂度自动计算方法更侧重于对C代码的时间复杂度进行分析和计算,从而可以更快速、准确地对C程序代码时间效率进行判定。

篇4:python简单实现计算过期时间的方法

分享给大家供大家参考。具体如下:

主要核心代码如下:

sUrl = ‘www.163.com‘sock = urllib2.urlopen(sUrl) sock.headers.values()

篇5:python简单实现计算过期时间的方法

这篇文章主要介绍了Python实现监控程序执行时间并将其写入日志的方法,实例分析了Python日志操作的相关技巧,需要的朋友可以参考下

本文实例讲述了Python实现监控程序执行时间并将其写入日志的方法,分享给大家供大家参考。具体实现方法如下:

# /usr/bin/python# -*- coding:utf-8 -*-from time import timedef logged(when): def log(f,*args,**kargs): print ‘‘‘ called: functions:%s args: %r kargs: %r ‘‘‘ % (f,args,kargs) def pre_logged(f): def wrapper(*args,**kargs):log(f,*args,**kargs)return f(*args,**kargs) return wrapper def post_logged(f): def wrapper(*args,**kargs):now = timetry: return f(*args,**kargs)finally: log(f,*args,**kargs) print “time delta:%s” % (time()-now) return wrapper try: return {“pre”:pre_logged,“post”:post_logged}[when] except KeyError,e: raise ValueError(e),‘must be “pre” or “post”‘@logged(“post”)def hello(name): print “hello,”,namehello(“world!”)‘‘‘等同于: hello = logged(“post”)(hello(“world!”))‘‘‘

篇6:python简单实现计算过期时间的方法

此函数通过python实现了一个简单的计时器动能:

‘‘‘ Simple Timing Function.This function prints out a message with the elapsed time from theprevious call. It works with most Python 2.x platforms. The functionuses a simple trick to store a persistent variable (clock) withoutusing a global variable.‘‘‘import timedef dur( p=None, clock=[time.time] ): if op != None: duration = time.time() - clock[0] print ‘%s finished. Duration %.6f seconds.‘ % (op, duration) clock[0] = time.time()# Exampleif __name__ == ‘__main__‘: import array dur() # Initialise the timing clock opt1 = array.array(‘H‘) for i in range(1000): for n in range(1000):opt1.append(n) dur(‘Array from append‘) opt2 = array.array(‘H‘) seq = range(1000) for i in range(1000): opt2.extend(seq) dur(‘Array from list extend‘) opt3 = array.array(‘H‘) seq = array.array(‘H‘, range(1000)) for i in range(1000): opt3.extend(seq) dur(‘Array from array extend‘)# Output:# Array from append finished. Duration 0.175320 seconds.# Array from list extend finished. Duration 0.068974 seconds.# Array from array extend finished. Duration 0.001394 seconds.

篇7:python简单实现计算过期时间的方法

采用多个波段观测数据的对比研究方法是研究星系特征的一个有效手段。在星系团的特征研究中, 能够在星系团内证认出星系成员是非常关键的一步。最广泛的一种证认方法是Huchra和Geller的找朋友算法 (Friends of Friends) 。

本文主要描述了统一不同数据库坐标格式的方法、寻找中性氢观测的光学对应体方法和证认星系团成员的方法。第一章介绍Sloan数字巡天计划 (SDSS) 和Arecibo中性氢巡天 (ALFA) 项目, 第二章介绍星系团数据分析方法和Python语言实现, 第三章进行简单的总结。

1 光学巡天与中性氢巡天

由于不同的巡天项目有着不同的观测原理, 从而形成了对同一位置的观测目标不一致现象, 并且观测结果表示形式不一, 因此在采用多波段观测研究星系特征的方法 (如采用光学巡天和中性氢气巡天多波段研究星系特征) 时, 就需要找到中性氢巡天的光学对应体并且将单位表示统一化。

1.1 Sloan数字巡天计划 (SDSS)

Sloan数字巡天第九批释放的数据 (Data Release 9, DR9) [3]实现了14 555平方度的天空覆盖, 含有恒星光谱668054个、星系光谱1457 002个。DR9数据库内包含有许多的表格, 如Photo Obj All、Photoz、Region、Stellar Mass Passive Por和Two Mass等。在DR9数据库内查询表格内的信息需要使用SQL查询语言。查询时需要整理出需要的观测数据, 然后在casjobs内用SQL语言实现表格的交叉查询。星系的位置坐标, 查询结果显示的是以角度为单位, 即赤经和赤纬单位都是角度。

1.2 Arecibo中性氢巡天 (ALFA)

ALFALFA观测数据已经释放了40%的数据库 (a.40) [4]内包含的观测参数包括有星系的位置 (赤经和赤纬) 、中性氢谱线流量密度、观测速度达到峰值的50%的观测值W50和中性氢的观测类型等。其中, 星系的位置坐标表示形式为, 赤经 (hhmmss.s) +赤纬 (ddmmss) 的形式。

2 星系团数据分析方法及Python语言实现

采用整合多波段观测数据的方法来对比研究星系团的特征, 需要统一多波段的观测数据格式和寻找中性氢观测的光学对应体, 之后对星系团成员进行证认。本文主要运用Python语言来实现统一不同数据库的数据格式、寻找光学对应体和证认星系团成员的算法 (F0F) 。Python[2]是一种非常流行的面向对象的高级解释型语言, 其语法非常简洁并且便于人理解, 拥有便捷的文本处理方法和很多强大的数学库、绘图库, 天然支持高精度计算, 所以越来越多的应用在了科学计算中。

2.1 寻找中性氢观测的光学对应体

光学巡天数据库 (DR9) 内星系数据查询结果中, 星系的位置坐标 (赤经和赤纬) 是以角度单位。中性氢巡天数据库 (a.40) 中星系位置坐标表示形式是, 赤经+赤纬, 单位表示为, 时分秒 (hhmmss.s) +度分秒 (ddmmss) 的形式。将星系位置坐标格式统一为以角度为单位的方法, 我们是利用python语言来实现。

ra和dec分别表示星系转换以后的赤经和赤纬。将a.40的位置坐标转换为角度制的方法如下:

统一位置坐标单位以后, 将中性氢巡天数据库 (a.40) 内的星系位置坐标与光学巡天数据库 (DR9) 内的星系位置坐标相减, 满足小于1个角分, 即小于约0.016度的两个星系视为可能为同一个星系。

这个星系在中性氢巡天数据库 (a.40) 和光学巡天数据库 (DR9) 内, 红移的比较满足以下关系的确定为同一个星系。

式中的ZHI、Zoc和z Err分别表示, 中性氢巡天数据库 (a.40) 中的星系红移、光学巡天数据库 (DR9) 中的光学红移和光学巡天数据库 (DR9) 中的光学红移误差。

2.2 找朋友算法 (Friends Of Friends)

本文引用的是Huchra和Geller的找朋友算法 (FOF) [1]来实现证认星系团成员, 这是最常用的一种验证星系成团性的算法。具体的算法流程图如下:

找朋友算法主要是计算星系的3个物理参量 (星系的赤经、赤纬、星系的测光红移) 来寻找星系的成员。

其中, θij表示星系i和星系j之间的角距离, H0表示哈勃常量, 这对星系的平均速度为, vi和vj分别表示星系i和星系j的速度。

星系i和星系j必须满足以下三个条件才能视为属于一个星系群或星系团内:

参数DL和VL主要是根据使用的星系数据库来具体取值。一般将研究中将群的最小成员数Nmin设置为3个。

找朋友算法主要是计算星系的3个物理参量 (星系的赤经、赤纬、星系的测光红移) 来寻找星系的成员。

其中, θij表示星系i和星系j之间的角距离, H0表示哈勃常量, 这对星系的平均速度为, vi和vj分别表示星系i和星系j的速度。

星系i和星系j必须满足以下三个条件才能视为属于一个星系群或星系团内:

参数DL和VL主要是根据使用的星系数据库来具体取值。一般将研究中将群的最小成员数Nmin设置为3个。

用以上方法就可以输出在一个天区内的星系团成员情况表3FOF算法的Python实现通过上述过程, 执行Python程序, 本文从光学巡天数据 (DR9) 和中性氢巡天数据 (a.40) 中获得了星系团的特征数据。通过该数据, 研究者可以做出一系列的星系团特征图, 来分析星系团的结构与环境特征。本文通过这个特征数据的分析, 得到了与黄珊等人[5]做出的a.40星系的特性研究结果一致。

3 总结

由于不同的天文观测项目有不同的观测原理, 所以在不同的数据库内查询的星系数据, 通常需要经过转换坐标单位格式、辨认同一星系、搜集同一星系的多波段数据、整理数据计算物理参量来研究星系特征的过程。研究星系团特征前, 一般需要证认其星系团成员后才能研究其特征。本文介绍的证认方法是找朋友算法 (FOF) 。通过python语言来实现a.40内的光学对应体的找寻过程, 进而整合出星系的光学数据和中性氢的观测数据, 以及实现了找朋友算法。数据的分析结果表明了我们的研究方法是正确可靠的, 为下一步的科学研究打下了良好的数据基础。

摘要:多波段观测数据来整合分析星系团特性是研究星系特性的有效方法。由于不同的巡天项目的观测原理和工作波段等不同, 各种巡天项目得到的星系观测数据格式不统一。本文描述了利用多个观测数据库来获得星系团特征数据的研究方法并给出了Python语言的实现。通过统一多波段的观测数据格式和找到中性氢观测的光学对应体, 之后利用找朋友算法 (Friends of Friends, FOF) 进行星系团认证, 从而获得分析星系团特性的数据。

关键词:多波段观测数据,星系团特性,FOF算法,Python语言

参考文献

[1]C.S.Botzler, J.Snigula, R.Bender, et al.Finding structures in photometric redshift galaxy survey:An extended friends-offriends algorithm.Mon.Not.Roy.Astron.Soc.349 (2004) 425.

[2]Python:http://www.python.org/.

[3]dr9:http://skyserver.sdss3.org/CasJobs/.

[4]a.40:http://egg.astro.cornell.edu/alfalfa/data/index.php.

篇8:python简单实现计算过期时间的方法

一个应用程序可以包含若干个Activity。可以让某个Activity对象使用Intent对象来启动其它的Activity对象。

2 Intent类的一个构造方法

Intent(Context packge Context,Class<?cls):该构造方法的参数packge Context是当前应用程序所在的上下文,参数cls是打算启动的Activity对象的类的名字。

例如:

假设,已经有如下类的声明:

class Calculator extends Activity

class Main Calculator extends Activity

那么,下面这条语句

Intent intent=new Intent(this,Main Calculator.class);

作用是:当前类的对象(Calculator类的当前对象this),打算启动的Activity对象的类的名字是Main Calculator。

接下来的语句

start Activity(intent);

作用是:实现两个Activity之间的切换。从当前的Activity,启动另外一个Activity,即Main Calculator。

3一个Activity对象使用Intent对象来启动另一个Activity对象的实例

【例1】在Android中实现简单的计算能力测试系统。计算随机给出的两位数的加减法算术题,要求用户回答,答对的提示“正确”,答错的提示“错误”。随时给出答题的正确率。

(1)第一个Activity的相关程序,文件Calculator.java:

(2)第二个Activity的相关程序,文件Main Calculator.java:

(3)配置文件Android Manifest.xml,在</application>之前,新增加Activity语句如下:

单击图1的“欢迎测试”按钮,出现的第二个Activity的初始界面如图2所示。

第二个Activity,单击“出题”按钮,输入运算结果,然后单击“判断”按钮,运行结果如图3所示。

4结束语

通过学习Android中Intent类的构造方法,我们可以使用Intent类的构造方法来创建Intent类的对象,实现同一个应用程序中多个Activity对象的切换,从而实现更多的功能。

这个简单的计算能力测试系统的界面welcome.xml和test.xml比较简单,在这里就不介绍了。另外,这个系统还可以扩展,实现乘、除等计算功能。限于篇幅,不再详细讲解了。

摘要:介绍了Android中Intent类的一个构造方法,使用这个构造方法来创建Intent类的对象,实现同一个应用程序中多个Activity对象的切换,从而实现更多的功能。

关键词:计算,测试,Android,Activity,Intent

参考文献

[1]耿祥义,张跃平.Android手机程序设计实用教程[M].北京:清华大学出版社,2013.

[2]李刚.疯狂Android讲义[M].北京:电子工业出版社,2013.

篇9:论简单结构的稳定性及其计算方法

关键词:稳定性,临界荷载

1 稳定问题的分类

1.1 结构的平衡状态

根据“结构受到外力干扰, 撤除外力干扰后能否回到其原始的平衡状态”, 把结构的平衡状态分为三类: (1) 若结构能回到原来的平衡状态, 称为稳定平衡状态; (2) 若结构继续偏离, 而且不能回到原来的平衡状态, 则称为不稳定平衡状态; (3) 如果结构既不继续偏离, 也不能回到原来的平衡状态, 而是另外停留在了一个新的平衡位置, 则称为随遇平衡状态。

1.2 结构失稳的形式

(1) 分支点失稳。分支点失稳的研究对象是理想构件的完善体系, 所谓的完善体系是指构件的轴线无初曲率, 并且轴向力无初偏心所确定的体系。分支点失稳可能出现新的、有质变的平衡形式和变形形式, 平衡形式具有二重性。

(2) 极值点失稳。极值点失稳的研究对象是实际工程结构中的非完善体系, 所谓的非完善体系是指构件有初曲率、荷载有初偏心、材料不均匀或有垂直于杆轴的横向外力所确定的体系。极值点失稳时, 结构原来的平衡形式并没有发生本质上的改变。

2 确定临界荷载的方法

结构稳定性计算的中心问题就是求解临界荷载, 防止结构在使用过程中出现失稳破坏。在实际的临界荷载计算过程中基本原则是“完善体系分支点失稳, 并根据小挠度理论求解临界荷载”。求解完善体系分支点失稳的临界荷载方法有很多, 其中最重要最常用的方法是静力法和能量法。

2.1 静力法

静力法是根据体系在临界状态具有平衡二重性而提出的方法。利用静力平衡条件, 假定新的平衡形式后, 列出平衡方程, 然后寻求使结构在新形式下能保持平衡的荷载, 其最小值就是要求的临界荷载。

(1) 对有限自由度体系的静力求解法。对于有限个自由度的结构体系, 列出新的平衡形式下的 (有限个) 独立平衡方程, 它们是含有限个 (与自由度个数相同) 独立位移参数的齐次线性代数方程。根据临界状态的静力特征, 要求位移参数有非零解, 所以应使方程组的系数行列式D=0, D=0即为稳定问题的特征方程。系数中包含荷载, 可从稳定方程中求出最小根Fp cr, 即为临界荷载。

(2) 对无限自由度体系的静力求解法。对于具有无限个自由度的体系, 先设定一个符合支承情况的变形曲线, 并根据变形曲线建立近似微分方程:EIY”=±M。

关于正负号的确定:当由弯矩形成的曲线在所选用的坐标系中的曲率为正 (切线斜率由小变大) 时, 取正号;反之 (切线斜率由大变小) , 取负号。此规定可以简单地理解为:根据已假定的变形形态, 若开口方向沿水平轴正向, 则取正;反之, 则取负号。求解这个微分方程并利用边界条件获得一组关于位移参数的齐次线性代数方程组。根据失稳时产生新的变形这一条件, 位移不恒等于零, 即位移参数不恒等于零, 必有其系数行列式为零, 即:D=0, 从而求得临界荷载的稳定方程。该稳定方程有无穷多个解, 同样取最小解即为临界荷载。

2.2 能量法

能量法是根据体系处于临界状态时的能量原理而提出的方法。在某些复杂的情况下, 用静力法确定临界荷载比较困难, 如边界条件复杂, 以致根据它们导出的行列式为高阶的, 不易展开求解。特别是对于各种变截面压杆及轴向荷载沿杆长连续变化的压杆, 用能量法既简便又能满足精度。

(1) 对有限自由度体系的能量求解法。具有有限个自由度的体系, 用有限个独立参数表示所设的失稳变形曲线, 结构的势能为这有限个 (与自由度个数相同) 独立参数的函数。根据势能驻值原理, 结构势能Ep的一阶偏导数等于零, 即δEp=0, 然后根据势能有非零解的能量特征得到特征方程, 求出荷载的特征值Fppf4i (i=1, 2, 3..., n) , 取最小值即为临界荷载Fp cr。

(2) 对无限自由度体系的能量求解法。根据势能驻值原理, 对于弹性体系, 在满足支撑条件的一切可能的位移中, 要满足势能的一阶偏导数为零。但要从无数多个可能的位移中找出Fp后再求最小值, 是比较繁琐的。一般只选定一些可能的位移并求出Fp, 从中找出它们的最小值, 可以作为临界荷载的一个近似值。瑞雷-里兹法采用具有n个参数的已知位移函数来代替真实的未知失稳曲线, 可以有效地将无限自由度体系转化为有限自由度体系, 然后按有效自由度的情况来确定临界荷载。此法的关键在于选取恰当的变形曲线, 该曲线应满足几何边界条件且尽量满足力学边界条件。若所设曲线与真实的失稳曲线一致, 则用能量法求得的临界荷载是精确的;若不一致, 则所求荷载是大于精确解的近似解, 因为将无限自由度体系化为有限自由度体系, 减少了自由度, 相当于在某些地方人为地加上了外力约束, 增加了体系抵抗变形失稳的能力, 所以求得的近似解略大于精确解。

3 结语

失稳破坏是结构工程中一种常见的破坏形式, 国内外因失稳破坏而导致结构倒塌的事故已有多起。近年来, 随着结构构件截面的不断丰富和高强材料的应用, 受压构件向着轻型、薄壁发展, 可以预见未来对构件稳定性计算的研究也将逐步加深。

参考文献

上一篇:关于感谢有你五年级学生500字优秀下一篇:弘扬长征精神,做好本职工作