Pythonで非同期処理
Pythonでマルチプロセスまたはマルチスレッドによる非同期処理を実装する方法を調べました。ここでは、典型的なバッチ処理(prepareが処理対象イテレータ、executeはprepareの要素ごとに呼び出す処理)で、async/awaitを実装していないexecute処理を非同期化してみます。サンプルでは並行数を「3」としています。
サンプルコード
import asyncio import time def now(): return time.strftime('%X') def prepare(): return [ ('A', 1), ('B', 1.3), ('C', 1.6), ('D', 1.9), ('E', 2.2), ] def execute(name, sec): for i in range(3): print(name + '>' + now()) time.sleep(sec) print(name + '<' + now()) def run(): loop = asyncio.get_event_loop() async def _run_tasks(its, limit): sem = asyncio.Semaphore(limit) async def _run_task(args): async with sem: return await loop.run_in_executor(None, execute, *args) return await asyncio.gather(*[_run_task(it) for it in its]) loop.run_until_complete(_run_tasks(prepare(), 3)) print('--' + now()) run() print('--' + now())
結論
loop.run_in_executor() を使うと、どんな処理でも並列化できる!
本家サイトはこちら
docs.python.org
ここに記載したコードは下記サイトで動作確認しました。
www.jdoodle.com
取消線の入ったセルを検索する
標準のFindNextでは検索できない「取消線の入ったセル」を検索するためのクラスです。「」の部分は簡単にカスタマイズできるので、簡単に任意の条件で検索する機能を作ることができます。
CellFinder
アクティブセルから「前へ」「次へ」を検索するクラスです。FindNext/FindBackに渡すICellFinderクラスで検索条件を判定します。
Option Explicit 'セル位置判定Enum Private Enum vbCompareAddress vbBeforeCell vbActiveCell vbAfterCell End Enum '検索範囲決定 Private Function FindRange() As Range If Selection.CountLarge = 1 Or Selection.MergeCells Then Set FindRange = ActiveSheet.UsedRange Else Set FindRange = UsedRangeInSelection End If ' このFunctionはNothingを返さない If FindRange Is Nothing Then Set FindRange = ActiveCell End If End Function Public Function UsedRangeInSelection() As Range Set UsedRangeInSelection = Intersect(ActiveSheet.UsedRange, Selection) End Function 'セル位置判定 Private Function CompareAddress(c As Range) As vbCompareAddress If ActiveCell.Address = c.Address Then CompareAddress = vbActiveCell Else CompareAddress = IIf(ActiveCell.Row < c.Row Or (ActiveCell.Row = c.Row And ActiveCell.Column < c.Column), vbAfterCell, vbBeforeCell) End If End Function '順方向検索 Public Sub FindNext(finder As ICellFinder) Call FindNext_(finder, vbAfterCell) Call FindNext_(finder, vbBeforeCell) Call Find(finder, ActiveCell, vbActiveCell) finder.NotFound End Sub Private Sub FindNext_(finder As ICellFinder, ca As vbCompareAddress) With FindRange Dim i As Long For i = 1 To .CountLarge Call Find(finder, .Cells(i), ca) Next End With End Sub '逆方向検索 Public Sub FindBack(finder As ICellFinder) Call FindBack_(finder, vbBeforeCell) Call FindBack_(finder, vbAfterCell) Call Find(finder, ActiveCell, vbActiveCell) finder.NotFound End Sub Private Sub FindBack_(finder As ICellFinder, ca As vbCompareAddress) With FindRange Dim i As Long For i = .CountLarge To 1 Step -1 Call Find(finder, .Cells(i), ca) Next End With End Sub '検索判定 Private Sub Find(finder As ICellFinder, c As Range, ca As vbCompareAddress) If ca = CompareAddress(c) Then If finder.Find(c) Then c.Activate End End If End If End Sub
ICellFinder
検索判定処理のインターフェースクラスです。FindでTrueを返すと検索にヒットしたことになります。
Option Explicit '検索判定処理 Public Function Find(c As Range) As Boolean End Function '見つからなかった場合の処理 Public Sub NotFound() End Sub
StrikethroughFinder
(ありがちな)取消線書式が設定されたセルを判定するクラスです。Findの引数cがチェック対象のセルで、取消線書式が付いていたらTrueを、なければFalseを返します。
Option Explicit Implements ICellFinder '検索判定処理 Public Function ICellFinder_Find(c As Range) As Boolean 'セル単位 If Not IsNull(c.Font.Strikethrough) Then ICellFinder_Find = c.Font.Strikethrough Exit Function End If '文字単位 Dim i As Long For i = 1 To Len(c.Value) If c.Characters(Start:=i, Length:=1).Font.Strikethrough Then ICellFinder_Find = True Exit Function End If Next ICellFinder_Find = False End Function '見つからなかった場合の処理 Public Sub ICellFinder_NotFound() MsgBox "取消線は見つかりませんでした" End Sub
使い方
標準モジュールでショートカットキーを割り当てます。このサンプルでは、F3キーで「次へ」Shift+F3キーで「前へ」取消線書式を含むセルを検索しています。つまりCellFinderをベースとして、ICellFinderを実装したクラスを用意するだけで、好みの検索機能を追加できるようになります!
Private finder As New CellFinder Private ifinder As New StrikethroughFinder Sub Auto_Open() Application.OnKey "{F3}", "FindNext" Application.OnKey "+{F3}", "FindBack" End Sub Sub FindNext() finder.FindNext ifinder End Sub Sub FindBack() finder.FindBack ifinder End Sub
ファイルを検索する
Excelで指定したフォルダ内のファイルをピックアップする処理を書くときに使うクラスです。
FileFinder
Option Explicit ' ------------------------------------------------------------------------------- ' FileFinder クラス ' 指定フォルダ内のファイルを検索するクラス ' Find メソッドで検索を開始します ' 検索結果は OnFind イベントで処理してください ' ------------------------------------------------------------------------------- ' 検索対象ファイル名の RegExp オブジェクト Private filter As Object ' 検索対象ファイルの拡張子名の Array オブジェクト Private extentions As Variant ' サブフォルダーも検索するフラグ Private recursive As Boolean ' ------------------------------------------------------------------------------- ' OnFind イベント ' Find でファイルが見つかった場合に発火します ' 引数 ' file 検索で見つかった FileSystemObject.File オブジェクト ' ------------------------------------------------------------------------------- Public Event OnFind(file As Variant) ' ------------------------------------------------------------------------------- ' FileSystemObject プロパティ ' ------------------------------------------------------------------------------- Public Property Get FileSystemObject() As Object Static fso As Object If fso Is Nothing Then Set fso = CreateObject("Scripting.FileSystemObject") End If Set FileSystemObject = fso End Property ' ------------------------------------------------------------------------------- ' Find ' 指定フォルダー内のファイルを検索します ' 引数 ' find_root 検索のルートフォルダー文字列を指定してください ' file_filter 検索したいファイル名を指定してください(部分一致・正規表現可) ' file_extentions 検索したいファイルの拡張子を指定してください ' 例>Excelブックを検索したい場合 Array("xls","xlsx") を指定する ' find_subfolders サブフォルダーも検索する場合は True を指定してください ' ------------------------------------------------------------------------------- Public Sub Find(find_root As String, Optional file_filter As String = "", Optional file_extentions As Variant = Nothing, Optional find_subfolders As Boolean = True) ' ファイル名フィルター作成 Set filter = CreateObject("VBScript.RegExp") With filter .Pattern = file_filter .IgnoreCase = True .Global = True End With ' 拡張子名フィルター作成 If IsArray(file_extentions) Then extentions = file_extentions Else extentions = Array() End If ' サブフォルダーも検索するフラグ recursive = find_subfolders ' 検索実行 Call Dive(FileSystemObject.GetFolder(find_root)) End Sub ' フォルダー内を検索する Private Sub Dive(folder As Variant) ' ファイルを検索する Dim file As Variant For Each file In folder.Files If IsTarget(file) Then RaiseEvent OnFind(file) End If Next If recursive = False Then Exit Sub End If ' サブフォルダーを検索する Dim subfolder As Variant For Each subfolder In folder.SubFolders Call Dive(subfolder) Next End Sub ' ファイルが検索対象か判定する Private Function IsTarget(file As Variant) As Boolean IsTarget = IsTargetFile(file) And IsTargetExtention(file) End Function ' ファイル名が検索対象か判定する Private Function IsTargetFile(file As Variant) As Boolean If filter.Pattern = "" Then IsTargetFile = True Exit Function End If IsTargetFile = filter.Test(file.Name) End Function ' 拡張子が検索対象か判定する Private Function IsTargetExtention(file As Variant) As Boolean If UBound(extentions) = -1 Then IsTargetExtention = True Exit Function End If Dim extension As String extension = FileSystemObject.GetExtensionName(file) Dim ext As Variant For Each ext In extentions If StrComp(extension, ext, vbTextCompare) = 0 Then IsTargetExtention = True Exit Function End If Next IsTargetExtention = False End Function
使い方
FileFinderは Findメソッド で検索パラメーターを指定します。ファイルが見つかると、見つかったファイル FileSystemObject.Fileオブジェクト を引数とした OnFindイベント を発火するので WithEventsキーワード を使ってイベントを受け取ります。WithEventsキーワード は標準モジュールでは使えません。クラスモジュールを使ってください。
Private WithEvents ff As FileFinder Public Sub Test() Set ff = New FileFinder ff.Find "C:\test", "hoge", Array("xls", "xlsx"), True End Sub Private Sub ff_OnFind(file As Variant) Debug.Print file.Path End Sub
Windows版 Slack のフォントを変更する方法
2019/08/25 追記
4.x.x系ではこちらの記事の方法となるそうです。(Slack使わなくなったから知りませんでした。。。)
Windows 版 Slack のフォントを変更する 4.x.x 対応
autotune.hatenablog.com
つい先ごろSlackが日本語対応されましたが、日本語表示にすると、フォントの圧迫感?みたいなのがあって何だか疲れる気がしたので、任意のフォントに変更する方法を探してみました。
■注意事項
この方法は動作保証外だと思うのでダメだったら諦めてください。またアプリの再インストールなどが必要になることがあるかもしれません。自己責任でお願いいたします。
■対象バージョン
2.9-3.0
■手順
node.jsが使用するキャッシュファイルに、フォント指定のCSSを注入します。
C:\Users\[User]\AppData\Local\slack\app-2.9.0\resources\app.asar.unpacked\src\static\ssb-interop.js
の末尾に下記を追加します
onload = function(){ $("<style></style>").appendTo("head").html("*{font-family:'Yu Gothic UI' !important;}"); };
これでアプリを再起動すればフォントが適用されます!常駐させていると×ボタンで閉じてもアプリが終了しないので ハンバーガーメニュー>ファイル>Slackを終了する で終了させてください。
Windows版 Slack (英語)でEnterで改行させる方法
日本語だとEnterで改行させるオプションが追加されていますが、これを英語でも使う方法です。どちらかと言うと英語圏の人には需要あるかも。
■注意事項
この方法は動作保証外だと思うのでダメだったら諦めてください。またアプリの再インストールなどが必要になることがあるかもしれません。自己責任でお願いいたします。
■対象バージョン
2.9-3.0
■手順
node.jsが使用するキャッシュファイルで、オプション判定のfunctionを上書きします。
C:\Users\[User]\AppData\Local\slack\app-2.9.0\resources\app.asar.unpacked\src\static\ssb-interop.js
の末尾に下記を追加します
onload = function(){ TS.utility.contenteditable.isCursorInPreBlock=function(){ TS.model.prefs? TS.model.prefs.enter_is_special_in_tbt=!0: TS.prefs.setPref("enter_is_special_in_tbt",!0); return !0; }; };
これでアプリを再起動すればEnterで改行されるようになります!常駐させていると×ボタンで閉じてもアプリが終了しないので ハンバーガーメニュー>ファイル>Slackを終了する で終了させてください。
Android開発2017春
あの 自戒の日 から二年半あまり。やらなきゃやらなきゃと思いつつ忙しいからしょうがないよね?と流されまくりましたが、ようやく最初の目標を達成しました。
初作品の メトロケ は、リアルタイム時刻表というか列車位置情報を表示するアプリになりました。作ってみて分かった最大の問題は、東京メトロは列車の本数が多いので列車位置を細かく知れたところでまったく有難くなかったこと。運転見合わせじゃなければそのうち来る。みたいな。これだけじゃ仕方ないので(このアプリに付けるべきか微妙かなーと思いながらも)PASMOの残高表示機能や駅名の読み上げ機能など付けてみました。英語併記や読み上げ機能は、万が一、外国人向けにマッチするかも。開発環境構築込みで80hくらいかかりました。
Daily Counter は、日々のエクササイズのセット数を記録するアプリが欲しくて作りました。運動している最中にタップするので、そこそこ荒いタップでも大丈夫なようにボタンを大きくし、ちゃんとタップできたか常に画面を確認するのはつらいので、カウントを読み上げるようにしました。また、preferenceの使い方を覚えるために、読み上げ機能の設定を持たせてみました。こちらは今のところ40hくらい。
次は何つくろうかな!
■Windows開発環境
Java
http://www.oracle.com/technetwork/java/javase/downloads/index.html
AndroidStudio
https://developer.android.com/studio/index.html
bitbucket
https://bitbucket.org/product
GITクライアント
https://git-scm.com/
■参考サイト他
Androidアプリ開発
https://akira-watson.com/android/adt-windows.html
Android開発ガイド
https://developer.android.com/develop/index.html
google play
https://play.google.com/store/apps/developer?id=beer@jp