読者です 読者をやめる 読者になる 読者になる

頭の中は異空間

生活を日々ハックしてよりよくするブログ

iphoneが壊れた時に考えるべきこと

iphoneが去年いかれてしまったので、別のに変えました。そして今年また調子が悪くまた変えました。いい加減出費がひどくて嫌になります。通常、どのキャリアの携帯もサポート期間中だろうと本体を無償で交換、というサービスを提供しません。そこはまあ突っ込まないというより仕方ないとして、実際壊れたら購入の流れになるところですが、ここが考えどころです。金を無尽蔵に出せるわけではないので、よく考えて購入しないと泣きを見そうでね。

 

本当にすぐ買い換える必要があるのか?

ここでよく考えたいのが、実際にすぐ買い換える必要があるのか、人によってはなくてもそこまで困らないんじゃないかということ。特に筆者のように友人が少ない人には

高い金を出して買い換えるのが予算的にどうしてもって人は、借金して買う前に踏みとどまるべし。

一人暮らしなら、今やSkypeやLINEというアプリがあるではないですか。自宅デスクトップPCもしくはノートにそれを入れれば、普段外出しない人は事足ります。iPadなどのタブレット端末やMNP済みで電話が出来ないスマホ(SIMの入れ替えをするなら壊れた携帯と同じキャリアに限る。キャリアが違うならネット専用かな...)など壊れた携帯以外にポータブルデバイスを持っているなら、かつポケットWiFiを契約済みならそれを普段持ち歩いて必要な時にネットを見れば良い。電話についてもメールについてもLINEくらい今はネットリテラシーがない人でさえ当たり前に入れてますから、それで出来ればいいと思います。調べてみたら回線契約なしでも電話出来そうだし、やり取りも既読かどうか見れるのでLINEの方が便利。それが難しい場合は、後述のような中古の端末を購入するのが合理的。

実家暮らしなら、実家の電話番号を教えてそこにかけてもらえばOK。もしくは一人暮らしと同様の手段。

今時の人もそうでない人もFacebook/Twitter/LINEを押さえておけばどれかしらやってるはずなので、そこで連絡取ってくれって言うだけ。楽。少し古いですが総務省のサイトにもある通り、今やSNS経由の連絡は劇的に増えているので、使っていて当たり前くらいの感覚になります。だから意外と携帯の電話やメールがなくっても意外となんとかなっちゃいますね。メールについてはGmail, Yahoo mailなどのフリーメール機能もあることですからそちらを利用すればOK

興味があればこの方法でやってみてどうも不便だと感じれば購入したらいいでしょう。

 

買い換えるなら中古 or 新verが出た直後

今や毎年のようにiphoneの新型が発売されています。ITのニュースサイトやそれ関連のサイトを見ると、すでにiphone8の噂が出ています。

news.livedoor.com

gigazine.net

技術の進歩は早い!と実感しますね。さて新たにスマホを購入するなら、新型を欲しくなるかも。でもそれって本当に必要でしょうか?という疑問が。

筆者の場合、必要最低限のスペックと機能がどれかを調べます。つい最近までは譲り受けたiphone4Sを使っており、これが3GでしかもiOSバージョンの問題か知りませんが動作が半端じゃなく遅いのでかなりストレスでした。だからこそ、買い替えを決断しました。iPadMNP済み携帯も持ってますがこれはこれで別の用途に使いたいし、今持っているWifi端末は3月末には解約する予定っていうのもあります。

そこで今回購入したのはこれ

5Sも今は古いと言われるかもしれませんが、ほとんど傷がなく、税込送料込で15000円。中々悪くない買い物でした。

f:id:notwo:20170214005449j:plain f:id:notwo:20170214005457j:plain

6では2万円超えが当たり前だったので控えました。ちょっと探せばこのようにリーズナブルな価格で代替出来るものが見つかります。

もし最新版が良ければ、中古でなくSIMフリーが良さそう。とは言え今のところSIMフリー端末についてはまだ詳細を調べていないためここには書きません。既に他所の多くのブログやニュースサイトに取り上げられているとおり、大手3キャリアによる2年縛りの解除SIMロック解除義務化といったニュースは記憶に新しいです。従来とは大分料金体系も違っているので、購入前には改めて調べなおして損のない支払いプランを選択したいもの。今後もっとリーズナブルなプランを提供する業者が現れることを期待して、それまでは手元のスマホを長持ちさせてみてはいかがでしょうか。

 

そもそも最新でなくても困らない

スマホのトレンドを常に追っかけている人でもなければ常に最新、なんてのは不要かと。今使っている5Sで実用に耐えますし、事足りています。さすがに4S以前は無理がありますが。2017年2月現時点で出ている7も、故障しない限り現役でいられるはず。Androidでも考え方は一緒。買い換えるきっかけは故障以外にはどうしてもそのバージョンで特定のアプリが動かないとか、スマホ自体の動作がおそすぎるとか、最新バージョンのスマホがどうしても欲しい理由があるときに限るかと。多少古かろうが誰かに迷惑がかかるわけでもなし、こだわりがなければ買い換えずにずっと使うことは賢い選択だと思います。

 

