2019|sitateru tech blog

sitateru tech blog

シタテルの技術やエンジニアの取り組みを紹介するテックブログです。

2019年2月21日木曜日

Alexaスキルを作ろう - 第2回

こんにちは。シタテルでエンジニアをしている熊谷です。

SPECというサービスのバックエンド開発などを行っています。

今回は前回の続きで、Alexaスキルの作成について書いていきます。


今回は、前回作成したスキルから呼び出されるLambdaを作成します。

まずAWSコンソールにログインして、Lambda - 関数の作成に行きます。

そこから「一から作成」、「設計図」などが選べます。

「設計図」でalexaを検索すると、
それぞれのスキルタイプに合わせたsdkが用意されています。
使用したいタイプのsdkがある場合は、それを使用しましょう。

今回はとても単純なスキルを作成したので、「一から作成」を選択します。
いろいろな言語が選べますが、今回はNode.jsで作成しました。

関数を作成すると、シンプルなレスポンスを返す関数が書かれているので、その中身を変更します。

今回作成したスキルは、「言葉を逆さまにする」です。
シンプル...!

コードを記述します。

exports.handler = async (event) => {
  const word = event.request.intent.slots.word.value;
  const response = {
    "version": "1.0",
    "response": {
      "outputSpeech": {
        "type": "PlainText",
        "text": word.split('').reverse().join('')
      },
      "shouldEndSession": false
    },
    "sessionAttributes": {}
  };
  return response;
};

こんな感じになりました。

responseの形式について、詳しくは応答の形式を参考にしてください。
「intent.slots.word」の部分の「word」は前回設定した「スロット名」に対応します。

次にこのLambdaを呼び出すトリガーを設定します。

「トリガーの追加」から、「Alexa Skills Kit」を選択して、スキルID(alexa developer consoleを参照)を設定します。

alexa developer consoleでテストしてみましょう。

前回、スキルの呼び出し名とサンプル発話を設定しました。

テスト画面で、

「<スキルの呼び出し名>を開いて、<サンプル発話>おはよう」と入力すると‥


ちゃんと逆さまにして返してくれましたね!

シンプルなスキルですが動くと面白いと思います。


今回はここまでにします。

次回は実機でのテストとスキルの公開について書ければと思います。

ありがとうございました!

, , , , , ,

2019年2月18日月曜日

Google Cloud Functionsで画像を自動リサイズする

Google Cloud Functions

こんにちは、DevOpsチームの甲斐です。
今回は、Google Cloud Functions(以下、GCF)で画像を自動リサイズする手順を紹介したいと思います。

GCFとはAWSでいうところのLambdaです。いわゆる、サーバーレスってやつですね。
最近はGCPを触ることが多いのですが、先日GCP上のWordPressのアップロード画像をリサイズするために、
GCFを使って自動的に画像をリサイズするようにしました。
AWSのLambdaも触ったことありますが、GCFのほうが手間が軽い印象を持ちました。
まだGCFをお使いになったことがない方は、ぜひご参考にしていただければと思います。

前準備

GCFを使う上で必要な環境は以下のとおりです。

  • GCPプロジェクトの作成
  • 課金の有効化
  • Cloud Functions APIの有効化
  • Cloud SDKのインストール

詳細は、以下に書かれていますので、こちらをご参照ください。
https://cloud.google.com/functions/docs/quickstart-console?hl=ja

今回の仕様

今回の仕様は以下のとおりです。

  • Google Cloud Storage(以下、GCS)の当該バケットのuploadsディレクトリにアップロードされた画像を自動的にリサイズ
  • リサイズする画像フォーマットはimage/jpegのみ
  • オリジナル画像は".orig"拡張子をつけてバックアップ
  • リサイズされた画像はオリジナルの画像と同じ名前で上書き

実装

それでは、早速実装の手順を紹介していきたいと思います。
今回はNode.js v8で書きました。それ以外にもNode.js v6, Python(beta), Go(beta)が使えます。

1. 作業ディレクトリの作成

mkdir -p gcf/convert_image
cd !$

2. npm init

npm init

3. 必要なパッケージをインストール

今回は、@google-cloud/storage(GCS関連パッケージ)とgm(画像編集パッケージ)をインストールします。

npm install @google-cloud/storage gm --save

4. コーディング

コードは以下のとおりです。
最初に少しハマったところとしては、リサイズした画像でオリジナル画像を上書きすると
再びイベントが発火されるので無限ループに陥ってしまったことです。
対策としてメタデータにコンバート済みである旨を記述し、処理の最初にメタデータをチェックすることで判断するようにしました。

'use strict';

const gm = require('gm').subClass({imageMagick: true});
const fs = require('fs');
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();

