那是自个儿做出来的简练版本,前面包车型客车UI设计就看大家的艺术细胞了

数据库的名字叫WawaDB,是用python完结的。不问可知python是灰常庞大啊!
简要介绍 记录日志的要求平常是这么的:

图片 1

有了pywin32是或不是就能够在Windows上扬威耀武了?

代码:

图片 2image

只扩大,不修改,写入定期间顺序写入;

近八个月白天都在加班加点,中午在恶补深度学习的文化以及学习tensorflow,前面学着学着感到paddlepaddle框架(百度继Echarts外又一位心巨作!)也是不易的取舍,有很详细的求证文书档案,对纵深学习神经互联网感兴趣的同窗能够视作入门的挑三拣四,个人还未尝试,前期不时间大概会指向paddlepaddle举行学习并写些心得。

是的。

from django.utils.safestring import mark_safe

class Paginator(object):

    def __init__(self,current_page,total_item_count,base_url,per_page_count=10,show_pager_count=11):
        """
        :param current_page:  当前页码
        :param total_item_count: 数据库数据总条数
        :param base_url: 分页前缀URL
        :param per_page_count:   每页显示数据条数
        :param show_pager_count: 对多显示的页码
        """
        self.current_page = current_page
        self.total_item_count = total_item_count
        self.base_url = base_url
        self.per_page_count = per_page_count
        self.show_pager_count = show_pager_count

        #获取页码数及最后一页上显示的条目数
        max_pager_num, b = divmod(total_item_count, per_page_count)

        if b:
            max_pager_num += 1
        self.max_pager_num = max_pager_num

    @property
    def start(self):
        """
        #每一页显示的第一条数据
        :return:
        """
        return (self.current_page-1)* self.per_page_count

    @property
    def end(self):
        """
        #每一页显示的最后一条数据
        :return:
        """
        return self.current_page * self.per_page_count

    def page_html(self):
        """

        :return:
        """
        page_list = []

        #如果当前页为第1页,则上一页按钮不可用
        if self.current_page == 1:
            prev = ' <li><a href="#">上一页</a></li>'
        else:
            prev = ' <li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,)
        page_list.append(prev)

        half_show_pager_count = int(self.show_pager_count / 2)

        # 页面显示的总页数小于定义的页面上显示的页数时
        if self.max_pager_num < self.show_pager_count:
            pager_start = 1
            pager_end = self.max_pager_num + 1
        else:
            #当前页码数小于定义的页面显示的页数的一半时
            if self.current_page <= half_show_pager_count:
                pager_start = 1
                pager_end = self.show_pager_count + 1
            else:
                #当前面码数大于定义的页面显示的页数的一半时
                if self.current_page + half_show_pager_count > self.max_pager_num:
                    pager_start = self.max_pager_num - self.show_pager_count + 1
                    pager_end = self.max_pager_num + 1
                else:
                    #正常显示的时候
                    pager_start = self.current_page - half_show_pager_count
                    pager_end = self.current_page + half_show_pager_count + 1

        #遍历循环当前页的每一条记录
        for i in range(pager_start, pager_end):
            if i == self.current_page:
                tpl = ' <li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
            else:
                tpl = ' <li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
            page_list.append(tpl)

        # 如果当前页为最后一页,则下一页按钮不可用
        if self.current_page == self.max_pager_num:
            next = ' <li><a href="#">下一页</a></li>'
        else:
            next = ' <li><a href="%s?page=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)
        page_list.append(next)

        return mark_safe(''.join(page_list))

软件成果视图

大方写,小量读,查询日常查询四个年华段的数额;

