Tera TermでCtrl+sを押してしまったとき

Tera Termでvimを使いファイルを編集し、保存するときについついCtrl+sを押してしまうときがある。
操作は固まってしまい、仕方ないのでvimやbashのプロセスをkillしたりしていた。

しかし、Ctrl+sは危険なショートカットではなく、画面出力が止まっているだけだそうだ。
Ctrl + qで画面出力が再開される。

Ctrl + sを押し、画面が止まり、パニックになり、いろいろタイプする。
Ctrl + qを押すことで、それまでの慌てた対応が一気に出力される。

まとめ

Tera Termを使うときはサーバのメンテを行っている時なので、もう少し慎重に作業するよう心がけよう。

同じタグの記事
同じカテゴリの記事

Python自前のクラスをWithに対応させる

自前のクラス、使い終わったらclose()して欲しい。
将来の自分は、ちゃんとclose()を呼び出してくれるだろうか?
例外が発生した場合も、ちゃんとclose()を呼び出してくれるだろうか?

自前のクラスもwithでクローズ出来たら構文がスッキリする。
Javaならjava.lang.AutoCloseableインターフェースを継承してclose()メソッドを実装すれば、try-with-resource構文が使えるようになりスッキリする。
では、Pythonではどうするのだろうか。

__enter__、__exit__メソッド

自前のクラスに__enter__と__exit__を実装すればよいようだ。

__enter__は__init__の後に呼ばれる。
__enter__は戻り値としてselfを返却すればよい。

__exit__はwithが終わったところで呼び出される。
引き数は必ず4つ受け取る必要がある。withから渡される。
with内で例外が発生したとき、その情報が入っているらしい。

class MyClass:
    def __init__(self, init_value):
        self.xxx = Xxx(init_value)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.xxx.close()

    def proc(self, proc_value):
        self.xxx.yyy(proc_value)

with MyClass('ABC') as m:
    m.proc('LMN')

このような実装で、withから抜けた時にMyClassがちゃんと閉じられる。

まとめ

FTP接続し複数ファイルを転送したらcloseするとか、
DB接続し処理が完了したらcloseとかいろいろ使えそうだ。
キレイにまとまってよかった。

同じタグの記事
同じカテゴリの記事

Pythonで正規表現

相変わらず、ログの集計。
今回は、ログファイルより特定のキーワードが含まれる行を取得したい。
特定のキーワードは2種類。
ログファイルなので、お決まりのフォーマットで出力されている。
キーワードが2つなので、正規表現を利用してみる。

正規表現モジュール

Pythonで正規表現を利用するためにはreをインポートする。

import re

単純に部分一致する行を見つけたいのであれば以下の様で良い。

text = 'test X start'
if re.search('(X start|X end)', text) is not None:
    print(text)

ファイルの内容を行単位で繰り返し評価する場合は、正規表現オブジェクトをあらかじめ作成しておいた方が良いかも。

r = re.compile('(X start|X end)')
with open('log.log', 'r') as r:
    for line in r:
        if r.search(line) is not None:
            print(line.strip())

re.searchの戻り値を利用する

単純に存在するかどうかを判定するだけであれば、is not Noneで評価すればよいが、matchオブジェクトが返ってきているので、それを使うのも良い。

text = '----+----1----+----2----+----3'
m = re.search('1.*2', text)
print(m.group())
print(m.start())
print(m.end())
print(m.span())
# 1----+----2
# 9
# 20
# (9, 20)

m.start()やm.end()は、文字の切り出しに便利かもしれない。

まとめ

正規表現は書き方がわかるといろいろ便利。

同じタグの記事
同じカテゴリの記事

もうすぐ新元号(続報)

もうすぐ新元号。新元号も決まり、Java Runtimeがアップデートした。
それぞれのJava Runtimeで実行してみる。

サンプルプログラム

import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Wareki {
    public static void main(String[] args) {
        System.out.println(System.getProperty("java.version"));
        toWareki("1989/01/07");
        toWareki("1989/01/08");
        toWareki("2019/04/30");
        toWareki("2019/05/01");
    }

    public static void toWareki(String seireki) {
        try {
            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.JAPAN);
            Date date = df.parse(seireki);
            SimpleDateFormat sdf = new SimpleDateFormat("GGGGyyyy.M.d", new Locale("ja", "JP", "JP"));
            System.out.println(seireki + ":" + sdf.format(date));
        } catch (Exception e) {
            System.out.println("Err." + e.getMessage());
        }
    }
}

