[tesseract4.1.1] Ubuntuにtesseract(Eng、日本語、簡体字中国語、繁体字中国語、スペイン語)を入れよう

1. PPA(パーソナル・パッケージ・アーカイブ)を追加
$ sudo add-apt-repository ppa:alex-p/tesseract-ocr
$ sudo apt-get update

2. Tesseractインストール
$ sudo apt install tesseract-ocr
$ sudo apt install libtesseract-dev

$ tesseract -v
tesseract 4.1.1-rc2-25-g9707
$ tesseract –list-langs
List of available languages (2):
eng
osd

3. 日本語、簡体字中国語、繁体字中国語、スペイン語をインストール
$ sudo apt install tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract-ocr-spa
$ tesseract –list-langs
List of available languages (6):
chi_sim
chi_tra
eng
jpn
osd
spa

4. pyocr install
$ pip install pyocr

5. 中国語の画像を読み取る

$ tesseract chinabank.jpeg output -l chi_sim
中国平安
PINGAN

保险’ 银行. 投资

6. pythonで書く

from PIL import Image
import sys
import pyocr

tools = pyocr.get_available_tools()
langs = "chi_sim"

img = Image.open('images.jpeg')
txt = tools[0].image_to_string(
		img,
		lang=langs,
		builder=pyocr.builders.TextBuilder(tesseract_layout=6)
	)
print(txt)

$ python app.py
中国平安
PINGAN
保险; 银行.投资

さて、これをDjangoで実装したい。
思ったより考えるの難しいな。

PythonでCSVを出力したい

DjangoでCSVを出力したいのですが、まずはlocalでpythonで試します。

– encodingを付けないと文字化けするので注意が必要

import csv

file = open('new.csv', 'w', newline='', encoding='utf_8_sig')
w = csv.writer(file)
w.writerow([2191,'テラ',851])
w.writerows([[4563,'アンジェス',1435],[3911,'Aiming',693],[3776,'ブロードバンドタワー',384]])

file.close()

$ python test.py

writerowをforループで良さそうです。これをDjangoで実装します。

Pythonで今月、前月、来月、昨年、毎月あたりを取得する

### 今日
まず本日から

from datetime import datetime, date, timedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d'))

$ python test.py
2020-10-10

#### 今年、今月、来月、前月

from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d')) # 今日

print(today.year) # 今年
print(today.month) # 今月

next_month = today + relativedelta(months=1)

print(next_month.year) # 来月
print(next_month.month) # 来月

one_month_before = today - relativedelta(months=1)

print(one_month_before.year) # 前月
print(one_month_before.month) # 前月

$ python test.py
2020-10-10
2020
10
2020
11
2020
9

前月や翌月など月ごとの計算はtimedeltaではできないらいしいので、relativedeltaを使うと良いらしい。
月単位で計算できるrelativedeltaはかなり使えますね。

Pythonでqrコードを作りたい

QRコード画像生成ライブラリ「qrcode」をインストールします。

$ pip install qrcode
$ pip install pillow

### テキストを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('test text')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

### URLを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('https://www.google.com/')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

アラ? 凄い簡単に出来ますね。。。簡単過ぎてビックリした。

Python & reportlab でPDF見積書を作成

pythonでPDFの見積書を作っていきます。
reportlabでテーブルではなくテキスト配置で右寄せがわからないのが脛に傷。

# -*- coding: utf-8 -*-

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.lib.pagesizes import A4, portrait
from reportlab.platypus import Table, TableStyle
from reportlab.lib.units import mm
from reportlab.lib import colors


def make(filename="estimate"): # ファイル名
    pdf_canvas = set_info(filename) # キャンバス名
    print_string(pdf_canvas)
    pdf_canvas.save() # 保存

def set_info(filename):
	pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename))
	pdf_canvas.setAuthor("hpscript")
	pdf_canvas.setTitle("見積書")
	pdf_canvas.setSubject("見積書")
	return pdf_canvas