exports.convertImage = data => {
  if (data.resourceState === 'not_exists') {
    console.log(`Skip because not_exists`);
    return;
  } else if (!data.name) {
    console.log(`Skip because no name`);
    return;
  } else if (!data.name.startsWith('uploads')) {
    console.log(`Skip because not uploads: ${data.name}`);
    return;
  } else if (data.name.endsWith('.orig')) {
    console.log(`Skip because original image: ${data.name}`);
    return;
  } else if (data.contentType !== 'image/jpeg') {
    console.log(`Skip because not image/jpeg: ${data.contentType}`);
    return;
  }

  const file = storage.bucket(data.bucket).file(data.name);
  console.log(`Uploaded image : ${file.name}`);

  const tempLocalPath = `/tmp/${path.parse(file.name).base}`;
  return file
    .getMetadata()
    .then(data => {
      console.log('[Check already converted or not]');
      const metadata = data[0];
      if (metadata.metadata && metadata.metadata.isConverted) {
        console.log(`${file.name} is already converted.`);
        Promise.reject();
      } else {
        console.log(`${file.name} is not yet converted.`);
        Promise.resolve();
      }
    })
    .catch(err => {return;})
    .then(() => {
      console.log('[Download file]');
      return file
        .download({destination: tempLocalPath})
        .catch(err => {
          console.error('Failed to download file.', err);
          return Promise.reject(err);
        });
    })
    .then(() => {
      console.log('[Backup a image]');
      return file.copy(`${file.name}.orig`);
    })
    .then(() => {
      console.log('[Convert a image]');
      return new Promise((resolve, reject) => {
        gm(tempLocalPath)
          .samplingFactor(2, 2)
          .strip()
          .quality(85)
          .interlace('Line')
          .colorspace('sRGB')
          .write(tempLocalPath, (err, stdout) => {
            if (err) {
              console.error('Failed to convert image.', err);
              reject(err);
            } else {
              resolve(stdout);
            }
          });
      });
    })
    .then(() => {
      console.log('[Upload a converted image]');
      const options = {
        destination: file,
        resumable: false,
        metadata: {
          metadata: {
            isConverted: true
          }
        }
      };
      return file.bucket
        .upload(tempLocalPath, options)
        .catch(err => {
          console.error('Failed to upload a converted image.', err);
          return Promise.reject(err);
        });
    })
    .then(() => {
      console.log('[Remove a temporary file]');
      return new Promise((resolve, reject) => {
        fs.unlink(tempLocalPath, err => {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        });
      });
    });
};

5. デプロイ

デプロイは以下のようにします。
今回の場合、runtimeはnodejs8になります。また、メモリやタイムアウトもオプションで設定できます。

gcloud functions deploy <name> --entry-point <entry-point> --runtime <runtime> --trigger-bucket <trigger-bucket> --region <region> [--memory <memory> --timeout <timeout>]

デプロイが完了したら、以下のコマンドで正常に登録されたことを確認します。

gcloud functions list

6. テスト

サンプル画像を当該バケットにアップロードし、正常にリサイズされることを確認します。

% gsutil cp sample.jpg gs://<bucket>/uploads/
% gsutil ls -l "gs://<bucket>/uploads/sample.jpg*"
   2601078  2019-02-14T02:37:45Z  gs://<bucket>/uploads/sample.jpg
  14583723  2019-02-14T02:37:43Z  gs://<bucket>/uploads/sample.jpg.orig
TOTAL: 2 objects, 17184801 bytes (16.39 MiB)

まとめ

簡単ですが、GCFで画像をリサイズする実装手順を紹介しました。
今回はGCSをトリガーにしていましたが、それ以外にもGoogle Cloud Pub/SubやHTTPリクエストをトリガーにすることも出来ます。
GCFの詳細については本家ドキュメントをご参照ください。

https://cloud.google.com/functions/docs/?hl=en

また、以下のGitリポジトリにGCFのサンプルプログラムがありますので参考にしてみてください。

https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/functions

, , , , , , ,

2019年2月12日火曜日

半分解展研究所レポート(2019/01/18)















こんにちは、エンジニアの鶴巻です。
1月18-19日に開催された半分解展研究所のレポートを書きたいと思います。

半分解展研究所とは?

衣服標本家の長谷川彰良さんの展示会です。

100年〜200年前の衣服を半分・分解したものが「標本」として展示されています。

全ての展示品は、分解したパーツからパターンを抜き取って
縫製された試着サンプルが用意されています。

そのため、200年前の衣服を実際に着て体験することができます。

ゲストトークショーや、長谷川さんによるZOZOオーダーメイドスーツのデモもあり、情報量が盛りだくさんのイベントでした。

展示品

展示品のひとつひとつに、解説とその服にまつわる長谷川さんのエピソードが丁寧に綴られていました。洋服作りについて、ど素人な私ですが、弊社の衣服づくりのコンシェルジュである宇藤さんが一緒だったので、いろいろと教えてもらいながら展示品を楽しむことができました。