好了言归正传,7月低的时候邻近结业,突发奇想想知道知道大二开端捡起python到后天总括写了稍稍行代码,也终于给和谐叁个评判吧。

    # -*- coding: cp936 -*- #   
    import os  
    import pythoncom  
    from win32com.shell import shell  
    from win32com.shell import shellcon  

    def set_shortcut(filename,lnkname,iconname):#如无需特别设置图标,则可去掉iconname参数  
        shortcut = pythoncom.CoCreateInstance(  
        shell.CLSID_ShellLink, None,  
        pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink)  
        shortcut.SetPath(filename)  
        shortcut.SetIconLocation(iconname,0)#可有可无,没有就默认使用文件本身的图标  
        if os.path.splitext(lnkname)[-1] != '.lnk':  
            lnkname += ".lnk"  
        shortcut.QueryInterface(pythoncom.IID_IPersistFile).Save(lnkname,0)  

    if __name__ == "__main__":  
        #获取"启动"文件夹路径,关键是最后的参数CSIDL_STARTUP,这些参数可以在微软的官方文档中找到  
        startup_path = shell.SHGetPathFromIDList(shell.SHGetSpecialFolderLocation(0,shellcon.CSIDL_STARTUP))  
        #获取"桌面"文件夹路径,将最后的参数换成CSIDL_DESKTOP即可  
        desktop_path = shell.SHGetPathFromIDList(shell.SHGetSpecialFolderLocation(0,shellcon.CSIDL_DESKTOP))  
        file_name=""#要创建快捷方式的文件的完整路径  
        icon_name=""#图标文件的完整路径(非必须)  
        lnk_name1= startup_path+"\\我的桌面快捷方式.lnk"#将要在此路径创建快捷方式  
        lnk_name2= startup_path+"\\我的启动组快捷方式.lnk"  
        set_shortcut(file_name,lnk_name1,icon_name)  
        set_shortcut(file_name,lnk_name2,icon_name)  

应用方法:

 号:960410445 群里有志同道合的小伙伴,互帮互助, 群里有不错的视频学习教程和PDF!

MongoDB的平素集合很好的满意了这几个须求,可是MongoDB占内部存储器相当大,有一点点儿火穿蚊子,无独有偶的以为。

规律很简单,利用文件夹遍历情势获取.py文件,读取py文件内的行数。

从浏览器中收取当前的页码数

咱俩举行创设软件研商所须要的模板库,首先要开展引用。

WawaDB的思绪是每写入一千条日志,在贰个索引文件里记录下当前的日子和日志文件的偏移量。

# -*- coding: utf-8 -*-
# @Date    : 2017-05-25 23:46:39
# @Author  : Alan Lau (rlalan@outlook.com)
# @Version : Python3.5


import os


def fw(path):
    fileArray = []
    for root, dirs, files in os.walk(path):
        for fn in files:
            if (fn.split('.'))[-1] == 'py' and r'D:\Sofrware\Python35' not in root:
                # 判断是否为py文件,因为我的python第三方包安装在了D:\Sofrware\Python35这个路径下,因此跳过这个文件夹
                file = str(root+'\\'+fn)
                fileArray.append(file)
    return fileArray


def ifcode(path):
    files = fw(path)
    return files


def line_counter(file):
    counter = 0
    try:
        with open(file, 'rb') as f:
            content = f.readlines()
        content = list(filter(lambda line: line != b'\r\n', content))  # 过滤空行
        counter = len(content)
    except Exception as e:
        counter = 0
        pass
    else:
        pass
    finally:
        pass
    return counter

from datetime import datetime


def main():
    path = r'D:\\'
    counter = 0
    files = ifcode(path)
    i = 0
    for file in files:
        i += 1
        counter += line_counter(file)
        if counter > 10*i:
            print('got %s lines.' % counter)
    print('u have done %d python files.' % len(files))
    print('u have done %d lines code, good luck Alan...' % counter)


if __name__ == '__main__':
    t_s = datetime.now()
    main()
    t_e = datetime.now()
    print('[finished in %s]' % (t_e-t_s))
current_page=int(request.GET.get("page",1))

import requestsfrom tkinter import *from tkinter import
messagebox</pre>

