【python】psycopg2

psycopg2はpythonからPostgreSQLに接続するためのライブラリ
C言語で書かれたlibpgのラッパー

ライブラリのインストール
$ pip install psycopg2

データベース作成
postgres=# create database mydb;
CREATE DATABASE

テーブル作成
postgres=# \c mydb
You are now connected to database “mydb” as user “postgres”.
CREATE TABLE users(
id SERIAL,
email varchar(255) NOT NULL,
password varchar(255) NOT NULL,
PRIMARY KEY(id)
);

mydb=# \dt
List of relations
Schema | Name | Type | Owner
——–+——-+——-+———-
public | users | table | postgres
(1 row)

import psycopg2

connection = psycopg2.connect(host='localhost',
								user='postgres',
								password='password',
								database='mydb')

with connection:
	with connection.cursor() as cursor:
		sql = "INSERT INTO users(email, password) VALUES(%s, %s)"
		cursor.execute(sql, ('webmaster@python.org', 'very-secret'))

	connection.commit()

mydb=# select * from users;
id | email | password
—-+———————-+————-
1 | webmaster@python.org | very-secret
(1 row)

withを使わずに記述することも可能。その場合は、自動的に閉じないため明示的に閉じる必要がある

import psycopg2

connection = psycopg2.connect(host='localhost',
								user='postgres',
								password='password',
								database='mydb')

cursor = connection.cursor()
sql = "INSERT INTO users(email, password) VALUES (%s, %s)"
cursor.execute(sql, ('webmaster2@python.org', 'much-secret'))

connection.commit()

cursor.close()
connection.close()

なるほど、psqlに接続するためのライブラリってことね

[Python] pandasとは

Pandasはデータ解析を容易にする機能を提供するPythonのデータ解析ライブラリ
Pandasの特徴は、データフレーム(DataFrame)などの独自のデータ構造が提供されており様々な処理が可能
表形式のデータをSQLまたはRのように操作することが可能

Pandasの例
– CSV, Excel, RDBなどにデータを入出力できる
– データの前処理(NaN/Not a Number, 欠損値)
– データの集約及びグループ演算
– データに対しての統計処理及び回帰処理

import pandas as pd
# from pandas import Series

s1 = pd.Series([1,2,3,5])
print(s1)

$ python3 main.py
0 1
1 2
2 3
3 5

### データフレーム
データフレームは二次元のラベル付きデータ構造で、Pandasでは最も多く使われるデータ型

import pandas as pd
df = pd.DataFrame({
	'名前':['田中','山田','高橋'],
	'役割':['営業部長','広報部','技術責任者'],
	'身長':[178, 173, 169]
	})
print(df)
print(df.dtypes)

print(df.columns)

$ python3 main.py
名前 役割 身長
0 田中 営業部長 178
1 山田 広報部 173
2 高橋 技術責任者 169
名前 object
役割 object
身長 int64
dtype: object
Index([‘名前’, ‘役割’, ‘身長’], dtype=’object’)

import pandas as pd
data = {
	'名前':['田中','山田','高橋'],
	'役割':['営業部長','広報部','技術責任者'],
	'身長':[178, 173, 169]
	}
df = pd.DataFrame(data, columns=["名前","役割","身長"])
df.columns = ["Name", "Position", "height"]

print(df)

$ python3 main.py
Name Position height
0 田中 営業部長 178
1 山田 広報部 173
2 高橋 技術責任者 169

### head()とtail()

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(20, 2))
print(df.head())
print(df.tail())

print(df.head().append(df.tail()))
print(df.head(3).append(df.tail(3)))