ツナギになるストームコート

こちらはストームコートの展示の説明文です。暗い写真で申し訳ないです。
説明文に掲載されている写真がストームコートで、第2次世界大戦下のイギリス軍特報バイク部隊のユニフォームとして採用されたコートです。
写真では膝丈のツナギに見えますが、下の写真がストームコートの試着サンプルです。

このロングコートが、ボタンのはめ方でツナギになり、快適にバイクを跨ぐことができるコートに変形するようです。機能性の良さにびっくりしました。

ストームコートについての長谷川さんのブログ記事はこちら

背筋が自然と伸びるフランス革命の市民の服

フランス革命を起こした市民たちの服「カルマニョール」を試着してみました。
着用前は、腕が後ろの方についていて、背中が窮屈そう、という印象。
実際に試着すると、かなりの猫背の私が自然と背中がシャキッとなりました。

とても感動したので、この日に私が着ていたコートとの比較写真を載せておきます。

わざとらしく見えるかもしれませんが、どちらも自然な姿勢です。

カルマニョールを着用した左の写真は顎が上を向いており、背筋が伸びた姿勢。
それに対し、自分のコートを着用している右の写真は顎が下を向いて、猫背に。

着用した服によって、背筋の伸ばし方が自然に変わるというのは、目からウロコな体験でした。

デモ:ZOZOオーダースーツから視る「着心地と運動量」

ZOZOオーダースーツをターゲットに、着心地と運動量を着眼点とした長谷川さんの解説とデモがありました。noteにも詳しく書かれています。

「わきの下がピタリとはまっている」ことは、腕を動かす時の着心地の良さが劇的に違うことを長谷川さんはnoteでも今回のイベントでも強く語っています。「靴紐を結ぶ動作」のデモがありましたが、「靴紐を結ぶ動作」が服に高い負荷をかけることを初めて意識しました。また、「わきの下がはまる」服として、100年前のブルックスブラザーズのモーニングのデモもありました。100年前でも人間の体は同じなので、「着心地の良さ」の原理は普遍的であることを知りました。

「わきの下がはまる」を実現するためには正確な採寸と緻密なパターン設計が必要なのだそうです。ZOZOオーダースーツは、オーダーメイドならではのポイントである「わきの下がはまる」ジャケットはつくれるのでしょうか。ぜひnoteを読んでみてください。

ZOZOSUITによって誰もが自分で「正確な採寸」ができ、それにピタリと合わせた衣服の生産ラインが確立すれば、オーダーメイドと量産というアンビバレントな衣服の製造が両立し革命的だ、とワクワクしました。(長谷川さんの展示品の説明文より、欅坂46好きが垣間見えた気がしたので、欅坂46の楽曲である「アンビバレント」という表現を使ってみました)

トークショー:「 技術職が伝えるのは 」

縫製、パタンナー、デザイナーのそれぞれのプロの技術を持つ3人の方のトークショーもありました。テーマの通り、専門性に特化した「情報発信」をしていることが登壇者の共通点です。

「なぜ発信するのか」を切り口に、モデレーターの長谷川さんがどんどん深掘りかつ直球の質問を投げかけます。登壇者の方がアドリブで答えていく緊張感とゆるさの混じったトークショーでした。

登壇者についてはこちら

「なぜまっすぐに縫う必要があるのか」「パタンナーのこだわりを知ってほしい」「技術は全てツールと考えている」の3つの言葉が特に印象に残っているので、それについて触れたいと思います。

なぜまっすぐに縫う必要があるのか

これは、縫製のプロである風間さんの「プロの定義は、まっすぐに縫うこと」という言葉への問いです。これに対して「まっすぐに縫うということは、パターン通りであるということ」というパタンナーの萩山さんの回答が印象に残っています。

パタンナーはデザイナーが意図したものを再現するためにパターンを作る。縫製者はパタンナーの意図を再現するためにまっすぐに縫う。デザイナーが目指すものを作り出すためには、パタンナーさんと縫製者の方のプロとしての技術が必要だということを改めて実感しました。

パタンナーのこだわり

「パタンナーのこだわりを買う人にも知って欲しい」

パタンナーの萩山さんは、あまり誰も発信してこなかった「パタンナーにしかわからないこと」をnoteで発信しています。パタンナーの方のこだわりは1mm以下の世界のこともあるそう。ただ、買う人はなかなかそこに気づけない。

造り手のこだわりを知ることで価格の設定の説得力にもつながる、ともおっしゃっていました。「服の見どころ・腕の見せどころ」と題して、ファッション初心者にも分かりすい解説記事をnoteに書かれています。 ファッション無知な私にとって、これから服を納得して購入するために大変ありがたい記事ばかりです。(まだ全部は読めていないです)

技術は全てツールと考えている

