よしたく blog

ほぼ週刊で記事を書いています

ゲームセンターCXの放送日がわかるGoogleカレンダーを作成した

映像配信サービスの発展でテレビを見る機会は減っているが、自分が見続けているものに「ゲームセンター CX」がある。

otn.fujitv.co.jp

ゲームセンター CX は、お笑い芸人よゐこの有野がファミコンスーパーファミコンなどのいわゆるレトロゲームをプレイしゲームクリアを目指す番組だ。 最近は YouTube でゲーム実況が流行っていたりするが、それらの前身となるものだと思っている。

大好きな番組だがケーブルテレビで不定期放送ということもあり見逃してしまうことがたまにある。 見逃さないためにはホームページにアクセスし、次回の放送日時を確認したり、番組公式 Twitter を注視する必要がある。 この辺りを自分から能動的に取りに行くのではなく、自動化したかったので Google カレンダー を作成した。

Google カレンダーを使っている人はスムーズに使ってもらえると思う。

calendar.google.com

なお、このカレンダーはあくまで 1 ファンが個人的に作ったもので、ゲームセンター CX の関係者には一切関係がない。

技術的な小話

今回は Google App Script(GAS)を使って Web サイトをスクレイピングし、Google カレンダーに予定を作成する方法をとった。 GAS を使った理由は 2 つあり、GAS 単体でスケジュール実行ができることと、Google カレンダーへの追加が容易(そう)だったからだ。

プログラムは 100 行ほどの手続き型で作成している。 Web サイトをスクレイピングスクレイピングした情報を元にカレンダーを照会、新しい放送が入っていなければ予定を作成すると言ったことだ。 手続き型で作成した理由は、サクッと作成したかったことと今後の拡張性がなさそうと踏んだため、そのようにした。

新しい放送予定を追加できたときの通知方法は LINE を使用した。 当初は自分宛てに Gmail 経由で通知しようとしたが設定がうまくいかず、別の方法を模索した結果行き着いた。 トークンを生成し指定された URL を叩くだけなのでとても楽だし、簡素化されていて個人的なプロダクトだとこちらに寄せるほうが楽だと思った。 個人的に Slack に通知が来ると仕事の連絡と混同して身構えてしまうので、LINE だとそのようなこともなく良かった。

正常稼働を確認してから記事にするつもりだったが、不具合を見つけて遅くなってしまった。 画像が多いサイトだったので alt 属性からスクレイピングしていたが、alt 属性が前の放送日時のものになっていたりして、自分が実装する立場のときには気をつけようと身が引きしまるものを感じた。

GitHub Actionsを使って、個人タスク用のissueを毎日作成する

GitHub の issue で個人的なタスクを管理する方法を知った。 プログラマではないので普段から GitHub を使うことはないのだけれども、タスクの管理場所に迷っていたのでひとまず手を出してみようと思う。 毎日issueを作成するのも大変で、少しでもハードルを下げることを意識してGitHub Actionsで毎日自動的に作成するようにしてみた。 今回はその実現方法を記しておく。

issueのテンプレートを作成する

まずはissueを作成するためのテンプレートを作成する。 これから始めるのでまずはシンプルなものを作成し、今後必要があればカスタマイズする方向で進める。

今回はworkリポジトリを作成し、配下に.github/ISSUE_TEMPLATE/todolist.mdを作成した。

---
name: TODO リスト
about: 今日終わらせることの終了済み状態を書こう
title: ''
labels: 'tasks' 
assignees: 'yoshitaku-jp'

---

GitHub Actionsを作成する

次に毎日作成したいのでGitHub Actionsを設定する。

引き続きworkリポジトリ配下に.github/workflows/create_todolist.ymlを作成した。

GitHub ActionsはUTCで実行されるため、JSTの5時で実行されるようにした。 また、スケジュール実行の調査中に時刻通りに動いてくれないことも発生したため、手動実行の手段も残しておいた。

