分类 默认分类 下的文章

线性同余发生器

线性同余发生器

线性同余发生器(Linear congruential generator,LCG)是一种能产生具有不连续计算的伪随机序列的分段线性方程的算法,它代表了最古老和最知名的伪随机序列生成器算法之一。

生成器定义

$$
X_{n+1}=\left(a X_{n}+c\right) \bmod m
$$

  • $X​$是伪随机序列

  • $m,m>0​$表示模量

  • $a,0<a<m​$表示乘数

  • $c,\leq0<m​$表示增量

  • $ X_{0},0\leq X_{0}<m $表示初始值

当$c=0$时,该发生器称为乘法同余发生器MCG

MCG的实现

#include <stdio.h>

#define A 48271L
#define M 2147483647L

double Random(void) {
    Seed = (A * Seed) % M;
    return (double)Seed / M;
}
void Initialize(unsigned InitVal) {
    Seed = InitVal;
}

这种实现方法实现地很直观,但存在一个问题。在32位机器上A * Seed会导致乘法溢出与截断,虽然程序能继续运行,但它影响最终的计算结果,从而影响伪随机性。

Schrage's method

Schrage方法推导过程
推导过程
因为$R<Q$,故所有的余项均可计算而没有溢出。此外,仅当余项的值小于0时候$\delta\left(x_{i}\right)=1$。

#include <stdio.h>

#define A 48271L
#define M 2147483647L
#define Q ( M / A )
#define R ( M % A )

static unsigned long Seed = 1;

double Random(void) {
    long TmpSeed;
    TmpSeed = A * (Seed % Q) - R * (Seed / Q);
    if (TmpSeed >= 0)
    {
        Seed = TmpSeed;
    }
    else
    {
        Seed = TmpSeed + M;
    }
    return (double)Seed / M;
}
void Initialize(unsigned InitVal) {
    Seed = InitVal;
}

A站视频信息分析

1.使用scrapy框架重写了一下a站的视频爬虫,共爬取895,799条视频信息。爬取了包括标题、播放量、弹幕数、评论数、收藏数、香蕉数量、作者信息、视频类别等信息。

2.各类别视频数量

各类别视频数量统计图

3.播放量TOP20视频(TOP1有点假,刷的)

播放量TOP20视频

4.播放量区间统计

('1-10', 9),
('10-100', 807),
('100-1k', 58297),
('1k-10k', 716989),
('10k-100k', 98948),
('100k-1m', 19524),
('1m-10m', 1164),
('10m-100m', 58),
('>100m', 3);

请输入图片描述

A站视频数据-201902-可用phpMyAdmin导入.sql

诗词

梅花引·荆溪阻雪

蒋捷 宋

白鸥问我泊孤舟,是身留,是心留?心若留时,何事锁眉头?风拍小帘灯晕舞,对闲影,冷清清,忆旧游。
旧游旧游今在否?花外楼,柳下舟。梦也梦也,梦不到,寒水空流。漠漠黄云,湿透木棉裘。都道无人愁似我,今夜雪,有梅花,似我愁。

雨霖铃·寒蝉凄切

柳永 宋

寒蝉凄切,对长亭晚,骤雨初歇。都门帐饮无绪,留恋处,兰舟催发。执手相看泪眼,竟无语凝噎。念去去,千里烟波,暮霭沉沉楚天阔。多情自古伤离别,更那堪,冷落清秋节!今宵酒醒何处?杨柳岸,晓风残月。此去经年,应是良辰好景虚设。便纵有千种风情,更与何人说?

python 装饰器

举例

现有一个函数,我们想测试它的运行时间,一个直接的方法就是更改原函数,记录其开始与结束时间。但这样很暴力,而且在想进行多方面修改时容易混乱,破坏其可读性,不利于程序扩展。这事装饰器就派上用场了。

装饰器

形象的说,Python的装饰器是一个包装函数的函数。在不改变原函数的情况下执行一些其它的操作。例如插入日志、性能测试、事务处理等等。

实例

    def spamrun(fn):
        def sayspam(*args):
                print "spam,spam,spam"
            return sayspam
        @spamrun
        def useful(a,b):
            print a**2+b**2
           
    useful(3,4)


 - 输出:
    spam,spam,spam
 def addspam(fn):
     def new(*args):
            print "spam,spam,spam"
            return fn(*args)
        return new
    @addspam
    def useful(a,b):
        print a**2+b**2     
useful(4,3)



 - 输出: 
    spam,spam,spam
    25

 def addspam(fn):
     def new(*args):
            fn(*args)
            print "spam,spam,spam"
        return new
    @addspam
    def useful(a,b):
        print a**2+b**2     
useful(4,3)

- 输出:
    25
    spam,spam,spam

[Project]聊天室-Python

目的:通过一个小项目练习与学习Python

服务端:

ChatServer类:
  attr:
    server:服务器Socket
    CONNECTIONS:包含所有已连接的Client Socket与Server Scoket
    host、post 主机、端口
    RCVBUF:接受缓冲区大小
  methods:
    broadcast_data:每接受一次信息,将信息发送给其它所有客户端
    run:通过select实现非阻塞监听

客户端:

Client类:
  attr:
    s:Client Socket
    host_name、ip: 本机名、本机ip
    des_host、des_port:服务器地址与端口
  methos:
    hint:刷新标准输出缓冲区
    run:监听stdin与Client Socket

Tips:

   客户端无法再Windows下使用
   "On Windows, the underlying select() function is provided by the WinSock library, and does not handle file descriptors that don’t originate from WinSock" ---Python Doucumentation

   服务端运行在远程服务器时以服务器地址做参数构造Server

GUI编程

1.通过修改text['State']='disabled'可以使文本域不可被编辑。同样当自己需要插入时需要先改变State为normal
2.如何使Scrollbar始终指向文本域底部?通过text.see(END)可实现。参见说明:
QQ截图20161205122250.png

遇到问题

  1. 点击'发送时',提示超时,发送失败。

  2. 在Ubuntu环境下测试时,发现每次连接后发送消息后会自动断开连接。
    排除客户端错误,在服务端代码对应位置插入异常输出,提示str类型异常,发现
    self.broadcast_data(set(self.CONNECTIONS)-{sock},("\r" + '<' + str(sock.getpeername()) + '> ' +data).encode('ascii'))
    data忘记做了类型转化,data改为data.decode('ascii')

  3. 回到第一个问题,发现每次提示发送超市关闭GUI时,服务端输出连接成功。原来root.mainloop()循环会阻塞run中监听循环.在点击发送时实际上并未连接至服务器.
      解决方案:将run放入另一个线程中便可解决。

  4. 使用os_exit()方法退出进程,在测试时发现服务端报错

    "\rClient {} is offline\n".format(sock.getpeername()))
    OSError: [Errno 107] Transport endpoint is not connected

    猜测os_exit()使得后面代码没有被正常执行,客户端已关闭socket,服务端调用socket方法出现错误。
    解决方法:将os._exit()去掉,使得服务端能正常关闭socket,然后通过chat.run线程退出进程。

下一步:

  1. 补全Save功能
  2. 处理非正常退出进程

更新0315

  1. 已补全Save功能
  2. 已处理非正常退出问题
  3. json打包发送数据
    代码见https://github.com/starsD/pyChatroom