Taskの備忘録

こんにちは。弱小エンジニアのいすいです。

 

最近プロジェクトを引き継いで、コードの改修を行っているのですが、

そのコードが何とも杜撰笑笑

 

元々の担当者はもう辞めちゃった人で、

技術はあるのですが、結構雑な人だったっぽい笑笑

 

スペルミスやら、NGなコーディングしているとか色々あったけど、

特にいまいちと思ったのが、

Taskの付け方!

 

とりあえず色々なところにTaskがつけられて、全てすぐにawaitされている。。

 

まあ自分も実際よく分かってないし、人のこと言えないのですが、、

そんなこんなでこの機会に非同期について学び直しました。

 

Taskで処理する場所

まず、Taskで処理を行うと言うことは、非同期で処理する目的かと思いますが、

根本的に非同期にする場所というのは重い処理の箇所です。

 

何でもかんでも非同期にしてもアプリの性能は良くなりません。

 

具体的に非同期にした方が良いのは、

ファイル読み込みや、APIアクセス、DBアクセスとかですかね。

 

すぐにawaitしない方が良い時

戻り値がTask型だと、awaitで受け待ちにすると思いますが、

すぐにawaitで待たない方が良い時があります。

 

それは非同期にしたい箇所でTask型の変数をまとめてawaitしたい時です。

まとめてawaitするのは以下のようなコードです。

Task taskA = Task.Run(()=>
{
    Thread.Sleep(3000);
});

Task taskB = Task.Run(()=>
{
    Thread.Sleep(3000);
});

Task taskC = Task.Run(()=>
{
    Thread.Sleep(3000);
});

// ここでまとめてawait
await Task.WhenAll(taskA, taskB, taskC);

こうすることで、taskAとtaskB,TaskCを非同期で処理できます。

 

一度ここでawaitについておさらいすると、

awaitが付いている処理では、awaitにたどり着くと、メインスレッドに呼び出し元が戻ります。

つまり、メソッドAからメソッドBを呼び出し、メソッドBのawaitに辿り着いた時、メソッドAのメソッドB呼び出し以降の処理がメインスレッドで続行されます。

それと同時にサブメソッドでメソッドBのawaitの処理が実行され、それが終わると、await以降のメソッドBの処理がメインスレッドに戻ってきて実行されます。

例えば以下の場合、

void MethodA()
{
    MethodB();
    Console.WriteLine("A");
}

async void MethodB()
{
   await MethodC();
   Console.WriteLine("B");
}

async Task MethodC()
{
    await Task.Run(()=>
    {
        Thread.Sleep(3000);
        Console.WriteLine("C");
     });
}

上記例を実行すると、

A
C
B

の順番で出力されます。

MethodCで3秒スリープしている間に、MethodAがメインスレッドで処理を進め、MethodCが完了したあと、MethodBが最後まで実行されます。

 

ちなみに、MethodCの処理中にMethodAの処理は完了してしまうことになります。

 

ここで大事なのは、awaitするとその先は受け待ちになってしまうことです。

その先を非同期で処理したい場合にはawaitを付けてはいけません。

なので、何でもかんでもawaitで呼び出せば良いというわけではないのです。

 

ちなみに、ネットではasync voidはだめっていう記事が多いのですが、

async voidでも良くないですかね?

損はないからasync Taskにしとけってことですかね。。

 

ちなみに、Task.Wait()とかはデッドロックのリスクがあるので、しない方がいいみたいですね。

あまり良く理解していませんが、これは気をつけとこうと思います。

 

Taskを重ねてもあまり意味ない

先ほどのTaskとawaitの話をよく聞いておかないと、

Taskを重ねてしまうような無駄なコードを書いてしまう可能性があります。

例えば以下のようなものです。

async void MethodA()
{
    await Task.Run(async ()=>
    {
         await MethodB();
    });
}

async Task MethodB()
{
    await Task.Run(()=>
    {
         Thread.Sleep(3000);
     });
}

上記のようなコードは実際にありました。。😅😅

awaitしている間は受け待ちになるので、上記のって言ってしまえば以下のと同義です。