企画デザイナー・プランナーのうにくまさんは、「時代に合わせて持っている技術をアップデートするにはどうしたらいいか分からない」と困っているアパレル業界や工場向けに情報を発信しています。

うにくまさんはデザイン、パターン、マーケティングなど様々な方面に知見を持っている方です。「それらの技術は全てツールと考えている」という言葉が印象的でした。

おそらく縫製工場さんなどが持っている技術力も「洋服を作る」ためのツールの1つなのだと思います。シタテルが世の中に提供しようとしているのも服作りのツールで、そして自分自身の職であるエンジニアもIT技術というツールを使う仕事です。

自分はIT技術を使うことが無意識に目的になってしまうことが多く、「技術は全てツール」はハッとさせられる言葉でした。手段が目的になってしまいやすい点は、IT業界でも衣服業界でも「技術者」に共通し、それが自然と下請け体質に繋がってしまうのかもしれないと勝手に思いをめぐらせました。

まとめ

おそらく、アパレル業界の中でもマニアックな展示であり、衣服におけるそもそもの知識のない私にとって、半分解展研究所はとてつもなく情報量の多いイベントでした。私がつかみ切れたのはほんの一部分だと思いますが、知らなかったことや普段意識していなかったことに気づくことができ、とても楽しかったです。弊社の衣服づくりのプロの宇藤さんに解説してもらえたことも大きかったです。「地の目」や「トワル」など教えていただいて初めて知る言葉でした。

展示自体がリバースエンジニアリングであり、衣服づくりの「技術」に主にスポットが当たっていたので、専門的なことは分からずも、ITエンジニアを重ねて共感する部分もありました。ただ、ITの技術はハードウェアもソフトウェアもどんどん進化していきますが、洋服がソフトウェアで人間がハードウェアだとすると、人間の体は200年前と変わらない。好まれる洋服のシルエットは時代とともに変わっても、「動いた時の着心地の良さ」という普遍的な技術を、昔の服から知ることができることに面白さを感じました。

今後は衣服製作やアパレル業界の知識を増やしつつ、また長谷川さんのイベントが開催されたら足を運びたいなと思っています。

2019年2月11日月曜日

セミナーってこういう形もアリなのかと気づいた話


こんにちは!
シタテル株式会社エンジニアのいしづかです。

これまで、ぼくは社内外いろいろなセミナーに参加してきました。

新卒で勤めていた会社では出社初日からビジネスマナー研修がありましたし、本業に関わるプログラミング言語やフレームワークなどの技術的なものは今でも機会があれば参加しますし、はたまた「女性部下との接し方」みたいなやつも参加したことがありますし、そういえば速読のセミナーなんかにも行ったことがあります(身についてはいないけど・・・)。

多かれ少なかれ、ご経験があることだと思います。


これらは基本的に講師が登壇して内容を解説し、ワークを通じて体験するといった流れでセミナーが進行していきました。


もちろんコレ自体が悪いというわけではありません。
しかし、悩みとして一般論としては理解できたけれど、そこから具体に落とせず、結局セミナー前後であまり変化がないというものがありました。


それはセミナーに望むぼく自身の姿勢に大いに問題があるのは承知の上です。目的意識を持って参加してないからだ、と。
しかしながら、なかなかそこから抜け出しきれない状態にありました。


そういうご経験、ありません?(同意を求めてみる)


先日「フィードバック法」に関するセミナーを受けたのですが、その内容はもちろんですが、セミナーのやり方自体がぼくの中でかなり新鮮で、いい気づきがありました。

今回はぼくの気付きについてレポートしたいと思います。

【講師=参加者全員】伝え合う形式のセミナー

ぼくが受けたのは「効果的なフィードバック」という名目のセミナーでした。オンライン開催で、参加者は講師含めて15名です。

資料は事前に配布されており、参加者は事前に目を通しておくことになっていました。


「フィードバック」というのは自分が見知ったことについて感じたことや考えたことを相手に伝えることです。
そこにはIメッセージだのYouメッセージだのという様々なテクニックがあるのですが、今回は内容については割愛します。


このセミナーでは1名の講師がいて全体を進行していたのですが、全体を通して講師の方がしゃべっている時間はほとんど無かったというのが最大の特徴だったように思います。


具体的なシチュエーションを設定して参加者同士でワークをすることはありますが、それについて「自分はどのように感じたか」や「自分だったらどうするか」といったことをシェアし合うという形で進んでいきました。


ぼくにとってこのやり方で進んでいくセミナーはとても新鮮でした。
今まで参加したセミナーでは「なんでも当てはまる一般論」を取り扱うことが多かったですが、今回のフィードバックセミナーではすごく個別具体的なシチュエーションに対して意見を出し合うという形でした。


その中でも同じシチュエーションについて話しているのに人によって感じ方や対策が異なっているのが見えるというのがとても印象的だったのを覚えています。