他の部分は参考にさせてもらった記事から引用させてもらった。

<2020/01/06 追記>

id:chatii0079 さんにコメントにて、issueのタイトルに挿入される日時が日本時間になっていないご指摘と修正方法をご連絡いただきました。ありがとうございます! 下記ymlは修正済みのものです。 <追記ここまで>

name: create_todolist
on:
  schedule:
    - cron: "5 20 * * *"
  workflow_dispatch:
  
jobs:
  create_todolist:
    name: Create Todolist
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2
      
    - name: Get current date
      id: date
      run: echo "::set-output name=date::$(TZ=Asia/Tokyo date +'%Y/%m/%d')"
      
    - name: Create a new issue
      uses: imjohnbo/issue-bot@v2.3
      with:
        title: Today Tasks - ${{ steps.date.outputs.date }}
        pinned: false
        close-previous: true
        template: ".github/ISSUE_TEMPLATE/todolist.md"
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

qiita.com

iPhoneのデフォルトカメラをMicrosoft Pixに変更する

iPhone のショートカットを導入してから、身近なところの効率化に興味が湧いている。 自分が繰り返し実行する iPhone 操作を思い返すと、カメラを使う時はデフォルトではなく Microsoft Pix を使うことが多い事に気がついた。 そして iPhone の待ち受け画面右下にあるカメラアイコンから起動させていないことも気がついたので、ここに Microsoft Pix を当てはめられないか調べ割り当ててみた。

ちなみに、Microsoft Pix は Microsoft が開発しているカメラアプリで、エンジニアには無音設定ができるカメラとしてカンファレンスなどの勉強会で使われることが多いと思う。 自分は普段使いでも料理を撮るときに使っている。 以前開発を停止する案内があったが、ここ最近 Pix という名前で突如復活した。 知らない人のために紹介しておく。

Microsoft Pix カメラ

Microsoft Pix カメラ

  • Microsoft Corporation
  • 写真/ビデオ
  • 無料
apps.apple.com

待ち受け画面のショートカットは設定ができない

最近の iPhoneウィジェット機能が追加されたり少しずつ変わっていっているが、現在のところ待ち受け画面にあるカメラのアイコンとライトのアイコンを変更する方法は無い。 Apple の思想的に変更できることはなさそうだが、ウィジェットが入ってきたことを考えると今後変更ができそうかなという思いもある。 待ち受け画面のカメラアイコンに Microsoft Pix を設定できれば最高だったが、できないことなので別の方法を模索する。

カメラを起動した時に Microsoft Pix を起動させる

そこで、カメラの起動に対して Microsoft Pix を起動させるショートカットを設定する。 そうすることで、通常のカメラを起動したタイミングで Mixrosoft Pix が起動する。

設定方法

まずはショートカットアプリを開き、右上の「+」ボタンをタップする。

f:id:yoshitaku_jp:20201230150244p:plain

「個人用オートメーションを作成」をタップする。

f:id:yoshitaku_jp:20201230150325p:plain

下にスクロールし、「App」をタップする。

f:id:yoshitaku_jp:20201230150415p:plain

「選択」をタップする。

f:id:yoshitaku_jp:20201230150820p:plain

アプリを選択する画面になるので「カメラ」と入力し、カメラをタップする。 その後、「完了」をタップする。

f:id:yoshitaku_jp:20201230150846p:plain

f:id:yoshitaku_jp:20201230150948p:plain

「App」がカメラになっていることを確認し、「次へ」をクリックする。

f:id:yoshitaku_jp:20201230151004p:plain

「アクションを追加」をタップする。

f:id:yoshitaku_jp:20201230151019p:plain

「スクリプティ」をタップする。

f:id:yoshitaku_jp:20201230151033p:plain

「Appを開く」をタップする。

f:id:yoshitaku_jp:20201230151046p:plain

「選択」をタップする。 次にアプリを選択する画面になるので「Pix」と入力し、「Pix」をタップする。 その後、「次へ」をタップする。