まとめると

買う前に調べたり必要な機能が何か洗い出したりやるべきことはあるので、そんなときこそ冷静になろうって話でした。携帯代は削ろうと思えば削れる出費ですし、毎月のしかかってきますので、出来る限り工夫しましょう。

jQuery、JSまわりでよく起こすであろうバグをざっくりと。

HTML JavaScript
f:id:notwo:20170108184111p:plain

焦ったり急いでコーディングしてると忘れがちで結構やらかしている事が多いミス。JSは自由度が高すぎる言語なので決まりをある程度設けないと滅茶苦茶なコードになってしまいますね。前に実際にやらかしたミスや今後も気をつけないと繰り返しそうな凡ミスの例を書き出してみます。

 

バグの温床

data, attr, propでのデータ取得(get)/更新(set)

qiita.com

上記事に分かりやすくまとまっています。それぞれどのような特徴があるかを知った上で使い分ければミスしません。

 

$(this)の中身

関数が入れ子になっていると起こりうる現象。thisの参照先が異なるためにバグの温床になりやすいです。他サイトでも説明されきってる感じですが一応。

// 実際には下記のように書かずに$(".hoge").on('change', ~~~と書きますが分かりやすくするために。
$(".hoge").each(function() {
  // ここの$(this)と
  $(this).find('input').on('change', function() {
// ここの$(this)は違う console.log($(this));
}); };

 

id読み込み時の挙動

id属性はuniqueである必要があるので、idが重複していた場合通常は正しくJSが動作しないはず。

昔のIEではJSの挙動がおかしくなっていましたが、ChromeFireFoxではなんと中で独自に解釈したのか、ID重複後もエラーを吐かずに動作していました。なぜなんだろう。。

最新Ver(現時点で55.0.2883.87 m (64-bit))のChromeで試しにやってみると、・・・

 <body>
<div id="hoge">最初のid</div>
<div id="hoge">2つめのid</div>
<div id="hoge">3つめのid</div>
</body>

に対して

f:id:notwo:20170108193008p:plain

この通り、動くみたいです。最初のidに合致する要素を取ってきています。

しかし異常な挙動であることに代わりはないので、うっかりダブらせてしまったら速攻で削除してやるべし。

 

true/falseの空判定

!!"false"

これはtrueになります。文字列のfalseもtrueもtrueとして扱われるので、わかりづらいです。文字列でfalseになるのは""のみ。関数や変数の中身で判定する時、文字列が返ってくるとわかっているなら必ず === ""の空判定をするべし。

もう一つ、勘違いしやすい判定として

if []

もしくは

if {}

これはfalseになるかと思えばtrue。if文にundefinedやfalse, nullが入れば当然falseとして扱われますが、[]/{}自体は中身が空にもかかわらず1つの空でないオブジェクトとして扱われるのが原因。配列を判定するとわかっていれば

変数.length > 0

連想配列jsonであれば

Object.keys(変数).length > 0

とすれば中身が空かどうか判定出来ます。

最後に、曖昧比較(==)と厳密比較(===)。前者は変数の型を半ば無視して判定するので、本来falseなはずがtrueにしちゃう。例えば

100 == "100"

これはCやJavaなどでは明確にfalseになるのですが、JSでは==を使う限りtrue扱いです。StringとNumberで比較して同一とか何の冗談だと。でも企業のコードでこういうの多いです。PHPとかJSみたいな動的型付け言語では変数の型がわかりづらいことで、バグの温床になります。関数に渡す変数の型が違ったせいでエラーを吐いていた場合、この変数の型違いによるものが起こりうるので、余程の理由(ってなんだ?)がない限りは厳密比較を使うべし。

 

null.~~

例えば要素取得してattributeへアクセスする場合。$("~~")が存在しない場合nullになり、null.attribute名でCannot read propertyとなります。

要素名をtypoによって引き起こすことはテストによって排除出来るので、動的な要素変更があった場合に起こりうるバグです。class名やid属性変更後は特に注意です。

 

find, closest等による要素取得

viewのツリー構造が予めわかっていればfindだけでなくclosest, next等で要素を狙って取得できますが、ツリー構造に変更があった場合はその取得の仕方も変えないといけません。id属性やclass属性で取得していればclass名、id名を変えない限り影響はないのでまだ安心です(変える時は注意)。

 

自由度が高いからと言って好き放題やらない

1つのロジックを作るのにも多くの手段がありますが、実際書き方1つ違うだけでシンプルできれいなコードにもクソコードにもなります。

クソコードの例としては

unkode-mania.net

を見れば大体わかりそうなものです。本当にひどい例です(笑)

そうならないためには、言語ごとに役割を明確にもたせておくのが良いかと。

 

他の酷い例

関数名とreturn内容が合ってなかったり

  // タイトルを返すと書いてあるのにコメントを返している
  function title() {
    ~~(処理)
    return comment;
  };

(残念ながら某所で↑の例を実際に見ました...)

HTMLにif, forなどの複雑な構文を埋め込む(erbとして書きます)

<div class="~~~">
<% if hoge %>
  <% fuga.each do |f| %>
    <span class="~~">xxx</span>
    <% if piyo >
      book = Book.find ~~
      ...
    <% end %>
  <% end %>
<% end %>
</div>

Viewの役割に複雑な構文を突っ込んでいるだけでなく、クエリも走らせています。これでは見づらくて仕方ない。

こういう酷い例を見たら多少リスクを犯してでもついでに直しておいて、次見た時読みやすくしておくのがまともなエンジニアってもんでしょう。リファクタリングで多少のミスが出てもそれが致命的なものでないなら、それは大した傷ではないと思います。寧ろクソコードが新しく生み出され続けることのほうが余程重症なので。

ここではJS、特にjQueryを使った際のバグについて書きましたが、他の言語でも色々ひどい例は見てきたので、また何か酷いのを見つけたら書くと思います(笑)

SESで受信したメールをLambdaを通して転送&S3に保存 - Lambda(Python)/S3/SES

AWS Python

 

SESを設定することでメール送受信が可能になります。ここでは受信したメールをS3に保存し、更に中身を転送してみます。

 

SES

ここではオレゴンのリージョンを選択します。認証済みドメインであればどんなメールアドレスでも使えます。ドメインの認証方法は

notwodaily.hatenablog.com

などを参照。

認証済みドメインを用いて、SESでメール受信する際にS3へ保存するトリガーを設定します。詳細なやり方は

docs.aws.amazon.com

に倣ってできます。

 

S3

メールを保存するためのバケットを用意します。LambdaのIAMで参照出来るようにプロパティでバケットポリシーを設定(Principalを"*"とか設定すればOK)。

この時点で、SESで認証済みのドメインにメールを何かしら送信すればS3に内容が保存されます。実際に試してみると、

f:id:notwo:20170101191043p:plain

 このようになるはずです。

 

Lambda(Python)

S3にメールが保存されたというトリガーを設定してその都度Lambdaの処理を走らせるようにfunctionを作成します。

function

f:id:notwo:20170101192409p:plain
f:id:notwo:20170101192415p:plain

上画像の通りに設定。

ここではS3から保存されたメールのオブジェクトを取得→中身を解析→SESで送信の流れで処理を書きます。解析でやることは主にread()したあとにsubject, body(plain text), body(html), fromの中身を取得することです。html形式とplain text形式の両方が含まれます(相手が対応していない場合はhtmlはないかもしれません)。

メール転送はsend_mailだけ、中身は単純です。ここで注意しないといけないのは、replyおよびSourceにはSESで認証済みドメインしか使えないということ。このため、もしfrom情報を含めたければsubjectかbodyのどちらかに仕込むことになります。

コードは下記。

 

code

from __future__ import print_function

import json
import urllib
import base64
import boto3

s3 = boto3.client('s3')

EMAIL_TO = "送信先アドレス"

def send_mail(from_address, reply, subject, body, html_body):
    client = boto3.client('ses', region_name='us-west-2')
    client.send_email(
        Source="noreplyなど、送信専用アドレス",
        Destination={
            'ToAddresses': [
                EMAIL_TO,
            ]
        },
        Message={
            'Subject': {
                'Data': subject,
            },
            'Body': {
                'Text': {
                    'Data': 'from: ' + from_address + '\n' + 'body: ' + body + '\n' + 'html_body: ' + html_body,
                },
            }
        },
        ReplyToAddresses=[
            reply,
        ],
        ReturnPath="noreplyなど、送信専用アドレス"
    )

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        mail = response['Body'].read().replace('\n','').replace('\r','')

        from_address = mail.split('envelope-from=')[1].split(';')[0]
        subject = mail.split('Subject: ')[1].split('To: ')[0]
        body = base64.b64decode(mail.split('base64')[1].split('--')[0])
        html_body = base64.b64decode(mail.split('base64')[2].split('--')[0])
        reply = "noreplyなど、送信専用アドレス"
        send_mail(from_address, reply, subject, body, html_body)
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

以上です。細かく解説すると、

bucket = event['Records'][0]['s3']['bucket']['name']

でバケット名を、

key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))