「過去このような経験があったので、自分としてはこの点を重視しています」といったお話を各参加者がなさるのですが、ぼく自身が経験したことのないことを具体的に聞けるというはとてもリアリティがあって、良い追体験の機会になりました。

シェア型セミナーがおもしろいなと思った点

今回のセミナーは実際にやってみて自分たちがどのように感じたのかといった生々しい部分がしっかり活用できている点がとても良かったと感じました。


一般論的な知識については、資料を読めば大体のところは理解できます。
ぼくもセミナーでしゃべる側になることもあるのですごく反省しているのですが、書いてあることをそれらしく読むだけでセミナーやった(受けた)気になってしまうという罠にハマり続けていた部分があります。


大事なのは具体的な気づきや発見を自分の中に発生させて、それを自分で認識できたのか、という点のハズです。

今回のように、とあるシチュエーションについて自分はどう感じてどう行動しようと思うのかを考え発表しつつ他の人の話も聞くことで、単なる一般論だった知識が「経験」まで昇華されていくプロセスを体験することができたように思いました。


このやり方の一番の特徴は参加者によって得られるものが変わるという点でしょうか。
これまでの経歴によって1つのケースを見たときの感じ方も当然変わってきます。そうするとセミナー中にシェアされることも変わります。


これはメリットでもありデメリットでもありますが、現場の生の声が聞けるというのはかけがえのないものだと思うので、個人的にはそこそこ肯定派です。

自分の困りごとについて様々な意見がもらえたというのは、通常のセミナーではあまりないことだったので、とても有用でした。

まとめ

セミナーの形式にはいろいろなものがありますが、シェア会形式というのもなんかオトナな勉強の仕方みたいで、ぼくはいいなぁ〜と思いました。


特に社内セミナーとかだと、主催する人が一番やりたいと思ってる人だったりするので、一方的にしゃべって終わりってケースも少なくはない気がします。

シェア会形式だと、講師の人は進行役に徹するので、参加者が主役となってみんなで作り上げる会みたいな感じにしやすいです。


組織づくりやコミュニケーションなど、明確な答えが存在しないような話について扱うときはシェア会形式を取ってみるのもおもしろいと思います。

2019年2月1日金曜日

衣服素人でもsitateruとMakuakeで服が作れた [仕組み編]

こんにちは、エンジニアの工です。
私が、sitateruとMakuakeを使って服を作ってみたことについてシリーズで書いていこうと思います。
プリント屋さんでTシャツを作ったことはありますが、完全オリジナルの服を作るのは初めてなので、ドキドキしました。

私が実施したプロジェクトはこちらです。













sitateru × Makuakeの連携

ご存知の方もいるかと思いますが、sitateruは、クラウドファンディングサービスMakuakeと連携して衣服生産のサポートを行なっています。
プレスリリース

仕組み

Makuakeで資金調達、sitateruで生産を行う仕組みです。
一例ですが、大まかなフローはこのようになっています。

  1. 「sitateru」を通してサンプルを生産
  2.  サンプルを撮影し、「Makuake」でクラウドファンディングを実行
  3. 支援者へのリターンとして「sitateru」で商品を量産















クラウドファンディングで資金を集めて、何かしらのサービスを使って生産するというのは、個人でそれぞれやりとりすれば実現できますが、
明示的に連携することで、それぞれのサービスがシームレスにつながって、実行者の負担を減らしてよりプロジェクトをスムーズに進められるようになっています。
例えば、 sitateruへの量産分のお支払いはクラウドファンディング支援金入金後での対応が相談できたりします。

sitateru×Makuakeで素人でも衣服生産を実現できる

ブランドを立ち上げたい、いいアイデアがあるけど..となっても
個人がオリジナルの服を作るのは、
どこから何をやればいいの..?😑
需要あるの...?😂
資金足りないし、採算とれるの...?😅
とか不安要素がたくさんです...
私もずっと服を作りたいという思いはありましたが実行できていませんでした。
この不安をMakuake×sitateruの仕組みで解決し、実際にイマジネーションを形にして服を作ることができました。

実行した流れ

私が具合的に実行した流れはこんな感じです。
  1. 企画する
  2. sitateruに相談する
  3. sitateruでサンプルを作る
  4. Makuakeに正式申し込みをする
  5. Makuakeにコンテンツを作る
  6. ファンディングページを公開する
  7. クラウドファンディングのための施策を行う
  8. ファンディング期間終了
  9. sitateruでプロダクトを量産する
  10. プロダクトを支援者に発送する

まとめ

sitateru×Makuakeで衣服素人でもイマジネーションを形にできる!

今回は仕組みについて、説明していきました!
次回から上に記載した流れを細かく書いていこうと思います!
お楽しみに👯


, , , ,

2019年1月28日月曜日

WEBエンジニアが知っていてもいいかもしれない出版やデザインの話

こんにちは、シタテルでエンジニアをやっている茨木です。

