Chong's Site book

  • 首页

  • 标签18

  • 分类25

  • 归档33

  • Hexo_docs

  • references

  • markdown_ref

免费注册Oracle Cloud

发表于 2019-09-28 | 更新于 2019-09-29 | 分类于 Oracle Cloud

Larry在甲骨文Oracle OpenWorld 2019上大笔一挥,推出了终身免费的Oracle Cloud试用。虽然没办法跟Oracle的律师计较always free能维持多久,可以看得见的是羊毛还是值得一薅的。

免费注册

  • 注册网址:https://www.oracle.com/cn/cloud/free/

注册步骤不复述了,网上有很多教程,一步一步填写就行了。
注册的过程中可能会遇到的问题,如收不到手机验证码,可能是以前注册过只能换手机试试了;信用卡审核不过,可以淘宝买visa或者master的1美元礼品卡注册一下。

  • 登陆地址
    Oracle Cloud的控制台最近应该是被墙了,现在要访问的话要自备梯子,也许过段时间就好了。
    控制台URL:
    韩国区 https://console.ap-seoul-1.oraclecloud.com/
    东京区 https://console.ap-tokyo-1.oraclecloud.com

控制台登陆界面:

登陆后可以看到,VPS虚机,自治数据库,数据仓库都有终生免费的功能可以使用,还是很值得个人学习折腾折腾的。

##Compute Instance VPS功能使用
在Compute / Instance 界面可以轻松创建各种虚机的实例Instance。
如果打算长期使用的话,配置估计要选最低的。不过现在反正有Larry给的300刀,选个几十核几十G内存的试试也未尝不可。
操作系统可以选Window、Oracle Linux、 Ubuntu

我这里就做了个Ubuntu虚机,安装配置完成之后可以保存为自己定义的镜像模板,只要资源允许以后无限复制使用都可以。

Instance IP配置

创建的实例,要勾选分配公网IP,这样才能正常通过公网访问。 VCN的私网IP是虚拟机内网使用的,VCN后面的网络配置能控制这两者之间的映射和过滤规则。

VCN及安全规则配置

VCN Virtual Cloud Networks 从名字能猜出它管理这Oracle Cloud的虚拟网络及防火墙规则。从Internet外网对Oracle云内部的访问,需要经过VCN的路由才能通,同时Oracle Cloud内部的网络也在VCN中定义及管理。
新建虚机实例的时候,会创建一个默认VCN配置。着点很好理解,如果系统不自动创建,新建的实例可定时不能访问的,那就比较不友好了。
根据Oracle Cloud的文档,在默认VCN的管理下,Linux实例可以直接通过22端口SSH上去管理,window实例需要手工添加一条映射的安全规则才能远程桌面。

就是这个默认的安全规则Security Lists了,个人用的话改改这个就基本上够用了

第一条是默认带过来的,允许22端口ssh, 请忽略第2、3、4条,比较偷懒的允许所有协议访问。大家自己用的时候千万别学这样,自己加需要的协议和端口就好了。

Ubuntu防火前设置

如果设置了允许所有规则,依然无法访问虚机,比如ssh正常但是开启tomcat,但是默认的8080网页访问不了,那估计是linux自己的防火墙拦住了。
关闭系统防火前及iptable限制试试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#停止firewall
systemctl stop firewalld.service

#禁止firewall开机启动
systemctl disable firewalld.service

#关闭iptables
service iptables stop

#去掉iptables开机启动
chkconfig iptables off
#开放所有端口
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
#Oracle自带的Ubuntu镜像默认设置了Iptable规则,关闭它
apt-get purge netfilter-persistent
reboot
#强制删除
rm -rf /etc/iptables && reboot

登陆用户设置

登录到云服务器,直接使用命令sudo -i 就可以切换到root权限,如果你想要使用root登录,请使用以下命令(密码是zzPasspword,你可以替换为其它的):
修改成允许root登陆,允许root密码登陆,修改root登陆密码

1
2
3
4
echo root:zzPasspword |sudo chpasswd root
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config;
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config;
sudo service sshd restart

如果你想要开机就使用root登录,可以使用以下命令(密码是zzPasspword,你可以替换为其它的):

1
2
3
4
5
6
7
8
#编辑cloud.cfg
vim /etc/cloud/cloud.cfg
#在最后加入以下代码
#!/bin/bash
echo root:zzPasspword |sudo chpasswd root
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config;
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config;
sudo service sshd restart