でファイル名を取得しています。LambdaのトリガーにS3を設定した場合必ずこれで取得できる構造になっています。

肝心の内容は

response = s3.get_object(Bucket=bucket, Key=key)
mail = response['Body'].read().replace('\n','').replace('\r','')

でメールオブジェクトを読み取ったあと、それぞれ

from_address = mail.split('envelope-from=')[1].split(';')[0]
subject = mail.split('Subject: ')[1].split('To: ')[0]
body = base64.b64decode(mail.split('base64')[1].split('--')[0])
html_body = base64.b64decode(mail.split('base64')[2].split('--')[0])

で送信元、タイトル(subject)、本文(body)、本文HTMLの4つを取得しています。元々のメールオブジェクトの中身は改行付きで1つの文字列として扱っておりわかりづらいので、mail = の行で改行を削除しています。そのうえで、ほしい情報を前後の文字列を見てsplit関数でうまいこと取り出しています。ゴリ押しですね...

S3のメールをダウンロードして中身のテキストを確認するとわかりますが、bodyの文字列がbase64エンコードされています。これをbase64デコードするために

base64.b64decode

を用いています。そのため、頭の

import base64

を忘れないこと!

これ以外の情報がほしければ、同様にsplitを使って文字列を切り出して取得する。

 

ここではS3にメールを保存しっぱなしにしていますが、メールが溜まってきたら容量は圧迫されるので、転送完了後に削除しちゃっても良いかもしれません。