$ python3 main.py
0 1
0 0.330724 -1.143377
1 -0.123135 1.368603
2 1.230545 0.606766
3 0.687297 -1.633271
4 0.365082 0.226383
0 1
15 0.822776 -2.105489
16 1.306649 0.672192
17 0.846219 0.454775
18 -0.376438 -0.903396
19 -1.165510 -0.558250
0 1
0 0.330724 -1.143377
1 -0.123135 1.368603
2 1.230545 0.606766
3 0.687297 -1.633271
4 0.365082 0.226383
15 0.822776 -2.105489
16 1.306649 0.672192
17 0.846219 0.454775
18 -0.376438 -0.903396
19 -1.165510 -0.558250
0 1
0 0.330724 -1.143377
1 -0.123135 1.368603
2 1.230545 0.606766
17 0.846219 0.454775
18 -0.376438 -0.903396
19 -1.165510 -0.558250

その他に多様な機能がある。

PythonでPDFからテキストを抽出する

$ pip3 install pdfminer3

#!/usr/bin/env python3  
# -*- coding: utf-8 -*-

from pdfminer3.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer3.converter import PDFPageAggregator
from pdfminer3.pdfpage import PDFPage
from pdfminer3.layout import LAParams, LTTextContainer

resourceManager = PDFResourceManager()
device = PDFPageAggregator(resourceManager, laparams=LAParams())

pdf_file_name = './sample.pdf'
with open(pdf_file_name, 'rb') as fp:
	interpreter = PDFPageInterpreter(resourceManager, device)
	for page in PDFPage.get_pages(fp):
		interpreter.process_page(page)
		layout = device.get_result()
		for lt in layout:
			if isinstance(lt, LTTextContainer):
				print(lt.get_text())
device.close()

読み込み対象のPDFはこちら

これで実行してみる
$ python3 pdf_text1.py
1. フリーランス新法概要 1

1. フリーランス新法(フリーランス保護新法) 概要

2022年秋の臨時国会でフリーランス保護新法が成立すると報道されています。では、フリーランス保護新法とは一体どんなものなのでしょうか。
業務委託を行う事業者の遵守事項が規定されます。

ア) 業務委託の開始・終了に関する義務
①事業委託の際の書面の交付等
事業者がフリーランスに対して仕事を依頼するときは、「業務委託の内容(仕事内容)、報酬額等」を記載した書面を交付するか、メールなどの電磁的記
録を提供しなければならない
また一定期間以上、継続してフリーランスと仕事をする場合、契約期間や契約の終了事由、中途解約時の費用などを合わせて記載する必要がある
②契約の中途解約・不更新の際の事前予告
「中途解除日または契約期間満了日の30日前まで」にその旨を予告をしなければならない。またフリーランスから求められれば、事業者は契約の終了
理由を明らかにする必要がある。

イ) 業務委託の募集に関する義務
①募集の際の的確表示
不特定多数のフリーランスを対象に仕事を募集する場合は、正確かつ最新の情報を伝えなければならない。虚偽の表示や誤解を生むような表示は禁

②募集に応じた者への条件明示、募集内容と契約内容が異なる場合の説明義務
事業者は応募してきたフリーランスに対し、仕事内容や報酬等を明示しなければんらない。募集時点で明示した情報と異なる内容で契約した場合は、
その旨を説明する必要がある。

ウ) 報酬の支払いに関する義務
事業者はフリーランスから納品物やサービスの提供を受けた日から60日以内に報酬を支払わなければならない。

エ) フリーランスと取引を行う事業者の禁止行為
フリーランスに責任のある理由なしに受領を拒否する
フリーランスに責任のある理由なしに報酬を減額する
フリーランスに責任のある理由なしに返品を行う
相場に比べ、著しく低い報酬額を不当に定める
正当な理由なく、物の購入やサービスの利用を強制する
金銭やサービス、その他の経済上の利益を提供させる
フリーランスに責任のある理由なしに給与の内容を変更させたり、やり直させたりする

関係者外秘

1

2. フリーランス新法概要

2. フリーランス新法(フリーランス保護新法) 概要

オ) 就業環境の整備として事業者が取り組むべき事項
①ハラスメント対策
②出産・育児・介護との両立への配慮

2. 違反した場合の対応等
行政から必要な履歴確保措置が執行される

3.フリーランスの申告及び国が行う相談対応の実現
事業者に違反行為があった場合、フリーランスはその旨を国の行政機関に申告することができる。

関係者外秘