接下来定时间询日志时,先把索引加载到内部存储器中,用二分法查出时间点的偏移量,再展开日志文件seek到钦定地方,那样就可以相当慢定位顾客要求的数据并读取,而没有必要遍历整个日志文件。
性能 Core 2 P8400,2.26GHZ,2G内存,32 bit win7

结果:

从数据库中抽出的总的记录数

接下去先为大家的软件起个好听的名字,以及实行岗位一定

写入测验:

图片 3

item_list=models.数据表.objects.all()
total_item_count=item_list.count()

master = Tk() # 实例进程 master.title(‘ZZQ–翻译软件’) # 题目命名
master.geometry(‘400×96+416+362’) # 给软件固定地点和长度宽度。</pre>

一成不改变1分钟写入10000条数据,共写入5个小时的数目,
插入300万条数据,每条数据51个字符,用时2分51秒

4487112行代码……

使用Paginator类实例化二个页码的靶子:

然后供给采取到一点爬虫的学问,url是大家选用的翻译网站,笔者利用的是有道,你们也足以选择任何的,只须求将网站进行修改就能够换来团结想要的网站。

读取测试:读取钦点时期段内包含有些子串的日志

page_obj=Paginator(current_page,total_item_count,"/index/")

需要注意的是:

    实例化page_obj的时候,可以定义每页显示的记录个数per_page_count及显示在页面上的页码的个数show_page_count

    每页显示的记录数per_page_count默认值为10,
    页面显示的页码的个数show_page_count默认值为11

def fanyi():url =
“” #
被爬虫网站content = entey1.get() #
获取第三个框里面所输入的剧情printdata = {‘i’: content,’doctype’:
‘json’}r = requests.post(url, data=data).content.decode()ret =
json.loadsresult = ret[‘translateResult’][0][0][‘tgt’]res.set #
显示结果</pre>

数量范围 遍历数据量 结果数 用时(秒)

概念重临到顾客端的笔录列表

作者们一共设置了多个框,第一个为大家输入想要进行翻译的原委,第贰个框是用于出口答案的。

5小时 300万 604 6.6

item_list=models.数据表.objects.all()[page_obj.start:page_obj.end]

在这边大家得以举办框大小以及体制的宏图了,这也是显现我们艺术细胞的入眼战场。

2小时 120万 225 2.7

最后动用render或然redirect再次来到给客户端

entey2 = Entry(master, fg=’blue’, font=(‘GB2312’, 16), textvariable=res)
# 设置分界面样式 entey2.grid(row=1, column=1) # 定位输入框地点</pre>

1小时 60万 96 1.3

return render(request,"aaa.html",{"item_list":item_list,"page_html":page_obj.page_html()})

最后是输出键以及退出键,输出键就是翻译键;而退出键正是退出窗口的键,相当于关闭窗口。

30分钟 30万 44 0.6 索引 只对日记记录的时光做索引,
简单介绍里大概说了下索引的完毕,二分查找鲜明没B
Tree功用高,但貌似意况下也差不了二个数目级,何况完毕特别轻松。

不安装后退键,后退键就提交你们去完善了,还挺期望您们开展宏观和美化,小编会很向往你们的能力和艺术细胞的。

因为是萧条索引,并不是每条日志都有索引记录它的偏移量,所以读取数据时要往前多读一些数额,防止漏读,等读到真正所需的数据时再真正给客户再次来到数据。

button1 = Button(master, text=’万能键’, width=10, font=(‘STKaiti’, 16),
command=fanyi) # 设置分界面样式 button1.grid(row=2, column=0, sticky=W)
button1 = Button(master, text=’拜拜’, width=10, font=(‘STKaiti’, 16),
command=master.quit) # 设置分界面样式 button1.grid(row=2, column=1,
sticky=E)</pre>

正如图,举例客户要读取25到43的日志,用二分法找25,找到的是30所在的点,

那是本人的率先篇技能硬货,假若写的糟糕,还请多包含,招待给我们提提出。