情報は能動的に取っていかないと駄目だって話

マインドセット

 

また、失念しました。。受動的に(しかも勝手に)組まれてるスケジュールってかなり合わせづらい。せめて候補日を指定してもらって、そこからこちらが選ぶとかしないとね。自己管理能力がないで諦めて思考停止するのはもったいなさすぎます。

これは改善しないといけないな、と思いついたのと、同時にこれは自分への戒めの意味としても大事なことだから書いておかないと、と思って書いた記事です。

 

強く興味を持つ

好きなことに対しては自然と能動的になり、頭に残る。間違いない。

経験上、忘れっぽい筆者でさえ例えばガキの頃どんなゲームやってたか、とか最近だったらいつ飲酒したか、とかしっかり覚えています。本気で好きなことは忘れるはずがなくて、ネットサーフィンするにしても興味のある情報に関してはどんどんググって賢くなっていける(取る情報によりますが)。

逆に興味が無いことは何百回言われても忘れるし、めんどくさいとしか思わないので言われてもできないことが多いと思います。一方的に「勉強しろ」って言われて手が動く人も珍しいのでは。

 

自分が発信する側にまわる

予定を自分から組んでいって、参加する/しないも相手に促されるんじゃなくて自分からはっきり答える。これがベストかな。

そういう自分から発信する習慣をつけるためにはブログ書くでも良し、イベントやるでもよし、身内で発表会やるでもよし。行動力が試されますけど、よくよく考えてみたらみんな就活やるときだって自主的に情報とって自分から説明会予約したりインターンやったり面接とか試験受けに行くわけで。ということは誰にでも行動力は元々備わっていて、ある程度の危機感というかやらざるを得ない状況に追い込まれたら誰だってやるってことですね。

 

ほんの少しでも能動的な動作が必要

大事な予定があるなら頭に入れるでなくてリマインダーを設定するとか、なんでそれが大事なのか自分の頭で理解する。ほんとうに大事だとわかっていれば忘れるはずがないので。

もし自分が情報を発信する側にまわるなら、やることが厳密になって良いかもしれません。このブログでも書いていることは大したことはないけど、それでも自分から情報を発信していくことで頭の中が整理されるし、アホなことを書くとそれがそのまま晒されて恥をかくことになるので、自分が有名じゃないからってあまり適当なことは書きたくありません。つまり書こうと思ったらそれが正しいか、念入りに調べることくらいはする→正しい知識が身についていくというメリットが生まれます。

 

まとめると

些細な事から改善して、下手なミスをしないように、そしてそんな小さなことで恥をかかないように常日頃から意識しよう、そしてそのために情報は自分から積極的に取る週間をつけようという話でした。

2017年の予定

 

来年はこんなことやってやろう

今年は予想通り自分にとっては激動の年になったことは間違いないです。はてなブログで記事を書き始めたのも実際にものづくり開始してプロダクト(自分の所有物じゃないけど)を出したのも、度重なる引っ越しをしたのもこの1年間での出来事でした。
毎年必ず1個は自分にとって大きな出来事があるのですが、来年はどうなることやら。
そこで、今のうちにざっくりとその目標、というよりはやることを書いていきます。

 

  • プロダクト出す(スマホゲーム、webアプリ)
  • 今年制作したサイト、フォームの運用と管理画面作成
  • 自分の個人用Web site作成、リリース→Herokuがいいかなー?

この3本柱、特に前者2つを中心に個人のスキルアップと場数を増やすことに心血を注ぎます。

 

やろうと思っているネタ

これからHerokuなりAWSなりで作ろうと思っているネタを書いてみます。

設計は頭のなかで思い描いている程度なので、この通りには出来ないかもしれませんが。

 

自分年表

1画面で作成。画面に記載した年表をダウンロード出来る。それを読み込めば復元可能。

 →これなら会員登録が不要になるうえ、データをサーバ上に保存する必要がないので漏洩の心配なし。

 →製作者にとってもユーザにとってもうれしい。

 

