下手の横好き

文系卒エンジニアのしがない技術ブログ

Githubリポジトリ検索ツールを作った

動機

  • Githubの検索が結構使いづらい
  • 非同期で検索したい
  • axios使ってみたい

成果物

Github Repository Search

github.com

使い方

検索ボックスにワードを打ち込むと、非同期で30件検索する。

使用API:
Search | GitHub Developer Guide

検索条件:

https://api.github.com/search/repositories?q={{ 検索ワード }}+in:name&sort=stars

表示する情報

f:id:teinen0411:20180611122952p:plain

  • リポジトリ名(full_name)
  • リポジトリURL(html_url)
  • スター数(stargazers_count)
  • フォーク数(forks_count)
  • ウォッチ数(watchers_count)
  • 説明(description)
  • ホームページ(homepage)

使ったものたち

今後の改善案

  • ソート条件を指定できるように(スター数、フォーク数、最終アップデート等...)
  • 単体テスト追加
    • lodashのモック化が出来ず断念した
  • アカウント認証追加

参考

Computed Properties and Watchers — Vue.js

Lodash Documentation

Preact: Fast 3kB alternative to React with the same modern API. Components & Virtual DOM.

ポートフォリオサイトを作った話

動機

  • 自分のスキルや成果物を公開できる場を作りたかった
  • Vue.js使ってみたかった
  • github.io使ってみたかった

URL

Let me SHOW

githubはこちら

github.com

使ったもの

FW, ツール系

  • Vue.js
    • vue-loader
  • Sass
  • PostCSS
    • とりあえずautoprefixerだけ
  • yarn
  • webpack

ライブラリ

今後

  • Sass -> PostCSS移行する
  • デザインを定期的にアップデートする
  • Workに載せられるアプリ等を作る

Pythonの内包表記について調べた話

動機

近頃、業務でAWS(特にLambda)を使っている。

aws.amazon.com

Lambdaで「EC2インスタンスのAMIを定期取得」するためのスクリプトPythonで組もうと思い、色々と調べていた時の事。

qiita.com

上記記事で見慣れない表記を発見。

return sum([
    [instance for instance in reservation['Instances']]
    for reservation in reservations
], [])

sum()関数は、イテレータブルなオブジェクトの総和を求める関数。
見慣れないのはこの部分。

[instance for instance in reservation['Instances']] for reservation in reservations

リスト内包表記とは

公式ドキュメントは以下。
5. データ構造 — Python 3.6.5 ドキュメント

リスト内包表記はリストを生成する簡潔な手段を提供しています。
主な利用場面は、あるシーケンスや iterable (イテレート可能オブジェクト) のそれぞれの要素に対してある操作を行った結果を要素にしたリストを作ったり、ある条件を満たす要素だけからなる部分シーケンスを作成することです。

基本的な記法

通常のリスト生成はこんな感じ。

list = []

for i in range(10):
  list.append(i)

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

一方、リスト内包表記を使うとこうなる。

list = [i for i in range(10)]

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

リスト内包表記の基本的な記法は以下。

[i for i in iterator]

if節の使用

リスト内包表記は、括弧の中の 式、 for 句、そして0個以上の for か if 句で構成されます。 とある。

通常記法:

list = []

for i in range(10):
  if i % 2 == 0:
    list.append(i)

list
# >>> [0, 2, 4, 6, 8]

リスト内包表記:

list = [i for i in range(10) if i % 2 == 0]

list
# >>> [0, 2, 4, 6, 8]

複数のfor節の使用

2つのリストから要素を操作することが可能。
以下のコードでは、2つのリストからそれぞれ値の違うもの同士をペアにしている。

