[Python] 265 日付・時刻の文字列化関数

前回記事の続きです。

日付・時刻の文字列化コードは使用頻度がかなり高いため関数にしました。

import datetime

datetime_now = datetime.datetime.now()

def now():
    datetime_now_str = datetime_now.strftime('%y%m%d%H%M')
    return datetime_now_str

def today():
    datetime_today_str = datetime_now.strftime('%y%m%d')
    return datetime_today_str
from my_library import date

print(date.now())
print(date.today())
--------------------------------------------------

出力
--------------------------------------------------
2106081330
210608

[Python] 264 日付・時刻の文字列化

ファイル名に今日の日付や現在時刻を付ける場合の文字列作成コードです。

import datetime

datetime_now = datetime.datetime.now()
datetime_now_str = datetime_now.strftime('%y%m%d%H%M')
datetime_today_str = datetime_now.strftime('%y%m%d')

filename_now = f"/{datetime_now_str}.csv"
filename_today = f"/{datetime_today_str}.csv"

print(filename_now)
print(filename_today)
--------------------------------------------------

出力
--------------------------------------------------
/2106080730.csv
/210608.csv

[Python] 263 C言語でモジュールを作成

[macOS Catalina 10.15.7]

これまで自作モジュールはPythonで書いてきましたが、高速化が必要な場合にC/C++モジュールで対応するためテストしてみました。

1.C言語モジュールの作成

#include <Python.h>

static PyObject* 
hello_world (PyObject *self, PyObject *args) {
  printf("Hello_world\n");
  Py_RETURN_NONE;
}

// メソッドの定義
static PyMethodDef TestMethods[] = {
  {"hello_world", (PyCFunction)hello_world, METH_NOARGS, "test1: hello_world"},
  {NULL, NULL, 0, NULL}
};

// モジュールの定義
static struct PyModuleDef testmodule = {
  PyModuleDef_HEAD_INIT,
  "test",
  NULL,
  -1,
  TestMethods
};

// メソッドの初期化
PyMODINIT_FUNC PyInit_test (void) {
  return PyModule_Create(&testmodule);
}

2.setup.pyの作成

from distutils.core import setup, Extension
setup(name='test',
        version='1.0',
        ext_modules=[Extension('test', ['test.c'])]
)

3.C言語モジュールのビルド

python setup.py build_ext -i

4.C言語モジュールの動作チェック

作成されたtest.cpython-39-darwin.soファイルをあらかじめ用意しておいたc_moduleフォルダへコピーし、以下のコードを実行。

c_moduleフォルダをライブラリとして認識させるため、フォルダ内に空の__init__.pyを置くようにする。

そしてc_moduleフォルダまたはシンボリックリンクをこのコードと同じところに置く。

なお今後のためにc_moduleフォルダを作成しましたが、soファイルをソースコードと同じところに置くだけでも1行目”import test”にて実行可能です。

from c_module import test

test.hello_world()
--------------------------------------------------

出力
--------------------------------------------------
Hello_world

参考サイト

[Python] 262 subprocessモジュール2 日付を出力 続編

[macOS Catalina 10.15.7]

前記事でBashにて3日後の日付を出力させるのに苦労しましたが、仕切り直しで再調査したところあっさり解決しました。

info dateコマンドで出力されるドキュメントが参考になりました。やはり分からなければ開発元のドキュメントを読むのが基本ですね。

UNIXのタイプによってルールが全く異なるというのがよく分かりました。ちなみにmacOSはBSDベースです。

import subprocess
from subprocess import PIPE

# 3日後の場合 Bash
com_date_3 = subprocess.run("date -v+3d +%y%m%d", shell=True, stdout=PIPE, stderr=PIPE, text=True)
date_3 = com_date_3.stdout

print(f'date_3 {date_3}')
--------------------------------------------------

出力
--------------------------------------------------
date_3 210531

[Python] 261 subprocessモジュール1 日付を出力

[macOS Catalina 10.15.7]

Bashのコマンドで日付を出力させてみました。

今日の日付は特に問題ないですが、3日後の書き方でドハマりしました。

とりあえず出力できましたが、他にスマートな書き方がないのであればこの使い方ではBash&macOSは却下です。

Zshにすれば普通になるのでしょうか。

import subprocess
from subprocess import PIPE
import datetime

# 今日の日付 Bash
com_date = subprocess.run("date +%y%m%d", shell=True, stdout=PIPE, stderr=PIPE, text=True)
date = com_date.stdout

print(date)

# 今日の日付 Python
date_today = datetime.date.today()
date_today_str = date_today.strftime('%y%m%d')

