信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    経験が浅い方にお勧めの本

    お久しぶりです。JSです。4月に新入社員が入りましたので、経験が浅い方にお勧めの本を紹介したいと思います。ここで紹介する本は基本的に、私が就職してから1~3年以内に読んだ本になります。有名な本が多いので、既に読んだことがある方もいらしゃっるかもしれません。・Webを支える技術 -HTTP、URI、HTML、そしてRESThttps://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042URIとHTTPの基本について書かれており、ステータスコードについても詳細に書かれており、業務に大変役立つと思います。読みやすい本なので、経験が浅い方でも充分理解できると思います。・プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E7%9F%A2%E6%B2%A2%E4%B9%85%E9%9B%84/dp/4822283151私は学生時代プログラミング未経験の状態で、新卒の受託開発会社に入社しました。入社前にこの本を渡され、読んでほしいと言われた本なので紹介します。内容は基本情報技術者試験にでそうな内容が中心なので、既に資格を取得済みの方や学生時代に専門の方は読む必要はないと思います。・リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニックhttps://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655読みやすいソースの書き方が書いてあります。自分がソースを書く際に参考になり、ソースレビューする際に役立ちます。・良いコードを書く技術 -読みやすく保守しやすいプログラミング作法https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E6%8A%80%E8%A1%93-%EF%BC%8D%E8%AA%AD%E3%81%BF%E3%82%84%E3%81%99%E3%81%8F%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E4%BD%9C%E6%B3%95-WEB-DB-PRESS-plus/dp/4774145963こちらも基本的にリーダブルコードと同じで、読みやすいソースの書き方が書いてあります。リーダブルコードも分かりやすいと思いますが、こちらはそれより更に分かりやすいです。・体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8/dp/4797393165私は第1版しか持っておりませんが、webの脆弱性の紹介とその対策が書かれています。対策は様々な種類のプログラミング言語で書かれているので、役立つと思います。経験が浅い方には少し難しい内容もありますが、分かりやすい本だと思います。・新装版 達人プログラマー 職人から名匠への道https://www.amazon.co.jp/%E6%96%B0%E8%A3%85%E7%89%88-%E9%81%94%E4%BA%BA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-%E8%81%B7%E4%BA%BA%E3%81%8B%E3%82%89%E5%90%8D%E5%8C%A0%E3%81%B8%E3%81%AE%E9%81%93-Andrew-Hunt/dp/427421933Xこちらも新卒の会社で入社前に渡され、読んでほしいと言われた本なので紹介します。プログラマ必読の本らしいですが、新装版ではないのを初めて読んだ時には全く理解できない内容も結構ありました。そこは飛ばして、数年後に読むと良いと思います。以上になります。興味がある方は是非読んでみて下さい。
  • テクログ

    Lambdaを試してみました

    お久しぶりです。在宅勤務になり、時間に余裕ができたのでAWSを色々試していました。今回はLambdaについて紹介したいと思います。処理の内容はS3のimagesにjpgの画像をアップすると、別のバケットにリサイズされた画像がアップされ、画像のアップロードパスと登録日時がdynamoDBに登録されます。まず、Lambda上でPillowを使えるようにするために、EC2で下記を実行しました。sudo yum -y install gcc openssl-devel bzip2-devel libffi-devel wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz tar xzf Python-3.8.1.tgz cd Python-3.8.1 sudo ./configure --enable-optimizations sudo make altinstall pip3.8 install pillow -t . 上記で作成されたPILとPillow.libsとPillow-7.1.2.dist-infoとlambda_function.pyをzipで固めてアップロードします。次にLambdaのトリガーの設定ですが、S3を選択し、下記内容を入力し、追加をクリックします。バケット sample イベントタイプ すべてのオブジェクト作成イベント プレフィックス-オプション images/ サフィックス-オプション .jpg トリガーの有効化 チェック 次にdynamoDBで画像管理テーブルとautoincrementがないためidを管理するテーブルを作成します。テーブルを作成後、idsテーブルにtable_nameがs3_images、idが0を登録します。・s3_images id 主キー   数値型 upload_path 文字列型 created_at  文字列型 ・ids table_name 主キー 文字列型 id                数値型 次にS3で下記の二つのバケットを作成します。sample sample-resize 最後にlambda_function.pyは下記の内容です。import boto3 import os import sys import uuid from urllib.parse import unquote_plus from PIL import Image import PIL.Image import datetime s3_client = boto3.client('s3') dynamodb = boto3.resource('dynamodb') def resize_image(image_path, resized_path):   with Image.open(image_path) as image:     image.thumbnail(tuple(x / 2 for x in image.size))     image.save(resized_path) def get_id(table_name):   table = dynamodb.Table('ids')   data = table.update_item(     Key = {       'table_name': table_name     },     UpdateExpression = 'ADD id :id_val',     ExpressionAttributeValues = {       ':id_val': 1     },     ReturnValues = "UPDATED_NEW"   )       res = table.get_item(     Key = {       'table_name': table_name     }   )   return res['Item']['id'] def insert_dynamodb(id, upload_path):   table= dynamodb.Table('s3_images')   now = datetime.datetime.now()   table.put_item(     Item = {       'id': id,       'upload_path': upload_path,       'created_at': now.strftime("%Y-%m-%d %H:%M:%S")     }   ) def lambda_handler(event, context):   for record in event['Records']:     bucket = record['s3']['bucket']['name']     key = unquote_plus(record['s3']['object']['key'])     tmpkey = key.replace('/', '')     download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)     upload_path = '/tmp/resized-{}'.format(tmpkey)     s3_client.download_file(bucket, key, download_path)     resize_image(download_path, upload_path)     s3_client.upload_file(upload_path, '{}-resized'.format(bucket), key)           id = get_id('s3_images')     insert_dynamodb(id, upload_path) これでS3のsampleバケットのimagesにjpgの画像をアップすると、sample-resizeバケットにリサイズされた画像がアップされます。Lambdaの設定は一部割愛しましたが、以上となります。
  • テクログ

    LINE Notify APIを試してみました

    初めまして。1月からお世話になっておりますJGです。最近LINE Notify APIを使い、毎朝自分のLINEに通知させました。それについて触れたいと思います。下記URLからLineIDでログインし、必要事項を入力します。その後、アクセストークン発行をクリックし、発行されたトークンをコピーして保存してください。https://notify-bot.line.me/ja/天気予報を取得する処理は下記のlivedoorを使用しました。http://weather.livedoor.com/weather_hacks/webservicePHPで処理を書き、作成したものをHerokuに上げ、毎朝通知するようにHerokuのスケジューラを設定しました。下記ソースのTOKENに、LINEのアクセストークンを指定すれば動きます。自分の住んでいる東京と出身地の神奈川の天気を通知するために、$city_listを下記のように指定しています。興味がある方は、是非試してみてください。<?php define('TOKEN', ''); define('MESSAGE_NOTIFY_API_URL', 'https://notify-api.line.me/api/notify'); define('WEATHER_API_URL', 'http://weather.livedoor.com/forecast/webservice/json/v1?city='); $city_list = [   130010,   140010,   140020 ]; foreach ($city_list as $city) {   //天気予報を取得   $weather_data = get_weather_data($city);   if (empty($weather_data)) {     $msg = "天気予報取得失敗です。";   } else {     //通知メッセージを作成     $msg = create_message($weather_data);   }   //通知   send_msg($msg); }   function get_weather_data($city) {   $ch = curl_init();   curl_setopt($ch, CURLOPT_URL, WEATHER_API_URL.$city);   curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   $response = curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   $weather_data = json_decode($response, true);   curl_close($ch);   return $weather_data; } function create_message($arr) {   $msg = '';   $title = $arr['title'] ?? '';   $msg .= $title."\n\n";   for ($i = 0; $i < 2; $i++) {     $date = $arr['forecasts'][$i]['date'] ?? '';     $date_label = $arr['forecasts'][$i]['dateLabel'] ?? '';     $weather = $arr['forecasts'][$i]['image']['title'] ?? '';     $min = $arr['forecasts'][$i]['temperature']['min']['celsius'] ?? '';     $max = $arr['forecasts'][$i]['temperature']['max']['celsius'] ?? '';     $msg .= $date_label.'('.$date.')'."\n";     $msg .= '天気: '.$weather."\n";     $msg .= '最高気温: '.$max."\n";     $msg .= '最低気温: '.$min;     if ($i < 1) {       $msg .= "\n\n";     }   }   return $msg; } function send_msg($msg) {   $post_data = http_build_query(['message' => $msg]);   $ch = curl_init(MESSAGE_NOTIFY_API_URL);   curl_setopt($ch, CURLOPT_POST, true);   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);   curl_setopt($ch, CURLOPT_HTTPHEADER, [     'Content-Type: application/x-www-form-urlencoded',     'Authorization: Bearer '.TOKEN,     'Content-Length: '.strlen($post_data)   ]);   curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   curl_close($ch);   return true; }