[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
# >>> [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

パフォーマンス

iPython%%timeitで計測してみる。

通常記法:

list = []

for i in range(10000):
  list.append(i)

# >>> 1000 loops, best of 3: 1.08 ms per loop

リスト内包表記:

list = []
list = [i for i in range(10000)]

# >>> 1000 loops, best of 3: 337 µs per loop

うむ。速い。

これらを踏まえて

もう一度こちらを見てみる。

[instance for instance in reservation['Instances']] for reservation in reservations

この記法は通常記法にすると

for reservation in reservations:
  for instance in reservation['Instances']:
    # instanceに対する処理

と読める。理解が深まった。

いろいろな内包表記

Pythonの内包表記には、リスト内包表記の他にも

  • 辞書型内包表記
  • ジェネレータ型内包表記
  • 集合型内包表記

等があるらしい。奥が深い。
(友人の記事。感謝。)

qiita.com

ジェネレータや集合(set)については、Pythonに於けるイテレータを改めて学んだ後にまとめたいと思う。
(まだまだPython初心者のため、使ったことがない) 今回は使ったことのある辞書についてのみ記述する。

辞書型内包表記

任意のキー:値のペアを作ることが可能。

{key: val for key, val in zip(range(3), ['hoge','fuga','piyo'])}
# >>> {0: 'hoge', 1: 'fuga', 2: 'piyo'}

zip()関数と相性がいいみたい。どこかで使い所はありそう。

まとめ

いいところ

  • ワンライナーで記述出来る
  • 通常記法よりもパフォーマンスがいい
  • ifif elseと併用出来、対応力が高い。

工夫次第なところ

  • 可読性の担保
  • map()filter()との使い分け

PythonRubyは使ってて刺激が多い言語だと改めて感じた。
これから色々試していきたい。
以上。

参考

qiita.com

qiita.com

qiita.com

AWSを使い始めた話

導入

Qiitaでこんな記事を見かけた。

qiita.com

かくいう私、4月に入って初めてAWSに触れた。
元々AWSアカウントを持ってはいたものの、触ったことがなかった。

AWSに持っていたイメージ

  • とにかく色々出来る
  • サービス感の連携が強い
  • 低コスト

...これでもエンジニア(3年目)だ。何とも恥ずかしい。

使い始めたきっかけ

社内開発用のアプリケーション構築の為に使用を始めた(社用アカウント)。
コストについては余り気にしなくても良いとのことで、色々試している。

使ってみた感想

エンジニアには

  • フロントエンド
  • バックエンド
  • インフラ

のような区分けがある(多分まだある)のだが、
そういった区分けに縛られる時代ではないのだなと感じた。

これだけ簡単にインフラ構築が可能な以上、
どのレイヤのエンジニアだろうと、何から何まで構築できる能力を
付ける必要があるなと、ひしひしと感じた。

どのサービスで何をやっているのか

  • IAM
    • カスタムロール、ポリシーの作成
  • Amazon EC2
  • Amazon S3
    • CloudTrailによるログ、モニタリング情報収集
  • AWS Lambda
  • CloudWatch
    • Lambda関数のスケジューリング(cron)
    • CloudTrailによるAPI呼び出しからのイベント発火
  • CloudTrail
    • API呼び出しの監視
  • Amazon VPC
  • Route 53

とりあえず、この辺りは一通り基本を抑えた。

これから学びたいサービス

まとめ

この1ヶ月間ガッツリAWSを使ったことで、サーバー周りやネットワークの知識を付けることが出来た。
触れる前は「敷居が高いな」と感じていたが、触ってみると全然そんなことはなく、秒単位課金の料金体系や12ヶ月の無料期間も相まって非常に触れやすいサービスだと感じた。

今後も暫くAWSを活用して業務を行っていく為、様々な「知らない」から脱却すべく頑張っていきたい。

【解決】yarn addでwebpackを追加する時にエラーが出た話

概要

以下のページで学習中の話。 qiita.com

yarn add --dev webpack (以下略)の部分でエラーが発生。

upath@1.0.4: The engine "node" is incompatible with this module. Expected version ">=4 <=9"

原因

qiita.com

どうやらnode v10.0.0でwebpackをインストールする際に起こるらしい。

解決策

上記記事にあったコマンドを試すもダメ。

yarn intall --ignore-engines

エラーメッセージを読むに、nodeのバージョンを下げれば行けそう。 その為、nvmnodeのバージョンをv8.11.1にダウン(v.9.0.0ではうまく行かなかった。要検証)。

MacBook-Pro-2016:react-spa USER$ nvm install 8.11.1
Downloading and installing node v8.11.1...
Downloading https://nodejs.org/dist/v8.11.1/node-v8.11.1-darwin-x64.tar.xz...
######################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v8.11.1 (npm v5.6.0)

MacBook-Pro-2016:react-spa USER$ node -v
v8.11.1

めでたく解決。

MacBook-Pro-2016:react-spa USER$ yarn add --dev webpack babel-core babel-loader babel-plugin-transform-react-jsx babel-preset-react react react-dom
yarn add v1.6.0
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
success Saved 271 new dependencies.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
✨  Done in 9.98s.

rbenvがrehash出来ないエラーを解決した話

環境

MacBook-Pro-2016:~ USER$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.4
BuildVersion:   ******

MacBook-Pro-2016:~ USER$ rbenv -v
rbenv 1.1.1

事象

Railsで開発する為に、Homebrewでrbenvをインストールした。

MacBook-Pro-2016:~ USER$ brew install rbenv

今回はRuby2.5.1を使おうと思いインストール。

MacBook-Pro-2016:~ USER$ rbenv install 2.5.1
ruby-build: use openssl from homebrew
Downloading ruby-2.5.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2
Installing ruby-2.5.1...
ruby-build: use readline from homebrew


Installed ruby-2.5.1 to /Users/USER/.rbenv/versions/2.5.1

すると、以下のエラーが発生。

rbenv: cannot rehash: /Users/USER/.rbenv/shims isn't writable

改めてrehashしてみてもダメ。

MacBook-Pro-2016:~ USER$ rbenv rehash
rbenv: cannot rehash: /Users/USER/.rbenv/shims isn't writable

エラーメッセージから推察すると、書き込み権限がないらしい。

対処

chmodで権限を変更する必要があると予想。

rbenvの権限を見に行ってみたところ。

MacBook-Pro-2016:~ USER$ ls -la ~/.rbenv/
total 0
drwxr-xr-x   4 USER  admin   128  4 12 10:27 .
drwxr-xr-x  57 USER  admin  1824  4 12 10:36 ..
drwxr-xr-x   9 root  admin   288  4 12 10:29 shims
drwxr-xr-x   5 USER  admin   160  4 12 10:43 versions
drwxr-xr-x   9 root  admin   288  4 12 10:29 shims

...(゚Д゚)
所有者がrootになってました。

別にsudoで実行してもいいのですが、Railsで開発進める中で不便に感じる部分(特にDB周りとか)が出てきそうなのでささっと所有者変更。

MacBook-Pro-2016:~ USER$ sudo chown USER ~/.rbenv/shims/
MacBook-Pro-2016:~ USER $ ls -la ~/.rbenv/
total 0
drwxr-xr-x   4 USER  admin   128  4 12 10:27 .
drwxr-xr-x  57 USER  admin  1824  4 12 10:36 ..
drwxr-xr-x   9 USER  admin   288  4 12 10:29 shims
drwxr-xr-x   5 USER  admin   160  4 12 10:43 versions

無事にrbenv rehash出来ました。

MacBook-Pro-2016:~ USER$ rbenv rehash
MacBook-Pro-2016:~ USER$ rbenv versions
* system (set by /Users/USER/.rbenv/version)
  2.5.1

参考

teratail.com

qiita.com

Javaを学ぶ -Java 8 Stream編-

背景

  • 業務で半年ぶりにJavaを触るので、言語レベルでの復習をしたい。
  • 公式のドキュメントに目を通しておきたい。
  • 自分の中のJavaは7で止まっている為、少しずつ新機能を学びたい。

Streamとは

Java SE 8から実装された、コレクション(配列、リスト等)を扱いやすくするAPI
参照: Stream (Java Platform SE 8)

それまで拡張for文等で煩雑になりがちだった、コレクションに対する操作を明快にしてくれる。

Streamでは同じくJava SE 8で実装された、これまた重要なラムダ式を用いている。
...が、今回はラムダ式に関する解説は省略する。後日また改めて記事でまとめる予定。

Streamの構造

Streamは以下のような構造を持つ。

collection.stream() // streamの取得     
          .filter() // 中間操作
          .sum();   // 終端操作

上記の例で解説していく。

  1. stream() ...streamの取得
    Collection.stream()メソッドによって、コレクションのストリームを作成する。 ここで作成したストリームに対して操作を行っていくことになる。

  2. filter() ...中間操作
    取得したストリームに対して、0個以上の中間操作を行う。
    代表的なものはfilter(Predicate)で、あるストリームを別のストリームに変換する。

  3. sum() ...終端操作
    0個以上の中間操作を行った後、1つの終端操作を行う。
    代表的なものにcount()sum(), forEach(Consumer)等がある。

Streamのサンプル

サンプル1: リスト内の奇数を合計し、出力する
  • Streamを使わない場合
List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = 0;

for(Integer i : integerList) {
  if (i % 2 != 0) {
    sum += i;
  }
}

System.out.println(sum); // 25
  • Streamを使う場合
List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

Integer sum = integerList.stream()
                         .mapToInt(x -> x)
                         .filter(i -> i % 2 != 0)
                         .sum();

System.out.println(sum); // 25

Streamを用いた記述の方が圧倒的にシンプルな上に読みやすい。

サンプル2: 各要素を操作し、新しいコレクションを生成する
  • Streamを使わない場合
List<String> langs = Arrays.asList("Java", "Ruby", "Go", "Python");
List<String> langWithBlacket = new ArrayList<>();

for(String lang : langs) {
  langWithBlacket.add("[" + lang + "]");
}

System.out.println(langWithBlacket); // [[Java], [Ruby], [Go], [Python]]
  • Streamを使う場合
List<String> langs = Arrays.asList("Java", "Ruby", "Go", "Python");
System.out.println(langs.stream()
                        .map(s -> "[" + s + "]")
                        .collect(Collectors.toList()));
                        // [[Java], [Ruby], [Go], [Python]]

場合によっては新規の変数を準備する必要がなく、記述量が減る。

サンプル3: コレクション内の要素全てに判定をかける
  • コレクション内の要素に空白が含まれていないか判定
List<String> names = Arrays.asList("John", "Mark", "Andy", "Judy");    System.out.println(names.stream()
                            .allMatch(s -> !s.isEmpty()));
                            // true
  • コレクション内の要素に条件を満たすものがあるか判定
List<String> names = Arrays.asList("John", "Mark", "Andy", "Judy");
System.out.println(names.stream()
                            .anyMatch(s -> s.startsWith("A")));
                            // true

List<String> names = Arrays.asList("John", "Mark", "Andy", "Judy");
System.out.println(names.stream()
                            .anyMatch(s -> s.startsWith("K")));
                            // false

個人的にこの機能はものすごく便利。

他にも、ラムダ式の強みを活かしてインタフェースを扱うことも可能。

まとめ

煩雑になりがちだったコレクションに対する操作を、シンプルに記述出来るStreamは非常に便利で、扱う機会が多いため学習した。
特に、少ない記述量で中間操作をチェーン出来る点が非常に良いと感じた。
だいぶ前にリリースされたJava SE 8だが、ラムダ式とともにまだまだ学習が足りない為、継続的に学習していく。

参考

Stream (Java Platform SE 8)

[Java8] はじめて触るStreamの世界 | Developers.IO

Java8のStreamを使いこなす - きしだのはてな

Java Stream APIをいまさら入門 - Qiita