免费VPS性能评测

bench.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#命令1:
wget -qO- bench.sh | bash
#或者
curl -Lso- bench.sh | bash

#命令2:
wget -qO- 86.re/bench.sh | bash
#或者
curl -so- 86.re/bench.sh | bash

#备注:
bench.sh 既是脚本名,同时又是域名。如果以上失效,请使用以下地址下载再执行脚本:
#下载地址:
https://github.com/teddysun/across/blob/master/bench.sh

LemonBench

虚拟机使用

虚机和网络都配置好了,剩下就是用来做什么了。
相信很多人会用来做梯子,这个需求可以考虑 v2ray,配置还是比较方便的。
也可以用来做数据分析装上Anaconda 和Jupyterlab,公网可用,这是多么惬意啊。

Jupyter Notebook 500:Internal Server Error

发表于 2019-08-12 | 分类于 Python , Jupyter

Jupyter Notebook 500:Internal Server Error

毫无预兆,突然Jupyter Notebook除了能打开目录页面,打开其他任意notebook文件都是现实 500:Internal Error。

检查Jupyter Notebook的控制面板,发现报错了。
具体错误内容好像是用jinjia2模板渲染网页的某个模块出问题了。进一步确认应该是刚装好的notebook extensions模块的问题。

解决办法

决定先重装 nbextensions 试试

卸载:

1
conda remove jupyter_contrib_nbextensions

重装

1
conda install -c conda-forge jupyter_contrib_nbextensions

重装之后Jupyter Notebook功能恢复正常。

SQLAlchemy和cx_Oracle使用中碰到的数据库编码问题

发表于 2019-08-08 | 分类于 Python , SQLAlchemy

1. 系统结构及问题

最近在搭建基于Jupyter notebook,panda,dash plotly的数据分析系统。从各个业务系统抽取数据,分析展示。
难免会涉及到中间数据保存,最后返现还是绕不开数据库。为了方便选了Oracle XE,看重其pluggable PDB实在是方便,每个库还可以不同字符编码,兼容各个业务系统。
然鹅,当我用pd.to_sql输出到DB的时候,却发现各种编码问题,并不是SQLAlchemy create engine的时候指定编码就能解决的。

数据分析系统

2. 数据读取

当业务系统库是UTF-8,我在XE DB中建了一个UTF-8的PDB,本已实现免除encoding转换。各库中都保留原来的编码,python中提取之后都是unicode,理想很完美。

现实是当我用cx_Oracle读取UTF-8业务库的数据,pandas中数据内容很正常。
此处穿件连接的encoding选项功能很正常。
1
2
3
con = cx_Oracle.connect(data_driver.MAIN_CONNECT_STRING,encoding="UTF-8")

df_all = pd.read_sql_query(con=con, sql=str_sql)

3. 数据写入PDB

写入数据库时,如果直接用cx_Oracle驱动代码比较麻烦,一般直觉肯会用Pandas的DataFrame.to_sql。这样底层的令人痛疼的create table, insert 都一边去,自己要做的就是在pandas里面整理数据,to_sql扔给数据库持久化保存。从效率来看,to_sql也远比 to_excel效率高,节省资源。

写入数据库,代码节大概如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#SQLAlchemy 建立数据库engine
#这里按照文档,用了encoding='utf-8'。 双方数据都是utf-8编码,正常应该没问题。
engine = create_engine('oracle://' + 'DATANA:datana@XE_PDB3',encoding='utf-8')

#查看数据库编码,确实是 SIMPLIFIED CHINESE_CHINA.AL32UTF8
engine.execute("select userenv('language') from dual").fetchall()

#写数据
df_all.to_sql(name='表明_table'
,con=engine # utf-8 的sqlalchemy engine
,if_exists='replace'
,chunksize=10000
,dtype={ 'column name' : sqlalchemy.types.VARCHAR(10) # 对于pandas中object的列,要定义类型,否则。。。自动clob也是慢
}
,index=False
)
写代码的时候自信满满以为照顾到了各方编码,结果还是出来GBK编码错误. 数据中心有'\xa0'全角空格,gbk无法编码。
返回错误
1
UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 0: illegal multibyte sequence

4. 问题排查及解决

错误出来之后,首先想到的是数据库编码有问题。
重复检查数据库,确实双方都是UTF-8, 分析用的XE PDB中也确实是UTF-8, 手工录入'\xa0'都没有问题。所以排除数据库自身编码的问题。