索 引:0 10 20 30 40 50
日志:|………|………|………|………|………|>>>a =
[0, 10, 20, 30, 40, 50]>>>bisect.bisect_left(a,
35)>>>3>>>a[3]>>>30>>>bisect.bisect_left(a,
43)>>>5>>>a[5]>>>50

因而大家要往前倒一些,从20(30的前贰个刻度)初步读取日志,21,22,23,24读取后因为比25小,所以扔掉,
读到25,26,27,…后归来给客户

读取到40(50的前三个刻度)后就要剖断当前数量是或不是超过43了,如若凌驾43(重回全开区间的多寡),就要告一段落读了。

全体下来大家只操作了大文件的少之又少一些就获取了顾客想要的多少。 缓冲区
为了减弱写入日志时多量的磁盘写,索引在append日志时,把buffer设置成了10k,系统私下认可应该是4k。

同理,为了拉长读取日志的成效,读取的buffer也安装了10k,也亟需依赖你日志的尺寸做适度调解。

目录的读写设置成了行buffer,每满一行都要flush到磁盘上,幸免读到不完整的索引行(其实施行表明,设置了行buffer,还能读到六分之三的行)。
查询 啥?要扶助SQL,别闹了,100行代码怎么帮忙SQL呀。

前几日询问是一贯传入一个lambada表明式,系统遍历内定期限内的多寡行时,满足客商的lambada条件才会回到给顾客。

理当如此如此会多读取比非常多客户无需的多少,并且每行都要进行lambda表明式的演算,可是不能,简单便是美啊。

原先小编是把一个索要查询的基准和日志时间,日志文件偏移量都记录在目录里,那样从目录里寻觅出切合条件的偏移量,然后每条数据都如日志文件里seek叁次,read叁次。那样好处唯有三个,便是读取的数据量少了,但缺点有多个:

目录文件特别大,不便利加载到内部存款和储蓄器中

老是读取都要先seek,貌似缓冲区用不上,特别慢,比延续读贰个段的多寡,并用lambda过滤慢四五倍
写入 前边说过了,只append,不退换数据,并且每行日志最终边是时间戳。

多线程

查询数据,可以二十八线程同一时候询问,每便查询都会打开二个新的日记文件的描述符,所以并行的多少个读取不会动手。

写入的话,尽管只是append操作,但不承认二十多线程对文本实行append操作是或不是平安,所以建议用叁个类别,二个专项使用线程进行写入。
锁 未有其余锁。 排序
私下认可查询出来的数目是定时间正序排列,如需任何排序,可取到内部存款和储蓄器后用python的sorted函数排序,想怎么排就怎么排。