私は出版・DTPをかじったことが少しだけあるのですが、デザインや文章校正の基礎知識はエンジニアの仕事でも活用できる機会が時折あったりします。

基本的なキーワードだけ簡単にご紹介します。
興味がでたらぜひ本格的なデザインや文章校正の本などで調べてみてください。
少し気にするだけでも、画面が結構「それっぽく」なりますので、コスパの良い知識だと思います。

ジャンプ率

1画面(1紙面)でのフォントサイズの変化率を指す言葉です。

一般に、落ち着いた雰囲気にしたい場合はジャンプ率を小さく、派手な印象を与えたい場合はジャンプ率を高くすべきと言われています。

色の指定方法

RGB

WEBエンジニアがまず思いつくのはこれかと思います。光の三原色ですね。

HSB

色相(Hue)、彩度(Saturation)、明度(Brightness)の3要素で色を指定する方法があります。
色相は赤系・青系などの色味、彩度は鮮やかさ(小さいほどグレーに近くなる)、明度は明るさ(小さいほど黒に近くなる)を表します。

SBを固定し、Hのみを変動させることで、比較的まとまりのある色のバリエーションが作りやすいです。

例えば、画面上でステータスAとステータスBの表示色を変えて視認性を上げたい、といった場合には、色相のみ違う2色を用いると、比較的おさまりが良かったりします。

CMYK

インクの4色です。基本的に印刷物の色味はCMYKで表現されます。
WEBだと気にする機会はあまりないですが、RGBやHSBで表現できる色は、必ずしも同じ見え方のCMYKに変換できない、という点は知っておいてもいいかもしれません。

人物写真の「首切り」

インタビューに添付される人物写真において、人物の顔部分に背景の直線(窓枠等)が被る構図はNGとされています。

必ずしも合理的な理由はない(私が知る限りでは)ですが、確かにちゃんとしたサイトや紙面の写真では見ない構図ですから、気にしておくといいかと思います。

文章の書き方

表現したい内容によって正しい日本語の書き方というのは当然変わりますが、かっちりした文章を書く場合には新聞ルールを参考にすると、素人感が出なくていいです。

  • 「出来る」と「できる」はどちら?
  • 「行なう」と「行う」はどちら?
  • 「〜です(〜)。」「〜です。(〜)」はどちら?

たとえばこういう疑問に対して、どっちがプロっぽいか、という回答を与えてくれます。

文献としては共同通信社の記者ハンドブックなどがメジャーですが、買うと高いので、新聞社サイトの文章を参考にするなどでもいいかもしれません。


以上です。散文になってしまいましたが、ご参考になれば幸いです。
, , , , ,

2019年1月24日木曜日

Gulp+EJSでページを量産

こんにちは!
シタテル株式会社UI/UXデザイナーの堤です。

複数の静的ページを作る際に便利なGulp+EJSについて紹介します。

今回やりたかったこと

  • 静的なページを量産
  • 共通パーツはテンプレート化したい

導入方法はNode.jsがインストールされている環境でプラグインをインストールします。

$ npm install gulp gulp-merge-json gulp-ejs gulp-rename fs

ディレクトリ構成

gulpfile.js

// gulpプラグインの読み込み
var gulp = require('gulp');
var merge = require('gulp-merge-json');
var ejs = require('gulp-ejs');
var rename = require('gulp-rename');
var fs = require('fs');

//jsonファイルの結合 ※複数のjsonファイルがなければ不要
gulp.task('json', function () {
  gulp.src('./app/data/origin/**/*.json')
    .pipe(merge({
        fileName: 'pages.json'
    }))
    .pipe(gulp.dest('./app/data'));
});

//設定ファイルの読み込み
const jsonData = './app/data/pages.json';
const json = JSON.parse(fs.readFileSync(jsonData));

// ejsをhtmlへ変換
gulp.task("ejs", function() {
    for (var key in json.pages) {
        var data = json.pages[key];
        data.path = key;
        var layout = data.layout;
        gulp.src("./app/ejs/" + layout + ".ejs")
            .pipe(ejs(data))
            .pipe(rename(key + '.html'))
            .pipe(gulp.dest('./public'));
    }
});

pages.json

{
    "pages": {
        "index": { //出力するhtmlファイル名
            "layout": "index", //使用するejsファイル名
            "title": "タイトル1"
        },
        "hoge/index": {
            "layout": "index",
            "title": "タイトル2"
        }
    }
}

index.json

<% include common/_head %> //includeするejs ファイルを指定
<%= title %> //jsonファイル内でしている要素が入る

実行方法

$ gulp json //jsonファイルの結合が必要な場合
$ gulp ejs

まとめ

ejsではjavascriptが使用できるためループ処理なども可能です。

あまり利用する場面は多くないですが、エンジニアさんに 依頼するほどでもないけど、ぱぱっと複数ページを作る必要があるときに便利です!