其次想到的是操作系统默认编码,因为服务器是windows,通过chcp 650001,改变默认编码为unicode,在启动python,这样貌似没地方会使gbk编码了吧。应该完美了。
测试之后,还是被打脸了,错误信息一点变化都没有。

最后想排查cx_Oracle 和SQLAlchemy 这两个库。
读取数据的时候pandas直接使用的cx_Oracle 连接,指定utf-8编码之后数据是正常的,所以基本上定位是SQLAlchemy的问题。

创建engine的时候,这里指定的encoding是否有效存疑啊。看来还是SQLAlchemy和cx_Oracle集成的时候出现了问题。
1
engine = create_engine('oracle://' + 'DATANA:datana@XE_PDB3',encoding='utf-8')
翻了几篇官方文档,试了各种。。。。此处省略一万种选择。最后找到希望

Custom DBAPI connect() arguments

SQLAlchemy对于创建 engine这件事情,提供了深度客制化的选择。对于cx_Oracle兼容不太满意的情况,可以自己建一个creator,保证cx_Oracle的配置都做好之后,再传给SQLAlchemy。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 定义基于cx_Oracle的creator,在里面生成connection,保证使用UTF-8编码。这是能正常work的,在读取的时候也验证过。
def con_creator():
return cx_Oracle.connect('datana/datana@XE_PDB3', encoding="UTF-8")

#连接库生成SQLAlchemy engine时,调用creator,这时encoding写上就写上吧,可能真没用。
engine = create_engine('oracle+cx_oracle://', creator=con_creator ,encoding='utf-8')


#写数据,这回没有烦人的encoding 错误了。拜拜了gbk
df_all.to_sql(name='表明_table'
,con=engine # utf-8 的sqlalchemy engine
,if_exists='replace'
,chunksize=10000
,dtype={ 'column name' : sqlalchemy.types.VARCHAR(10) # 对于pandas中object的列,要定义类型,否则。。。自动clob也是慢
}
,index=False
)

摆脱了这个编码问题,继续我建设功能感人的数据分析平台之路。

EBS外币会计核算(二)

发表于 2019-07-17 | 分类于 EBS

EBS中买入外币,或接受外币投资

核算分录:

1
2
3
4
5
6
7
8
USD增加
借记: USD 10000 银行存款
贷记: USE 10000 已实现汇兑损益

CNY 自动根据外币日记账录入的汇率,自动生成CNY记账分录。

借记: CNY 10000 银行存款
贷记: CNY 10000 已实现汇兑损益

购入外币之后,直接计入外币分录,以后每个财务期间外币根据当期汇率和购入汇率差生成重估日记账分录。

EBS将外币卖出,比如换成人民币

1
2
3
4
5
6
7
8
USD减少
借记: USE 5000 已实现汇兑损益
贷记: USD 5000 银行存款

CNY 自动根据外币日记账录入的汇率,自动生成CNY记账分录。

借记: CNY 45000 已实现汇兑损益
贷记: CNY 45000 银行存款
1
2


零IT资源也能在线数据分析

发表于 2019-06-18 | 更新于 2019-07-15 | 分类于 Python , DataAnalysis

技术是第一生产力

现在是最好的时代,也是最坏的时代。
在技术宅的眼中,除了知识本身,其他的都应该免费,这将会是多么美好的时代。
很久以前,我们需要做数据分析,需要有自己的计算机资源,需要学习各种安装包准备环境,为了能随处展示还要做成各种格式的ppt。这些慢慢都可以成为历史了。
现在你只需要专心在技术本身,Python、Jupyter、Numpy、Pandas等等,对于不依赖大规模数据计算,对计算机依赖不高的部分工作。只要你有一根网线一个终端就可以在任何地方做数据分析,随时展示给目标人群。

解决方案 Github + JupyterNote + Binder

GitHub仓库

GitHub作为代码和资源池仓库,保存所有数据(连接)、源码、以及分析结果。

JupyterNote

数据分析,最方便的工具还是Jupyter NoteBook。实时交互,文档和代码统一,所见即所得。

选用JupyterNoteBook,对于在线的互动计算资源,可以选用官方的Binder

Binder

