採用基準

採用基準

採用基準

まとめ

グローバルに活躍するために必要なのは地頭や論理的思考能力よりもリーダーシップが必要であり、リーダーシップとは役職や年齢ではなく全ての個人が発揮すべき能力であり、求められるもの。

所感

組織において、小さな問題も大きな問題も、いつか誰かが解決してくれるものではなく、自分が先頭に立って最善な行動をし、集団に働きかけて成果を最大化する・・・そういった行動・思考でいるか否かは当人の成長度合いに大きな影響を及ぼすのだろうと思います。

職場ではもちろん、日常の些細な「これどうするんだ?」といったことに対して、行動に移さないまでも「自分ならこうする」という考え(本書では「ポジションをとる」という表現)を常に持つのはトレーニングの第一歩としてはいいのかもしれないですね。

リーダーと聞くと、学級委員長や部活の部長、職場のプロジェクトリーダーなど、どうしても役職を想像してしまいますが、役職に囚われずに、日々今自分がいる組織の成果・価値を最大化するための行動をしていくことが、社会にとってのプラスになっていくのだと信じて行動していくことが大事なのかもしれません。

ABC175 復習

1ヶ月ぶりくらいに挑戦しました。
結果はC問題までAC・・・。

A - Rainy Season

単純に文字数を数えるだけではWAになってしまうことに注意します。
連続してRが出る回数が答えとなるため、R以外が出現した場合はカウントを初期化するなどすればOKですね。
なお、公式解説によれば、ありうる解は23のパターンしかないので、全て試す方法もあるとのことでした。

s = input()

cnt = 0
ans = 0
for i in s:
  if i == 'R':
    cnt += 1
  else:
    cnt = 0
  ans = max(ans, cnt)

print(ans)

B - Making Triangle

少し考えましたが、Nが100までしかないので、N3でも十分に間に合います。
そこで、以下のように3重ループを回し、各辺の長さが異なるかつ、三角形として成り立つものの個数をカウントします。

N = int(input())
L = list(map(int, input().split()))

cnt = 0
for i in range(N):
  for j in range(i + 1, N):
    if L[i] == L[j]:
      continue
    for k in range(j + 1, N):
      if L[i] == L[k] or L[j] == L[k]:
        continue
      a = L[i]
      b = L[j]
      c = L[k]
      if a + b > c and b + c > a and c + a > b:
        cnt += 1


print(cnt)

C - Walking Takahashi

除算と剰余をうまく使用すれば解けます。 考え方としては、

  1. 近づけるところまで近づく
  2. 余った移動回数分については何度やっても結果は変わらない

といった風になるでしょうか。 例えば、 X=100、K=9999、D=17 である場合を考えてみると、
まず初めに可能な限り近くと、 100 - (17 * (100 / 17)) = 15となるため、現在位置は15となります。 これ以上近づくにはもう一度移動して、座標(−2)の位置に移動することとなります。 残った移動回数を試すにしても、−2の位置か、15の位置が最も近い座標の候補となります。
(−2 + 15と、15 - 17 を繰り返すことが最善になるため) つまり、残った移動回数が奇数か偶数かで、答えを判別できることとなります。

補足として、入力X(現在地)が負数の場合は正数に直してしまった方がやりやすいかなと思います。

X, K, D = map(int,input().split())

ans = 0
X = abs(X)
if X == K * D:
  ans = 0
elif X > K * D:
  ans = X - (K * D)
else:
  div = X // D
  temp = K - div
  if temp % 2 == 0:
    ans = X - (div * D)
  else:
    ans = abs(X - (div * D) - D)

print(ans)

modal

JavaScriptCSSを使って、モーダルウィンドウを作成します。
実現方法は至って単純で、なんらかのボタンが押されたらモーダルのdisplay属性をnoneにしたりblockにしたりするだけです。

.modal {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  overflow: auto;
  background-color: rgba(0,0,0,0.5);
}

.modal-content{
  background-color: white;
  width: 500px;
  margin: 40% auto;
}
<!DOCTYPE html>
<html>
  <head>
    <title>learn modal window</title>
    <link rel='stylesheet' href='style.css'>
  </head>
  <body>
    <h1>modal test!</h1>
    <input type='button' id='btn' value='click!'>
    <!--このdivタグ内がモーダルウィンドウ-->
    <div id='modal' class='modal'>
      <div class='modal-content'>
        <div class='modal-body'>
          <h1>this is modal!</h1>
          <input type='button' id='closeBtn' value='close'>
        </div>
      </div>
    </div>
    <script src='main.js'></script>
  </body>
</html>
const btn = document.getElementById('btn');
const modal = document.getElementById('modal');
//ボタンを押した時に表示させる
btn.addEventListener('click', function() {
  modal.style.display = 'block';
})