f:id:yoshitaku_jp:20201230151101p:plainf:id:yoshitaku_jp:20201230150934p:plain f:id:yoshitaku_jp:20201230150918p:plain

最後に、「実行前に尋ねる」をオフにする。

f:id:yoshitaku_jp:20201230151119p:plainf:id:yoshitaku_jp:20201230151142p:plain

実行の様子

カメラアプリをタップして起動

f:id:yoshitaku_jp:20201230154733g:plain

待ち受け画面からも自動起動ができている

f:id:yoshitaku_jp:20201230154739g:plain

デメリットは通常のカメラアプリが使えない

実行前の確認をスキップする設定にしているので、この設定を組み込むと通常のカメラアプリが使えなくなる。 どうしても使いたくなったら、ショートカットから設定を無効にすると使える。 自分は今のところ困ったことはない。

yoshitaku-jp.hatenablog.com

コミットした日時を変更する

LeetCode で問題を解いた後にコミットを忘れることがあった。 細かいことではあるが、解いた日とコミットをちゃんとリンクさせておきたいと思ったため、git の日時を修正する方法を調べた。 おこなっていることは日時の変更で歴史の改ざんにあたってしまうので、あくまで自分の利用の範囲内だけでに留めて悪用しないことは意識してほしい。

そもそも Author と Committer がある

コミットの日時を変更するにあたり、コミットの情報には Author と Committer が存在していることを知った。 Author はコードを書いた人、Committer はコミットをした人になる。そして、それぞれおこなった日時が記録されている。 もちろん初めてコードを書いて、コミットした時は Author と Comitter は同じ人物になり、日時も同じになる。 仮にgit commit --amendなどでコミットを変更した時は、Comitter は別の人になるが、Author は最初にコミットした人物となる。 2 つ存在している理由は、元々の作成者とコミットした人を分けることで歴史の改ざんをおこなった場合でも記録しておくためである。

git logで表示されるものは Author の情報が確認できる。 Comitter の情報も確認する時はgit log --pretty=fullerを実行すると確認できる。

f:id:yoshitaku_jp:20201228150850p:plain

git rebase で改変する

まずは rebase を使って、コミットを変更する操作をおこなう。 git rebase -i HEADで rebase を実行する。 対象のコミットを edit に変更する。

git commit --amend --date="Thu, 31 Dec 2020 14:59:59 GMT"
git rebase --continue

rebase オプションの--committer-date-is-author-date

次にgit rebaseのオプションにある--committer-date-is-author-dateを実行する。 これをおこなうことで、Committer の日付を Author に適用できる。

https://git-scm.com/docs/git-rebase/2.17.0#Documentation/git-rebase.txt---committer-date-is-author-date

https://git-scm.com/docs/git-am#Documentation/git-am.txt---committer-date-is-author-date

参考にした記事

qiita.com

改変自体はシンプルな内容だったので記事を参考にさせてもらい、補足情報やURLをいくつかいれました。

mypyをVS codeで使うための手順

Python に限らず、プログラミングで開発する際には様々な便利ツールを導入する。 今回は Python の 型の状態を静的にチェックする mypy を VS Code に導入する方法をメモしておく。

mypy を有効にする

VS Code で mypy を有効にする。

f:id:yoshitaku_jp:20201228122936p:plain

f:id:yoshitaku_jp:20201228122951p:plain

mypy をインストールする

pip install mypy でインストールができる。 1 つ注意が必要で、Python の型ヒントを利用できるのが 3.5 以上になる。

docs.python.org

そのため、mypy が対応しているのも Python3.5 からになる。Python のバージョンには注意が必要。

確認

簡単なコードを書いてみる。 関数の引数に String を入れているのでエラーは発生していない。

f:id:yoshitaku_jp:20201228123007p:plain

関数の引数を int に変えてみると、エラーが発生する。 エーラの内容も mypy のものが確認でき、動作していることが確認できる。