, , , ,

2019年1月21日月曜日

Linuxのプロセス確認方法3つと終了方法3つ -killコマンドのバリエーション-

Photo by Sai Kiran Anagani on Unsplash

元インフラエンジニアの北爪です。

Linuxにてプロセスを終了する様々な方法について解説します。最後にプロセスを終了するとはどういうことかを説明します。

最初にプロセス終了コマンドとプロセスの確認コマンドをそれぞれ3つ紹介します。
その後に終了コマンドを詳しく解説し、最後にUNIXのシグナルについて簡単に解説します。

プロセスの確認コマンド3つ

  • リアルタイムでインタラクティブなプロセス確認方法、top コマンド
  • Linuxならパイプで繋ぎたいそんな確認方法は ps auxf コマンド
  • パターンマッチで調べたい pgrep -a コマンド

プロセスの終了コマンド3つ

  • インタラクティブにプロセスを終了するなら、top コマンド
  • pidを見て確認しながらプロセスを終了するなら kill コマンド
  • pidを確認するのと同時にプロセスを終了するなら pkill コマンド

topコマンド -インタラクティブにkill-

プロセスの状況を確認しながら、特定のプロセスを終了することができます。topコマンドを起動し、k を押すと、pidが聞かれた後に、送りたいシグナルを入力することができます。最後に確認(yes/no)が出て、プロセスを終了できます。

killコマンド -丁寧にkill-

ps aux | grep <プロセス名> もしくは、pgrep <プロセス名> にてpidを調べます。調べたpidを使って、kill -p <pid> にてプロセスを終了することができます。

pkillコマンド -patternでkill

プロセス名をパターンマッチングして終了ことができます。同時にマッチした複数のプロセスを終了することができます。

例えば、nginxが起動しており、master(親プロセス)とworker(子プロセス)が実行されているとします。以下のようになります。

root@0e1d355b28f0:/# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  18504  3528 pts/0    Ss   10:03   0:00 /bin/bash
root      3470  0.0  0.0 140624  1520 ?        Ss   10:11   0:00 nginx: master process /usr/sbin/nginx
www-data  3471  0.0  0.1 141000  3428 ?        S    10:11   0:00  \_ nginx: worker process
www-data  3472  0.0  0.1 141000  3428 ?        S    10:11   0:00  \_ nginx: worker process

pkill nginx これでnginxのプロセスを終了することができます。
また、-f オプションでは、プロセス名だけではなく、オプションを含めた全てのプロセス名がパターンマッチの対象になります。

pkillは、pgrepとセットで使うことでどのプロセスが対象になるのかを事前に調べることができます。 pgreppkill はオプションを共有しているので、pgrepにて対象のプロセスを調べることができます。

pgrepにてプロセスの探し方をオプションなしでプロセス名にて検索、-f オプションにてプロセス名全体にて検索の例を示します。-a オプションはプロセスの説明を表示します。

root@0e1d355b28f0:/# root@0e1d355b28f0:/# ps auxf | grep nginx
root      3789  0.0  0.0 140624  1512 ?        Ss   10:57   0:00 nginx: master process /usr/sbin/nginx
www-data  3790  0.0  0.1 141000  3384 ?        S    10:57   0:00  \_ nginx: worker process
www-data  3791  0.0  0.1 141000  3384 ?        S    10:57   0:00  \_ nginx: worker process

root@0e1d355b28f0:/# pgrep -a nginx
3789 nginx: master process /usr/sbin/nginx
3790 nginx: worker process
3791 nginx: worker process

root@0e1d355b28f0:/# pgrep -a -f master 
3789 nginx: master process /usr/sbin/nginx

root@0e1d355b28f0:/# pgrep -a -f worker        
3790 nginx: worker process
3791 nginx: worker process

次に、意図的に、先にnginxのmasterプロセスにSIGKILLをシグナルを送り、親プロセスのみ強制終了します(シグナルについては後述)。そのあとに親プロセスが消えた子プロセス(= Orphan process)のwoker(子プロセス)をpkill -f を使って終了してみます。

root@0e1d355b28f0:/# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  18616  3552 pts/0    Ss   10:03   0:00 /bin/bash
root      3789  0.0  0.0 140624  1512 ?        Ss   10:57   0:00 nginx: master process /usr/sbin/nginx
www-data  3790  0.0  0.1 141000  3384 ?        S    10:57   0:00  \_ nginx: worker process
www-data  3791  0.0  0.1 141000  3384 ?        S    10:57   0:00  \_ nginx: worker process
root      3805  0.0  0.1  34396  2828 pts/0    R+   11:02   0:00 ps auxf
root@0e1d355b28f0:/# pkill -KILL -f master
root@0e1d355b28f0:/# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  18616  3552 pts/0    Ss   10:03   0:00 /bin/bash
www-data  3790  0.0  0.1 141000  3384 ?        S    10:57   0:00 nginx: worker process
www-data  3791  0.0  0.1 141000  3384 ?        S    10:57   0:00 nginx: worker process
root      3807  0.0  0.1  34396  2792 pts/0    R+   11:02   0:00 ps auxf
root@0e1d355b28f0:/# pkill -KILL -f worker
root@0e1d355b28f0:/# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  18616  3552 pts/0    Ss   10:03   0:00 /bin/bash
root      3809  0.0  0.1  34396  2944 pts/0    R+   11:02   0:00 ps auxf