const closeBtn = document.getElementById('closeBtn');
//ボタンを押した時に非表示にする
closeBtn.addEventListener('click', function() {
  modal.style.display = 'none';
})

単純なモーダルウィンドウになっているので、多少のスタイルの修正は必要ですが、手っ取り早くモーダルを実現したいのであればこれで十分でしょう。

ctrl + Enterで処理を実行する

はじめに

ctrl + Enterに限らず、特定のキーを押下した際になんらかのイベントを発火させる方法です。

ソースコード

document.addEventListener('keydown', (e)=>{
  if (e.ctrlKey && e.keyCode == 13) {
    alert('ctrl and enter!');
  }
})

一応HTMLも。

<!DOCTYPE html>
<html>
  <head>
    <title>ctrl and enter click</title>
  </head>
  <body>
    click ctrl and enter!
    <script src='main.js'></script>
  </body>
</html>

解説

上記のソースコードは、ctrlと、enterを同時に押下するとアラートダイアログが出るようになっています。
'keydown'イベントが発火すると、イベントオブジェクトには、どのキーが押されたかの情報を持つようになります。
その情報について、e.ctrlKey && e.keyCode == 13の条件で、ctrlとenterが両方押されているか判定しているわけです。 なお、どのキーが押されたかのコード一覧はこちらが参考になります。

ちなみに、上記のコードではdocumentオブジェクトにaddEventListenerをしていますが、通常はelementByIdなどで取得した特定のDOMノードに対してイベントを付与するのが自然でしょう。

warning: Can't call setState on a component that is not yet mounted

React開発中に出現したワーニングを対処しました。
ワーニングなのでそこまでクリティカルではないと思いますが備忘として残します。

調査

ワーニングメッセージを直訳すると、

まだマウントされていないコンポーネントsetState()は呼び出すことができません

のようになるだろうか。

さて、私が書いたコードは下記のものになります。

  constructor(props) {
    super(props);
    this.state = {
      memos: this.fetchAllMemo(),
      value: null,
    }
    this.setState({
      key: this.state.memos.length
    })
    this.handleClick = this.handleClick.bind(this);
  }

ワーニングメッセージから察するに、コンストラクタ内でsetStateをしているのがよろしくないということなのでしょう。

マウントした直後にstateを変更できる方法があれば良さそうですね。

修正方法

componentDidMountを使用します。*1
修正後のソースコードはこちらになります。

  constructor(props) {
    super(props);
    this.state = {
      memos: this.fetchAllMemo(),
      value: null,
    }
    this.handleClick = this.handleClick.bind(this);
  }

  //constructorで実施していたsetStateを切り出す
  componentDidMount() {
    this.setState({
      key: this.state.memos.length + 1
    })
  }

これでワーニングは解消されました。

念のため、公式ドキュメントも見てみることにします。
公式ドキュメントによれば、

componentDidMount() の中で、あなたはすぐに setState() を呼び出すことができます。それは余分なレンダーを引き起こしますが、ブラウザが画面を更新する前に起こります。これにより、この場合 render() が 2 回呼び出されても、ユーザには中間状態が表示されません。このパターンはパフォーマンス上の問題を引き起こすことが多いので、慎重に使用してください。

とのことです。なるほど、componentDidMount()内であればsetState()を呼び出すこともできるが、多少なりともパフォーマンスに影響が出る恐れがあるということなのですね。

そうすると私の解決方法はベストな選択ではないのかもしれませんね・・。

終わりに

前述した公式ドキュメントのページには、以下のような記述もあります。

このページには React コンポーネントクラス定義の詳細な API リファレンスがあります。また、あなたが コンポーネントや props などの基本的な React の概念、および state やライフサイクルに精通していることを前提としています。

はい、精通していません・・。
コンポーネントのライフサイクル等、勉強すべきことはまだまだ多いですね。

日々精進。

*1:方法は他にもあるかもしれませんが・・

localStorage

JavaScriptで使用できるLocalStorageについて学びます。

LocalStorageとは

ブラウザにデータを保存できる仕組みです。 公式ドキュメントはこちらです。

使い方

localStorageへデータを保存する

//例
localStorage.setItem('key', value);

 localStorageへデータを保存する場合は上記のようにsetItem(key, value)を使用します。 keyに指定するのは一意の値となる文字列です。
データの修正やデータの削除の際に、この一意となる文字列を利用してデータの識別をします。
valueには保存する値を指定します。この時、valueには文字列や数値のほか、オブジェクトも保存することができます。 (ただし、オブジェクトの保存・取得は方法が少し異なります。(後述))

localStorageからデータを取得する

//例
localStorage.getItem('key');

保存したデータを取り出す場合は、setItem(key)を使用します。
keyには、保存する際に指定したkeyを使用します。
なお、指定したkeyに該当するデータが存在しない場合には、nullが返されます。

localStorageからデータを削除する

//例
localStorage.removeItem('key');