Binder 项目是官方提供的,为Github上托管的代码提供动态的计算资源的项目。
简单的说,只需要你在GitHub上托管JupyterNotebook项目库,你就能在Binder上动态创建一个Docker环境,环境中有包含运行代码所必须的软件及硬件资源。
Binder怎么能知道我们项目需要哪些软件环境了,其实就是在普通给的GitHub项目中添加了一个Configure文件。配置文件的格式及功能有很多,如果使用功能不复杂的话,简单了解一下## environment.yml就好了,简单的说就是个Conda环境的配置文件,加载的时候自动在Conda里面安装配置的软件。

阅读全文 »

Process PDF by Python(pdfminer)

发表于 2019-04-25 | 分类于 Python , basic , PDF

Portable Document Format(可移植文档格式)即PDF文件格式,是由Adobe发明,目前由国际标准化组织(ISO)维护的开放标准。

在Python中处理PDF有以下途径:

  • pdfminer系列,比较专业的文本提取工具。包括pdfminer、pdfminer.six等
    • pdfplumber 基于PDFMiner系列的高效提取pdf提取工具
  • PyPDF2 也是一款比较专业有口碑的python PDF处理工具。不仅支持文本,还支持元数据提取,以及其他分割、合并等编辑。支持Python3。
  • PyPDF4 pypdf2停止更新之后,分支出来的可能还在更新的新版本。

pdfminer系列工具

  • pdfminer是比较得到大家公认的PDF提取工具,然鹅更新停止在python2,从python3大行其道之后,大家就另寻新工具吧。
  • pdfminer.sixpython3来了,”幸运”的是,我们后来又了pdfminer.six分支,大家会及时的用脚投票,踩出一条新路。为什么是six呢,[Fork of PDFMiner using six for Python 2+3 compatibility]

pdfminer.six 安装

pip install pdfminer.six

阅读全文 »

Python-basic-10-Socket

发表于 2019-04-24 | 分类于 Python , basic , network

Socket


Get Hostname

1
2
3
4
5
6
7
8
9
10
11
>>> import socket
>>> socket.gethostname()
'root@bisratyalew'

>>> hostname = socket.gethostname()

>>> socket.gethostbyname('localhost')
'127.0.0.1'

>>> socket.gethostbyname(hostname) ### Returns ip address
'192.168.1.3'


FTP Client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import socket                   # Import socket module

port = 60000 # Reserve a port for your service.
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.

print('Server listening....')

while True:
conn, addr = s.accept() # Establish connection with client.
print('Got connection from', addr)
data = conn.recv(1024)
print('Server received', repr(data))

filename = 'mytext.txt'
with open(filename, 'rb') as f:
in_data = f.read(1024)
while in_data:
conn.send(in_data)
print('Sent ', repr(in_data))
in_data = f.read(1024)

print('Done sending')
conn.send('Thank you for connecting')
conn.close()


# client side server

import socket # Import socket module

s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 60000 # Reserve a port for your service.

s.connect((host, port))
s.send("Hello server!")

with open('received_file', 'wb') as f:
print('file opened')
while True:
print('receiving data...')
data = s.recv(1024)
print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)

f.close()
print('Successfully get the file')
s.close()
print('connection closed')