平成の変わり目をjava.versionと供に出力する。

実行

Java 6

1.6.0_45
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:平成31.5.1

Java 7

1.7.0_79
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:平成31.5.1

1.7.0_80
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:平成31.5.1

Java 8

1.8.0_191
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:平成31.5.1

1.8.0_201
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:平成31.5.1

1.8.0_211
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:令和元.5.1

Java 11

11
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:元号元.5.1

11.0.1
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:元号元.5.1

11.0.2
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:元号元.5.1

11.0.3
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:令和元.5.1

Java 12

12
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:元号元.5.1

12.0.1
1989/01/07:昭和64.1.7
1989/01/08:平成元.1.8
2019/04/30:平成31.4.30
2019/05/01:令和元.5.1

1.6、1.7は令和に対応していない。
1.8は1.8.0_211から対応している。
11は11.0.3から対応している。11は最初から新元号になることはわかっていたようで元号元と出力されている。
12は12.0.1から対応している。12も最初から元号元の表記がある。

まとめ

DotNetでは和暦の対応が急遽変更になったそうですが、Javaはそのまま元号が令和になっただけで大きな変更はなさそう。
しかし、DotNetの対応で確かにそうだなあと思ったのは、まだ元号が変わったわけではないので、現在の出力は平成31.5.1でも良いような気がする。令和になるのは令和元.5.1以降でも。
ましてや元号元.5.1なんて出力されたら、もっと困ってしまう。Java11で和暦変換していた人はどうしていたのだろうか?

同じタグの記事
同じカテゴリの記事

Pythonで昨日

FTPで昨日のログファイルを取得したい。
FTP取得自体は、以前から行っていたが昨日を求める必要がある。

Pythonで昨日を取得する

datetime.timedeltaで一日を表現して、それをマイナスすればよいようだ

import datetime
now = datetime.datetime.now()

# 今
print(now)
# 一日前
print(now - datetime.timedelta(days=1))

すばらしい。1日はdays=1で表現できて、それを減算すると一日前のようだ。

ならば、7日前は1週間前だ。

print(now - datetime.timedelta(days=7))

7日前は1週間前という表現もできるようだ。

print(now - datetime.timedelta(weeks=1))

1時間前も取得できる。

print(now - datetime.timedelta(hours=1))

プラスすれば1時間後

print(now + datetime.timedelta(hours=1))

datetimeの引き算の結果もtimedelta

そういえば、datetimeとdatetimeの引き算の結果もtimedeltaだった。

before = datetime.datetime.strptime('2019/4/16 16:30', '%Y/%m/%d %H:%M')
after = datetime.datetime.strptime('2019/4/17 17:15', '%Y/%m/%d %H:%M')
delta = after - before
print(delta.days)
print(delta.seconds)

daysは経過日数、secoundsは経過秒数が得られる。

まとめ

Pythonの日付時刻は一貫性があって美しい。

同じタグの記事
同じカテゴリの記事

Rubyでメソッドを定義する

Rubyの事を忘れないように、週に1回はRubyでツールを作る事にしている。
毎週作っている割に、やっと巡ってきたメソッドの定義の仕方。

Rubyでメソッドの定義

特に難しいことはなかった。

def my_func(arg1, arg2="Ruby")
    puts "#{arg1}, #{arg2} !"
    return arg1
end

my_func "Hello"
my_func "Hello", "JRuby"

my_funcが作成され、arg2はオプションになる。
戻り値はreturnで返す。returnは省略可能(Perlみたい)。

名前付き引数

def my_func(greet:, lang: "Ruby")
  puts "#{greet}, #{lang}!"
  return greet
end

my_func greet: "Hello"
my_func greet: "Hello", lang: "JRuby"

名前付き引数も使える。しかし、Pythonとは異なり、名前付き引数は必ず名前を指定しなくてはいけない。順番と名前をそれぞれ考慮してくれる訳では無いようだ。

まとめ

関数呼び出しにカッコをつけなくて良いのは、慣れると便利な気がしてきた。
今までは、カッコが当たり前だったのに、なくて良いとわかると付ける気がしない。Perlを思い出してきた。

同じタグの記事
同じカテゴリの記事