def print_string(pdf_canvas):
	# フォント登録
	pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))

	width, height = A4

	# 見積日
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(440, 810, '見積日: 2020年10月1日')

	# title
	font_size = 24
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(245, 770, '御 見 積 書')

	# 線
	pdf_canvas.line(50, 750, 550, 750)

	# 宛先
	font_size = 14
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(60, 710, '六本木ソフトウェア株式会社 御中')
	pdf_canvas.drawString(60, 690, '営業部  山田太郎 様')

	# 線
	pdf_canvas.line(50, 680, 350, 680)

	# 注釈
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(190, 670, '下記の通りお見積もり申し上げます。')

	# 納期、支払条件、有効期限
	font_size = 12
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(100, 635, '納期:')
	pdf_canvas.drawString(200, 635, '別途ご相談')
	pdf_canvas.line(200, 633, 350, 633)

	pdf_canvas.drawString(100, 615, '支払い条件:')
	pdf_canvas.drawString(200, 615, '月末締め翌月末払い')
	pdf_canvas.line(200, 612, 350, 612)

	pdf_canvas.drawString(100, 595, '有効期限:')
	pdf_canvas.drawString(200, 595, 'お見積り後2週間')
	pdf_canvas.line(200, 593, 350, 593)

	# 自社情報
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(360, 680, '丸の内ソフトウェア株式会社')
	pdf_canvas.drawString(360, 670, '〒100-0001')
	pdf_canvas.drawString(360, 660, '東京都千代田区千代田1-1-1')
	pdf_canvas.drawString(360, 645, 'TEL: 03-1234-5678')
	pdf_canvas.drawString(360, 635, 'E-mail: info@marunouchi-soft.com')
	pdf_canvas.drawString(360, 625, '担当: 田中一郎')

	# 合計金額
	font_size = 14
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(80, 550, '合計金額')
	pdf_canvas.drawString(180, 550, '800,000 円 (税込)')

	# 線
	pdf_canvas.line(50, 540, 350, 538)

	# 分類、型番、品名、規格寸法、基準単価
	data = [
		['分類', '型番','品名', '規格寸法','数量','基準単価'],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
	]
	table = Table(data, colWidths=(25*mm, 25*mm, 55*mm, 25*mm, 15*mm,30*mm), rowHeights=7.5*mm)
	table.setStyle(TableStyle([
			('FONT', (0, 0), (-1, -1), 'HeiseiKakuGo-W5', 8),
			('BOX', (0, 0), (-1, -1), 1, colors.black),
			('INNERGRID', (0, 0), (-1, -1), 1, colors.black),
			('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
		]))
	# table.wrapOn(pdf_canvas, 20*mm, 20*mm)
	table.wrapOn(pdf_canvas, 20*mm, 20*mm)
	table.drawOn(pdf_canvas, 18*mm, 100*mm)

	# 小計、消費税、合計
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(360, 250, '小計:')
	pdf_canvas.drawString(450, 250, '700000円')
	pdf_canvas.line(360, 245, 550, 245)	

	pdf_canvas.drawString(360, 230, '消費税:')
	pdf_canvas.drawString(450, 230, '70000円')
	pdf_canvas.line(360, 225, 550, 225)	

	pdf_canvas.drawString(360, 210, '合計:')
	pdf_canvas.drawString(450, 210, '770000円')
	pdf_canvas.line(360, 205, 550, 207)	

	# 宛先
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(60, 175, '備考')

	pdf_canvas.rect(50, 50, 500, 120)



	pdf_canvas.showPage()
	
if __name__ == '__main__':
	make()

$ python estimate.py

OK、これをDjangoに組み込みたい。この関数はviews.pyに書くけば良いのか???

Python&reportlabでPDFを生成2

# -*- coding: utf-8 -*-

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
import reportlab.lib.colors as color

def make(filename="test"):
	pdf_canvas = set_info(filename)
	print_string(pdf_canvas)
	# print_figure(pdf_canvas)
	# print_line(pdf_canvas)
	pdf_canvas.save()

# 初期設定
def set_info(filename):
	pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename), bottomup=False) # 原点は左上

	pdf_canvas.setAuthor("hpscript")
	pdf_canvas.setTitle("make pdf using reportlab")
	pdf_canvas.setSubject("reportlab")

	return pdf_canvas


# 文字
def print_string(pdf_canvas):
	pdfmetrics.registerFont(UnicodeCIDFont("HeiseiKakuGo-W5"))
	pdfmetrics.registerFont(UnicodeCIDFont("HeiseiMin-W3"))

	pdf_canvas.setFont("HeiseiKakuGo-W5", 15)
	pdf_canvas.drawString(50, 50, "日経平均レバレッジ上場投信")

	pdf_canvas.setFont("HeiseiMin-W3", 30)
	pdf_canvas.drawString(300, 100, "日経ダブルインバース上場投信")

if __name__ == '__main__':
	make()

$ python test.py

いけますね、なんとなく掴みました。
続いて図形

def print_line(pdf_canvas):
	pdf_canvas.rect(50, 150, 200, 250)

	pdf_canvas.setFillColor(color.blue)
	pdf_canvas.circle(400, 350, 50, stroke=False, fill=True)

