どうにもわからない。 @hogeai

わからないことをわかるまでログる

複数のタスクをiOSリマインダーに流し込む

困ったこと

iPhoneの日記アプリやメモ帳に複数タスクをメモした時、標準リマインダーにタスクを流し込んで一気に登録したかった。

前提

  • 標準リマインダーな人が対象
    • メモ帳とかに今日やることリストとかを書いて、それを標準リマインダーに流したい人
    • todoistなどサード・パーティTODOを使っている人は、戦略が変わるので対象外

戦略

  • 入力されたタスクを1行1件で標準リマインダに登録する
  • 登録する際は、workflowで流し込む
  • メモアプリを限定したくないのでクリップボード経由でWorkFlowに流し込む
  • textwellでも可能

Workflowの準備

Import WorkFlow Scriptadd-task

textwellスクリプト

Import Textwell Actionadd task

使いかた(クリップボード

  • workflowのスクリプトインストール
    • add-taskとして登録されます
    • List名を[task]としているので、別の標準リマインダに登録する際は編集
  • タスクを1件1行の複数行で書く
  • 登録したいタスクをコピーする(基本的にSelectALL)
  • workflow起動→「add-task」実行

textwellの人

  • workflow のスクリプトインストール
  • textwellスクリプトインストール
  • textwell でタスクを1件1行の複数行で書く
  • share->[add task]

Pandasで条件に一致した行の列値入れ替え

わからない

  • Pandasの行列入れ替えは簡単ですが、条件に従う行の列値入れ替えについては情報がなかった
import pandas as pd
import numpy as np
from IPython.display import display, HTML

検証内容

  • 列test3が1の場合、test2のデータをtest1に格納する
fuga=np.zeros(10)
hoge=pd.DataFrame(fuga,columns=["test1"])
fuga=np.zeros(10)
fuga[:]=-1
hoge["test2"]=fuga
hoge["test3"]=[0,1,0,1,0,1,0,1,0,0]
display(hoge)
test1 test2 test3
0 0.0 -1.0 0
1 0.0 -1.0 1
2 0.0 -1.0 0
3 0.0 -1.0 1
4 0.0 -1.0 0
5 0.0 -1.0 1
6 0.0 -1.0 0
7 0.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0

ど直球にやると

fuga=np.zeros(10)
hoge=pd.DataFrame(fuga,columns=["test1"])
fuga=np.zeros(10)
fuga[:]=-1
hoge["test2"]=fuga
hoge["test3"]=[0,1,0,1,0,1,0,1,0,0]
display(hoge)

# ここからど直球
hoge2=pd.DataFrame()
for i, row in hoge.iterrows():
    if row["test3"]== 1:
        row["test1"]=row["test2"]
    row=pd.DataFrame(row)
    hoge2=pd.concat([hoge2,row.T])

hoge2=hoge2.reset_index(drop=True)
hoge2
test1 test2 test3
0 0.0 -1.0 0
1 0.0 -1.0 1
2 0.0 -1.0 0
3 0.0 -1.0 1
4 0.0 -1.0 0
5 0.0 -1.0 1
6 0.0 -1.0 0
7 0.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0
test1 test2 test3
0 0.0 -1.0 0.0
1 -1.0 -1.0 1.0
2 0.0 -1.0 0.0
3 -1.0 -1.0 1.0
4 0.0 -1.0 0.0
5 -1.0 -1.0 1.0
6 0.0 -1.0 0.0
7 -1.0 -1.0 1.0
8 0.0 -1.0 0.0
9 0.0 -1.0 0.0

問題

  • データ件数が少ない場合は、上記でも問題ない
  • 多次元*100万データでは、1時間待っても反応がない

解決策

  • 条件に従うインデックスを記録
  • インデックス記載のデータを格納する
fuga=np.zeros(10)
hoge=pd.DataFrame(fuga,columns=["test1"])
fuga=np.zeros(10)
fuga[:]=-1
hoge["test2"]=fuga
hoge["test3"]=[0,1,0,1,0,1,0,1,0,0]
display(hoge)

# ここからIndex利用
piyo=hoge[hoge["test3"]==1].index
hoge.ix[piyo,"test1"]=hoge.ix[piyo,"test2"]
hoge
test1 test2 test3
0 0.0 -1.0 0
1 0.0 -1.0 1
2 0.0 -1.0 0
3 0.0 -1.0 1
4 0.0 -1.0 0
5 0.0 -1.0 1
6 0.0 -1.0 0
7 0.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0
test1 test2 test3
0 0.0 -1.0 0
1 -1.0 -1.0 1
2 0.0 -1.0 0
3 -1.0 -1.0 1
4 0.0 -1.0 0
5 -1.0 -1.0 1
6 0.0 -1.0 0
7 -1.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0

応用

  • test1とtest2のデータを入れ替える
fuga=np.zeros(10)
hoge=pd.DataFrame(fuga,columns=["test1"])
fuga=np.zeros(10)
fuga[:]=-1
hoge["test2"]=fuga
hoge["test3"]=[0,1,0,1,0,1,0,1,0,0]
display(hoge)

# ここから入れ替え
bk_df=hoge.copy()
piyo=hoge[hoge["test3"]==1].index
hoge.ix[piyo,"test1"]=hoge.ix[piyo,"test2"]
hoge.ix[piyo,"test2"]=bk_df.ix[piyo,"test1"]
hoge
test1 test2 test3
0 0.0 -1.0 0
1 0.0 -1.0 1
2 0.0 -1.0 0
3 0.0 -1.0 1
4 0.0 -1.0 0
5 0.0 -1.0 1
6 0.0 -1.0 0
7 0.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0
test1 test2 test3
0 0.0 -1.0 0
1 -1.0 0.0 1
2 0.0 -1.0 0
3 -1.0 0.0 1
4 0.0 -1.0 0
5 -1.0 0.0 1
6 0.0 -1.0 0
7 -1.0 0.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0

メモリを気にする場合

fuga=np.zeros(10)
hoge=pd.DataFrame(fuga,columns=["test1"])
fuga=np.zeros(10)
fuga[:]=-1
hoge["test2"]=fuga
hoge["test3"]=[0,1,0,1,0,1,0,1,0,0]
display(hoge)

# ここから入れ替え
piyo=hoge[hoge["test3"]==1].index
bk_values=hoge.ix[piyo,"test1"].values
hoge.ix[piyo,"test1"]=hoge.ix[piyo,"test2"]
hoge.ix[piyo,"test2"]=bk_values
hoge
test1 test2 test3
0 0.0 -1.0 0
1 0.0 -1.0 1
2 0.0 -1.0 0
3 0.0 -1.0 1
4 0.0 -1.0 0
5 0.0 -1.0 1
6 0.0 -1.0 0
7 0.0 -1.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0
test1 test2 test3
0 0.0 -1.0 0
1 -1.0 0.0 1
2 0.0 -1.0 0
3 -1.0 0.0 1
4 0.0 -1.0 0
5 -1.0 0.0 1
6 0.0 -1.0 0
7 -1.0 0.0 1
8 0.0 -1.0 0
9 0.0 -1.0 0

Pandasのilocとixにおけるスライスの注意点

Pandasの行方向のスライスが思わぬ動きをした話し

import pandas as pd
import numpy as np
from IPython.display import display, HTML

numpyのスライスに代入->想像通り

fuga=np.zeros(5)
fuga[1:3]=1
fuga
array([ 0.,  1.,  1.,  0.,  0.])

ilocのスライスに代入->想像通り

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.iloc[1:3,0]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 0.0
4 0.0

ixのスライスに代入->????

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.ix[1:3,0]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 1.0
4 0.0

原因

pandas.DataFrame.ix

However, when an axis is integer based, ONLY label based access and not positional access is supported.
Thus, in such cases, it’s usually better to be explicit and use .iloc or .loc.

  • Indexが整数のみの場合はラベルアクセスのみになるから注意。

検証

ラベルアクセスすると同じになる

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.loc[1:3,"test"]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 1.0
4 0.0

IndexをStrにすれば整数アクセス可能

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.index=[str(i) for i in hoge.index]
hoge.ix[1:3,"test"]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 0.0
4 0.0

結論

  • ixを使った行のスライスは型に気をつける
  • 行スライスの代入はilocを使うのが無難

ripgrepのVIM連携まわり(Unite/qfixhowm/fzf/Ctrlp)

ripgrepを導入してVIM周りも固めたい

  • Windowsでも使えるripgrep
  • はやい

わからない

Unite Grepのバックエンドをripgrepにする方法がわからなかった。
そこで、ripgrep+vim周りの情報を集約しておきます。

ripgrepの導入

ripgrepをデフォルトに

if executable('rg')
    set grepprg=rg\ --vimgrep\ --no-heading
    set grepformat=%f:%l:%c:%m,%f:%l:%m
endif

ripgrep + vim

ripgrep + Unite

if executable('rg')
  let g:unite_source_grep_command = 'rg'
  let g:unite_source_grep_default_opts = '-n --no-heading --color never'
  let g:unite_source_grep_recursive_opt = ''
  " Hit件数制御したいなら以下
  let g:unite_source_grep_max_candidates = 200
  " Windowsなら
  let g:unite_source_grep_encoding='utf-8'
endif

ripgrep + qfixhowm

" ripgrepを使う(PATHは通してある前提)
let mygrepprg = 'rg'
let myjpgrepprg = 'rg'
" マルチエンコーディングgrepを使用する
let MyGrep_MultiEncoding = 1
" マルチエンコーディングgrepで使用するエンコーディングリスト
let MyGrep_MultiEncodingList = ['utf-8', 'cp932']
" 外部grep(shell)のエンコーディング(Windows)
let MyGrep_ShellEncoding = 'utf-8'
" 以下、上記URL参考
" 実行時のオプションをripgrep用に変更(GNU Grepと同じ出力になるように)
let MyGrepcmd_useropt='-nH --no-heading --color never'
let MyGrepcmd_regexp=''
let MyGrepcmd_regexp_ignore='-i'
let MyGrepcmd_fix='-F'
let MyGrepcmd_fix_ignore='-F -i'
let MyGrepcmd_recursive=''
" gipgrepにファイルパターンとして「*」「*.*」を渡したらエラーになったのでその対策
let MyGrep_GrepFilePattern='.'

ripgrep + CtrlP

"ctrlP"{{{
if executable('rg')
  let g:ctrlp_user_command = 'rg --files %s'
  let g:ctrlp_use_caching = 0
  let g:ctrlp_working_path_mode = 'ra'
  let g:ctrlp_switch_buffer = 'et'
endif

or

if executable('rg')
  let g:ctrlp_use_caching = 0
  "let g:ctrlp_user_command = 'cd %s && rg "" -i -r --no-color -l ./**/*'
  let g:ctrlp_user_command = 'rg %s --files --color=never --glob ""'
endif

ripgrep + fzf

" Similarly, we can apply it to fzf#vim#grep. To use ripgrep instead of ag:
command! -bang -nargs=* Rg
  \ call fzf#vim#grep(
  \   'rg --column --line-number --no-heading --color=always '.shellescape(<q-args>), 1,
  \   <bang>0 ? fzf#vim#with_preview('up:60%')
  \           : fzf#vim#with_preview('right:50%:hidden', '?'),
  \   <bang>0)

ripgrep + denite

GoogleKeepでラベルなしを抽出

GoogleKeepでラベルがついていないものを抽出したい。

わからない

GoogleKeepで日常のメモを行っています。
GoogleKeepでは、ラベルなし検索ができないため、メモの整理に困っていました。

Netで検索

同問題に悩んでいる人はStackOverFlowでも見つかりましたが、解決策の記載がない。

BookMarkLetで解決できないか?

GoogleKeepのソース見てみたら、簡単にできそうだったので
今回はBookMarkletで実装することにした。

以下をBookmarkに追加

javascript:(function(){var%20memos=document.getElementsByClassName("IZ65Hb-TBnied");for(var%20i=0;i<memos.length;i++){var%20memo=memos[i].getElementsByTagName("label");for(var%20j=0;j<memo.length;j++){if(memo[j].innerText!=""){memos[i].style.display="none";break;}}}})();
  • 注意
    • GoogleKeepのページが完全にロードされるまで待ってください。
    • FireFoxBookmarkletが動作しません
      • about:config->security.csp.enable->falseが必要

F12でコンソールに張り付けるほうが早いかも

毎日する作業でもないので、BrowserからF12->Consoleに以下を張り付けてもOK。

javascript:(
    function()
    {
        var memos=document.getElementsByClassName("IZ65Hb-TBnied");
        for(var i=0;i<memos.length;i++)
        {
            var memo=memos[i].getElementsByTagName("label");
            for(var j=0;j<memo.length;j++){
                if(memo[j].innerText!="")
                {
                    memos[i].style.display="none";
                    break;
                }
            }
        }
    }
)();

Atom+Hydrogen(Jupyter)でPython

わからない

家でプログラミングする際に最適な環境がわからない。
求めるものは気持ちよさ。対象言語はPython

環境の構築

今回の環境は、Mac+Atom+Hydrogen
PythonはAnaconda環境
Atomを新しくしたかったので、最初からインストールしています。

DL

  • Atom
    • Download Macをクリック
    • zip解凍
    • atom.appをアプリケーションに入れる

Hydrogenをインストール

  • Atomを起動
  • Preference->Install
  • Hydrogenで検索->Hydrogen 2.2.2をインストール(公式)

python側の設定

Anaconda環境なので、以下を実行する

conda install ipykernel
python -m ipykernel install --user

Hydrogenでテストコード

変数出力と、matplotlibを確認 - Command + alt + Enter

import math
import numpy as np
from matplotlib import pyplot

pi = math.pi
x = np.linspace(0, 2*pi, 100)
y = np.sin(x)

pyplot.plot(x, y)
pyplot.show()

f:id:hogeai:20180120043413g:plain

とりま、ここまで

Atom実践入門──進化し続けるハッカブルなエディタ (WEB+DB PRESS plus)

Atom実践入門──進化し続けるハッカブルなエディタ (WEB+DB PRESS plus)

TimelineのFav/RTが多いツイートだけを確認したい

わからない

フォローしている人のFav/RTが多いツイートだけを確認したいのに
どうにもやり方がわからない。

Info

Androidでは【はむーん】を使っていました。
iPhoneでは、分析系はいまいち見つからない。

Twitter 分析」で検索すると多くのサービスが見つかりますが
【フォローしている人】という制約だけで、どのサービスがいいかわからなくなる。
いいのがあれば教えてください

結論

自分で作ったほうが早い気がする。
Python+TwitterAPI+VIMなら数分でしょ!

やったこと

クローリング系のプログラムを書くと、毎度毎度可視化の方法に悩みます。
この時のオススメはVIMに出力する】です。

VIMでコマンド叩いて、結果をVIMに出力すれば、VIMで完結するので最高!

こんな感じになります。

f:id:hogeai:20180111225227g:plain

:TwGetFav ->Fav数で降順 :TwGetRt -> RT数で降順

1時間ぐらいで作ったレベルなので、まだ200Tweetしか取れていません。
暇をみてエンハンスします。

ファイルの構成

/(任意)
├── config.py    #Twitter API の各種Key情報格納(CONSUMER_KEYなど)
└──get_tweet.py  #Twitter APIへのPython処理


config.pyの構成

# Twitter APIの値をはっつけてください。
CONSUMER_KEY = "(各自)"
CONSUMER_SECRET = "(各自)"
ACCESS_TOKEN = "(各自)"
ACCESS_TOKEN_SECRET = "(各自)"


実際のソース

ソースはGitHubにあげました

vimrc/init.vim

自分のフォルダ構成に合わせてください。
let l:tw_tmp_dir = '/tmp/vim/'
let l:python_file = '/[任意]/python-vim-twitter/get_tweet.py'

"vim script"{{{
function! s:get_tw_line(flg)"
    let l:tw_tmp_dir = '/tmp/vim/'
    if !isdirectory(l:tw_tmp_dir)
        call mkdir(l:tw_tmp_dir, 'p')
    endif

    let l:filename = l:tw_tmp_dir . 'tw_' . a:flg . '.text'
    let l:python_file = '/[任意]/python-vim-twitter/get_tweet.py'

    " ファイル生成
    silent execute "!python " . l:python_file . ' --file ' . l:filename . ' --flg ' . a:flg
    execute 'tabnew ' . l:filename
endfunction augroup END"

" メモを作成するコマンド
command! -nargs=0 TwGetFav call s:get_tw_line(1)
command! -nargs=0 TwGetRt call s:get_tw_line(2)
"}}}

Vim script テクニックバイブル ~Vim使いの魔法の杖

Vim script テクニックバイブル ~Vim使いの魔法の杖