狐の嫁入りっていいよね

理系と芸術系になりそなった文系卒、コンピュータグラフィックスを学ぶ

Duo3.0の復習用CDを一文ごとに分割して例文とともにAnkiにインポートした

この記事では以下のようなことを実現した。

youtu.be

オーストラリアに留学したときや大学受験時代にお世話になったDuo3.0を改めて最近触る機会があった。

DUO 3.0

DUO 3.0

これとは別売りの復習用CDを分割して例文とともにAnkiに入れられないかと思い、模索していたが何とか出来たのでメモとして残す。

DUO 3.0 / CD復習用

DUO 3.0 / CD復習用

Duo3.0は例文を丸暗記する価値のある単語帳として有名で、例文を覚えたうえで、その例文の単語を入れ替えるだけで日常会話レベルなら最低限なんとかなってしまうほど。昔留学していたときにすごく役にたった。構成としてが、560文が45セクションに分かれている。

ただ、問題点として復習用CDがセクションごとの収録なので、例えばセクション1を再生すると560ある中の1~12の例文がまとまって再生されてしまう。本来であれば例文の音声を一文ごとに分けて、560個のファイルになっているべきだが、CDのサイズ上45個のファイルになってしまっているとのこと。


AnkiとDuo3.0の親和性の高さは結構有名で、いろんな人が記事にしている。

www.love-koumuin.com

blog.livedoor.jp

しかし、①Duo3.0の復習用CDを例文単位に分割して、②例文のテキストとともにAnkiで音声を再生するという記事が見当たらなかったので書き記すことにした。


①Duo3.0の復習用CDを例文単位に分割

ここを参考にして、Duo3.0の復習用CDの「セクション単位の音声ファイル」を「例文単位の音声ファイル」に分割した DUO 3.0 CD 分割の方法

ファイル名が001.mp3~560.mp3ファイルになるので、これをWindowsであればC:\Users\xxx\AppData\Roaming\Anki2\xxx\collection.mediaに入れる。

②例文のテキストとともにAnkiで音声を再生する

ありがたいことにDuo3.0の日本語訳と英文をテキストにしてくれていたひとがいたので、これをエクスポートして加工する。

quizlet.com

加工したものを以下に置いておくので使ってください。

duo.tsv - Google ドライブ

@@@の列がある理由は後述。

次にこのファイルをAnkiにインポートする。

Ankiのメニューからファイル > 読み込むをクリック

すると以下のようなウィンドウが出てくる

f:id:lipton_lemontea:20181027235125p:plain

そのまま読み込む。

その後、Ankiのブラウザを開いて、追加した単語帳を選択し、Ctrl + Alt + Fで一括置換を行う。

その際、以下のように入力する。

検索文字列:@@@(\d{1,3})

置換文字列:[sound:\1.mp3]

「入力条件に正規表現を使う」にチェックを入れる

そしてOKを押す

f:id:lipton_lemontea:20181027235612p:plain

これで先ほどC:\Users\xxx\AppData\Roaming\Anki2\xxx\collection.mediaに入れた音声ファイルを呼び出すようになる。

Windows10とUnity2018で.NET4.6にしたらRiderが真っ赤になった

f:id:lipton_lemontea:20181026222658j:plain

実行環境

Windows10
Jetbrains Rider 2018.2
Unity 2018.2.12f1
.NET Framework 4.6

Unityで使うC#(というか.NET)のバージョンを上げたらプログラミングエディタに怒られた話。

Riderはいいぞ

UnityでC#のプログラミングをするとき、プログラミングエディタとして私の周りほぼ全員がMicrosoftVisual Studioを使っている。 私だけJetbrainsのRiderを使っている。Anki然り、素晴らしいものはとことん使い倒したい派なので割と声高々に布教するのだが、身近で使っている人が私だけというのは悲しい。

以下の書籍を読んで、エラーの原因を探す方法(=デバッギング)を覚えたあたりから開発効率が上がっている。

二冊ともJetbrains製品のJava専用プログラミングエディタである「IntelliJ IDEA」ベースで書かれているが、Jetbrains製品の操作方法はRider含めどれもほぼほぼ変わらないので参考になる。

こっちは少し古いし洋書だけど、上の本を覚えていれば「ほんほん、なるほどー」ってなる。エディタの知識に肉付けをしていく感覚で見れる。

IntelliJ IDEA Essentials (English Edition)

IntelliJ IDEA Essentials (English Edition)

まあ、それはいいんだけど、C#6系の$"hoge {fuga} {mogu}"式だったり、いろんな文法が使いたかったので、調べたらUnityが.NETフレームワーク4.x系に対応できるとのことだった。