# 線
def print_line(pdf_canvas):
	# 普通の線
	pdf_canvas.line(50, 450, 500, 450)

	# 赤い太い線
	pdf_canvas.setStrokeColor(color.red)
	pdf_canvas.setLineWidth(10)
	pdf_canvas.line(100, 500, 550, 500)

	# 破線
	pdf_canvas.setStrokeColor(color.black)
	pdf_canvas.setLineWidth(5)
	pdf_canvas.setDash([2, 8, 5, 10])
	pdf_canvas.line(150, 550, 600, 550)

	# 複数の線
	pdf_canvas.setLineWidth(1)
	pdf_canvas.setDash([])
	lines = [(100, 650, 200, 750),(200, 750, 300, 650),(300, 650, 300, 750),(100, 700, 400, 700)]
	pdf_canvas.lines(lines)

OK^^

PythonでPDFの見積書を描画したい1

販売管理システムの見積一覧ページで、詳細ボタンを押下するとPDFの見積書を表示し、ダウンロードボタンを押下するとPDFの見積書をダウンロードできるようにしたい。

最初なのでデザインはなるべくシンプルに
▼見積書イメージ

## reportlab
PDF作成ライブラリのreportlabを使用します。

– reportlabのインストール
$ pip install reportlab

### 初期設定
app.py

def make(filename="estimate"):
	pdf_canvas = set_info(filename)
	print_string(pdf_canvas)
	pdf_canvas.save() # pdfを保存

def set_info(filename):
	pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename))
	pdf_canvas.setAuthor("hpscript")
	pdf_canvas.setTitle("見積書")
	pdf_canvas.setSubject("見積書")
	return pdf_canvas

### 日本語設定

def print_string(pdf_canvas)
	# フォント登録
	pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))

	width, height = A4

	font_size = 24

	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)

	pdf_canvas.drawString(60, 770, '見積書')

### 表の描画
データ入力
-> 二次元配列で書く
e.g. 三行四列の場合

	data = [
		['(0,0)', '(1,0)', '(2,0)'],
		['(0,1)', '(1,1)', '(2,1)'],
		['(0,2)', '(1,2)', '(2,2)'],
		['(0,3)', '(1,3)', '(2,3)'],
	]

tableの大きさ指定
->全列30mm, 全行40mmの場合

table = Table(data, colWidths=30*mm, rowHeights=40*mm)

->1列目10mm、2列目20mm、3列目30mm、1〜2行目30mm、3〜4行目50mmの場合

table = Table(data, colWidths=(10*mm, 20*mm, 30*mm), rowHeights=(30*mm, 30*mm, 50*mm, 50*mm))

tableの装飾

	table.setStyle(TableStyle([
		...
	]))

表にフォントを設定する

('FONT', 始点, 終点, fontname, size)
('FONT', (0, 0), (2, 3), self.font_name, 10)
('FONT', (0, 0), (-1, -1), self.font_name, 10)

表を罫線で囲む

	('BOX', 始点, 終点, 太さ, color)
	('BOX', (0, 0), (2, 3), 1, colors.black)
	('BOX', (0, 0), (-1, -1), 1, colors.black)

四角の内側に罫線を書く

	('INNERGRID', 始点, 終点, 太さ, color)
	('INNERGRID', (0, 0), (2, 3), 1, colors.black)
	('INNERGRID', (0, 0), (-1, -1), 1, colors.black)

フォントの場所を指定

	('VALIGN', 始点, 終点, TOP or MIDDLE or BOTTOM)
	('VALIGN', (0, 0), (0, 3), TOP)
	('VALIGN', (1, 0), (1, 3), MIDDLE)
	('VALIGN', (2, 0), (2, 3), BOTTOM)

セルの結合

	('SPAN', 始点, 終点)
	('SPAN', (0,0), (0, 1))
	('SPAN', (2, 2) (2, 3))


指定した場所に線を引く
- 横線

	('LINEBEFORE', 始点, 終点, 太さ, color)
	('LINEBEFORE', (2, 1), (2, 2), 1, colors.black)

– 縦線

	('LINEABOVE', 始点, 終点, 太さ, color)
	('LINEABOVE', (0, 0), (0, 0), 1, colors.black)

テーブルを書き出す位置を指定

	table.wrapOn(pdf_canvas, 145*mm, 235*mm)
	table.wrapOn(pdf_canvas, 145*mm, 235*mm)

なんとなく基礎を理解したので、次は実際に書いていきたいと思います。

quandlから日経225データを取得する

$ pip install quandl

ダブルインバース(1357)のデータを見てみる
>>> import quandl
>>> quandl.ApiConfig.api_key = ‘hogehoge’
>>> data = quandl.get(‘TSE/1357’)
>>> data
Open High Low Close Volume
Date
2014-07-16 5270.0 5280.0 5230.0 5260.0 43965.0
2014-07-17 5230.0 5270.0 5190.0 5260.0 52325.0
2014-07-18 5400.0 5440.0 5350.0 5350.0 125707.0
2014-07-22 5320.0 5320.0 5240.0 5270.0 71590.0
2014-07-23 5250.0 5290.0 5250.0 5290.0 19141.0
… … … … … …
2017-12-18 1285.0 1289.0 1267.0 1268.0 20980910.0
2017-12-19 1263.0 1274.0 1259.0 1272.0 8550773.0
2017-12-20 1277.0 1281.0 1266.0 1268.0 8632009.0
2017-12-21 1274.0 1290.0 1269.0 1274.0 10881922.0
2017-12-22 1275.0 1281.0 1268.0 1270.0 8738199.0

