财务计算

1. 十进制浮点数的运算,由于计算机是二进制模拟的,迫于位数限制,总是逼近的。用 Decimal(str(123)) 来搞,和java的处理
方式一样

Python-Redis

1. 机器上先安装redis并启动

2. test redis
>> redis-cli可以进入redis的命令行,进行简单的get set测试

3. pip install redis,安装python的redis包

import redis
r = redis.Redis(host="127.0.0.1", port=6379, db=0)
r.set("k1", "hello world")
r.get("k1")
r.keys()
r.dbsize()
r.delete("k1")
r.save() #将数据写回磁盘,保存时阻塞
r.flushdb() #清空r中数据


#redis学习再看文档请 https://pypi.python.org/pypi/redis/2.9.1

python装饰器

1. 修改其他函数功能的函数。可以在不改变函数定义的同时,给函数加功能。OOP里面,可以通过继承时override父函数来达到
同样效果

2. 函数也是对象,所以可以将函数赋值给变量,通过变量来调用函数。函数中可以定义函数,也可以返回函数,函数可作为参数传递

3. 定义好的decorator函数,可以通过@来使用

def log(para="def"):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print "%s call %s" % (para,func.__name__)
            return func(*args, **kwargs)

        return wrapper
    return decorator


@log()
def test_decorator():
    print "normal function"

4. 常见场景
    #1 预处理/后处理,网站的授权检查,相当于中间件功能,配置上下文
    #2 记录函数行为,日志,缓存,记时
    #3 注入参数,提供默认参数,生成参数
    #4 修改调用的上下文,现场异步或者并行,类方法

5. 可以用类实现,类里可以实现更丰富的功能,而且可以通过继承扩展

from functools import wraps

class logit(object):
    def __init__(self, logfile='out.log'):
        self.logfile = logfile

    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile并写入
            with open(self.logfile, 'a') as opened_file:
                # 现在将日志打到指定的文件
                opened_file.write(log_string + '\n')
            # 现在,发送一个通知
            self.notify()
            return func(*args, **kwargs)
        return wrapped_function

    def notify(self):
        # logit只打日志,不做别的
        pass

FLASK

部署flask,Flask+Gunicorn+Gevent+Supervisor+Nginx 或者 flask + uWSGI + nginx

fx_app //项目文件夹
├── fx_app //项目主文件夹
│   ├── __init__.py //模块初始化
│   ├── static //css,js等资源文件
│   │   ├── css
│   │   │   ├── bootstrap-theme.min.css
│   │   │   └── bootstrap.min.css
│   │   ├── fonts
│   │   │   ├── glyphicons-halflings-regular.eot
│   │   │   ├── glyphicons-halflings-regular.svg
│   │   │   ├── glyphicons-halflings-regular.ttf
│   │   │   ├── glyphicons-halflings-regular.woff
│   │   │   └── glyphicons-halflings-regular.woff2
│   │   ├── images
│   │   └── js
│   │       ├── bootstrap.min.js
│   │       ├── jquery.ajaxupload.js
│   │       └── jquery.js
│   ├── templates //布局相关文件
│   │   ├── index.html
│   │   ├── layout.html //base 模板文件
│   │   └── upload.html
│   ├── upload
│   │   └── Smartrade_International_Co._Ltd_MT4_PL_September_2017.xlsx
│   ├── util
│   ├── views.py
│   └── views.pyc
├── instance //私有配置文件
│   └── config.py
└── run.py //入口函数
//run.py
# -*- coding: utf-8 -*-

from fx_app import app
app.run(debug=True)
//fx_app/__init__.py
# -*- coding: utf-8 -*-

from flask import Flask
app = Flask(__name__)

import fx_app.views
//fx_app/views.py
# -*- coding: utf-8 -*-

from flask import Flask, request, redirect, jsonify
from flask import render_template
from werkzeug.utils import secure_filename
import os

from . import app

UPLOAD_FOLDER = os.path.abspath('./fx_app/upload')