f:id:yoshitaku_jp:20201228123028p:plain

今年買ってよかったもの「FOR ゆ」

この記事は「今年買ってよかったもの Advent Calendar 2020」の参加記事です。 2020 年買ってよかったものは「FOR ゆ」です。

lifesupport.shop

「FOR ゆ」とは

「FOR ゆ」は眼鏡の愛眼が出しているお風呂専用メガネです。

f:id:yoshitaku_jp:20201225183610j:plain
https://lifesupport.shop/i/foryou より引用

銭湯・温泉・サウナが好きで、視力が弱い人は絶対に買ったほうがいい品です。 自分は銭湯・温泉・サウナが好きなのですが、視力が弱いために足元の段差や浴槽内の構造が見えなくて困ることがありました。 他にも露天風呂に行っても景色が楽しめないといったこともあります。 そんな自分に革命を起こしてくれたのが「FOR ゆ」です。

メリット

手を出しやすい値段

「FOR ゆ」の値段はなんと 3000 円(税抜)です。 メガネは 1 万円以上からといったイメージがありますが、飲み会 1 回分ぐらいで買えてしまいます。 試すのにも丁度いい価格です。

すぐに買える

「FOR ゆ」は、既製品として売っているのでお店に行って在庫があればすぐに買うことができます。 メガネは、視力を測定して度を調整したり、眼鏡の角度の調整をしたりと手元に来るまでに時間がかかります。 しかし、「FOR ゆ」は湯に浸かる直前、眼鏡の愛眼へ行って買うだけで終わります。

サウナーに優しい金属未使用

「FOR ゆ」のすごいところは金属を一切使っていないところです。 全部ポリカーボネートと呼ばれるプラスチックで作られています。 つまりサウナに入っても熱による変形がないのです。 ちなみに耐熱温度は 120° ~ 130° と公式サイトにありました。

デメリット

選べる度に限界がある

「FOR ゆ」で選べる度数は 5 種類です。

自分もそうですが、左右で視力が違う人は、ちょっと見え方に癖があるはずです。 湯に使っている間だけ掛ける品物なので、妥協するべき点でしょう。 下の度の範囲から外れてしまう人は残念な点かもしれません。

  • +2.50
  • -3.00
  • -4.00
  • -5.00
  • -6.00

お風呂に入っている間だけ見えて、値段も 3000 円なら文句はなにもないですが、唯一のデメリットとしてあげてみました。

まとめ

今までは、サウナにテレビが設置されていても見れなかったですが、今ではテレビを見て時間をつぶすことができるようになり最高です。 室内の時計も見れなかったので腕時計を持っていってましたが、それもしなくていいのでとても助かっています。 銭湯・温泉・サウナが好きのメガネ人は 1 回買って体験してほしいです。

yoshitaku-jp.hatenablog.com

Karabiner-Elementsを使っているMacでピアソンVUEの試験を受けてはいけない

強い言葉を使うのは好きではないのですが、注意喚起を含むためこうしておきます。

結論

Karabiner-Elements を使っている Mac でピアソン VUE の試験を受けると、試験問題配布のタイミングでピアソン VUE アプリが落ちて試験が受けられません。

詳細

他の方が詳しく書いてくださっているので、紹介して省略します。

dev.classmethod.jp

yaamaa-memo.hatenablog.com

背景

ご時世だからか「テストセンターで受験すること」と「在宅で受験すること」の選択肢があり、自分は在宅での受験を選びました。 自室には社用 PC の Windows と私用 PC の Mac がありました。 自分は変に気を使って、「社用 PC を使っている時に業務連絡が飛んできて、チャットツールが立ち上がって失格…なんてことになったら嫌だなぁ」と思いを巡らせて私用の Mac を使うことにしました。

