ラブびあ

ビール。ときどきラブ

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

最後に

もう3年も前の投稿とのことですが、これを読んで、いまさらながら触発されまして、過去に作った機能をリファクタリングしてみて、この日記をつけました。投稿した方、ありがとうございました!
qiita.com

ファイルを検索する

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

アイコン
http://icooon-mono.com/

google play
https://play.google.com/store/apps/developer?id=beer@jp