ずっと5月

3日坊主してます

LeetCode #1 TwoSum

仕事でSwiftを触ることになった。しかしチュートリアル的なもの以外の経験がなくて今年一番の焦りを感じたのでLeetCodeで入門しようと思った。なんでLeetCodeなのかというと先月あたりに社内のつよつよエンジニアの人におすすめされたから。

手始めに問題のリスト一番上にあったTwoSumというそれぞれint型の配列と変数(target)を与えられてそこから配列の何番目と何番目を足せばtargetになるか、という問題をやった。Easyらしく苦しむことなく楽しくできた。

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        for i in 0...(nums.count - 1) {
            for j in 1...nums.count - 1 {
                if (i >= j) {
                    continue
                }
                if (nums[i] + nums[j] == target) {
                    return [i, j]
                }
            }
        }
        return [0,0]
    }
}

解き終わって正解だと判定されたらこんな感じで速度とメモリ使用量を教えてくれる。ついでに次こういう問題どう?って感じで勧めてくれる。
f:id:uminokaze521:20191210000013p:plain

safari12でだけclickイベントが発火しない

仕事中に出会ったのでメモ safari12になってからJSのselect要素に対するclickイベントが発火しなくなった。

<form id="hoge" method="post">
    <p>性別<br>
      <select name="sex">
        <option value="man">男性</option>
        <option value="woman">女性</option>
      </select>
    </p>
  </form>
<script>
$("#hoge").on("click",function(){
//なにか処理
});
</script>

そもそもselect要素の選んでいる選択肢が変わったときに発火する処理を設定するときはclickよりchangeが適しているはずなので、この知見を活かす機会はなかなかないと思うけど、、、

GithubのGraphQL API v4を使ってコミット数を取得&Twitterにツイートする

やっていき力が回復したのでやっていき。 Githubのコミット数をTwitterに投稿するなにやらを作った。

github.com

ggると同じものがすでにある。 blog.koogawa.com

丸パクリも嫌だったのでGithub APIの中でも最新のGraphQL API v4を使うことにした。 以下を参考にクエリを作成する

Query | GitHub Developer Guide

qiita.com

query{
  viewer {
    repositories(first: 100) {
      nodes {
        defaultBranchRef {
          target {
            ... on Commit {
              history(since: "2018-05-01T11:31:28+00:00") {
                totalCount
              }
            }
          }
        }
      }
    }
  }
}

作成したクエリを試しに動かしてみる
以下のページで試しに動かせる。
GraphQL API Explorer | GitHub Developer Guide

結果は以下。いい感じになった。
f:id:uminokaze521:20180610205055p:plain

これをPHPで実行する。

<?php
require_once __DIR__.'/vendor/autoload.php';
use Dotenv\Dotenv;

class GithubAPI {

    private $accessToken;
    private $client;

    public function __construct() {
        $dotenv = new Dotenv(__DIR__);
        $dotenv->load();

        $this->accessToken = getenv('GITHUB_ACCESS_TOKEN');
    }