①Unityでまず.NET 4.xを使えるようにする ②Riderで怒られる ③その解決方法

の順で書いていく。

①Unityでまず.NET 4.xを使えるようにする

Unityで.NET 4.xを設定する手順

Edit > Project Setting > Playerをクリック

f:id:lipton_lemontea:20181026225125p:plain

そうするとPlayer SettingというメニューがInspectorに現れる。

f:id:lipton_lemontea:20181026225248p:plain

その中の、Other Setting > Configurationとたどっていくと、

Scripting Runtime Versionという項目があるので、.NET 4.x Equivalentを選ぶ。 f:id:lipton_lemontea:20181026225429p:plain

Unityの再起動を促されるので、再起動する。

②Riderに怒られる

次にRiderを開いたら真っ赤になって、怒ってきた。

f:id:lipton_lemontea:20181026225811p:plain

真っ赤っか。

Event Logにはこんな感じで吐いていた。

2018/10/26

22:36   Project 'Assembly-CSharp' load finished with warnings: フレームワーク ".NETFramework,Version=v4.7.1" の参照アセンブリが見つかりませんでした。これを解決するには、このフレームワーク バージョンの SDK または Targeting Pack をインストールするか、SDK または Targeting Pack をインストールしているフレームワークのバージョンにアプリケーションを再ターゲットしてください。アセンブリはグローバル アセンブリ キャッシュ (GAC) から解決され、参照アセンブリの代わりに使用されるため、アセンブリが目的のフレームワークに正しくターゲットされない場合もあります。 at (1179:5)

22:36   Project 'Assembly-CSharp-firstpass' load finished with warnings: フレームワーク ".NETFramework,Version=v4.7.1" の参照アセンブリが見つかりませんでした。これを解決するには、このフレームワーク バージョンの SDK または Targeting Pack をインストールするか、SDK または Targeting Pack をインストールしているフレームワークのバージョンにアプリケーションを再ターゲットしてください。アセンブリはグローバル アセンブリ キャッシュ (GAC) から解決され、参照アセンブリの代わりに使用されるため、アセンブリが目的のフレームワークに正しくターゲットされない場合もあります。 at (1179:5)

22:36   Project 'Assembly-CSharp-Editor-firstpass' load finished with warnings: フレームワーク ".NETFramework,Version=v4.7.1" の参照アセンブリが見つかりませんでした。これを解決するには、このフレームワーク バージョンの SDK または Targeting Pack をインストールするか、SDK または Targeting Pack をインストールしているフレームワークのバージョンにアプリケーションを再ターゲットしてください。アセンブリはグローバル アセンブリ キャッシュ (GAC) から解決され、参照アセンブリの代わりに使用されるため、アセンブリが目的のフレームワークに正しくターゲットされない場合もあります。 at (1179:5)

22:36   .NET Framework Not Installed: Download and install .NET Framework 4.7.1 Developer Pack

③その解決方法

調べたら同じようなことで怒られている人もいたんだけど、私のOSはWinで下記の人のOSはMacなので、解決方法が違った(ので記事にした)。

qiita.com

結論としては、Unity側での設定でRiderの怒りは静まった。

UnityのEdit > Preferenceをクリック

その後PreferenceウィンドウのRiderをクリック

Override TargetFrameWorkVersionにチェックを入れる。

その後、RiderとUnityを再起動したら怒られなくなった。

f:id:lipton_lemontea:20181026230316j:plain

f:id:lipton_lemontea:20181026230325j:plain

めでたし。

選択ソート

今本当にやるべきことではないかもしれないが、基本的なアルゴリズムの勉強。

今日は選択ソート。

選択ソート

まず、 選択ソートとは線形探索のアルゴリズムをもとにして、 最小値を探し出していくアルゴリズム

この本の選択ソートのフローチャートとにらめっこして理解したうえで

Pythonで体験してわかるアルゴリズムとデータ構造

Pythonで体験してわかるアルゴリズムとデータ構造

この本の三章を写経した。その後理解しているかどうか試すために、C#の練習がてらC#で書き下ろした。

ポイントとしては、 ①比較する方と②比較される方のループを実行する。 配列Aの要素数をNとすると、①比較する方のループは配列Aの最初からN-1までで、対して、②比較される方のループは配列Aのイテレーター+1からNまで

ループの計算量はO(N)。そして、選択ソートでは①比較する方と②比較される方の二つのループを実行するから、O(N*N)。なので、選択ソートの計算量はO(N2)になる。