100多行的数据库代码 “`python

– coding:utf-8 –

import os import time import bisect import itertools from datetime
import datetime import logging

default_data_dir = ‘./data/’ default_write_buffer_size = 102410
default_read_buffer_size = 1024
10 default_index_interval = 1000

def ensure_data_dir(): if not os.path.exists(default_data_dir):
os.makedirs(default_data_dir)

def init(): ensure_data_dir()

class WawaIndex: def init(self, index_name): self.fp_index =
open(os.path.join(default_data_dir, index_name + ‘.index’), ‘a+’, 1)
self.indexes, self.offsets, self.index_count = [], [], 0
self.__load_index()

def __update_index(self, key, offset):
    self.indexes.append(key)
    self.offsets.append(offset)

def __load_index(self):
    self.fp_index.seek(0)
    for line in self.fp_index:
        try:
            key, offset  = line.split()
            self.__update_index(key, offset)
        except ValueError: # 索引如果没有flush的话,可能读到有半行的数据
            pass

def append_index(self, key, offset):
    self.index_count += 1
    if self.index_count % default_index_interval == 0:
        self.__update_index(key, offset)
        self.fp_index.write('%s %s %s' % (key, offset, os.linesep))

def get_offsets(self, begin_key, end_key):
    left = bisect.bisect_left(self.indexes, str(begin_key))
    right = bisect.bisect_left(self.indexes, str(end_key))
    left, right = left - 1, right - 1
    if left < 0: left = 0
    if right < 0: right = 0
    if right > len(self.indexes) - 1: right = len(self.indexes) - 1
    logging.debug('get_index_range:%s %s %s %s %s %s', self.indexes[0], self.indexes[-1], begin_key, end_key, left, right)
    return self.offsets[left], self.offsets[right]

class WawaDB: def init(self, db_name): self.db_name = db_name
self.fp_data_for_append = open(os.path.join(default_data_dir,
db_name + ‘.db’), ‘a’, default_write_buffer_size) self.index =
WawaIndex(db_name)

def __get_data_by_offsets(self, begin_key, end_key, begin_offset, end_offset):
    fp_data = open(os.path.join(default_data_dir, self.db_name + '.db'), 'r', default_read_buffer_size)
    fp_data.seek(int(begin_offset))

    line = fp_data.readline()
    find_real_begin_offset = False
    will_read_len, read_len = int(end_offset) - int(begin_offset), 0
    while line:
        read_len += len(line)
        if (not find_real_begin_offset) and  (line < str(begin_key)):
            line = fp_data.readline()
            continue
        find_real_begin_offset = True
        if (read_len >= will_read_len) and (line > str(end_key)): break
        yield line.rstrip('\r\n')
        line = fp_data.readline()

def append_data(self, data, record_time=datetime.now()):
    def check_args():
        if not data:
            raise ValueError('data is null')
        if not isinstance(data, basestring):
            raise ValueError('data is not string')
        if data.find('\r') != -1 or data.find('\n') != -1:
            raise ValueError('data contains linesep')

    check_args()

    record_time = time.mktime(record_time.timetuple())
    data = '%s %s %s' % (record_time, data, os.linesep)
    offset = self.fp_data_for_append.tell()
    self.fp_data_for_append.write(data)
    self.index.append_index(record_time, offset)

def get_data(self, begin_time, end_time, data_filter=None):
    def check_args():
        if not (isinstance(begin_time, datetime) and isinstance(end_time, datetime)):
            raise ValueError('begin_time or end_time is not datetime')

    check_args()

    begin_time, end_time = time.mktime(begin_time.timetuple()), time.mktime(end_time.timetuple())
    begin_offset, end_offset = self.index.get_offsets(begin_time, end_time)

    for data in self.__get_data_by_offsets(begin_time, end_time, begin_offset, end_offset):
        if data_filter:
            if data_filter(data):
                yield data
        else:
            yield data

def test(): from datetime import datetime, timedelta import uuid, random
logging.getLogger().setLevel(logging.NOTSET)

def time_test(test_name):
    def inner(f):
        def inner2(*args, **kargs):
            start_time = datetime.now()
            result = f(*args, **kargs)
            print '%s take time:%s' % (test_name, (datetime.now() - start_time))
            return result
        return inner2
    return inner

@time_test('gen_test_data')   
def gen_test_data(db):
    now = datetime.now()
    begin_time = now - timedelta(hours=5)
    while begin_time < now:
        print begin_time
        for i in range(10000):
            db.append_data(str(random.randint(1,10000))+ ' ' +str(uuid.uuid1()), begin_time)
        begin_time += timedelta(minutes=1)

@time_test('test_get_data')   
def test_get_data(db):
    begin_time = datetime.now() - timedelta(hours=3)
    end_time = begin_time + timedelta(minutes=120)
    results = list(db.get_data(begin_time, end_time, lambda x: x.find('1024') != -1))
    print 'test_get_data get %s results' % len(results)

@time_test('get_db')   
def get_db():
    return WawaDB('test')

if not os.path.exists('./data/test.db'):
    db = get_db()
    gen_test_data(db)
    #db.index.fp_index.flush()

db = get_db()
test_get_data(db)

init()

if name == ‘main‘: test() “`

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图