    public function GetCountsCommits(){
        $date = date("c",strtotime("-1 week"));
        $query = <<<EOT
        query{
            viewer {
                repositories(first: 100) {
                    nodes {
                        defaultBranchRef {
                            target {
                                ...on Commit {
                                    history(since: "{$date}") {
                                        totalCount
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

EOT;
        $contents = $this->postApi($query);
        return json_decode($contents);
    }

    public function postApi($query){
        $options = [
            'http' => [
                'method' => 'POST',
                'header' => [
                    'User-Agent: My User Agent',
                    'Authorization: bearer '.$this->accessToken,
                    'Content-type: application/json; charset=UTF-8',
                ],
                'content' => json_encode(['query' => $query]),
            ],
        ];
        $context = stream_context_create($options);
        return $contents = file_get_contents('https://api.github.com/graphql', false, $context);
    }

    public function countCommits($datas) {
        $repos = $datas->data->viewer->repositories->nodes;
        foreach($repos as $repo){
            $counts += $repo->defaultBranchRef->target->history->totalCount;
        }
        return $counts;
    }
}

こんな感じになった。あとはTwitterAPIを使ってツイートしてやればいい。
TwitterAPIの使い方は以下の通り

<?php
require_once __DIR__.'/vendor/autoload.php';
use Dotenv\Dotenv;
use Abraham\TwitterOAuth\TwitterOAuth;

class TwitterAPI {

    private $connection;

    public function __construct() {
        $dotenv = new Dotenv(__DIR__);
        $dotenv->load(); //.envが無いとエラーになる

        $consumerKey = getenv('TWITTER_CONSUMER_KEY');
        $consumerSecret = getenv('TWITTER_CONSUMER_SECRET');
        $accessToken = getenv('TWITTER_ACCESS_TOKEN');
        $accessTokenSecret = getenv('TWITTER_ACCESS_TOKEN_SECRET');

        $this->connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);

    }

    public function PostToTwitter($message){
        $result = $this->connection->post("statuses/update", array("status" => $message));
    }
}

実行の仕方は以下の通り。

<?php

require_once "GithubAPI.php";
require_once "TwitterAPI.php";

$github = new GithubAPI();
$result = $github->GetCountsCommits();
$counts = $github->countCommits($result);

$twitter = new TwitterAPI();
$twitter->PostToTwitter("今週は" . $counts . "回commitしました。" );

久しぶりにコードかけて楽しかった。

pythonを始めるためにPython Boot Campに参加した話

Python触ったこと無いマンがPythonチュートリアルをする勉強会に参加してきた。
これ。
pyconjp.connpass.com

PyCon JPではこれまでも年に1回東京で開催されるPyCon JPイベントでPythonを学べるチュートリアル講座を開催してきました。 今回は、以下のような人たちにPythonを知ってもらえる機会を提供できたらという思いで、Python Boot Camp(略してPyCamp)を企画しました。

  • 遠方に住んでいるためPyCon JPのチュートリアルに参加できずにいた方

  • Pythonを使っている人が周りにいなくてなかなか始められなかった方

遠方に住んでて周りにPython使ってる人もいないマンなのでまさに自分みたいな人間が対象やんけ!!と思って参加申し込みポチ-

こういう勉強会に参加したことなかったのでドキドキしながら参加したけど良い時間だった。

会場に行ってみると弊社の人がぼちぼちいたりなんだりでそれなりに質問しやすい環境で楽しくチュートリアル出来た。

簡単に構文とかリストの説明を受けてFizzBuzz書いてスクレイピングをするまで大体4時間ほど。
終わった後は13人ほどで懇親会へ。
美味しかったでつ。

内容的には自分ひとりで家でもできるものだったけど

  • 社外のエンジニアと話す機会で出来たこと、

  • 自分だけだと考えつかない深いところの質問とその返答

が聞けたことを考えるとお金払って行く価値はあった。良かった。

Conohaサーバー借りてUbuntu16.04の設定をした

nヶ月ぶりの更新になってしまってまずい感。。圧倒的三日坊主。 でもどうせ誰も見てない。1ヶ月に1アクセスもない。本人すらアクセスしないとこうなるんですねぇ
過疎ブログもほどほどにして今年はちゃんと更新してやっていきを高めたい。。。

昨日出来心でconohaサーバーを契約したので設定してみる。具体的には以下を設定する。

  • rootユーザーでログイン

  • root権限を持ったユーザーの作成

  • 作成したユーザーでのSSHログイン

  • rootユーザーでのログイン禁止

  • パスワードによるログイン禁止

  • ファイアウォールの設定

  • SSHのポート番号変更

  

サーバー契約

とりあえず↓参考にサーバーを契約する。今回選んだOSはUbuntu16.04の64bit

qiita.com

Qiitaの記事と若干選択肢が違うけどこのような感じで。
f:id:uminokaze521:20180207155314p:plain

rootでログイン

無事にサーバー追加出来たら、サーバーリストから先程追加したサーバーのネームタグをクリックしてサーバーの情報を見る。 ネットワーク情報にIPアドレスが書いてあるのでSSHする

$ ssh root@xxx.xxx.xxx.xxx

サーバー契約する時に決めたrootパスワードを入力する。   

ユーザー作成

ユーザーを作成する。

//ユーザー作成
# adduser maru  

//パスワード設定
# passwd marumaru3

//root権限を付与する
# usermod -G sudo maru

//作成したユーザーでログインしてみる
# su maru

maruユーザーになった後はちゃんとroot権限持ってるか確認する。

作成したユーザーでのSSHログイン

設定を編集

$ sudo vim /etc/ssh/sshd_config

sshd_configを編集して以下の項目がそれぞれ設定されているか確認する。
ちなみに、最初に載せたQiita記事にはRSAAuthenticationの設定も編集する必要があると書いてあるがサポートが終了したので書く必要は無いらしい。

PubkeyAuthentication yes
//以下のファイル名は任意に変更して良い
//後で作成するファイルを同じ名前にすること。
AuthorizedKeysFile      .ssh/authorized_keys

したらsshdを再起動する。

$ sudo service sshd restart

RSAAuthenticationの話は以下を参照。 qiita.com  

SSH鍵の生成・リモートログイン

~/.sshディレクトリを作成→鍵の生成→設定ファイルの編集(ローカルPC)→リモートログインの順で行う

$ cd ~/
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
//鍵を生成する
//ファイル名とパスワードを聞かれるので任意のものを設定する
$ ssh-keygen -t rsa -b 2048
Enter file in which to save the key: maru 
Enter passphrase:                          
Enter same passphrase again:
$ mv maru.pub authorized_keys
$ chmod 600 authorized_keys
$ cat maru

生成した公開鍵は先程AuthorizedKeysFileで設定したファイル名に変更して権限を600にしておく。 秘密鍵は今後使用するのでcatして出てきたものをコピーしておく

#### ローカルPCの設定 次はサーバーに接続する側で設定を行う。

$ cd ~/.ssh
//さっきコピーした秘密鍵をペーストする
$ vim maru
$ chmod 600 maru
$ vim ~/.ssh/ssh_config
//以下を追記。ユーザー名・秘密鍵の名前は適宜変更する。
#ConoHa
Host conoha
  HostName xxx.xxx.xxx.xxx
  User maru
  Port 22
  IdentityFile ~/.ssh/maru
$ ssh conoha

ここまで上手く設定できていればローカルPCからSSH接続ができる。
上手く行かなかった場合は

$ ssh conoha -vvv

SSHする時のログが表示されるのでこれを参考に対処すると良い。 私は読み込んでいるconfigファイルが違って上手く行かなかった。

rootユーザーでのログイン禁止

再び設定を編集

$ sudo vim /etc/ssh/sshd_config
//PermitRootLoginをnoにする
$ sudo service sshd restart

パスワードによるログイン禁止

これも設定を編集

$ sudo vim /etc/ssh/sshd_config
//PasswordAuthenticationをnoにする
$ sudo service sshd restart

ファイアウォールの設定

SSHのポート番号変更

sshd_configとufwの設定を変更する必要がある。

$ sudo vim /etc/ssh/sshd_config
//Portを任意のポート番号にする。
$ sudo service sshd restart

あとはufw
CentOSとかだとiptables の編集が必要だが、Ubuntuufwというのを編集する必要がある。

# ufw default deny
# ufw allow [任意のポート番号]
# ufw enable

ufwの詳しい使い方は以下のQiitaを参考にすると良さそう。

qiita.com

ローカルPCの~/.ssh/ssh_configのPortも任意のポート番号に変更する必要があるので注意。

以上!

複数ファイルから特定文字列を削除する

スクリーンショットを撮った時、名前が[スクリーンショット ****-**-** **.**.**.png]になるけど、
[スクリーンショット ]の部分が邪魔になった。

ということでトリム

$imageDir = opendir('images/');
while( $file_name = readdir($imageDir) ){

if(preg_match('/\.png$/',$file_name)){
rename("images/".$file_name , "images/".str_replace("スクリーンショット ","",$file_name));
}
}

Apacheをごにょごにょするときの自分用コマンド一覧

Apacheをゴニョゴニョする時メモ

とりあえず設定ファイル

$ vim /etc/httpd/conf/httpd.conf

apacheの再起動する

$ sudo /etc/init.d/httpd restart

エラーログみる

$ sudo tail -f /var/log/httpd/error_log