from excel_task import parse_fx_excel

@app.route("/cal")
def cal():
    return "Hell world"


@app.route("/")
def index():
    return render_template("index.html",name="index")


@app.route("/upload", methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect(request.url)
        file = request.files["file"]
        if file.filename == '':
            return redirect(request.url)

        if file:
            folder = os.path.join(UPLOAD_FOLDER)
            filename = secure_filename(file.filename)
            print folder
            filepath = os.path.join(folder, filename)
            file.save(filepath)

            data = parse_fx_excel(filepath)

            return jsonify({
                "ok": 0,
                "msg": "ok",
                "obj": data
            })

    return render_template("upload.html", name="upload")
//layout.html
<!doctype html>
<html>
  <head>
    {% block head %}
    <link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}" />
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/ui-lightness/jquery-ui.css" />
      <style>
          html,body{
              height: 100%;
              padding: 0;
              margin: 0;
          }
      </style>
    <title>{% block title %}{% endblock %} - My Webpage</title>
    {% endblock %}
  </head>
  <body>
    <div id="content" style="height: 100%;width: 100%;">{% block content %}{% endblock %}</div>
    <div id="footer" style="text-align: center;background-color: #3c3c3c;padding: 60px;color:grey">
      {% block footer %}
      &copy; Copyright 2017
      {% endblock %}
    </div>

    {% block js %}
    <script type="text/javascript" src="{{ url_for('static',filename='js/jquery.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static',filename='js/bootstrap.min.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static',filename='js/jquery.ajaxupload.js') }}"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
    {% endblock %}
  </body>
</html>
//upload.html
{% extends "layout.html" %}
{% block title %}Upload{% endblock %}
{% block head %}
  {{ super() }}
{% endblock %}
{% block content %}
<div style="padding: 30px;text-align: center;width: 600px;margin-left: auto;margin-right: auto">
    <p style="background-color: lightblue;padding: 30px;line-height: 28px;font-size: 14px">
        功能说明,啊哈哈哈,这里是功能说明
    </p>
    <div style="text-align:center;padding:20px;border:1px dashed #909090;" id="promptzone">
        click to upload
    </div>
    <div id="progressbar"></div>
    <div id="result"></div>
</div>
{% endblock %}
{% block js %}
{{ super() }}
<script>
    jQuery(function ($) {
    $.ajaxUploadSettings.name = 'file';

    $('#promptzone').ajaxUploadPrompt({
        url : 'upload',
        beforeSend : function () {
            $('#promptzone, #result').hide();
        },
        onprogress : function (e) {
            if (e.lengthComputable) {
                var percentComplete = e.loaded / e.total;
                // Show in progressbar
                $( "#progressbar" ).progressbar({
                    value: percentComplete*100,
                    complete: function () {
                        $(this).progressbar( "destroy" );
                        $("#result").show()
                        $("#result").text("上传成功,数据处理中...")
                    }
                });
            }
        },
        error : function () {
        },
        success : function (data) {
            console.log(data)
            $("#result").text("处理完成")
        }
    });
});
</script>
{% endblock %}

Flask的推送思路

1. sse,server send event,单项,服务器端推客户端,利用stream流,类似下载的方式。
需要浏览器支持EventSource。flask-sse
2. websocket,双向,服务器客户端各自实现websocket协议。flask-socketio

https://stackoverflow.com/questions/5195452/websockets-vs-server-sent-events-eventsource

TLDR summary:

Advantages of SSE over Websockets:

Transported over simple HTTP instead of a custom protocol
Can be poly-filled with javascript to "backport" SSE to browsers that do not support it yet.
Built in support for re-connection and event-id
Simpler protocol
Advantages of Websockets over SSE:

Real time, two directional communication.
Native support in more browsers
Ideal use cases of SSE:

Stock ticker streaming
twitter feed updating
Notifications to browser
SSE gotchas:

No binary support
Maximum open connections limit

results matching ""

    No results matching ""