在宅試験を選ぶと試験環境のシステムチェックがあるのですが「通過」します。 自分のテスト中には「Karabiner-Elements が動いてるぞ!」とアラートが上がっては来るのですが、そのまま最後の画面になり成功と判定されます。 しかし、チェック段階では通過しますが、実際の問題配布ではエラーとなり失格になります。

Windows だとどうなるか

他の記事になかった情報として 別の PC、例えば Windows だとどうなるかを載せておきます。 たまたま Windows も手元にあったので、そちらでもテストをおこないました。 そこでは試験環境のシステムチェックの途中で、模擬問題が出力されます。 Karabiner-Elements が入っている Mac で受けた人には表示されていない内容で、おそらくアラートが上がっているタイミングで確認ができないのではないかと思います。

今後

自分はエラーで失格になったと思い放置していたので、こちらの記事にありました

その後サポートの方とメールでやりとりして、今回の試験結果の取り消しなど対応していただけました。

の情報を信じて、サポートの方とやり取りしてみます。 US キーボードにして Karabiner-Elements を使っている Mac の人は気をつけてください。

【LeetCode】14.longest-common-prefix をPythonで解く

問題はこちら

leetcode.com

Example 1:

Input: strs = ["flower","flow","flight"]
Output: "fl"

問題の解説に載っている例を持ってきた。 リストの中に格納されている複数の文字列を、前から 1 文字ずつ取り出していく。 取り出した文字が同じかどうかを判定し、同じなら 2 文字目へ、違うのならば同じ部分だけを出力するものになる。

回答例はこのようになる。

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        prefix = ""
        if not strs:
            return prefix

        for i in zip(*strs):
            if len(set(i)) == 1:
                prefix += i[0]
            else:
                return prefix

        return prefix

解説

空文字の判定

そもそも送られてくるstrsがからの場合は空文字を返す。

prefix = ""
if not strs:
    return prefix

forで回して、文字の判定

for i in zip(*strs):
    if len(set(i)) == 1:
        prefix += i[0]
    else:
        return prefix

まずzip関数を使う。 引数にリストを指定し、iにタプルの形で受け取っている。 Example 1のstrs = ["flower","flow","flight"]だと、1回目のループ処理でiは(f,f,f)を受け取る。

次にif文の部分になる。 set(i)で、タプルになっているiをセット型にしている。 set型は値を重複して持たないので、同じ文字は1つにまとめられる。 Example 1では、iが(f,f,f)となっていたが、{f}になる。 {f}となっている要素をlen関数を使って中身の数を確認し、1ならprefixに格納している。

今回はいくつかの文字列が、先頭からどこまで同じかを確認する問題だった。 つまり、len関数を使った時に1以外の数が返ってくれば、同じ文字ではないということになるので、それ以降は確認する必要がない。

【Django】アプリケーションをディレクトリにまとめた時の設定変更箇所

Django でアプリを複数作っていくとルートディレクトリが見づらくなっていく。

.
├── accounts
├── manage.py
├── posts

そこで、app ディレクトリを作成し、その中にアプリを入れる形をとってみた。

.
├── app
    ├── accounts
    ├── posts
├── manage.py

それに伴い、いくつか設定を変えなければいけない部分があったので、メモしておく

アプリケーションの設定変更

今回は posts を例に出して進めていく。

まずはapp/posts/apps.pyを変更する。

ルートディレクトリに作成した時は、次のようになる。 name がアプリケーション名になっている。

from django.apps import AppConfig

class PostsConfig(AppConfig):
    name = "posts"

app ディレクトリ配下に作成した時は、次のようになる。 name がルートディレクトリに作成したときと変わっている。 app は posts から見た親ディレクトリを指していて、ドットで階層を表している。 つまり、name の部分に親のディレクトリも記述するようになる。

from django.apps import AppConfig

class PostsConfig(AppConfig):
    name = "app.posts"

アプリケーション側の設定は以上になる。 アプリケーションが変わったことにより、それを読み込む settings.py も変更が必要になる。

settings.py の設定変更