async void MethodA()
{
    await Task.Run(()=>
    {
         Thread.Sleep(3000);
     }
}

もちろん、場面によって前者の方が適していることはあるかと思います。

ですが、Taskとawaitの仕組みをしっかり理解していないと、

意味のないコードを書いてしまうので要注意です。

macbookが水濡れしたが、外部キーボードで何とかなった話

こんにちは弱小エンジニアのいすいです。

本日は愛用してきたm1のmacbookが水濡れしてキーボードが壊れていたのですが、何とか今使えている方法をご紹介します。

今困っている人の参考になればと😃😃

 

macbookは水濡れしてもまだ使える!

結論から先に言うと、macbookが水濡れしてキーボードが使えなくなっても、

諦めるのは早いかもしれません。

 

外部キーボードを用意すれば、

macアプリを駆使して動く可能性は十分あります!

 

僕は誤反応してしまうまで故障したキーボードでも、

現在は動いています。😁

 

macbookが水濡れした時の驚愕の修理代

1ヶ月ほど前、全くの自分の不注意によって、赤ワインをmacbookにこぼしてしまいました。

この時キーボード等普通に使えていましたが、内部の水濡れが気になったので、

念の為Appleコールセンターにチャットで相談。

 

無料で点検してくれることに。

ほっと胸を撫で下ろします。😌

 

その後チャットで点検の会話を進めます。

誤字をしてしまい、バックスペースを押すと、そのまま送信。

あれ。。??

 

不安になってもう一度トライ。。

 

やはりバックスペースを押すと、送信される(もしくは入力が確定される)!

 

これはキーボード壊れたっぽい?笑笑(ほんとは笑えてない)

オペレーターにそのことを伝えると、修理に出すべきだと打診され、

オンライン修理費はなんと、、

 

130,000円!!!!

まじか、、、😨😨😨😨

 

アップルストアに駆け込み🏃‍♂️🏃‍♂️🏃‍♂️🏃‍♂️🏃‍♂️

 

しかし、ここでも13万円。。。

 

濡れただけだからそれを乾かしたり、一部交換するだけだと思っていましたが、濡れたと思われる箇所は全て取り替えるからそれだけかかるみたい。。

甘かった。。

なんと、apple care ++ に入っていれば、4万以内で修理できたとのこと。

なぜ購入時に入っていなかったのか。。2〜3万をケチった自分が悔やまれる。

次は絶対apple care ++入ろう。

 

その後、店員さんには買い替えをお勧めされました。

 

自分のm1のmacbook proはストレージを512GBにしていたので、購入時の定価は約17万。

買い換えるよりは修理に出した方が良い気はする。。

でもどっちにせよすごい痛手。。

 

故障しているので下取りもできませんでした。

また、メルカリでも売れないだろうと思いました。

 

最後の望み

この時、自分の中では

1.修理に出す(約14万)

2.買い換える(約17万 + appcare++の2万)

3.ほぼ性能の変わらないm1のmacbook airに乗り換える(約15万+applecare++の2万)

の3つで迷っていました。

 

ですが実は、

故障しているのはキーボードだけで、外部キーボードでつなげばまだ使えるのでは?という可能性も考えていました。

 

この時自分のmacでは、キーを押していないのに、キーが何度も勝手に押されている現象が起きていたので、この現象を抑えないといけません。

調べたところ、

内蔵キーボードのキー受付を無効にするiOSアプリがあったのです!

 

それは、karabinerというアプリです!

調べればすぐ出てくると思います。

 

あとはキーボードを買うだけ。

しかしmac純正のキーボードはお値段がなかなか。。

 

非純正のmac専用のキーボードもなかなかな値段します。

 

背に腹は変えられず、1万を超えているキーボードを買うしかないかと考えていた時、

電化製品の店員さんに、windowsのキーボードもmacで使えて、

logicoolならコマンドをmac用にできますよとの話を聞きました。

 

なあーにー!?

 

目から鱗でした。

そんなことできるんですね。笑笑

 

試しに1700円ぐらいの一番安いlogicoolのキーボードを購入。

帰ってつないでみると、macで使えました!!

 

ただこの1700円のキーボードだとmac用にキーボードを変換してくれるlogicoolの対象商品ではなく、karabinerでキーの調整はしました。

 

よかった〜〜〜〜〜〜

 

結論

そもそもですが、macbookを購入するときは、

apple care ++にケチらず入りましょう笑笑

 

安いPCではないのですから、2万でちゃんと保険つけましょう。

 

apple care++に入っていなくて、

水濡れしてしまった場合は、外部キーボードで暫定的に対処できる可能性があります。

新しくキーボードを購入する必要がある人は、純正を買うのではなく、

非正規品で一旦試すことをお勧めします。

一度の水濡れぐらいなら、外部キーで動くと思います。

ただ、今自分のmacは、常にどこかしらのキーが押されていて、その受付をアプリで無視しているだけなので、バッテリーとかの消耗が激しいかもしれません。

また、スリープ状態は大丈夫なのですが、システム終了するとkarabinerアプリが停止して内蔵キーが反応してしまうので、macがすぐ立ち上がってしまい、システム終了できないのが残念な点です笑笑

 

とはいえ捨てるのは勿体無い方にはぜひ試してみても良いかもしれないです。

【反省】2年目にして仕事ができない

久しぶりの投稿になってしまいました🙇

申し訳ありません。。

 

今日はプログラミングではなく、今の自分の仕事の現在地について話します。

 

今の自分に足りていないもの

みなさん、最近の仕事は順調でしょうか。

私は全くうまくいっていません。

難しい仕事ではないのに、なぜかうまく行きません。

その原因を考えた結果、根本は自分の意識にあると思いました。

それは以下です。

①物事をロジカルに考えられていない。

②仕事ができるようになりたいという思いが足りない

 

①には多くある細かな原因を総収してロジカルシンキングとしています。

 

最近の失敗談(資料作り)

最近の失敗談として、クライアントに提出する資料作成のことを挙げさせてもらいます。

(本当はもっと失敗談はあります。。😢)

先日クライアントに提出する資料の作成を依頼されました。

先輩たちの資料は何度も見たことがありますが、自分が作成するのは初めてです。

資料の内容は半日あれば終わるものでした。

しかし、作成して上司に持っていってもOKがもらえず、結局3日間試行錯誤した結果、完成させることができませんでした。

結局先輩に代わりに作成してもらいました。

 

なぜ資料が作れなかったのか

原因を

①物事をロジカルに考えられていない。

②仕事ができるようになりたいという思いが足りない

にそって考えます。

 

先に②から。 

まず、資料作りに関しては、自分の普段の準備が足りていませんでした。

いつかは自分も資料を作成することになるのに、今まで資料作りの勉強を一切していなかったのです。

資料作りに自信があるわけではないので、前もって先輩たちの資料を参考に勉強しておくことはできたはずです。

なぜこのような事態になっていたかというと、自分は好きなことだけやっていたい甘えん坊で、今までプログラミングの勉強に9割力を注いでいました。

業務に関しては手を抜いていたわけではありませんが、自分から新しい仕事を学びに行くことは決してありませんでした。

(例えば人に聞くだけでなく、過去の資料から学ぶなど)

 

今まで仕事は段階的に教えてもらっていたので、資料作りもいつか教えてもらえるだろうとどこか甘えていたのです。

 

①については、

とはいえ初めてでも、優秀な人なら資料作りできちゃうと思います。

自分ができなかった理由は、仕事で大切なロジカルシンキングができていなかったからです。

クライアントに伝える資料なのに、相手にわかる資料にできていませんでした。

その時はそれがわかっていてもどうすれば良いのか分かりませんでしたが、今ならロジカルシンキングが足りていなのだと気づきました。

ロジカルシンキングは考え方の概念のように思っていましたが、ロジカルシンキングは何かを伝える時のテクニックになり得るのです。

 

その他仕事の反省点

資料作りでは顕著に自分の足りないところが現れましたが、

他にも、議事録でダメ出しをもらう、技術調査が思うようにいかない、上司の意図することを汲み取れない、などなどがありました。

これらも共通で、①のロジカルシンキングができていないこと、②の仕事に対する姿勢が原因にあると思っています。

①はすぐに身に付くものではありませんので、徐々に訓練していきます。

②は現時点で赤信号一歩手前だと思います。3年目でそんなことに気づいていたらおしまいでした。②は今日からすぐに変えていきたいと思います。

 

まとめ

自分は今まで成功してきた経験がありません。

プログラミングができるようになれば、何か成功できると思っていましたが、そんな単純ではありませんでした。

1年目でプログラミングばかりやってきたことは後悔していません。

しかし、プログラミングはアプリ開発の一部の流れにすぎないことを改めて認識し、

他にも大切な仕事があること、その仕事ができるようになるには自分から動かないといけないことを胸に刻みます。

 

価値のある仕事ができる人間になりたいです。

EF Coreで悲観的ロック

こんにちは、弱小エンジニアのいすいです。

今日はEntity Framework Coreで悲観的ロックをする方法を教えます。

正直、概念に関しては合っているか自信がないのですが、やりたいことは達成できるとおもいます。

まちがっていたらごめんなさい。

 

やりたいこと

やりたいことしては以下です。

【API仕様】あるAPIの処理でDBのデータから条件Aをクリアしたら、新しくデータを追加できる

【問題】同時アクセスを受けたときに「条件A」を両方クリアし、両方ともデータが追加される

【理想】同時アクセスを受けた時、2番目の方が「条件A」をクリアしていない場合は2番目の方はデータが追加されてほしくない

【解決案】Select〜Insertの間、他のトランザクションのDBへのアクセスをロックしたい

解決案が悲観的ロックのことだと自分は認識しています。

↓参考URL(悲観的ロックとは)

https://qiita.com/NagaokaKenichi/items/73040df85b7bd4e9ecfc

 

SQL Server(他のDBでも)にはロックの概念(UPLOCKなど)が存在していますが、

insertを制御する機能は見当たらず、そもそもトランザクションを制御するのはDBでは無理なのでは?という結論に至りました。

(DBレベルでのロックは更新ロックが限界だと思われる)

 

解決方法

トランザクションにはトランザクション分離レベルというものが存在し、

トランザクション中のDBへのアクセスを段階ごとに制御できるらしい。

 

↓参考URL(トランザクション分離レベル(対象SQL Server)とは)

https://qiita.com/song_ss/items/38e514b05e9dabae3bdb

 

上記によるとトランザクション分離レベルはデフォルトではREAD COMMITTEDになっているらしく、SERIALIZABLEにすれば、悲観的ロックができそう

 

それがわかったら、Entity Framework Coreでトランザクション分離レベルを設定しよう。(SQL Serverでもトランザクション分離レベルは設定できそうだが、EF Coreの方が早そう)

 

↓参考URL(EF Coreでのトランザクション(Microsoft公式)について)

https://docs.microsoft.com/ja-jp/ef/core/saving/transactions

 

上記によると、EF CoreではTransactionScopeでトランザクション分離レベルを設定できるみたい

なので、悲観的ロックをしたい処理を下記で囲めば良い

using (var scope = new TransactionScope(
    TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
   // 処理(select~insert)
    scope.complete();
}

実際にinsert処理に該当するSaveChanges()にブレークポイントを置いて、同時アクセスしてみてください。

ちゃんと条件に一致してない2番目の方はエラーで返されると思います。

 

以上でEF Coreの悲観的ロックが達成できること祈ります。

 

楕円状にpythonで並べる

お久しぶりです。未経験エンジニアのいすいです。

最近Webサイトで要素をカッコよく配置したいなって時に、楕円状に並べたらカッコよくね!?って思い、要素を楕円状で等間隔に並べようと試みました。

そしたら、楕円状に並べるのって意外とむずい!😱

というのは、楕円って弧の長さ求めるのすごく大変みたいなんです。

楕円の弧の長さは以下の公式になります。

a:長半径、b:短半径

 

この積分は楕円積分と言って、既知の初等関数であらわすことが出来ないことがわかっています。つまり、これ以上簡単な式に直せないんです。

とはいえ積分をプログラミングでやると数値計算のアルゴリズムとか考えなくちゃいけなくて大変そう。。

 

うーん

どうしよ。。

 

と、ここで、pythonにはすごい便利なライブラリがあったことを思い出しました。

それがScipyです。

このscipyを使うと簡単に積分が解けちゃいます。🤪

(ぶっちゃけ最強です。)

というわけで、本日はpython(scipy)を用いて楕円状に物を配置するやり方をご紹介します。

 

楕円の前提

楕円状に物を配置するとは?

ということに関してですが、以下のような図を想定しています。

オレンジの線が楕円で、長半径a、短半径b

オブジェクト(今回は円を想定してますが、別にどんな形でもOKです。ただし、中心点は考える必要があります。)の中心点が楕円上にあるようにします。

正直オブジェクト自体(形、大きさ等)は重要ではなく、楕円上の等間隔の点の座標を求めることが今回の目的になります

 

求めるもの

今回は、長半径a、短半径b、オブジェクト数nから

各オブジェクトの中心点の座標を求めます。

UIは触れないのかよ!と思われた方もいるかと思いますが、それは各々で好きなように反映させてください。🙇🏻‍♂️

得られた座標は一番上から半時計まわりに順番に並べたものになります。

ちなみに長半径と短半径は逆でも問題ありません。

座標は楕円の中心を原点(0,0)としています。シチュエーションに応じて左上を原点にしたりとカスタマイズしてください。

 

コード

あらかじめ scipy は pip でインストールしておいてください。

# NumPyをインポート
import numpy as np

# mathをインポート
import math

# SciPy積分パッケージをインポート
from scipy import integrate

# 長半径
A = 440

# 短半径
B = 290

# オブジェクトの個数
N = 10

# 0からradiamまでの弧の長さ取得
def getArcLengthDiff(radian1, radian2):
    # 関数を定義
    y = lambda x: np.sqrt((A * np.cos(x))**2 + (B * np.sin(x))**2)

    # yを0からpiまで数値積分
    integ = integrate.quad(y, radian1, radian2)

    return integ[0]

# 楕円一周分の長さ
L = getArcLengthDiff(0, 2* np.pi)

# オブジェクト間の距離
d = L / N

# 計算結果のラジアンリスト
radian_list = [np.pi/2]

# 1つ前のラジアン(一番上スタート)
radian_prev = np.pi/2

# 1周後のラジアン
radian_end = 5 * np.pi /2

# 一つ目のラジアン(一番上スタート)
r1 = np.pi/2

# 2つ目のラジアン
r2 = radian_end

for i in range(N-1):
    while(True):
        if r2 - r1 < math.pow(10, -10):
            radian_list.append(r2)
            radian_prev = r2
            r1 = r2
            r2 = radian_end
            break

        midium = r2 + (r1 - r2)/2
        arc = getArcLengthDiff(radian_prev, midium)
        if arc < d:
            r1 = midium
        else:
            r2 = midium

# 各オブジェクトの座標
location_list = []

for radiam in radian_list:
    location_list.append((A*math.cos(radiam)+450, 300-B*math.sin(radiam)))

print([(int(l[0]),int(l[1])) for l in location_list])

コード解説

まず最初に長半径a、短半径b、オブジェクト数nを設定してください。

実行するとint型にパースされた座標(x,y)のリストが出力されると思います。

コードの処理の流れは以下です。

scipyを用いて、弧の長さを求める関数を定義

長半径a、短半径bから楕円の一周の長さ取得

1周の長さをオブジェクトの個数nで割って、オブジェクト間の距離を計算

2分探索を用いて、オブジェクト間距離になるラジアンを計算 
✖️(かける) オブジェクト個数

求めたラジアンから座標を取得

 

以上となります。

 

理系の人間はなぜ面白くないのか

こんにちは未経験エンジニアのいすいです!

本日は多くの人を敵に回しそうなテーマとなってますが、

長年の疑問にようやく答えが見つかったので、整理も兼ねて書き残させてください。

テーマが結論ではなく、ちゃんとオチがありますので最後まで読んでいただけたら幸いです。

ちなみに本稿はコミュ障改善ノウハウとかはなく、ただの持論のまとめです。
(改善方法もちょっと載せますが)

 

レッツゴーーーーー👉👉👉👉👉

 

面白くないの定義

まず面白くないという発言を弁解させてください。

ここでいう面白くないは友達/同僚との日常会話レベルを指しています。

人間性で言えばむしろ、理系の方が面白い人が多いと思っています。
(怒られないようにここは強調)

私の周りには非常に個性的な人が多いです!
(知り合いには物理の公式を丸3日寝ずに解いたほどの物理オタクがいます)

 

しかし、日常生活でごく一般的な理系の人間と何気ない会話をしている時を考えてください。

理系って真面目すぎませんか?😟

 

理系にもコミュ力53万の人もいたりして例外も多いので、思い切ってペルソナを立てましょう!

 

峰津理 学(ぶつり まなぶ)

物理学科 2年

物理の授業についてくため、毎日放課後授業の復習をして、成績は良い

バイトせず。恋人なし。

 

自分が理系大学にいたときによくいたタイプの人です。

この人はちゃんと大学の授業をついて行けていて優秀です。

そのために努力もできていて素晴らしい人です!

 

でも、そこそこの知り合い同士の飲み会するとき、あまりしゃべれません。面白いことを言わなくちゃいけない雰囲気が苦手です。

もちろん、コメディな人が一番えらくて、面白くない人はだめということはないです。

理系トークは大盛り上がりですし、理系のコミュニティにいる間は何も困りません。

でも、物理を理解できるほど優秀で、努力もできて、頭の良い人のはずなのに、なぜ面白いことが言えないのでしょうか。面白くないということはバラエティある人たちとの交流機会を逃してしまうのではないでしょうか。

これが私が長年答えの見つからなかった疑問なのです。

 

コミュ障がコンプレックス

かくいう私は大学生の時、友達に話題を振られると面白いことが言えず、「頼むから話題を振らないでくれー!」と心で念じるほどのコミュ障でした。(まあ今でもなかなかのコミュ障笑笑)

実は先ほどのペルソナは自分に近かったりします。
(素晴らしい人とか自分で言うな)

とは言え花の大学生。自然と自分のいる環境では面白いことを言ったり、盛り上げたりすることを求められていました。

面白いことが言えないのをずーーーーとコンプレックスになっていました。

 

転機としては、自分がバイトを始めて、サークルで遊ぶことが多くなり、授業をサボり始めた時です。

割と友達との会話に面白いことを言えるようになってきました。

そこで僕は思ったわけです。

勉強ばっかしていたから面白くなかったんだ。。。と

 

そして大学生後半は単位取れればOK精神で留年して、さらに面白くなりました。(皮肉)

ここで思ったのは、コミュ力と勉強は両立できないということ、

特に物理のような頭を120%活用しないと理解できないものは、コミュ力とトレードオフになるということでした。

大学終わりでの結論は、「物理ばっかやっていたから、コミュ障だった。物理を捨てたからコミュ力を手に入れたんだ」というものでした。

 

唯一、プログラミングは理解というより覚えるに近いので、コミュ力とのトレードオフにならないだろうという考えもありつつ、IT業界に就職しました。
(プログラミングが面白かったというのがIT志望の主な理由ですが)

しかし、今年物理学科卒の優秀な後輩が入ってきて、自分の理論が崩れさりました。

その後輩は私の3倍近くのスピードでプログラミングの勉強をしているのに、理解度が私より高かったのです。

完敗しました。自分は物理を捨ててきましたが、その人は物理をちゃんと理解できていたからこそ、プログラミングも凄まじいスピードで習得していったのです。

さらにITで大切なのは覚えるのではなくちゃんと理解することでした。

この出来事がきっかけで自分を改め、自分も物理の勉強の時のようにしっかり理解するように心がけました。

 

2ヶ月後。。。

 

そしたら途端にコミュ障になってしまいました。笑笑

どうしようもなくなりました。

コミュ力を保つべきなのか、プログラミングの理解を優先するべきなのかわからなくなりました。

そもそも物理を捨てた選択は正しかったのだろうか、物理とコミュ力を両立させられる方法はあったのだろうか、を悩み続けました。

悩んで悩んで、出た結論が次のセクションです。

 

理解力とコミュ力は思考が違う

結論は割と当たり前でもしかしたら普通なのかもしれません。

(私にとっては目から鱗に近いのですが)

 

今までは、

物理を理解しようとしてるからその分コミュ力が下がる、

コミュ力を上げようとするから物理が理解できない、

のような因果関係ばかりに目をむけ、
そこには何かお互いがトレードオフになってしまう原因のようなものがあるのではないかと考えていました。

 

しかし、実際はお互いが邪魔しあっていたのではなく、それぞれ全く違う思考法に基づいたもので、トレードオフなんかではなかったのです。

そしてこの結論を受け入れることが自分に必要だと気づきました。

 

次のセクションで具体的に解説します。

 

論理的思考と直感的思考

「物理を理解すること」は論理的思考

「面白いことをいう」は直感的思考に分類されると考えます。

直感的は非論理的の意味で使用します。なので、感情的や物理的という意味も含めます。なんとなく直感的がふさわしい気がするので直感的を使っています。)

論理的思考と直感的思考がどれだけ違うのかというと、

A = Bという関係が前提にあった場合、

論理的思考は「AだからB」のような考え方をし、

直感的思考は「AだからC」というような考え方をします。

わかりますでしょうか。

論理的思考にはA=BだからBを選んだという根拠が見えますが、

直感的思考にはCというそもそも候補に上がっていなかったものが選ばれています。


この例では、論理的思考と直感的思考の違いを明確にするため極端な例にしましたが、それぞれをまとめると、

論理的思考:具体的な根拠がある

直感的思考:具体的な根拠はなく、根拠は直感によるもの

 

「物理を理解すること」と「面白いことを言うこと」に当てはめて考えます。

「物理を理解すること」は分かりやすいですね。

「重力があるからりんごが地面に落ちる」というような「AだからB」を突き詰める作業になります。

 

「コミュ力」は若干しっくり来ないかもしれませんが、人間の会話の好みを考えればわかるかもしれません。

というのは、人は「AだからB」という普通の話を聞いてもあまりおもしろく思わないのです。

人が面白いと感じるのは「AだからC」というCという予想もしていなかった選択がされた時なのです。

具体的に言うと、梅雨の時期に「梅雨だから雨降ってるね」と言っても何も面白くありません。「梅雨だから焼肉食べたいね」と言った方が何倍も面白いです。(面白くねーよと言うツッコミはやめてね)

ここで「梅雨だから焼肉食べたいね」の「梅雨」と「焼肉食べたい」の関係に具体的な根拠はありません。

あるのはこういえば面白いかな?と言う直感による根拠だけです。

(私はいないと思うのですが、根拠があって面白いことを言える人っているのでしょうか?お笑いのノウハウとかではなく、「Aの後にBと言えば、それがAとのギャップになって…うんたら」とちゃんと根拠があってウケてもらえる人)

 

実は「理解すること」と「面白いことを言う」は真逆の思考方なわけですね。

なのに理系の人間は論理的思考を使って会話してしまう傾向にあるわけです。

先に言っておきますが、仕事中は論理的思考をするべきです!

アイデア出しでは直感的思考を使うのもいいですが、最終的に決断するときは論理的思考です。ビジネスもです。

そうでないと、成功した時、失敗した時の根拠が得られません。

 

理系が論理的思考を使ってしまうのには学問としての性かもしれません。

理系と文系の違いを次のセクションで説明します。

 

 

反復可能な知識と反復不可能な知識

この言葉は最近知った東浩紀さんの言葉を引用しています。

↓ひろゆきが論破された動画です。

こちらによると、

物理、化学、地学、医学、工学、等の「学」のつく分野というのは「何度同じことしても同じ結果が返ってくる」という「反復可能な知識」を学ぶこと。

逆に、歴史、思想、言語、これらは「同じことを繰り返しても同じ結果になるとは限らない」「反復不可能な知識」ということ。

つまり、理系は「反復可能な知識」、文系は「反復不可能な知識」という大きな分類で分けられるという主張です。

 

確かに。すごく納得のいく説明ですね。

この分類を応用すると、「反復可能な知識」は完璧に「理解力」を必要とし、「反復不可能な知識」は「直感力」が求められるような気がしてきませんか。

「反復不可能な知識」は理解力も求められますが、

歴史で言えば「感情」、英語で言えば「直感」も必要な感じがします。

 

以上を踏まえると理系は学問的に「理解力」を必要とし、

文系より圧倒的に論理的思考力を使うことが多いことがわかりました。

 

つまり「理系の人間はなぜ面白くないのか」の答えは、

「学問的に論理的思考力を使うことを余儀なくされ、論理的思考力では面白い発言は生まれないから」

です!

 

 

理系のコミュ力アップ方法

原理としては、

理系の勉強だけをしているようでは「論理的思考力」しか鍛えられません。

なので、「直感的思考力」も鍛えるべきです。

鍛え方としては「AだからC」を意識するようにしましょう。

ただこの直感は一朝一夕で身に付くものではありません。

論理的思考は癖がつけば誰でもできるようになるのですが、直感だけは経験でしか培われません。

意外と理系の人間は論理的思考が癖になってて、「AだからC」は難しいですよ。笑

バンコクのカオサン通りで一晩踊れば身に付くのではないでしょうか。

これはまだ自分の中で確信していないことなのですが、一度どっちかに振り切れる必要があるのではないかと考えています。

どういうことかというと、勉強一筋だった人は、勉強を捨てて友達との遊びだけに没頭する時間をある期間実践しないと本当に変われない気はします。

一度振り切れてみるのも楽しいですよ笑

 

 

まとめ

つまりは「理系はいつも根拠のある論理的思考をしているんだから、直感的思考を求められるおもしろいことなんてすぐに出ないよね」ってことです。

「AだからB」だけでなく、「AだからC」のような考え方もしようねという話です。

Progateは復習で使うべし

こんにちは未経験エンジニアのいすいです。

 

本日はプログラミング学習ツールProgateを使っていて思ったことをお話しします。

 

 

HTML&CSSは普通に難しい

プログラミングのきっかけとしてHTML&CSSから始める人がいると思います。

自分もその一人です。

 

それは世間でHTML&CSSが簡単だと言われているからですね。

HTML&CSSはプログラミングじゃないとまで言われています。

ちょっと待ってください。。。。

 

普通にHTML&CSSむずいんですげどーーー!!!!!

あれ、話が違う、、

 

そりゃ、Hello World!と表示するだとか、ボタンを置いたり、フォームを作ったりとかコントロール単体は簡単ですよ?

 

しかし、WebサイトやWebアプリでHTML&CSSを使うとなると急に難しくなります。

 

その場合、全体をバランスを保ちながらHTML&CSSを構築しなくてはならず、例えばタグを一つ増やす、減らすで大きく変化しますし、CSSをいじれば想定していない箇所も変更される可能性があります。

 

つまりは、実践でHTML&CSSを使うとなると、ある程度の技術と経験が必要になるわけです。

 

(pythonとかのプログラミング言語の方が全然楽!)

 

HTML&CSSも舐めてはいけないということを頭に入れながら話を進めます。

 

 

Progateはすごく良い

昔の話ですが、自分はHTML&CSSの学習をProgateから始めました。

(というより、プログラミングの学習自体の最初がProgate)

その時初心者編を受講しましたが、全くできるようにならず、頭に入らず、一度プログラミングから離れました。

 

Progateって例題を解いていくスタイルだと思うのですが、スライドと例題を往復しながら進めるのが結構めんどくさいんですよね。

 

「〜の背景を〜にする」とか書いてあっても、スライドなりネットなりで調べないとわかるわけなく、またスライドに解説がない部分もあるので結構な頻度で解答をみるハメになります。

 

ネットゆえにスライドのどこに何が書いてあったか記憶に定着しづらく、遡るときも大変です。

 

Progateは使えない。これが最初の感想でした。(何様)

 

 

そんなこんなで、Progateでの学習は諦めて、書籍のHTML&CSSを購入し、これを進めました。

いやー、書籍は最高ですね。わかりやすくて、スイスイ覚えられます。

 

HTML&CSSの書籍を2冊読んだ後、JavaScriptやPHP、JQueryなどの学習を経て、

2つのWebアプリを作成しました。

 

このWebアプリ作成時、HTML&CSSの知識はそこそこついていたと思うのですが、実際に自分で作成してみるとほんとに苦戦しました。汗

 

当てたいスタイルが全然うまくいかなかったり、HTMLのメンテナンス性が低かったり、もうゴミのようなコードでした。

(やりたいことはゴリ押しでなんとかできましたが、コードがめちゃくちゃでどこにも手を加えられない状態でした。)

 

そんなこんなで1年ぶりぐらいにProgateをやってみたんですよね。

 

そしたら、めちゃくちゃわかりやすかったんです。笑

 

特に、コードが即プレビューに反映されるので、試したいことをバンバン試せるのがすごく良かったんです。

スライドとかも、「あーそれってそういうことだったんだ」とか「その方法、あの時のWebアプリで使えたな」とか発見も多かったです。

 

有料コンテンツも即登録しました!

 

ある程度知識が増えたからこそ、Progateは最高の学習ツールになりました。

 

 

結論、Progateは復習で使うべし

タイトル回収になります。

結論としては、Progateは初学に向いていないと思います。

もちろん、Progateも学習にはなりますが、最初は書籍から始めた方が効率が良いと個人的には思います。

 

その後、少なくとも1つWebサイトないし、Webアプリを下手くそでいいので自分で作成してみてください。

 

何かの模倣ではなく、一から自分で何かアイデアを出して、設計して、試行錯誤しながら作るのが良いと思います。

 

クオリティは問いません。しかし、自分がここはこうしたいと思うことは妥協せず、調べながらできる限り実装してください。

 

その過程で、HTML&CSSの課題や反省点が生まれてくると思います。

その課題や反省点を頭に入れながら、Progateを受講してください。

 

きっと、Progateの良さに気づくと思います。

【毎日ビジネス格言②】ヒラメ社員はいらない

ヒラメ社員とは、上司の顔色を伺い絶対に反対しない人である。

これには持続的競争優位性と一時的競争優位性というのが関係してくる。

 

 

持続的競争優位性とは

昔は競争優位性が高い企業は、なかなか落ちることはなくその位を維持できたのである。

10年ほど前までのトヨタがそれに該当する。

 

 

一時的競争優位性とは

一時的競争優位性とは持続的競争優位性が終わった今の時代を指す。

現代は廃れ流行りが非常に早い。

一つの事業をとっても賞味期限が短いのである。

 

 

ヒラメ社員が通用しなくなった

昔の持続的競争優位性の時代は同じことをやれば成功した。

そのため、今のやり方を肯定するヒラメ社員というのは評価されたのである。

 

しかし今は一時的競争優位性の時代となり、昔の成功モデルをどんどん変えていく必要ができた。

企業は「何が賞味期限切れを起こしているのか」を素早く察知しなくてはいけなくなったのである。

 

したがって、企業としては素直に事実を認め、変化を受け入れる姿勢が必要になったのである。

Angularで地図を複数表示する(leaflet)

今日はAngularで複数の地図を表示する方法を紹介します。

(とはいえこの方法が必要となるシチュエーションはあまりないのかなとは思います笑。が、必要となった時参考にしてください)

 

地図を表示したい

まず、地図を表示するにはleafletというOpenMapStreetのAngularライブラリを使います。

 

leafletの使い方は以下を参考にしてください。

https://qiita.com/uedayou/items/30f88d88238f648e8ee6

ここから先はleafletは使える前提で話を進めます。

 

 

 

 

複数の地図を表示する

ページに一つだけ地図を表示する場合は何も問題ありません。

 

上記のURLを参考に地図を表示できます。

 

 

問題は地図を複数表示する場合です。

 

複数の地図を表示する場合以下2つのパターンが考えられます。

 

  1. html文に<div id=”map”></map>を地図の数分追加する
  2. 地図を表示するコンポーネントを別で定義し、コンポーネントを地図の数分追加する

 

1番は大丈夫ですが、2番は工夫が必要になります。

 

そもそも何が問題になるかというと、leafletの以下の文

this.map = L.map('map').setView([34.702485,135.495951], 13);

map関数の引数’map’はhtmlの「map」というidの要素を指すことです。

 

map関数はHTMLElement型の引数も受け取れますが、HTMLlElement型の要素は、javascript標準装備のDOM関数document.getElememntById関数でしか取得できません。

 

つまり、htmlのあるidと地図オブジェクトを結びつけているわけです。

 

idは一意なので、複数の地図を表示するにはidを地図分用意しなくてはいけません。

 

 

1番について考えてみましょう。

 

htmlに直接ダグを増やせる場合は問題ないですね。

<div id="map1"></map>
<div id="map2"></map>
<div id="map3"></map>
<div id="map4"></map>
<div id="map5"></map>
<div id="map6"></map>
・・・

上記のようにidを被らないようにするだけです。

 

map関数も地図の数分実行します。

 

 

 

 

問題が起きるケースとは。。。

2番はどうでしょう。

以下のような構造を考えてみます。

 

地図を表示するコンポーネントは別で定義したい。

地図を表示するコンポーネント:map.component.ts

上記コンポーネントを追加するコンポーネント:app.component.ts

表示したい地図の数分app.compoennt.htmlにセレクターを追加すると表示できるはず?

 

 

map.component.ts

import { Component, OnInit } from '@angular/core';

import * as L from 'leaflet';

@Component({
  selector: 'map-component',
  template: '<div class="map" id="map"></div>'
})
export class MapComponent implements OnInit {
    map: any;

    ngOnInit(){
        this.map = L.map('map').setView([34.702485,135.495951], 13);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(this.map);
    }
}

 

 

app.component.html

<div class="container">
  <map-component></map-component>
  <map-component></map-component>
  <map-component></map-component>
  <map-component></map-component>
  <map-component></map-component>
  <map-component></map-component>
</div>

 

 

 

実行してみます。

 

左上の一つしか表示されていません。

 

 

これは、6つのdiv要素に同じmapというidが付けられ、6つのマップがmapというidに紐づけられているからです。

 

idは一意なので左上のdiv要素でidが引っかかり、他のdiv要素にマップが結びつけられなかったためだと思われます。

 

 

 

 

解決方法

map.component.tsのクラス変数(静的プロパティ)を利用する方法を紹介します。

 

map.component.tsに以下の赤文字部分を追加します。

 

map.component.ts

import { Component, OnInit } from '@angular/core';

import * as L from 'leaflet';

@Component({
  selector: 'map-component',
  template: '<div class="map" id="map" ・・・①></div>'
})
export class MapComponent implements OnInit {
    static number: number = 0; ・・・②

    map: any;

    ngOnInit(){
        MapComponent.number++; ・・・③
        document.getElementsByClassName('map')[MapComponent.number-1].id = 'map' + MapComponent.number; ・・・④
        this.map = L.map('map' + MapComponent.number ・・・⑤).setView([34.702485,135.495951], 13);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(this.map);
    }
}

 

 

id=”map”削除

idに「map+識別番号」を割り振るので削除しておきます。

 

 

static number: number = 0 の追加

静的プロパティを定義します。これでMapComponentのインスタンス作成時に初期化されないプロパティを使用できます。

最初は0を入れておきます。

 

 

MapComponent.number++; の追加

ngOnInitが実行されるたび(MapComponentインスタンスが生成されるたび)に静的プロパティをインクリメント(+1すること)します。

 


document.getElementsByClassName(‘map’)[MapComponent.number-1].id = ‘map’ + MapComponent.number; の追加

document.getElementsByClassName(‘map’)でmapというクラスのhtml要素を全て取得します。ここで所得される要素はElement型の配列です。Element要素はmap関数にそのままぶち込むことはできません。

取得した配列の「MapComponent.number-1」の要素のidに「map○」を設定します。(○は1から始まる整数)

 

①から④のコードで、

<div id="map1"></map>
<div id="map2"></map>
<div id="map3"></map>
<div id="map4"></map>
<div id="map5"></map>
<div id="map6"></map>

のようなidの割り振りになります。

 

 

‘map’ + MapComponent.number 

「map○」を指定してマップ関数を実行します。

 

 

 

実行結果は以下です。

 

6つとも地図が表示されました!(安心)

 

 

 

 

まとめ

今回複数の地図を表示する方法を紹介しました。

 

idを重複しないようにするというだけですが、原因がわからないと時間を食ってしまったところでもあります。

 

みなさんはこちら参考に好きなだけ地図を表示してもらいたいです。

 

 

ちなみに、ViewContainerRefなどで動的にMap.component.tsを追加する場合も今回のような方法で大丈夫です。

 

【毎日ビジネス格言①】何をやらないか決める

「まず何をやらないか決めよ」

これは世界をかける名経営アドバイザーマイケル・ポーターの言葉である。

ポータによると、経営戦略はトレードオフだという。

あちらを立てればこちらが立たなくなるというのである。

確かにそうだ。

例えば北海道のセーコーマートは、大手コンビニチェーン「セブン・ローソン・ファミマ」の勢いを完全に跳ね返している。

それは大手チェーン店と違い、セーコーマートは北海道だけで展開し24時間営業に拘らないが、自社製造で高品質かつ安価を実現し、過疎地域にも出店しているのである。

それが大手コンビニチェーンと差異を生み出し、地元民から圧倒的な指示を得ているのである。

1999年出版のポーターの書籍によると次のように述べられている

「日本企業は、『全てのものを、全ての顧客へ』と考えて、お互いに模倣しあい競走して、改善するだけだ。日本企業には戦略がない。日本企業は戦略を学ぶべきだ」

ここに私の持論を付け足すと、模倣してうまく行くのはブルーオーシャンなマーケットのみだと考える。

(もっともレッドオーシャンでも戦略の取り方によってはブルーに変わると思うが)

昨今でいうYoutuberがその典型であり、5〜6年前なら人気youtuberと同じことをすれば売れたのである。

簡単に考えると、全てを求めようとすると一つ一つが中途半端になり、カスタマーの心に刺さらないということだと思う。

PAGE TOP