localStorageからデータを削除する場合はremoveItemを使用します。
保存されているデータと、指定したkeyが一致するデータを削除します。

オブジェクト(連想配列)のlocalStorageへの保存・取得について

前述したlocalStorageへの保存・取得方法は、文字列や数値ではうまくいきますが、オブジェクトに対しては想定と異なる結果となってしまいます。

//オブジェクトを用意
let person = {
  name = 'taro',
  age = 20
}
//localStorageへ保存?
localStorage.setItem('taro', person);
//データ取得
localStorage.getItem('taro'); //=> [object Object] になってしまう!

上記ではうまくいかないため、保存時と取得時に、JSON文字列化およびparseを行います。

//データ保存時
localStorage.setItem('taro', JSON.stringify(person));
//データ取得時
JSON.parse(localStorage.getItem('taro'));

アロー関数

アロー関数について勉強します。

基本の書き方

まずはおなじみの、公式サイトからの引用です。

アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。

なるほど。後半部分(また、this,~ )についてはいったん置いておくとして、前半部分について考えてみます。

通常の function 式の代替構文です。

通常のfunction式の代替構文とのことなので、まずはアロー関数とfunction式を比較してみましょう。
以下で両者の書き方をそれぞれ試していますが、挙動は同じものになります。

//アロー関数
let double = (n) => n * 2;

//function式
function double(n){
  return n * 2;
}

//どちらもdouble(n)で呼び出せる
console.log(double(3));

また、上記のアロー関数はこの書き方以外にも、引数の個数などで、記述の方法が異なります。 以下、例を示します。

// returnを書かない場合はブロックの記述は不要
(a, b) => a + b;
//returnを書く場合はブロックで囲む
(a, b) => {return a + b;}
//引数が1つの場合は()が不要
n => n * 2;
//引数がない場合は()が必須
() => console.log('hello!');

ここまでが基本的な書き方ですね。
さて、公式ドキュメントでは以下のようにも述べられています。

2 つの理由から、アロー関数が導入されました。1 つ目の理由は関数を短く書きたいということで、2 つ目の理由は this を束縛したくない、ということです。

1つ目の理由については視覚的にも明らかですね。それでは2つ目の「thisを束縛したくない」とはどういったことでしょうか。

thisを束縛しない

そもそも、thisを束縛するってのがわからないんですよね・・・。
以下、公式ドキュメントより。

アロー関数以前は、関数の呼び出し方法に応じて自身の this 値を定義していました

つまり、thisをどのオブジェクトに紐付けるか・・例えばグローバルなのか、自身のインスタンスなのか。そう言ったことをthisの束縛というふうに理解できます。*1

それではまずは、「thisが束縛される」コードを実際に見てみましょう。(アロー関数より前の関数定義方法)

//コンストラクタの場合
function person(name, age) {
  //このthisは自身のインスタンスを指す
  this.name = name;
  this.age = age;
  
  setInterval(function growUp() {
    //このthisはpersonインスタンスを指さずに、
    //グローバルオブジェクトを指す。
    this.age++;
    //グローバルオブジェクトにageはないので、NaNとなってしまう
    console.log(this.age); 
  }, 1000);
}

taro = new person('taro', 20);
console.log(taro)

//関数の場合
function hoge() {
  //'use strict'を用いて厳密モードにすると、
  'use strict';
  //このthisはundefinedとなる
  console.log(this);
}

function huga() {
  //'use strict'を用いない場合、thisはグローバルオブジェクト(この場合はWindowオブジェクト)を指す
  console.log(this);
}

上記の通り、関数の呼び出し方法によって、thisの指すオブジェクトが変化していきます。これが、「thisを束縛する」という意味なんですね。

それでは次に、「thisを束縛しない」、アロー関数についてもコードで試してみます。 公式サイトでは、以下のように記述があります。

アロー関数内の this 値は通常の変数検索ルールに従います。このためスコープに this 値がない場合、その一つ外側のスコープで this 値を探します。

比較しやすくするため、前述したPersonのコンストラクタ関数で実施していたgrowUp()関数をアロー関数で書き換えてみましょう。

function person(name, age) {
  this.name = name;
  this.age = age;
  //アロー関数に変更
  setInterval(() => {
    //前述したスコープの探索ルールに基づき、personオブジェクトを指す
    this.age++;
    console.log(this.age);
  }, 1000);
}

元々、コンストラクタ関数内に定義していたgrowUp()をアロー関数に直したことで、this.age++がpersonインスタンスのもつageプロパティを加算することができるようになりました。 このように、アロー関数を使用すると、thisが束縛されなくなるため、開発者の直感にある程度従った挙動にできるメリットもあります。

終わりに

駆け足でしたが、アロー関数について学びました。
JavaScriptも変化が早くて、ついていくのが大変ですね。

*1:これを読むと良いかもしれません