かんたんなソース解析ツール

解析といってもpythonでごっそり書くわけじゃなく。例えばrubyならpartial構造を洗い出したり、Cでいうdoxygen的な役割を持たせても良い。

 

パズルゲーム

筆者がゲームを作ろうと思うコンセプトに、老後もボケないきっかけを作ろう、というのがあります。筆者の老後はもちろん、誰に対しても有効な手段なはず。気力がないからボケる、をなくすきっかけが作れれば幸いです。

ただ、何を作るかは未決定だし素材も全くないので課題まみれという。。そしてどれも来年中に収まるか微妙なところですが(笑)

ところで、面白い記事を見つけました。

↓↓ダークソウルおじいちゃん

news.denfaminicogamer.jp

筆者の老後もこうありたい、と思っています。いつまでも元気なのが一番ですね。

ということでやることにはアプリが多そうです。

これをいちいちパクる奴もいないでしょうけど、どうせなら筆者より先に誰かが作って夜に出してくれる人がいても良いでしょう。

 

 

書いた記事は決して無駄じゃない

ところで、ここ1年頭から記事を書き続けてきました。時々、昔のくだらなすぎる記事は消しています。

来年以降も当然記事を書き続けるので本当に残したい記事を残すのですが、その記事はWeb上に眠らせておくのも勿体無いし、自分がこれまで築き上げてきた集大成とも言えるので、それらはいずれ物理的に形にしたいと思うわけです。

書いたものは(はてなブログが落ちない限り)残り続けるわけで決して無駄じゃないのはわかりますが、後々昔の記事をいちいち見返すのも手間なので。どこかで時間を作ってやろう。年末~年明けでもいいかな。

そこで、下記サービスを使って製本することが出来ます。

www.mybooks.jp

ある程度の規模になったら本の厚さも考えて一度製本してしまうのも選択肢ですね。

 

ということで適度に体力づくりもしつつ、来年は更に飛躍する1年にしよう。

俺は資産1兆円の植物人間な人生よりも、資産100万円でも健康な人生を選ぶ。

マインドセット

 

タイトルの意味

別に資産100万円しかなくても満足って言いたいわけではありません(笑)もちろん金は必要ですが、それ以上に健康さが大事ということが言いたいです。健康体ならいくらでも稼げるので。

筆者は結構な数のサプリを買って食事もなるべく決めたものを食っています。月1~2万円くらいはサプリ代で平均的に消えていきます。サプリとかそんなにたくさん買って高いでしょ?なんて言われるかもしれませんが、今は高く感じても後々になれば気にならなくなります。寧ろ不健康で医者にかかり続けるほうがどれだけ医療費で家計を圧迫することか。

将来的に、というより老後はあきらかに体力が衰えて怪我をしやすく病気になりやすくなるのに、なぜ若いうちに対策してる人が少ないか、理解に苦しみます。

別にサプリ買わなくていいんじゃん?と言う人もいますが、アルギニンやビタミン○○などサプリがないと不足しがちな栄養素もあるのも(おそらく)知らず、しかもそういう人に限って普段の食事がデタラメだったり。笑わせるなと。

 

健康は長期的に見れば得だらけ。

 これを「それは知っている」といえる人はほとんどいないはず。なぜなら大抵はそういう行動をしていないので...身体を見ればそんな人は。面倒だけど、絶対若いうちから対策した方が良い。ずっと怠けてた人が老後から対策する余裕ないと思いますし。

健康でいることに普段は得に思わないかもしれませんが、病気になれば嫌でも気づきます。いや、高熱を出して身動き取れなくなった経験でも同様。辛い。苦しい。社会人なら働けないうちは金が入らない(有給使えば一時しのぎは出来る)。

金が入らないどころか医療費で金は出ていくばかりで、損しかしてない。 それがなければ痛い思いも辛い思いもしなくて済むしなにより金が浮くので、健康的でいることによって結果的に得しかしてません。

 

日本はサプリ後進国

発展途上国と言ってもいいかもしれません。国産どころか海外の(主にアメリカ製)サプリなんて持ってる人はレアでしょう。統計を見たわけではありませんが、おそらく人口の1割未満な気がします。1割と言っても、日本の総人口1億2千万(2016/12現在)、その1/10だから1,200万人。成人は1億人、この1/10なら1,000万。キリの良い数字ですが、なんだかこれでも実感より結構多く感じますね?正しい知識を持ってる人がこんなに多いとはとても思えません...

それと比較してアメリカはサプリ大国ですが、これは文化の違いが大きそうです。

news.livedoor.com

確かに、病気になったら医者に行こう、ではないアメリカ的な考えなら当然かもしれませんね。医療費がシャレになりません。

そして含有量も違います。成分表記があるのは当然として、具体的な量を計算、比較してみれば一目瞭然です。やってみましょう。