ちなみにうかる!基本情報技術者試験午後のほうの選択ソートのフローチャート(P144)、最後の条件文って要るのか...??無くても動いたけど理由がわからん...。

Python3.8

二つの変数a,bの値の交換をするときは、一時的に値を代入するtempのような変数が必要。

temp = b
b = a
a = temp

しかしPythonでは変数tempに一時的に値を置かずに値の交換をa,b = b,aと一行で済ませることができる。やっぱりpythonは書きやすいなあ。

l = [2,3,4,1,6,7,8,9,5]

def sort(A):
    for i in range(0,len(A)-1):
        select_min(A, i)

def select_min(A, i):
    min = i
    for j in range(i+1, len(A)):
        if A[min] > A[j]:
            min = j
    A[i], A[min] = A[min], A[i]


sort(l)
print(l)

#[1, 2, 3, 4, 5, 6, 7, 8, 9]

Wandboxでのコードはこちら

C#5.19

public class SelectionSort{
    public static void Main(){
        int[] arr = {2,3,4,1,6,7,8,9,5};

        Sort(arr);

        for (int i = 0; i < arr.Length-1; i++)
        {
            System.Console.Write(arr[i]);    
        }
        
        
    }

    private static void Sort(int[] A)
    {
        for (int i = 0; i < A.Length - 1; i++)
        {
            SelectMin(A, i);
        }
    }

    private static void SelectMin(int[] A, int i)
    {
        int min = i;

        for (int j = i + 1; j < A.Length; j++)
        {

            if (A[min] > A[j])
            {
                min = j;
            }
        }

        int temp = A[i];
        A[i] = A[min];
        A[min] = temp;

    }
}

//12345678

Wandboxでのコードはこちら

あまりC#は書けないのだけど、System.Console.Write(arr)で配列は出力されないで一々for文回してあげないといけないのね...。

線形探索

アルゴリズムの勉強がてらメモ程度に。

初回なので超基礎の線形探索から。

線形探索

順番に並んでいるデータがあり、ある値を探したいときに、頭から探していくアルゴリズム

例えば、

4,3,6,5,7

という並びで値があって、5を探したいとする。 単純に頭から探していくとてもシンプルな方法。

流れとしては、

①開始

②4は5ではないので次へ

③3は5ではないので次へ

④6は5ではないので次へ

⑤5は5なのでこれを表示してループを抜ける。

⑥おわり (一つ前で探したい値が見つかっているので7に対しては何もしない)

Python3.8

もうPythonって3.8なのね。ちょっと前までは3.6だったのに。

list = [4,3,6,5,7]

find = -1
search = 5

for i in list:
    if i == search:
        find = i
        break

print(find)

Wandboxでのコードはこちら

C#5.18

public class Hello{
    public static void Main(){
        int[] arr = {4,3,6,5,7};
        int find = -1;
        int search = 5;
        
        foreach(int n in arr){
            if(n == search){
                find = n;
                break;
            }
        }
        
        System.Console.WriteLine(find);
        
    }
}

Wandboxでのコードはこちら

こうして書いてみるとPythonって楽に書けるし、こぢんまりとしててかわいいなあと思う。

Ankiを使い始めて一年で500時間勉強したので「なぜAnkiを使うのか」を書き連ねた

みんな大好きAnki

Ankiを真面目に使い始めて一年が経った。

Ankiで復習した時間はこの一年で延べ500時間を超えていた。

f:id:lipton_lemontea:20180928180130j:plain

名古屋人が朝起きたら喫茶店に駆け込みコーヒーとモーニングセットを頼むのが生活の一部となっているように、Ankiをやることが私の生活の一部になっている。

この500時間という数値は「Ankiで復習した時間」なので、「テキストを読んだり問題集を解いて新規に勉強した時間」と「Ankiの単語を登録に要した作業の時間」は含まれていない。「勉強のための作業は勉強時間に入らないんじゃないの??」と言われたそれまでだが、ここには新規に学習している時間は含まれていないので、ここ一年の実際の勉強時間はもっとあるのだと思われる。

なぜAnkiを使うのか

この記事ではAnkiが勉強に有効な理由を書いていきたい。

Ankiを使う理由:復習のスパンを手動で管理をしなくていい。