2017年末までのデータしか取得できない。

### 日経平均の取得
https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key=${api_key}

レスポンス結果
{“dataset_data”:{“limit”:null,”transform”:null,”column_index”:null,”column_names”:[“Date”,”Open”,”High”,”Low”,”Last”,”Change”,”Settle”,”Volume”,”Previous Day Open Interest”],”start_date”:”1990-09-26″,”end_date”:”2020-08-05″,”frequency”:”daily”,”data”:[[“2020-08-05”,22530.0,22555.0,22355.0,22395.0,-30.0,22390.0,22.0,6.0],[“2020-08-04”,null,22555.0,null,22435.0,135.0,22420.0,0.0,6.0],…// 省略

$ sudo apt-get install libpng-dev
$ sudo apt-get install libfreetype6-dev
$ sudo pip install matplotlib
$ sudo pip install ipython jupyter

$ python
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import json
>>> json.dumps([‘foo’, {‘bar’: (‘baz’, None, 1.0, 2)}])
‘[“foo”, {“bar”: [“baz”, null, 1.0, 2]}]’

### quandlからデータ取得
app.py

# API
import requests
import json
import datetime as dt
# date
from dateutil.relativedelta import relativedelta
from pytz import timezone

# データ前処理、グラフ表示
import numpy as np
import pandas as pd
from IPython import get_ipython
ipy = get_ipython()
if ipy is not None:
    ipy.run_line_magic('matplotlib', 'inline')
import matplotlib.pyplot as plt

fig = plt.figure()

# エンドポイントを定義
url = 'https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key=hogehoge'

# json でデータ取得
catched_response = requests.get(url)
json_data = catched_response.json()


columns = json_data['dataset_data']['column_names']
values = json_data['dataset_data']['data']

df = pd.DataFrame(values, columns=columns)
df.loc[:,'Date'] = pd.to_datetime(df.loc[:,'Date'])
df.set_index('Date', inplace=True)

df.loc[:,'High'].interpolate(inplace=True)
df.loc[:,'Last'] = np.minimum(df.loc[:,'Last'].interpolate(),df.loc[:,'High'])

today = dt.datetime.now(timezone('Asia/Tokyo'))
t_year = today - relativedelta(years=1)
t_date = t_year.strftime('%Y-%m')

df_target = df.loc[:t_date,'Last'].sort_index()
df_target.plot()
df_target.rolling(window = 5).mean().plot()
df_target.rolling(window = 25).mean().plot()

fig.savefig("dist/img/225.png")

$ python app.py

トップページに嵌め込みます。

matplotlibのグラフはクーロンで日次でバッチ処理すれば良いですね。
景気動向指数の予定だったが、CIの各指標がAPIで公開されていないので、225のチャートで良しとするか。
致し方がない。

luigi

データフロー制御フレームワーク
spotifyが開発
タスク同士の依存関係を解決し、オブジェクト指向でデータ処理のタスクが書ける
Hadoopとの連携

class Artists(luigi.Task):

	date_interval = luigi.DateIntervalParameter()
	use_hadoop = luigi.BoolParameter()

	def requires(self):
		if self.use_hadoop:
			return AggregateArtistsHadoop(self.date_interval)
		else:
			return AggregateArtists(self.date_interval)

	def output(self):
		return luigi.LocalTarget("data/top_artists_%s.tsv" % self.date_interval)

	def run(self):
		top_10 = nlargest(10, self._input_iterator())
		with self.output().open('w') as out_file:
			for streams, artist in top_10:
				out_line = '\t'.join([
						str(self.date_interval.date_a),
						str(self.date_interval.date_b),
						artist,
						str(streams)
				])
				out_file.write((out_line + '\n'))

	def _input_iterator(self):
		with self.input().open('r') as in_file:
			for line in in_file:
				artist, streams = line.strip().split()
				yield int(streams), artist

statsmodel

[vagrant@localhost python]$ pip install statsmodels

import numpy as np 
import statsmodels.api as sm 
import matplotlib.pyplot as plt 

data = np.loadtxt("data.txt")
x = data.T[0]
y = data.T[1]

nsample = x.size 

X = np.column_stack((np.repeat(1, nsample), x))

model = sm.OLS(y, X)
results = model.fit()

print(results.summary())