国内で売られている某サプリは商品1つ約250円で1回15mg, 計20粒の亜鉛が入っています。これをすべて摂れば、亜鉛は計15mg x 20 + 300摂取できる。

それに対して例えば筆者が以前買ったCountry LifeのCalcium Magnesium Zincは割引なし(iHerbなら割引されることが多い)で約2400円で1回3個分で50mg, 3計250 Tabletsなので 50mg x 250 / 3 ≒ 4166mg.

個数を合わせて比較すると、250 / 20 = 12.5だから、某サプリのほうは250 x 12.5 = 3700円にもなります!海外製に比べて1000円以上高い。。。

しかも後者の海外製は名前の通りカルシウム、マグネシウムも一緒に入っており、こちらはそれぞれ1回につき1000mg, 500mgも摂れてしまいます。ついでにL-グルタミン酸100mgも。圧倒的に破格だと思いませんか。

というわけで、サプリ先進国なアメリカから仕入れるのはおすすめです。サプリの種類も含有量も間違いなく勝っている。種類が多すぎて、逆に何買ったらいいか分からない、となるかもしれませんが(笑)

毎日摂取するとなるとそれなりに値段も張るし、別にサプリを買ってなくても健康な人はいると思いますが、そういう人は生活習慣が優れているので、そんな人達の食事を一朝一夕で素人が真似できるものではないと思います。仮にその人が毎日野菜を○○g食ってるし筋トレストレッチしてる、酒は週1回限り、睡眠時間は6時間確保していると言われたとして、真似できるでしょうか。

 

老後はロボットがいれば安心か?

安心ではないんじゃないでしょうか?

ロボットが今後増えてくれば直接動けなくても日常生活くらいはなんとかなるかもしれませんが、それって俺にとっては幸せではないです。

仮に資産が1兆円超えしていようが、病院でずっと何本もの管を刺されて身動きすら取れないまま何年も生きたとしても、それは生物学上は「生きている」ですが筆者にとっては「死んでいる」です。希望を持てないまま過ごすのなんてそんなもので、価値が無いと思っています。所詮は個人的な意見ですが。だから、自分がそうなったら延命はやらないでくれと家族に言っています。そもそも延命は無料ではないので、やりたくても出来ない可能性も高いのですが。

「ロボットがいてくれたほうが凄く助かる」は良いとしても、「ロボットがいないと何も出来ない」は違う。それだとまさにのび太です。ドラえもんも言ってるでしょう、日本中がのび太だらけになったら国が滅ぶと(笑)

 

健康は金で買う

タイトルと矛盾しそうですが、つまり金は健康のために使うのがベストと言いたいです。まず健康第一、余裕があればその他に、という優先順位です。カネを使わなくても運動は自力でできますが金をかけたほうが手っ取り早く肉体強化出来るし、知識を仕入れるには本を読む、プロと知り合うなどする必要があるのでただでなんでも出来るとは思いません。生きるのにも金がかかりますね。。。

 

まとめると