効率よく頭の中に知識を定着させるためには適切なタイミングで復習をする必要がある。(エビングハウスの忘却曲線

言い換えると、知識の定着には適切な学習管理が必要である。

がしかし、この「効率的に知識を定着させるために今日は何をやるべきなのか」を考える行為は一般的にとても煩雑な作業になる。

そこでAnkiを使えば、この煩雑な学習管理を人力で行う必要がなく、目の前に出されたカードを黙々と解いていくだけで記憶に定着ができるというわけである。これがAnkiを使う理由の一つ目。

Ankiを使う理由:覚えられる感覚が気持ちがいいから。

Ankiを繰り返していくと、知識を覚えつつ理解できている感覚があることがわかる。昨日わからなかった問題の理解が少しずつ進んでゆく。独立していた知識が繋がってゆく。知識が繋がるとき、霧が晴れるような快感を覚える。「そうか、そういうことだったのか」と。Ankiを続けていくとはもちろん多少のしんどさはあるが、この少しずつ成長できているこのイタキモチイイ感覚がなんともいえない。

Ankiというアプリの名前が「丸暗記」というニュアンスすら含みそうなのだが、そうではない。物事を理解するためには最低限覚えないといけないことがあり、かつ、それらを有機的に整理したうえで繋げてやる必要がある。この作業は属人的な部分が大きいかもしれないが、Anki上でやることも可能だと思う。いや、Ankiがそれを補助してくれるといったほうがいいか。知識をつなげるベースを作ってくれる。

Ankiを使い始めてから、使っていない時よりも「あーそうか、そういうことだったのか」と理解できる機会が圧倒的に増えている。知的好奇心を満たしてくれて単純にうれしい。だから触り続けるのだと思う。

Ankiを使う理由:努力が無駄になりにくい

「その知識を覚えるべきであり」かつ「適切に単語帳をAnkiに登録できている」のであれば、努力が無駄になりにくい。

Ankiに単語帳として登録する際にもルールがある。 参照: 効果的な学習法: 知識を定式化する20個のルール (目次)

このルールを守っていれば、Ankiを使わない時に比べて、適切に覚えられる。いわばスポーツの基本フォームのようなものだと思う。 トレーニングするフォームがおかしければ、トレーニングをしても効果が出づらい。むしろ害になることもある。このサイトの知識はそれを防いで、忘れそうなときに自動で(=適切なスパンで)その知識を出してくれる。

Ankを使う理由:昔勉強したものを引っ張ってこれる(データベース化)

これだけやっても必要な知識がパッとでてこなかったりする。 そんなときはAnkiは単語帳に登録した言葉の検索が可能だ。 「金属表現に最適な鏡面反射のシェーダー、なんだっけ。Ankiに入れてたな確か」→Ankiのデータベースで検索をする→「ああ、クック・トランスのシェーダーか。」というような感じで調べられる。個人的にはEvernoteGoogle Keepにぶち込むよりも「覚えつつメモを残せる(し必要に応じて検索もできる)」ため、これらよりも有意義なツールだと思う。

Ankiを使う理由:オープンソースソフトウェアでかつ、全世界から支持されているので開発中止になりにくい

同じようなソフトとして、zuknowがあった。が、サービス中止になった。

zuknow-magazine.hatenablog.com

組織がアプリ開発をしている場合、どうしても掛けた労力分の収益がないと撤退してしまう。zuknowの明確なサービス中止理由はネットでは見つからなかったが、アプリの開発中止をすると移行が面倒だ。また、いままで登録したものも無駄になってしまう可能性がある。

対して、Ankiはオープンソースソフトウェアであり有志によって作られている。かつ、その母体も世界規模でかなり大きいので、サービス停止ということになりにくい。他のツールを使わない理由はここにあるというのもAnkiを使う理由の一つだ。


結び

「Ankiはいいぞ」というお話だが、結局は「自分で勉強方法を探して、Ankiの使い方を調べて、工夫し続けてきたから、これだけ使い続けられた」ということだと思う。

その昔、私は法律の勉強をしていた。その際、背伸びをしてイエーリングの『権利のための闘争』(岩波文庫)を読んだことがあった。 岩波文庫読んでいる俺カコイイ」という時期が私にもあったことをここに正直に告白致します...。

その一説にこんなことが書いてあったことを思い出した。

諸国民が何の苦労もなしに法を手に入れたわけではなく、法を求めて苦心し、争い、戦い、血を流さねばならなかったからこそ、それぞれの国民とその法との間に、生命の危険を伴う出産によって母と子の間に生ずるのと同様の固い絆が生まれるのではないか? 何の苦労もなしに手に入った法などというものは、鸛が持ってきた赤ん坊のようなものだ。鸛が持ってきたものは、いつ狐や鷲が取っていってしまうかしれない。それに対して、赤子を産んだ母親はこれを奪うことを許さない。

権利のための闘争 (岩波文庫)

権利のための闘争 (岩波文庫)

こんなコムズカチイ古典の引用なんてしなくてもいいのだが、結局は勉強方法は自分で苦労して探すしかない。しかし、苦しんで探した分、自分の勉強方法に愛着が沸くし、問題解決能力の鍛錬になる。自分で作ってきた勉強法を改善できた分、喜びがある。

「やりたいことがあるが、勉強を死ぬほどやらないといけない.し覚えられる自信がない..」って思う人、そんなことでやりたいことをあきらめなくてもいい。そんなときはAnkiがサポートしてくれる。

自分の勉強方法を探すきっかけとして、Anki、おすすめですよ。

TeamViwerっていうリモートデスクトップツールが優秀だった

Team Viewerはいいぞというお話

注意:リモートデスクトップは便利だけど各自セキュリティー対策はきっちりしてね

私は出先のPCから自分の部屋に置いてあるPCによくリモートデスクトップでアクセスしている。リモートデスクトップとは簡単に言うと、あるPCから他のPCにアクセスし、あるPCから他のPCの操作ができるツールのことを指す。

私がリモートデスクトップを使用する理由としては三つある。

①環境が出先のPCに依存せず、いつでも自分が構築した環境にアクセスできること

②出先での作業をUSBやクラウドに保存しなくて済むこと

③重いPCを持ち歩かなくても済むこと

自分のPCのスペックが

CPU:i7-7700
メモリ:32G
SSD: 100G
HDD:1T
GPU:GTX1050 

なので割と物理的に重い。

移動にドアトゥードアで往復で二時間弱掛かる。「2,3kgある重りを背負って毎日往復で二時間移動する」のは大変面倒くさいルーティーンワークである。私の信条は「楽のためには努力を厭わない」である。勤勉かつ怠惰なのである。えっへん。

めんどくさいルーティーンワークは嫌いなのでそもそも如何にやらずに済ませるかを考えた。そこで解の一つとして「最低限のPCとネット環境さえあれば場所を選ばすいつもの環境とスペックで作業ができる」リモートデスクトップという手段が浮かび上がったのである。


その際にGoogle Chrome Remote Desktopを使用していた。(過去形)

f:id:lipton_lemontea:20180914180937j:plain

最初は「出先のPCから自分のPCを操作できて便利やなーgoogleさまさまだなー」と思って使っていた。

が、使っていくうちに問題が二点浮上してきた。

  • 問題点その①ショートカットがリモート側であまり使えない

  • 問題点その②マウスのカーソルが非表示になる

何か一枚挟んで間接的に操作をしている感覚がすごく、操作性が著しく低いのである。自分のPCをさも目の前にあるかのように操作をしたい(しかし持ち歩きたくない)と考える私にはこれは問題だった。

これらをTeam Viewerというリモートデスクトップツールが(無料で)解消してくれた。

f:id:lipton_lemontea:20180914180601p:plain


問題点その①ショートカットがリモート側であまり使えない

Google Chrome Remote Desktopの使いづらいところの一つ。

ウィンドウ切り替えのショートカット(Alt + Tab)やデスクトップを表示するショートカット(Win + D)をリモート側で実行したいのにされず、ホスト側で実行されてしまう。リモート側(自分のPC)でUnity弄ってエディタ弄ってわからないことがあったらChromeでググって...というようなウィンドウ切り替えを瞬時にできないのでイラっとする。

問題点その②マウスのカーソルが非表示になる

Google Chrome Remote Desktopで一番困ったのがホスト側ではマウスカーソルが表示されるのに、リモート側ではマウスカーソルが表示されないことである。

なんでも調べてみたらリモート側でマウスが接続されていないと表示されてないらしい。

いやそもそもマウスもってねえし...。めんどくさい。これは大変由々しき事態である。


TeamViewerを使えば上記問題点は解決した

リモート操作する側のパソコンのショートカットキーを使用したい場合の説明をします。 例えば、ワードやエクセルのショートカットで有名な、[Ctrl+Z(戻す)]や[Ctrl+A(全部選択)]などのショートカットキーを利用したい場合、設定を行う必要があります。

ショートカットキーの設定|TeamViewerの使い方より引用

もちろんカーソルもがっつり示してくれるようになった。

これで、何か一枚挟んで間接的に操作をしている感覚はなくなり、自分のPCをさも目の前にあるかのように操作できるようになった。

TeamViewer最高やん...

これでまた楽ができるようになった。私は満足である。

Prefabの使い方

最近Unityを勉強し始めた。 オブジェクトを大量生産するPrefabの使い方で混乱したのでメモ程度にざっくりまとめた。