FTP Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""
File transfer protocol used to send and receive files using FTP server.
Use credentials to provide access to the FTP client
"""

from ftplib import FTP
ftp = FTP('xxx.xxx.x.x') # Enter the ip address or the domain name here
ftp.login(user='username', passwd='password')
ftp.cwd('/Enter the directory here/')

"""
The file which will be received via the FTP server
Enter the location of the file where the file is received
"""

def recieve_file():
file_name = 'example.txt' """ Enter the location of the file """
with open(file_name, 'wb') as LocalFile:
ftp.retrbinary('RETR ' + file_name, LocalFile.write, 1024)
ftp.quit()

"""
The file which will be sent via the FTP server
The file send will be send to the current working directory
"""

def send_file():
file_name = 'example.txt' """ Enter the name of the file """
with open(file_name, 'rb') as LocalFile:
ftp.storbinary('STOR ' + file_name, LocalFile)
ftp.quit()


Back To Top

Python-basic-9-Asyncio

发表于 2019-04-24 | 分类于 Python , basic , concurrent

Asyncio

Definition

asyncio is a library included in Python 3.5 that supports a programming model where sometimes, operations that would normally block the thread until some other event happened (like getting a response from a network connection) instead allow other code to run on that thread while waiting.

asyncio takes a very, very explicit approach to asynchronous programming: only code written in methods flagged as async can call any code in an asynchronous way.

asyncio.run

This is new in Python 3.7

1
2
3
4
5
6
7
8
9
10
>>> import asyncio
>>> from concurrent.futures import ThreadPoolExecutor

>>> e = ThreadPoolExecutor()
>>> async def read_file(file_):
... loop = asyncio.get_event_loop()
... with open(file_) as f:
... return (await loop.run_in_executor(e, f.read))
...
>>> ret = asyncio.run(read_file('/etc/passwd'))


Socket with Asyncio

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import asyncio
import socket

host = 'localhost'
port = 9527
loop = asyncio.get_event_loop()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setblocking(False)
s.bind((host, port))
s.listen(10)

async def handler(conn):
while True:
msg = await loop.sock_recv(conn, 1024)
if not msg:
break
await loop.sock_sendall(conn, msg)
conn.close()

async def server():
while True:
conn, addr = await loop.sock_accept(s)
loop.create_task(handler(conn))

loop.create_task(server())
loop.run_forever()
loop.close()
1
2
3
4
5
output: (bash 1)

$ nc localhost 9527
Hello
Hello
1
2
3
4
5
output: (bash 2)

$ nc localhost 9527
World
World

Python-basic(8) Web Data Handling

发表于 2019-04-24 | 分类于 Python , basic , web

Web Data Handling


Make a Request

1
2
3
import urllib.request ## urllib module is used to send request and receive response from a server. It can used to get html / JSON / XML data from an api.

webData = request.urlopen("http://www.google.com") ## It opens a connection to google.com and returns an object of class http.client.HTTPResponse

Read

return the HTML data of the webpage.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

### Get Code
```.getcode()``` returns the status code of the connection establishment.


### HTML Parsing

```python
from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
def error(self, message):
pass

parser = MyHTMLParser()
f = open("check.html")
if f.mode == 'r': # file successfully opened
contents = f.read()
parser.feed(contents)

JSON Parsing

1
2
import json
json_data = json.loads(response)

XML Parsing

1
2
import xml.dom.minidom
doc = minidom.parse("check.xml")

Python-基础(7) Regular Expressions

发表于 2019-04-24 | 分类于 Python , basic , regular

Regular Expressions

在正则表达式中的字符:

  • Non-special chars match themselves. 非特殊字符,匹配字符自身
  • Exceptions are special characters. 特殊字符不是匹配自身,而是按照如下特殊字符匹配规则匹配

特殊字符匹配规则:

1
\       Escape special char or start a sequence.转义字符,用于停止特殊字符匹配功能
1
.       Match any char except newline, see re.DOTALL 匹配所有字符(不包括换行符)
1
^       Match start of the string, see re.MULTILINE 匹配行开始
1
$       Match end of the string, see re.MULTILINE 匹配行结束
1
[]      Enclose a set of matchable chars 列举
1
R|S     Match either regex R or regex S.  【|】或
1
2
()      Create capture group, & indicate precedence     分组符
After '[', enclose a set, the only special chars are:
1
]   End the set, if not the first char
1
-   A range, eg. a-c matches a, b or c   表范围
1
^   Negate the set only if it is the 1st char 否定

Regular Expression Examples

re.findall()

1
2
3
4
5
# split all string from a sentence
>>> import re
>>> source = "Python is great!"
>>> re.findall('[\w]+', source) #\w 匹配所有字母
['Python', 'is', 'great!']

Match hex color value

1
2
3
4
>>> re.match('^#?([a-f0-9]{6}|[a-f0-9]{3})$', '#ffffff')
<_sre.SRE_Match object at 0x0000000002F04120>
>>> re.match('^#?([a-f0-9]{6}|[a-f0-9]{3})$', '#cdcdcd')
<_sre.SRE_Match object at 0x0000000002EA3160>

Match username doesn’t have any special characters

1
2
3
4
>>> re.match('^[a-zA-Z0-9-_]{3,16}$', 'Check') is not None
True
>>> re.match('^\w|[-_]{3,16}$', 'che%ck') is not None
False

Match email address format

1
2
3
re.match('^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$',
... 'check@example.com')
<_sre.SRE_Match object at 0x0000000002EA3180>
12…4
Chong

Chong

33 日志
25 分类
18 标签
GitHub
© 2019 All right reserved