2

うおおおおおおお、これは凄い

【python3】タイムアウト設定

#!/usr/bin/env python3  
# -*- coding: utf-8 -*-

import sys
import time
from time_decorator import timeout, TimeoutError

class TimeoutDecoratorTest(object):
	def test(self, sleep_sec, timeout_sec):
		@timeout(timeout_sec)
		def inner_test():
			print("Start sleep " + str(sleep_sec) + " seconds.")
			print("Timeout in " + str(timeout_sec) + " seconds.")
			time.sleep(sleep_sec)
		try:
			inner_test()
			print("End sleep.")
		except TimeoutError:
			print("Timeout!")

if __name__ == '__main__':
	sleep_sec = int(sys.argv[1])
	timeout_sec = int(sys.argv[2])
	t = TimeoutDecoratorTest()
	t.test(sleep_sec, timout_sec)

タイムアウト処理を行うためのライブラリ
pip install wrap-timeout-decorator

import wrapt_timeout_decorator

@wrapt_timeout_decorator.timeout(dec_timeout=30)
def func():
while True:
pass

if __name__ == ‘__main__’:
func()

タイムアウトの設定をするのね

pythonのdebug

pdbを使用できる

import pdb

def factorial(n, sum=0):
	if n == 0:
		return sum

	pdb.set_trace()
	sum += n
	print(sum)
	return factorial(n-1, sum)

if __name__ == "__main__":
	factorial(5)
$ python3 test.py
> /home/vagrant/dev/test/test.py(8)factorial()
-> sum += n
(Pdb) bt
  /home/vagrant/dev/test/test.py(13)<module>()
-> factorial(5)
> /home/vagrant/dev/test/test.py(8)factorial()
-> sum += n
(Pdb) list
  3  	def factorial(n, sum=0):
  4  		if n == 0:
  5  			return sum
  6  	
  7  		pdb.set_trace()
  8  ->		sum += n
  9  		print(sum)
 10  		return factorial(n-1, sum)
 11  	
 12  	if __name__ == "__main__":
 13  		factorial(5)
(Pdb) 

Pythonのテストコード

# coding:utf-8

import unittest
import fizzbuzz as fb

class FizzBuzzTest(unittest.TestCase):
	def setUp(self):
		pass

	def tearDown(self):
		pass

	def test_normal(self):
		self.assertEqual(1, fb.fizzbuzz(1))

	def test_fizz(self):
		self.assertEqual("Fizz", fb.fizzbuzz(3))

	def test_buzz(self):
		self.assertEqual("Buzz", fb.fizzbuzz(5))

	def test_fizzbuzz(self):
		self.assertEqual("FizzBuzz", fb.fizzbuzz(3))

if __name__ == "__main__":
	unittest.main()

メインコード

# coding:utf-8

def fizzbuzz(number):
	if number % 15 == 0:
		return "FizzBuzz"
	if number % 5 == 0:
		return "Buzz"
	if number % 3 == 0:
		return "Fizz"

	return number

if __name__ == "__main__":
	for i in range(1, 101):
		print(fizzbuzz(i)) 

t$ python3 test_fizzbuzz.py
..F.
======================================================================
FAIL: test_fizzbuzz (__main__.FizzBuzzTest)
———————————————————————-
Traceback (most recent call last):
File “test_fizzbuzz.py”, line 23, in test_fizzbuzz
self.assertEqual(“FizzBuzz”, fb.fizzbuzz(3))
AssertionError: ‘FizzBuzz’ != ‘Fizz’
– FizzBuzz
+ Fizz

———————————————————————-
Ran 4 tests in 0.002s

FAILED (failures=1)

Pythonのpycファイルのマジックナンバー

Pythonファイル(平文ソースコード)をコンパイルするとpycファイルになる。
pythonユーザがpycファイルを作成する必要なし。モジュールとしてインポートされる場合に自動的に作成
元のモジュールが更新されると、次回インポート時にpycファイルも自動的に再作成