プロセスの終了とは シグナルについて

プロセスの終了は各プロセスにシグナルを送ることで外部から非同期にプロセスのコントロールを行います。

top kill pkill 全てのコマンドでデフォルトのシグナル(SIGTERM/15)です。つまり、TERMシグナルを送ることで、プロセスを終了しています。

TERM以外のシグナルを送ることも可能です。各シグナルは番号と英語による表記があります。kill pkill 共に -<signal> にてシグナルを送ることができます。これは数字でも文字でも可能です。例えば、強制終了はkill -KILL もしくは kill -9
kill -lコマンドでシグナルの一覧を出力することが可能です。


root@0e1d355b28f0:/# kill -l
 1) SIGHUP  2) SIGINT  3) SIGQUIT  4) SIGILL  5) SIGTRAP
 6) SIGABRT  7) SIGBUS  8) SIGFPE  9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX


終わりです!
, , , ,

2019年1月18日金曜日

FirefoxとChromeで画像の色味が違う問題

こんにちは!
シタテル株式会社UI/UXデザイナーの堤です。


以前出くわしたFirefoxとChromeが画像の色味が違う問題について解決方法をご紹介します。

画像はぱくたそさんから拝借

修正前

左がChromeで右がFirefox

微妙にFirefoxの色味が濃く出てしまいます。

修正後

解決方法

Photoshopで書き出しの際に「カラープロファイルの埋め込み」にチェックするだけ!

まとめ

以前なぜかわからずいろいろと調べていたところこの解決方法にたどり着きました。

微妙な違いにはなりますが、 写真が多いサイトだと全体の印象も変わってくるため気をつけたいと思います。

, , ,

2019年1月4日金曜日

【mac】操作スペースを使いこなす!

こんにちは!
シタテル株式会社エンジニアのいしづかです。

開発作業をしているといろんなソフトウェアを使いますね。
Slack・Webブラウザ・コードエディタ・gitツール・DBツール・・・etc

これらを1つのウィンドウ内に置いてキーボードで切り替えてもいいんですが、どうしてもゴチャゴチャ感は否めません。

macには「操作スペース」と呼ばれる仮想的なデスクトップ機能があります。
ディスプレイを何枚も持っているようなイメージの機能ですね。それを切り替えて使います。

今回はその操作スペースを使いこなすために、私が行っている設定をご紹介します。

操作スペースをつかう

Mission Controlを起動すると「デスクトップ1」って感じで表示されている部分、ここ Spacesバー って言うらしいです。最初はデスクトップ1だけですが、右端の+ボタンから増やすことができます。

私はいつも6つ用意しています。
それぞれ置いておくものを決めていて

  • デスクトップ1: Slack
  • デスクトップ2: Webブラウザ
  • デスクトップ3: コードエディタ(Visual Studio Code)
  • デスクトップ4: gitクライアント(SourceTree)
  • デスクトップ5: DBクライアント(SequelPro)
  • デスクトップ6: 予備

こんな感じで使っています。
どこに何があるか決めておくことで、ほしいウィンドウをパッと取り出せるようにしています。

ちなみに、このウィンドウの順番を使用状況に応じて並び替える機能があって、macさんの親切心なんですが、私にとって余計なお世話と化していたのでOFFにしています。

↓コレです。システム環境設定のMission Controlにあります。

すばやく切り替えるための設定

それでもデスクトップ1からデスクトップ4まで移動するにはトラックパッドを三本指でシャッシャッシャッと3回やることになります。

この行ったり来たりが地味にめんどくさい。。。

そこでショートカット1発で「デスクトップ○」を出すようにしています。

システム環境設定の「キーボード」でMission Controlのショートカット設定ができます。
↓コレです。

ここでは「control + 数字」を押すとデスクトップを切り替えるようにしています。

これでどのデスクトップを表示していても、Slackが見たければ「control + 1」ですし、コードエディタを出したければ「control + 3」で一発移動が可能です。

まとめ

ホントにちょっとしたことなんですが、毎日発生する微細な面倒事を放っておくと慣れてしまって当たり前になってしまうので、こんな細かい工夫も怠らないように心がけています。

みなさんそれぞれ快適な開発環境を構築しているようですので、その工夫を聞いて取り入れていきたいですね。

, , , ,