日常的に思っていることをざざっとまとめました。一昨年までは堕落した生活を送ってきたからこそ、心機一転、これからは健やかに生きようと思ってこんな生意気なことを書いています。でも、この考え方は中々理解されないんだろうなあ(;´∀`)少なくとも、国内でずっと右へ倣えしていたら絶対にこうはなりません(確信)筆者が偉そうに評価できることではないですが、周りに合わせることに一生懸命な人を遠目で見れるようになったら、なんとなく及第点な気がします。

ところで、タイトルは漫画「沈黙の艦隊」の海江田四郎のセリフ

牢獄の庭を歩く自由より 嵐の海だがどこまでも泳げる自由を
私なら選ぶ!!

をもじりました。元ネタはかつてない名言と思ったので、未だにお気に入りです(笑)この考え方が正しいかどうかはともかく、保守的な人間には一生言えないセリフです。これからリスキーな生き方をしていく自分にとって、何より励みになるし、大事なことだから心に留めておく必要があると思います。

というわけで今年も無事生き抜きます。

AWSでのサービス制作(申し込みフォーム) - AWS Lambda/API Gateway/S3/DynamoDB/SES/CloudFront/ACM/Route 53

AWS Python HTML JavaScript

 

f:id:notwo:20161222223656p:plain

概要

最初に紹介した記事

notwodaily.hatenablog.com

および、前回作ったテストアプリ

notwodaily.hatenablog.com

から一転して、本命のアプリを制作します。ここまで得た知識+αを総動員してその集大成を見せるときが来ました。大まかな図はdraw.ioで作りました。

 

IAM Role準備

ユーザー作成

ここでは開発者ということでdeveloperとでもします。

以下でdevelopersグループを作成してそこにユーザを紐付けて、作成

作成が終わったら、実際にS3やDynamoDBで操作ができるか、適当に触って確認してみましょう。

 

グループ作成

ダイアログでグループ名をdevelopersにします。Roleは

  • IAMFullAccess
  • AWSCertificateManagerFullAccess
  • AmazonS3FullAccess
  • CloudFrontFullAccess
  • AmazonDynamoDBFullAccess
  • AWSLambdaFullAccess
  • AmazonAPIGatewayAdministrator
  • AWSKeyManagementServicePowerUser
  • AmazonRoute53FullAccess
  • AmazonRoute53DomainsFullAccess

にチェックを入れて確認。最大10個までしか作れないので、一度設定して不要になったら権限を一部放棄しても問題ないです。アタッチ、デタッチは何度でも出来ますので。

これでもまだ権限的に相当強いですが、細かく設定するのが単に面倒なだけで。。本来は必要最小限にとどめたほうが良いのは言うまでもないです。

 

IAM Roleでログイン

上記まではroot相当の権限で操作していたはずですので、一旦ログアウトして、さっき作ったroleでログインし直します。

 

独自ドメイン取得/SSL準備

やり方は少し長くなるので別記事にまとめました。

notwodaily.hatenablog.com

 

API形だけ作成

Lambda関数作成に必要です。先にAPI名だけ用意します。

ここでのAPI名は制作するアプリ名としてちゃんとしたものをつけてあげましょう。

 

実データ配置(S3)

S3に必要なファイルを配置します。具体的にはLambda関数用のファイル(.py)をZIPで、他HTML/CSS/JavaScript/Image/Text(mail)をそれぞれ配置します。今回はこの方法で行きます。

その他、Lambda関数用ファイル(.py)と依存ライブラリをZIPにして別途LambdaへアップロードしてS3へPUTする方法もあります。

それについては

dev.classmethod.jp

の解説を見れば分かりやすいです。

 

バケットを作成してLambda関数用ZIPファイルを配備し、プロパティを覗いた例です。

f:id:notwo:20161127200352p:plain

S3へは直接アクセスさせずにCloudFrontを介する構成にしているので、ここでは公開後にプロパティのURLを叩いてもAccess Deniedエラーになります。

 

S3へのPOSTアクセス

これは禁止されているっぽく、実際にアクセスしてもMethodNotAllowedエラーが出ます。CORS設定してようが拒否られます。

stackoverflow.com

なのでPOSTしたいけどどうしてもS3のオブジェクトが欲しいって時はapi gateway経由で取得すると良い。

 

キャッシュコントロール

デフォルトでは設定がありませんがキャッシュが効いており、JSなど更新しても反映されるまでに時間がかかりすぎます。invalidationというのを使うらしい...

CloudFrontのDistributionsから該当のdistributionを選び、Invalidationsタブをクリックして、Create Invalidation

ここでパスを設定すればまとめてキャッシュを削除できます。毎回ここで消さないといけないのが面倒っちゃ面倒ですが。。

よく編集するJS, HTML, CSSは頻繁にアップすることになるので、まとめて

  /js/*
  /css/*
  /*.html

などして消せるようにしておくと楽です。

 

テーブル用意

DynamoDBにテーブルを用意します。データ構造を設計時に考えておくべきです。

セッションの永続化のためのテーブルを用意することも出来ますが、今回は単純な申込みフォームを用意するだけなので手を出しません。

noSQLなので複雑なオブジェクトも保存可能。だからこそあまり自由に作りすぎて後で階層が深すぎて取り出しに苦労する、なんてマヌケなことにならないように注意。

 

 

Lambda関数作成

必要なLambda関数を作成してAPIから叩けるようにします。

早速作ります。blueprintはBlank Functionを選択して最低限作ってもいいですが予めS3やDynamoDBを使うとわかっているので、それ用のblueprintを利用して書き換えたほうが楽でしょう。

runtimeをPython2.7に変更し、filterにとdynamodbと入れて出て来るmicroservice-http-endpoint-pythonを選択してNext

 

Configure triggers

API name:事前に作成したAPIの名前

Deployment stage:prod(最初のデプロイでは他にステージがないので選択出来ません)

Security:Open with access key(keyは未設定ですが、後でAPIコンソールで編集します)

 

Configure function

Name:実際に作るアプリに関する分かりやすい、愛のある名前をつけてあげましょう。

Description:どんな機能なのかを書いたらいいと思います。

Runtime:Python2.7

 

 

Lambda function code

Code entry type:Upload a file from Amazon S3

S3 link URL:別でS3に配備したLambda関数用ファイル(.py)のパス(https://s3.amazonaws.com/作成したバケット名/ファイル名)

 

Lambda function handler and role

HandlerAPIからLambda関数がコールされたときのエントリポイント。これの名前.pyがLambda関数のファイル名です。デフォルトのままでもいいです。こだわりがなければね。

Role:Create new role from template(s)

Role name:必要なroleは勝手に追加されていくので、ここではfunction名を決めるときの様に愛のある名前を!

 

HandlerはPythonのコード上ではデフォルトで

def lambda_handler(event, context):

となっている部分のことです。

ほかはデフォルトのままで。

Lambda関数はアップロード後にLambdaコンソール(画面)から修正できます。

 

Lambda関数作成後にエラーが出たら?

Create Function後は何かエラーが有る場合は下画像のようなwarningが出ます。 

f:id:notwo:20161127124957p:plain

Trigger作成に失敗しましたと言っています。Lambda関数作成時にTriggerにAPI Gatewayを指定したうえで、TriggerにまだAPIにリソースを追加していないからですね。メソッドをAPIのリソース直下に作成まで終わったらLambdaコンソール上でTriggerタブ→Add triggerからAPI Gatewayを追加すればOKです。さっきと同じ設定でいきましょう。すると作成したリソース直下に新たにANYメソッドが出来ているはずです。

 

IAM role違いによるエラー!?

後でAPI Gatewayを編集していくとわかりますが、Lambdaでは独自のIAMロールを用いるので、api gateway経由でPOSTすると

The role defined for the function cannot be assumed by Lambda

とか怒られるので、Lambda側で開発に用いているIAMユーザを許可させてやる必要があります。そこで、

dev.classmethod.jp

リソースベースのポリシー

の部分から下に倣うと出来ます。一緒にやってしまおう。

 

API作成

今回は予約フォームのために必要なAPIを準備します。

API名だけは先に用意してあるので、その中身を埋める作業です。まずルートリソース直下にリソースを作成します。次にそのリソース直下にメソッドを作成します。メソッドはLambda関数のTrigger設定時にANYが作成されているはずです。が、これは使いません。自分で新たにGETなりPOSTなり作成します。

 

API Key設定

dev.classmethod.jp

の通りの設定で大丈夫です(一部UIが異なりますが)。

ただし

docs.aws.amazon.com

にある通り、一度デプロイした後に出来るので、ここではまだ作らず先にデプロイまで進めたほうがいいですね。先に作成だけして無効にしておいてもいいですが。

 

CORS設定

後述するformとの連携のため(主にjqueryAPIの連携)、APIのCORS設定は必須です。

CORS設定は

qiita.com

とかを参考に。

はじめにAPIを作る時にCORS設定を同時に有効にしていなくても、後でリソースを選択してアクション→CORSの有効化、とすれば設定できます。しかもこちらならヘッダ情報も自動でつけてくれて大変便利!

統合リクエストのテンプレートマッピングも忘れずに。ここでどういう形式でLambdaにデータを渡すかを定義します。これがないとせっかくAjaxから渡したデータがlambda_handlerのeventに空で渡ってしまいます。

テンプレートマッピング公式ドキュメントを参考に。

 

フォーム作成

S3の実データ配置の一部ではありますが、制作するフォームについて補足します。

フォームの作りは

qiita.com

を参考にしました。API Gatewayへのアクセスは、すべてAjaxで行います。事前にgateway側でCORS設定をしておき、テンプレートマッピングも用意する必要があります。S3の項目で書きましたが、formを作成したとしてもmethodはgetのみです。で、

~~.on('click', function() {
  location.href="次画面のリンク";
}

みたいなことやれば出来ますが、かなりゴリ押し感もしますね。S3がただのストレージなので仕方ないといえば仕方ないのですが。

 

 

メール送信

SESの設定をします。それ用にドメインを持つ必要がありますが、

この辺は下記記事に別途まとめました。

notwodaily.hatenablog.com

 

ここまでで一通り完成です。とは言え、勿論まだ改善の余地だらけだし、正直これで無料期間終了したら月いくらになるのか計算もしてません。セキュリティ的にここがまずい、とか探せば出そうなのでこれを真似して作るなら注意。

 

作ってみてわかったこと

  1. とてもweb初心者には無理
  2. 言語そのものよりもインフラ、サーバ構築の知識が必要
  3. これ専用の学習コストは相当高い。Lambdaは利用できる言語にも縛られるので、すべてをAWS構築にする必要はないかもしれない。
  4. 記事を書きながらだと理解が速い→おそらく正確に書くことが求められるから分からないところは調べざるを得なくなるので。

といった具合です。独自の用語を覚えたりどれとどれが組み合わせられるのか、その仕様までまず理解するところから始まります。何もwebを知らない初心者からすればただの迷宮です。

初年度無料は確かに魅力としてはでかいしスペックをほとんど気にせず使えるのはありがたいんですが、多機能なサービスには複雑さが伴うことは避けられないといえます。無理してこれを使うくらいなら、規模が小さいうちはサーバも全部自前で用意してCentOS7(本記事執筆時点での最新Ver)を入れるとか得意な言語によっては無料のサービス(Rubyが出来るならHeroku)があるのでそれをまず試してみるのもあり。

 

筆者自身この日までAWSド初心者でしたが、これで大凡の仕組みというか制作のキモくらいはわかったつもりです。これで堂々とAWS使えますって言える(;´∀`)