マジックナンバーとは、ファイルの種類を識別するため、ファイル先頭に付与する特別なバイト列。Pythonのバージョンごとにpycファイルのマジックナンバーが決まっている。

$ python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import importlib.util
>>> importlib.util.MAGIC_NUMBER.hex()
‘550d0d0a’

Pythonでfor文を使って{辞書: [{辞書},{辞書},{辞書}…]}のjsonを作りたい

ありたいてに言うと、下記のような構造のjsonをfor文で作りたい

{
	"item": [
		{
			"area": "東京都","population": 1300, "capital": "東京"
		},
		{
			"area": "北海道","population": 538, "capital": "札幌市"
		},
		{
			"area": "沖縄","population": 143, "capital": "那覇市"
		}	
	]
}

for文で辞書を配列に入れて、それを辞書の中に入れてjsonにすればOK

ys = cl.OrderedDict()
result = []
for item in data:
	print(item["at"][:16] +" " + item["anm"] + " " + item["mag"] + " " + item["maxi"] + " " + item["cod"][:5] + " " + item["cod"][5:11]+ " " + item["cod"][12:-1])
	data = cl.OrderedDict()
	data["at"] = item["at"][:16]
	data["anm"] = item["anm"]
	data["mag"] = item["mag"]
	data["maxi"] = item["maxi"]
	data["tokei"] = item["cod"][:5]
	data["hokui"] = item["cod"][5:11]
	data["depth"] = item["cod"][12:-1]

	result.append(data)

ys["item"] = result
print(ys)

with open("test.json", "w") as f:
    json.dump(ys, f, ensure_ascii=False)

pythonによるjson操作と辞書の理解が浅かったので、これ作るのに丸一日かかった orz…
なんてこったい

Pythonでjson作成

import json

str = {
	"東京":{
		"population": 1300,
		"capital": "東京"
	},
	"北海道": {
		"population": 538,
		"capital": "札幌市"
	},
	"沖縄":{
		"population": 143,
		"capital": "那覇市"
	}
}

with open("population.json", "w") as f:
	json.dump(str, f, ensure_ascii=False)

{“東京”: {“population”: 1300, “capital”: “東京”}, “北海道”: {“population”: 538, “capital”: “札幌市”}, “沖縄”: {“population”: 143, “capital”: “那覇市”}}

なるほどー

[自然言語処理] チャットボット基礎

ChatterBot:
The program selects the closest matching response by searching for the closest matching known statement that matches the input, it then returns the most likely response to that statement based on how frequently each response is issued by the people the bot communicates with.

chat.txt

こんにちは
こちらこそ こんにちは
今日もよろしくお願いします

chat2.txt

こんばんは
こちらこそ こんばんは
もう眠いですね
おやすみなさい

main.py

from chatterbot import ChatBot 
from chatterbot.trainers import ListTrainer

bot = ChatBot("チャットボット試作品")

training_ = open('chat.text','r').readlines()
training2_ = open('chat2.text','r').readlines()

trainer = ListTrainer(bot)

trainer.train(training_)
trainer.train(training2_)

while True:
	try:
		bot_input = bot.get_response(input())
		print(bot_input)
	except(KeyboardInterrupt, EOFError, SystemExit):
		break

$ pip3 install chatterbot
$ pip3 install chatterbot-corpus
$ python3 main.py
[nltk_data] Downloading package stopwords to
[nltk_data] /home/vagrant/nltk_data…
[nltk_data] Package stopwords is already up-to-date!
[nltk_data] Downloading package averaged_perceptron_tagger to
[nltk_data] /home/vagrant/nltk_data…
[nltk_data] Package averaged_perceptron_tagger is already up-to-
[nltk_data] date!
List Trainer: [####################] 100%
List Trainer: [####################] 100%
こんにちは
こちらこそ こんにちは
もう眠いですね
おやすみなさい
もう眠いですね
おやすみなさい
こちらこそ こんばんは
もう眠いですね
aaa
もう眠いですね
そうですか
こちらこそ こんばんは
おはよう
もう眠いですね
こんにちは
こちらこそ こんにちは

なんだこれ…