print(date_today_str)

# 3日後の日付 Bash 時差+9-72=-63 このスクリプトは可読性低い
com_date_3 = subprocess.run("env TZ=JST-63 date +%y%m%d", shell=True, stdout=PIPE, stderr=PIPE, text=True)
date_3 = com_date_3.stdout

print(f'date_3 {date_3}')

# 3日後の日付 Python
days3 = datetime.timedelta(days = 3)
date_days3 = date_today + days3
date_days3_str = date_days3.strftime('%y%m%d')

print(f'date_days3_str {date_days3_str}')
--------------------------------------------------

出力
--------------------------------------------------
210527
210527
date_3 210530
date_days3_str 210530

[Python] 260 chromedriverのバージョン管理 Homebrew編

[macOS Catalina 10.15.7]

これまではseleniumが動かなくなるたびにGoogle Chromeのサイトから最新のchromedriverをダウンロードして配置していましたが、あまりにも非効率なのでHomebrewのchromedriverを使うことにしました。

以下、関連コマンド等を記しておきます。

chromedriverのインストール

brew install chromedriver

# .bash_profileに追記
export PATH="/opt/homebrew/bin:$PATH"

# インストール先の例(オリジナル)
/usr/local/Caskroom/chromedriver/[Chromeのバージョン番号]/chromedriver
/opt/homebrew/Caskroom/chromedriver/[Chromeのバージョン番号]/chromedriver

# エイリアス配置先の例
/usr/local/bin/chromedriver
/opt/homebrew/bin/chromedriver

brewのインストール先を確認

brew --prefix

chromedriverの最新バージョンと導入有無の確認

brew info chromedriver

chromedriverのアップデート(毎日crontabで定期実行)

brew upgrade chromedriver

Pythonコード内の記述

from selenium import webdriver

driver = webdriver.Chrome()

[Python] 259 pyenv 2.0.0に関する警告

pyenvを2.0.0にバージョンアップするとターミナル起動時に以下の警告が表示されるようになりました。

WARNING: `pyenv init -` no longer sets PATH.
Run `pyenv init` to see the necessary changes to make to your configuration.

調べたところpyenvコマンドのオプションが変更になったようです。

.bash_profileを以下のように変更すると警告は出なくなりました。3行目だけ手を入れてます。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

ちなみに以前はこのように記述していました。

eval "$(pyenv init -)"

[Python] 258 pyenv仮想環境にanacondaを導入

これまで簡単なコードの検討にはIDLEの対話モードを使っていましたが、jupyterも便利そうなので試してみることにしました。

以下、pyenv仮想環境へのanaconda導入過程です。anacondaのjupyterを使うと主要なライブラリをインストールする手間がかかりません。

macOSでは現時点で最新のanaconda3-2021.05をインストールします。

# pyenv仮想環境にanaconda3-2021.05をインストール
pyenv install anaconda3-2021.05

# pyenvに入っているPythonのバージョンを確認する
pyenv versions
[出力]
  system
  3.7.4
  3.8.2
  3.8.3
  3.8.5
  3.8.6
  3.9.0
* 3.9.2 (set by /Users/[ユーザ名]/.pyenv/version)
  anaconda3-2021.05

# anacondaを使う専用ディレクトリnotebookを作成しカレントディレクトリを移動させる
cd ~/notebook

# notebookディレクトリでのみanacondaを使うように設定する
pyenv local anaconda3-2021.05

# anacondaで使えるPythonのバージョンを確認する
python -V
[出力]
Python 3.8.8

# jupyterを起動する
jupyter-notebook

[Python] 257 空のディレクトリを削除する 類例

前記事で紹介したコードの”glob.glob”が同語の繰り返しで何となく野暮ったいので少し表現を変えてみました。

importが1行増えますが、こちらの方が私の好みです。

import shutil,os
from glob import glob

dir_l = [dir for dir in glob('親ディレクトリのパス/*') \
if os.path.isdir(dir)]]
print(dir_l)

for dir in dir_l:
    file_l = [file for file in glob(dir + '/*')]
    print(file_l)
    if len(file_l) == 0:
        shutil.rmtree(dir)

[Python] 256 空のディレクトリを削除する

備忘のためメモ書き。

同じ階層にファイルがあっても削除されません。

import glob,shutil,os

dir_l = [dir for dir in glob.glob('親ディレクトリのパス/*') \
if os.path.isdir(dir)]]
print(dir_l)

for dir in dir_l:
    file_l = [file for file in glob.glob(dir + '/*')]
    print(file_l)
    if len(file_l) == 0:
        shutil.rmtree(dir)