作成直後にアプリケーションを読み込む設定は何も書かれていないけど、ルートディレクトリに作成した時は、次のように設定することが多い。

INSTALLED_APPS = [
    """
    (中略)
    """

    "posts.apps.PostsConfig",
]

app ディレクトリ配下に作成した時は、settings.py の INSTALLED_APPS が次のようになる。 ここでもapp.を付けて、親フォルダとディレクトリを示すドットを付ける。

INSTALLED_APPS = [
    """
    (中略)
    """

    "app.posts.apps.PostsConfig",
]

今年やってよかったこと「サウナ」

この記事は「今年やってよかったこと Advent Calendar 2020」の参加記事です。 2020 年やってよかったことはサウナです。

サウナに出会ったきっかけ

そもそもサウナに出会ったきっかけです。 自粛やら在宅勤務やら、世間がまだまだ手探りだった頃、自分も自宅での勤務スタイルを探していました。 音楽を流してみたり、ラジオを流してみたり、映像を流しっぱなしにすることもありました。 映像系を探すときは、BGM の代わりとしたかったので流しっぱなしにしていても気を張らなくて良さそうなものを選んでいました。

その中で出会ったのが「サ道」でした。

www.tv-tokyo.co.jp

サ道

簡単にサ道の紹介を…。

原田泰造三宅弘城磯村勇斗、 そして宅麻伸。 芸能界きってのサウナ好き俳優が集結! サウナ好きによる サウナ好きのための 『サ道』いよいよドラマ化! 今回、本作を映像化するにあたって目指したのは“サウナ好きによるサウナ好きのためのドラマ”(中略)キャストもスタッフも自他ともに認めるサウナ好きが集結しました。

www.tv-tokyo.co.jp

この記事を書くためにホームページから引用しましたが、ここまでサウナ好きが集まって作られていたとは…。 すごいですね。

元々は漫画です

morning.kodansha.co.jp

ただ単にいろんなサウナ行って入ってそれを見ているだけなのですが、ドハマリしてしまいました。 自分は元々銭湯が好きだったので、サウナに対する抵抗もありませんでした。 むしろ、行きたい気持ちばかりが高まり、BGM 代わりとしての目的を他所に、夜ふかししながらサ道をイッキ見してました。 その後は、サウナ好きの友人に連れられ、いろんなサウナへ行くことになります。

サウナのなにが良かったか

サウナ好き全員がいいますが「ととのう」体験が最高でした。 暑いサウナに入って、水風呂で身体を締める。その後の「ととのい椅子」での休憩で、血が全身を駆けめぐります。 このパターンを 3 回ほど繰り返しますが、最後には疲れが吹っ飛んでます。

飲食スペースが有るところでは、その後のビールも最高ですし、就寝するときには泥のようになって爆睡できます。 翌朝にはスッキリして身体が軽いです!

行ったサウナ

ハマってしまったサウナ。 自分が今年行った場所をまとめておきます。 どこも良かったです!

北欧 / 上野駅

sauna-ikitai.com

境南浴場 / 武蔵境駅

sauna-ikitai.com

アサヒトレンド 21 / 三鷹駅

sauna-ikitai.com

かるまる 池袋 / 池袋駅

sauna-ikitai.com

サウナ&スパ カプセルホテル 大東洋 / 大阪・梅田

sauna-ikitai.com

サウナ&カプセルホテル ルーマプラザ / 京都・祇園四条駅

sauna-ikitai.com

サウナしきじ / 静岡・静岡駅

sauna-ikitai.com

スパリゾートプレジデント / 御徒町駅

sauna-ikitai.com

近所のサウナを探そう!

「サウナイキタイ」というサイトでサウナを探すこともできます。 どんどん行って欲しい!

sauna-ikitai.com

まとめ

サウナは全然怖いところではないので行ってほしいです。 行ってみたいけど不安な人は声かけてください! ととのいに行きましょう!

yoshitaku-jp.hatenablog.com