Photoruction工事中!

Photoructionの開発ブログです!

Laravel Collection: 業務でよく使うメソッドを解説

はじめに

Webエンジニアの春冨です。

フォトラクションに今年の7月に転職してから初めてLaravelを使って開発をしてます。

Laravelには便利な機能がいっぱいあって覚えるのが大変ですが、その中でもCollectionクラス(Illuminate\Support\Collection)がとても便利だったので紹介しようと思います。

LaravelのCollectionとは

LaravelのCollectionは、PHPで利用可能な配列操作をより書きやすく使いやすくするためのラッパーです。

また、Collectionはメソッドチェーンを使用して複数の操作を一連の流れで簡潔に記述できるため、コードの可動性が向上することも期待できます。

では実際に業務などでよく使用するメソッドをいくつか見ていきましょう。

ちなみにCollectionで使用できる全メソッドはLaravelの公式ドキュメントに載っているので、そちらも参考にしてください。

map

mapメソッドとは、コレクション内の各要素に対して指定されたコールバック関数を適用し、その結果から新しいコレクションを作成して返します。

例)

以下の例ではコレクションの各要素の値を使用して新しくインスタンスを生成しています。

このように各要素の値を使用して新しいものを作成したり、値を変換したりするのによく使用します。

$collection = collect([
    ['name' => 'yamada', 'age' => 20],
    ['name' => 'tanaka', 'age' => 25]
]);

$users = $collection->map(function ($user) {
    return new User($user['name'], $user['age']);
});

// 結果
[
  UserA {#6360
    +name: "yamada",
    +age: 20,
  },
  UserA {#6391
    +name: "tanaka",
    +age: 25,
  },
]
  

注意点としてはmapメソッドは元のコレクションを変更するのではなく、新しいコレクションを返すので結果は変数に入れるなどする必要があります。

filter

filterメソッドとは、コレクション内の各要素に対して指定されたコールバック関数を適用し、その結果がTrueのものを返します。

例)

以下の例ではageが20より大きいものだけを返すようにしてます。

このようにある条件を満たしたものだけを取得するときに使用します。

バリデーションチェックをして結果がTrueのものだけが欲しいみたいなシーンで使用したりします。

$collection = collect([
    ['name' => 'yamada', 'age' => 20],
    ['name' => 'tanaka', 'age' => 25]
]);

$result = $collection->filter(function ($item) {
    return $item['age'] > 20;
});

// 結果
[
  1 => [
    "name" => "tanaka",
    "age" => 25,
  ],
]
  

every

everyメソッドとは、コレクションの全要素に対して指定されたコールバック関数を適用し、その結果が全てTrueになるかを判定します。全てTrueになった場合はTrue、1つでもFalseがある場合はFalseを返します。

例)

以下の例ではコレクションの全ての要素のageが30より小さいかを判定しています。全て30より小さいので結果はTrueになります。

コレクション内の要素がある条件に対して全てTrueである必要があるため、例えば全ての要素がバリデーションチェックに通る必要があるシーンなどに使用します。

$collection = collect([
    ['name' => 'yamada', 'age' => 20],
    ['name' => 'tanaka', 'age' => 25],
    ['name' => 'satou', 'age' => 28]
]);

$result = $collection->every(function ($item) {
    return $item['age'] < 30;
});

// 結果
true

pluck

pluckメソッドとは、指定したキーの値をコレクションから取得します。

例)

以下の例ではコレクションからnameの値のみを取得してます。

第2引数を指定することで値をkey => valueの形で取得することもできます。ただし、注意点として第1引数がvalue、第2引数がkeyになります。

DBからデータを取得してきたときにある特定のカラムの値だけが欲しい時に使用することが多いです。

$collection = collect([
    ['name' => 'yamada', 'age' => 20],
    ['name' => 'tanaka', 'age' => 25],
    ['name' => 'satou', 'age' => 28]
]);

$result = $collection->pluck('name');

// 結果
[
  "yamada",
  "tanaka",
  "satou",
],
  

$result = $collection->pluck('age', 'name');

// 結果
[
  "yamada" => 20,
  "tanaka" => 25,
  "satou" => 28,
]
  

groupBy

groupByメソッドとは、指定したキーによりコレクションの各要素をグループにまとめます。

また、キーにコールバック関数を渡してその結果でグルーピングすることも可能です。

例)

以下の例ではキーにageを指定することで、ageが同じ値のものでグルーピングしてます。

groupByはグルーピングして終わりではなく、ある特定の値でグルーピングをした後に、その値に対して何か操作を実行するといった使い方が多いです。

$collection = collect([
    ['name' => 'yamada', 'age' => 20],
    ['name' => 'tanaka', 'age' => 20],
    ['name' => 'satou', 'age' => 28]
]);

$result = $collection->groupBy('age');

// 結果
[
  20 => [
    [
      "name" => "yamada",
      "age" => 20,
    ],
    [
      "name" => "tanaka",
      "age" => 20,
    ],
  ],
  28 => [
    [
      "name" => "satou",
      "age" => 28,
    ],
  ],
]
  

sortBy

sortByメソッドとは、指定したキーでコレクションをソートします。注意点としてはソート済みのコレクションは元の配列のキーを保持します。なのでキーをリセットするにはvaluesメソッドを呼ぶ必要があります。

また、第2引数に、ソートフラグを渡すことでソートの動作を調整できます。

例)

以下のようにキーを指定することでそのキーを使ってソートすることができます。ソートは昇順になるので降順でソートをしたい場合はsortByDesc()を使用します。

$collection = collect([
    ['name' => 'yamada', 'age' => 25],
    ['name' => 'tanaka', 'age' => 20],
    ['name' => 'satou', 'age' => 28]
]);

$result = $collection->sortBy('age')->values();

// 結果
[
  1 => [
    "name" => "tanaka",
    "age" => 25,
  ],
]

unique

uniqueメソッドは、コレクションの重複を取り除いた結果を返します。ネストした配列やオブジェクトを使用する場合は一意であることを決めるキーを指定する必要があります。

例)

以下の例のように一意にしたいキーを指定することで、その値が重複しているものを取り除いたコレクションを返します。

ある処理を実行するときに、同じ値に対して実行する必要がないときはuniqueでデータを絞ったりします。

$collection = collect([
    ['name' => 'yamada', 'age' => 25],
    ['name' => 'tanaka', 'age' => 20],
    ['name' => 'satou', 'age' => 25]
]);

$result = $collection->unique('age');

// 結果
[
  [
    "name" => "yamada",
    "age" => 25,
  ],
  [
    "name" => "tanaka",
    "age" => 20,
  ],
],

最後に

LaravelのCollectionについていくつか紹介しましたが、Collectionのメソッドはまだまだたくさんあります。

配列を使って複雑な操作をする場合は、もしかすると使えそうなメソッドが見つかるかもしれないので是非公式ドキュメントも読んでみてください!

株式会社フォトラクションでは一緒に働く仲間を募集しています

ChatGPTのカスタム指示を使ってみた

はじめに

こんにちは、AIエンジニアの志賀です。

このたびはChatGPTのカスタム指示に関する技術ブログをご覧いただきありがとうございます。

このブログでは、巷で流行しているChatGPTの、カスタム指示という機能を実際に使ってみた感想をお伝えできればと思います。

カスタム指示について

ChatGPTのUIを利用する際に、カスタム指示を使うことで対話や回答のカスタマイズが可能になります。

次のような手順でカスタム指示を行うことができます。

ChatGPTのUI内でカスタム指示を設定する手順は、直感的で簡単です。

自身のグーグルアカウントマークをクリックすると、カスタム指示というボタンが表示されます。

このボタンを選択すると、カスタム指示をChatGPTに入力する欄が表示されるので、カスタム指示を入力していきます。

カスタム指示を使ってみた

まずは、カスタム指示を設定しない状況で、ChatGPTに質問してみます。

私:

「経済」について具体例を使って説明してください。

ChatGPT:

経済は、資源や財貨の生産、分配、消費などに関わる人々や企業、政府などの活動全般を指します。具体例を挙げると、例えば貿易が経済において重要な要素です。国々がお互いの財貨やサービスを交換することで、それぞれの国の経済が発展したり、必要なものを得たりすることができます。例えば、日本が自動車をアメリカに輸出し、代わりにアメリカからは農産物を輸入することで、お互いの需要や供給を満たしあうことができます。

また、金融政策も経済に大きな影響を与えます。政府や中央銀行金利や貨幣の供給量などを調整することで、経済の成長を促進したり、インフレーションを抑制したりすることができます。例えば、金利を引き下げることで貸し出しを促進し、消費や投資を刺激することができます。

このように、経済は貿易や金融政策などの様々な要素によって影響を受けます。

次に、以下のようにカスタム指示を行ってみました。

ChatGPTにあなたについて何を知らせれば、より良い応答を提供できると思いますか?

⇒私は小学生です。

ChatGPTにどのように応答してほしいですか?

⇒小学生なので、小学生にも理解できるように説明してください。

設定後、再度ChatGPTに質問します。

私:

「経済」について具体例を使って説明してください。

ChatGPT:

経済にはいくつもの側面がありますが、例えばインフレーションという概念を考えてみましょう。インフレーションは、一般的に物価の上昇を指し、経済全体の物価水準が持続的に上昇する状態です。

例えば、住宅市場でのインフレーションを考えてみましょう。需給の変化や建設材料のコスト増加などにより、住宅価格が上昇します。これにより、同じ賃金を受け取る人々が住宅を購入することが難しくなります。住宅価格の上昇により、多くの場合、家を購入するために借り入れる必要が生じます。これが借入金利も上昇させ、さらに負担を増やす可能性があります。

また、インフレーションが継続的に高い水準で推移すると、消費者の購買力が減少する可能性があります。物価が上昇すると、同じ額のお金で購入できるものが減少するため、消費者は同じ生活水準を維持するためにより多くのお金を必要とします。

政府や中央銀行は、インフレーションを管理するために金融政策を調整します。金利の変更や貨幣供給の調整などを行い、インフレーションを抑制することを目指します。

この例では、インフレーションが経済に及ぼす影響を示しています。物価の上昇が消費者や市場にどのような影響を与えるかを理解することは、経済活動や政策について深く考える上で重要です。

残念ながら、小学生であるという設定があまり考慮されていません。

そこで、次のように質問します。

私:

カスタム指示が適用されていますか?私は小学生ですよ?

ChatGPT:

申し訳ありません、深い経済の話題はちょっと難しいですよね。もっと分かりやすい例を使って説明しましょう。例えば、お小遣いの使い方で経済を考えることができます。

たとえば、お小遣いを使ってお菓子を買う場合、お菓子の値段が上がると、同じお金では今まで買えた量よりも少ないお菓子しか買えなくなりますよね?これがインフレーションです。お菓子の値段が上がることで、同じお金では買える量が減ってしまうんです。

でもね、お小遣いをうまく管理して、お菓子だけでなく本やおもちゃも買えるようにするためには、お金を使うタイミングやどんなものを買うかを考えることが大切です。経済は、お金を上手に使って物事を計画することなんだよ。

チャットで指示することで、やっと小学生であることを考慮した回答になりました。

流石に、これで適用されたと思い、再度質問してみました。

私:

「経済」について具体例を使って説明してください。

ChatGPT:

もちろんです。例えば、農業の経済的な側面を考えてみましょう。農業は、経済において非常に重要な役割を果たしています。

農業では、作物の生産とそれらの作物を市場に提供することが主な活動です。例えば、米作りを考えてみましょう。農家が米を栽培し、それを市場に出荷して売ることで、消費者が米を購入できます。

経済的な観点では、農業には供給と需要の要素が関与します。例えば、米の需要が高まると、米の価格も上昇することがあります。これは需要が供給を上回ったために起こることが多いです。

一方、天候や農業技術の進歩などの要因により、作物の供給量が増減することもあります。例えば、天候が不順で作物の収穫量が減少すると、供給が減少し、価格が上昇する可能性があります。

さらに、農業は雇用の面でも重要です。多くの人々が農業に関わり、農作業を行うことで生計を立てています。農業が順調に行われることで、雇用が維持され、地域経済全体に影響を与えます。

このように、農業は経済において供給と需要、価格の変動、雇用の面など様々な要素を含む重要な分野です。

またも、小学生であることが考慮された回答になりませんでした。

カスタム指示を使ってみた感想

私が使用しているのが、ChatGPT3.5である事もあるかと思いますが、率直に言って、現段階では、実用的であるとは感じませんでした。

今後、ChatGPTがより進化して、カスタム指示がきちんと適用されるようになれば嬉しいですね。

終わりに

いかがでしたでしょうか。

もしかすると、カスタム指示の出し方によっては、ChatGPT3.5でも、有効に活用できるのかもしれません。

非常に簡単に試すことができるので、是非みなさんも試してみてください。

株式会社フォトラクションでは一緒に働く仲間を募集しています

Slackのスレッドに予約投稿する方法(ノーコード)

こんにちは。QAエンジニアの山本です。 この記事では、Slackのスレッドに予約投稿する方法を共有します。

概要

Slackのスレッドに予約投稿したいメッセージを、スプレッドシートに記載しておくと、Zapierが自動で予約投稿するシステムを作成します(^^)/

事前に準備して頂きたいもの

  • Googleアカウント
  • Slackアカウント
  • Zapierアカウント
  • SlackのワークスペースにZapierがインストールされていること

スプレッドシート・Zapierの作成手順

スプレッドシート

最初に、スプレッドシートを作成します。 完成イメージは、下記です。

スプレッドシートの完成イメージ
スプレッドシートの完成イメージ

作成手順

  1. 新規ファイルを作成します
  2. 完成イメージを参考に、1行目の項目名を入力します
  3. A列の予約IDの入力をします
  4. A~E列を枠線で囲みます
  5. G列に下記関数を入力します(見本は2行目の値です)
    =REGEXREPLACE(REGEXREPLACE($B2,".*archives/",""),"/.*","")
  6. H列に下記関数を入力します(見本は2行目の値です)
    =REGEXMATCH(REGEXREPLACE($B2,".*archives/",""),"/")
  7. I列に下記関数を入力します(見本は2行目の値です)
    =REGEXMATCH($B2,"thread_ts")
  8. J列に下記関数を入力します(見本は2行目の値です)
    =IF(AND($H2,$I2=FALSE),REGEXREPLACE($B2,".*archives/.*/p",""),"")
  9. K列に下記関数を入力します(見本は2行目の値です)
    =LEFT($J2,10)
  10. L列に下記関数を入力します(見本は2行目の値です)
    =RIGHT($J2,6)
  11. M列に下記関数を入力します(見本は2行目の値です)
    =IFS($I2,REGEXREPLACE(REGEXREPLACE($B2,".*thread_ts=",""),"&.*",""),$H2,CONCATENATE($K2,".",$L2),TRUE,"")
  12. O2のセルに下記関数を入力します
    =TEXT(NOW(),"YYYY-MM-DD")
  13. P2のセルに下記関数を入力します
    =TEXT(NOW(),"HH")
  14. Q2のセルに下記関数を入力します
    =COUNTIFS(D2:D100,O2,E2:E100,P2)
  15. R2のセルに下記関数を入力します
    =IFERROR(QUERY(A2:M100, "select C,G,M where D = date '"&O2&"' and E = "&P2&""),"")

スプレッドシートは、上記で完成です!

Zapier

次に、Zapierを作成します。 完成イメージは、下記です。

Zapierの完成イメージ
Zapierの完成イメージ

作成手順

最初にCreate a Zap画面で、下記のような文章を入力し、「Generate」をクリックします

Create a Zap画面
Create a Zap画面

英文の例:Once every hour, send values from Spreadsheet to the Slack thread

生成したアプリを開きます。

1. Zapの手順1に「Schedule by Zapier」を追加する

  1. App&eventで「Schedule by Zapier」を選択する
  2. Eventで「Every hour」を選択する
  3. Trigger>Trigger on weekendsで「no」を選択する
  4. Testを実行する

2. Zapの手順2に「Get Many Spreadsheet Rows 」を追加する

  1. App&eventで「Google Sheets」を選択する
  2. Eventで「Get Many Spreadsheet Rows 」を選択する
  3. Accountで自分のGoogleアカウントを選択する
  4. Action>Driveで上記のスプレッドシートが格納されているDriveを選択する
  5. Action>Spreadsheetで、上記のスプレッドシートを選択する ※スプレッドシートを検索する時は、スプレッドシートIDで検索する https://docs.google.com/spreadsheets/d/(スプレッドシートID)/edit#gid=0
  6. Action>Worksheetで、上記のスプレッドシートのシート名を選択する
  7. Action>Columnsに「Q:Q」を入力する
  8. Action>Row Countに「1」を入力する
  9. Action>First Rowに「2」を入力する
  10. Testを実行する

3. Zapの手順3に「Filter by Zapier」を追加する

  1. Appで「Filter by Zapier」を選択する
  2. Filter setup & testingで下記を選択する
    Filter by Zapier画面
    Filter by Zapier画面

4. Zapの手順4に「Get Many Spreadsheet Rows 」を追加する

  1. App&eventで「Google Sheets」を選択する
  2. Eventで「Get Many Spreadsheet Rows 」を選択する
  3. Accountで自分のGoogleアカウントを選択する
  4. Action>Driveで上記のスプレッドシートが格納されているDriveを選択する
  5. Action>Spreadsheetで、上記のスプレッドシートを選択する
  6. Action>Worksheetで、上記のスプレッドシートのシート名を選択する
  7. Action>Columnsに「R:T」を入力する
  8. Action>Row Countで下記画像の値を選択する
    Action&gt;Row Countの値
    Action>Row Countの値
  9. Action>First Rowに「2」を入力する
  10. Testを実行する

5. Zapの手順5に「Looping by Zapier」を追加する

  1. App&eventで「Looping by Zapier」を選択する
  2. Eventで「Create Loop From Line Items」を選択する
  3. Action > Line itemsで下記画像の値を選択する
    Action &gt; Line itemsの値
    Action > Line itemsの値
  4. Testを実行する

6. Zapの手順6に「Send Channel Message」を追加する

  1. App&eventで「Slack」を選択する
  2. Eventで「Send Channel Message」を選択する
  3. Accountで自分のSlackアカウントを選択する
  4. Action>Channel・Message Textに下記を選択する
    Action&gt;Channel・Message Textの値
    Action>Channel・Message Textの値
  5. Threadで下記画像の値を選択する
    Threadの値
    Threadの値
  6. Testを実行する
    ※送信予定のメッセージが2個以上ある時でも、Testでは1個のメッセージしか送信されない

7. Timezoneを日本の時間に変更する

  1. サイドメニューのDetailsアイコンをクリックする
  2. Timezoneを「GMT+09:00 Asia/Tokyo」に変更する

8. 「Publish」をクリックする

完成!!

株式会社フォトラクションでは一緒に働く仲間を募集しています

CREチームへインタビューしてみた。

みなさんこんにちは、CREチームのとよかずです!

運営担当である僕がアドカレ1本目の記事を執筆していくことになりました(緊張)

どんな記事にしようかあれこれ悩んでいたのですが、自分が所属してるチームのことを改めて知ってもらう機会を設けてもいいのかなと思い、今回はCREチームへのインタビューを記事にしてみました!👏

✨CREチームへのインタビュー✨

とよかず:それでは早速始めていきたいと思います!自分が所属するチームに対して、インタビューするのはなんだか不思議な気分ですが、最後までお付き合いください(笑) まず始めに、各メンバー自己紹介をお願いします🙇‍♀️

田中(以下、よしき):CREグループのチームリーダーを務めます田中です。

未経験エンジニアとしてフォトラクションに入社しており、1年半ほど改修や案件をこなしたりしたのち、去年の11月からCREのチームリーダーを務めています。現在、フォトラクションに勤めて3年目になります。

豊田(以下、とよひろ):CREグループの豊田です。

新卒で住友林業に入社し、3年間の営業経験を積みました。タジくんと同じく、当時同業界への課題感を感じていました。以前は全く異なる分野でエンジニアとして活動していましたが、建設業界における社会への貢献と課題解決への志から、フォトラクションに転身しました。

田島(以下、タジ):CREグループの田島です。

元々、サブコンで施工管理者として働いており、同業界への課題感を感じたこと、またエンジニアの職種に興味を持ったことからフォトラクションへ入社しました。とよかずさんと同じく未経験からエンジニアとしてCREチームに入りまして、ちょうど半年たったくらいになります。

※とよかず入社エントリーはこちら↓↓↓

kojichu.photoruction.com

Q.CREチームでの業務について教えて下さい!

よしき:主な業務としては、お客様からの問い合わせ内容(仕様の確認・調査依頼など)に対して、『どんな事象が起きているのか』『どういう操作をしたら再現がするのか』『なぜそのような不具合が起きているのか』などの1次切り分けをするのが私たちの業務になります。

また、弊社では運用レポートというものをお客様に提出していますが、こういったデータの抽出や修正なども対応しております。なので、カスタマーサポート(以下、CS)とSaaSチーム(開発チーム)との架け橋的な存在がCREになります。

CREチームリーダー よしきさん

Q.そもそもなぜ、CREというチームが必要なのでしょう?

よしき:お客様からの問い合わせへの対応が主な業務になるとお話ししましたが、問い合わせって不確実性の塊だなと思っていてそこにCREチームのような一定のエンジニアリング知識を持った人たちが、介入することによって、不確実なものを確実なものにしていくということが必要になってきます。そうすることで、CS側からの不具合の問い合わせをスムーズにSaaSチームにお渡しすることもできますし、そもそもCREチームで解決できる内容であれば、ユーザー様へのレスポンスも早くなるため結果としてユーザー様の知りたい情報を素早く提供でき、顧客満足度向上に影響を与える事ができると考えています。そのためユーザー様に少しでも長くフォトラクションというプロダクトを使用いただくためにも、CREというチームが必要だと考えています。

とよかず:ユーザー様からしたら、とにかく早くレスポンスが欲しいですもんね。仮にCREというチームが存在しないことを考えるとユーザー様への影響しかり、社内関係各所でも色んなところで、悲鳴の声が上がりそうです…

ちなみに、CREポジションで働く皆様に質問があるのですが…

Q.ずばりCREの業務について、意識してることを聞かせてください!

よしき:意識してることとしては、バランスよくタスクを振るような心がけをしています。現在CREに所属してるみなさんは、いずれSaaSチームに送り出す事が開発組織で決まっているので、そのためにも調査タスクだけでなく改修タスクもこなしていってもらうことで、プロダクトの理解を深めつつ、技術力向上を目指していってほしいので、そういった意味合いから、偏りがないように気をつけてはいます。

また、エンジニアとしての成長という観点からCREチームでは2週に1回、勉強会という時間も設けています。各々がわからない部分やもっと深掘りしたい部分などを共有し、それについて議論したり、お互いの技術力を向上させていこうという目的のもと、教材となる本をチームで読み進めたりしながら、技術の理解を深めたりしています。

僕のは、どちらかというとリーダー視点の話しですね(笑)

←とよひろさん よしきさん→

とよひろ:CREでは「こういうバグがありました、不具合があります」という問い合わせが来てそれに対応するフローですが、その問い合わせから「ユーザーが本当に求めていることは何か」、「機能としてはこうなった方がいいんじゃないか?」などユーザー目線に立って、考えるように意識はしています。また、ユーザーに近いからこそSaaSチームにも見えない部分を見ることがCREの業務の一つかなと思っています。

タジ:UIパーツの呼称がそれぞれのユーザー様で異なるので、その点を汲み取る事を意識してます。例えば、UIパーツにオン/オフするボタンをエンジニアだとトグルボタンと言ったりしますが、人によっては「スイッチ」といったりするので、呼称の違いを確認し、事実がなにであるかを確認していくことを意識しています。

もう一つ、ユーザーの操作動線の確認も意識してるポイントになります。自分たちはコードベースで動線を考えるため、「前提としてこうだよね」って考え方があり、そこがユーザー様の動線と異なる事があるので、その点も意識してたりします。

とよかず:CREって、プロダクト探偵っぽいですよね〜

問題があって、仮説を立てて検証して、原因を特定していくって、まさに探偵っぽいなと思ってます(笑)

ちなみに僕が意識してることとしては、CSとSaaSとの間に僕らのチームがいるので、CS側に伝わる話し方とエンジニアに伝わる話し方を分けるようにしていて、認識の齟齬が出ないように余分な情報を取り除くことでクリアなコミュニケーションを意識してたりします。

タジ:確かに、通訳っぽい面もありますね

よしき:探偵兼通訳ですね…(ボソッ)

とよかず:職種増えましたね(笑)

業務については、お話しいただけたので、今度はチームについて伺いたいのですが…

Q.チーム作りにおいて意識してる取り組みなどありますか?

考えるよしきさん

よしき:CREには現在、業務委託の方を含め7名在籍しているのですが、各々別々の調査タスクをやっているため、そこで分かったことや詰まっていることなどを朝のデイリーの時間で共有してもら

うことで、一人で抱え込まないチームづくりを意識してはいます。またその時間で、他の人が触った機能についてのシェアをするなどして、情報共有を活発にするような取り組みを行っています。

とよかず:確かに、デイリーがあることによって、自分が触っていないタスクについても、頭の片隅には置いてあって、自分がその機能触る時に初見じゃない感はありますね〜

タジくんはその点、意識してることなどありますか?

タジ:質問内容とは少し違うのですが、デイリーについて話しをすると、CREメンバーが増えたことで、デイリーの時間が延びてしまっている問題はありますね。

一同:(確かに!!!)

よしき:個人がこなしてるタスクについては共有をして、それ以外の個人で共有したい事項については、また別の時間で共有する方がいいかもね〜

ということで、早速これをデイリーで取り入れていこうと思います!

とよかず:(まさに、最速挙動💨)

こういった疑問に感じたことや思っていることをその場で発信して、それをすぐに実行→改善できるのがCREチームの良さかもですね。お互いに敬意尊尚という価値観を持っているからこそ、職位関係なく自分の思っていることを伝えられる気がします。

Q.チーム内でのコラボレーションや情報共有の取り組みはありますか?

よしき:時たま発生するイレギュラータスクで、チームの絆というか、コミュニケーションが促進されている感じはありますね〜

それ以外にも最近は、一人がタスクを抱え込まないようなやり方も試していて、2人1組でタスクにあたってもらうようなことも試していたりします。調査といえど、それぞれのやり方や着眼点があったりするので、そういったところはお互いに刺激しあって、学んでいってもらいたい点になります。

とよかず:実際、自分以外の人のやり方って知る機会があまりないので、2人1組の取り組みはありがたいです。

Q.今後のCREチームとしての展望や目標について教えてください。

よしき:度々いってることになるのですが、チームの目標として「安定化」と「成長」というのを掲げており、安定化については「三方良し」を実現できればいいなと思っています。CREにおける三方良しとは、CRE・SaaS・CSかなと思ってまして、CS側については社内での体制変化もあり、注力してた部分はあるのですが、SaaSチームとの連携がうまくいかない部分があったので、その点を今後は注力しながら、お互いにスムーズに仕事を進めて行ければいいなと思います。

また成長については、チームとしての成長を目指しつつもメンバークラスの方々の成長を第一に考えています。CREチームでプロダクトへの理解を深めつつ、改修タスクなども行い、その中でエンジニアとしての成長を目指してもらい、最終的にはSaaSチームの一員となって第一線で活躍してもらいたいと考えています。そのためにも、一定の水準までスキルを伸ばせる仕組みを作っていくことが、今後の課題かなと思います。

最後は競馬の話で盛り上がっていました〜(笑)

おわりに

今回は自分のチームに対して、インタビューしましたが、改めて他のメンバーが意識してることを聞くことができ、自分の中での新しい気づきが増えました!その気づきを今後の業務の中でも積極的に意識していこうと思います!

これからもCREチームでは、ユーザー様に寄り添っていけるプロダクトを作れるようにチーム一丸となって業務に取り組んでいきたいと思いますので、応援のほどよろしくお願いします🙇‍♀️

株式会社フォトラクションでは一緒に働く仲間を募集しています

Zapierを使ってSlackのメッセージからNotionのDBにタスク追加

はじめまして、CREエンジニアの田島です。

今回は、Zapierを用いたNotiion⇄Slack連携について紹介したいと思います。

背景


弊社ではチャットツールとしてSlackを使用しています。当然、業務上のコミュニケーションはSlack上で交わされるわけですが、そこでタスクを振られることがあります(上長からだったり、他部署からだったりと状況は様々ですが)。

振られたタスクの優先度が低いなら、とりあえずブックマークしたいところですが、Slackのブックマークでは後々の管理がしんどいですよね。

だからといって、JIRA等のツールで管理するほどでもないしなーってとき、NotionのDBにタスクを投げ込みたい、そんな方のための記事になっています。

事前準備


各種ツールのインテグレーションは割愛します。

NotionでDBを配置するページにZapierコネクトが追加されていることを確認してください。

概要(動作イメージ)


Slackのメッセージに対してリアクションをすると、そのメッセージの内容をNotionのDBに追加できるようにします。

タスク投げ込み用DBの作成(Notion)


DBを用意します。DBには名前をつけておいてください(この場合、個人TASK)

プロパティは任意ですが、今回は上記画像のようにしました。

Zapを作成(Zapier)


1. Triggerを設定する

今回は、メッセージに対してリアクションが追加された時、をトリガーとします。

EventにNew Reaction Addedを指定します。

続いてトリガーの条件を指定します。

どのチャンネルに、誰が、どんなリアクションをしたとき、のような設定が可能です。

2. Formatterを適用する

Slackのメッセージが投稿された時間を依頼日としてDBに保存するため、日時をフォーマットします。

3. NotionのDBに追加する

EventはCreate Database Itemを指定します。

Databaseには、用意したNotionのDB名を指定してください。

後は、NotionのDBプロパティに合わせて設定を行ってください。

4. Zapを公開する

🎉Publishで完了です🎉

まとめ


業界的に、業務上使用するツールが多いですよね。

NotionやSlack単体でも各種ツールと連携することは可能ですが、間にZapierを挟むとかゆいところに手が届くかもしれません。

(NotionやSlackの今後のアップデートによっては、わざわざZapierを間に挟まなくても、やりたいことが実現できるようになるかもしれません。もしかしたらもうできるのかも。。。。)

株式会社フォトラクションでは一緒に働く仲間を募集しています

PDFの生成ができるライブラリReportLabの使い方

はじめに

こんにちは、AIエンジニアの志賀です。

このたびはPDFの生成ができるライブラリReportLabの使い方についての技術ブログをご覧いただきありがとうございます。

PythonReportLabというライブラリを使用すると、プログラムからPDFドキュメントを生成できます。

この記事では、ReportLabの基本的な使い方を解説します。

ReportLabを使ってPDFを生成する

環境のセットアップ

まず、PythonReportLabをセットアップします。

Pythonをインストール済みであることを確認し、ReportLabを以下のコマンドでインストールします。

pip install reportlab

基本的なPDFの生成

基本的なPDFの生成は以下のステップで行います。

まず、Pythonスクリプトを作成し、必要なモジュールをインポートします。

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

# PDFドキュメントの生成
c = canvas.Canvas("basic_pdf.pdf", pagesize=letter)

テキストを追加するには、以下のように drawString メソッドを使用します。

c.drawString(100, 750, "ReportLab")

このコードは、座標 (100, 750) にテキストを追加します。

次に、新しいページを追加するには以下のコードを使用します。

c.showPage()

これにより、新しいページが生成されます。テキストの他にもさまざまな要素を追加できます。

フォントとスタイルの設定

フォントとスタイルを設定することで、テキストをカスタマイズできます。

フォントの設定は以下のように行います。

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib import fonts

c = canvas.Canvas("styled_pdf.pdf", pagesize=letter)
c.setFont("Helvetica-Bold", 12)
c.drawString(100, 750, "Customized Text")

このコードは "Helvetica-Bold" フォントを使用してテキストを表示します。

テーブルの作成

テーブルはデータを整然と表示するのに役立ちます。

以下はテーブルを作成する基本的なステップです。

from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
from reportlab.lib import colors

doc = SimpleDocTemplate("table_pdf.pdf", pagesize=letter)
data = [["col1", "col2", "col3"],
        [1, 2, 3],
        [4, 5, 6]]

table = Table(data)
table.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, 0), colors.grey),
                           ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
                           ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                           ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
                           ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
                           ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
                           ('GRID', (0, 0), (-1, -1), 1, colors.black)]))

elements = [table]
doc.build(elements)

このコードは、データを含むテーブルを生成します。

図形の追加

ReportLabを使用して、PDFに図形を追加できます。

以下は簡単な例です。

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

c = canvas.Canvas("shapes_pdf.pdf", pagesize=letter)

# 線の描画
c.line(100, 100, 200, 200)

# 円の描画
c.circle(300, 150, 50)

# 四角形の描画
c.rect(400, 100, 100, 50)

c.save()

このコードは、線、円、四角形を描画し、PDFに保存します。

画像の挿入

画像の挿入も簡単です。

まず、PILライブラリを使用して画像を読み込みます。

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from PIL import Image

c = canvas.Canvas("image_pdf.pdf", pagesize=letter)

# 画像読み込み
image = Image.open("example.jpg")

# ReportLab ImageReaderに変換
image_reader = ImageReader(image)

# 画像を描画
c.drawImage(image_reader, 100, 100, width=200, height=150)

c.save()

このコードでは、"example.jpg" という画像をPDFに挿入しています。

PDFファイルの保存と出力

生成したPDFを保存するには、 save メソッドを使用します。

既にいくつかの例で使用していますが、以下に再掲します。

c.save()

終わりに

以上が、PDFの生成ができるライブラリReportLabの基本的な使い方の解説でした。

いかがでしたでしょうか。

是非、Python開発でReportLabを使って、PDFの作成をしてみてください。

株式会社フォトラクションでは一緒に働く仲間を募集しています

【tqdm】Pythonでコードの進捗を可視化!

こんにちは、エンジニアとして株式会社Photoructionでアルバイト中の伊藤純平です!

秋も深まり、「学びの秋」とも言われるこの時期は学びを深める絶好のチャンスかもしれません。今回は、Python開発で役立つプログレスバーのライブラリ、tqdmを詳しくご紹介します。

私のチームではPDFを扱うことが多く、PDFの分析や可視化などにおいて一つの処理が長くなってしまいます。コードがいつ実行し終わるのか、わからないと不安になりますよね。。。そんなときに便利なのがtqdmです。このライブラリを使えば、進捗を簡単に確認できます。

この記事では、tqdmの基本から便利な使い方までを解説します。機械学習や統計など一つの処理に時間がかかるコードが必要なプロジェクトに取り組んでいる方、またこれから取り組む方も、ぜひお読みください!

tqdmとは

概要

tqdmアラビア語で"進捗"を意味する"taqaddum"から来ています)は、Pythonで使える簡単で拡張性のあるプログレスバーのライブラリです。Pythonファイルだけでなく、Jupyter Notebookやgoogle colabでの利用も可能です。また、tqdm.autoというモジュールを使えば、実行環境に合わせて最適なプログレスバーが自動で選択されます。

下準備

はじめに、tqdmをインストールしておきます。以下のコマンドでtqdmをインストールできます。

pip install tqdm

基本的な使い方

基本的にはforループにtqdm関数を適用するだけで、プログレスバーが表示されます。

さらにtqdm.autoをインポートすると、コードが動作する環境に応じて適切なプログレスバーが自動で表示されるため、手動で環境を指定する必要がありません。

# tqdmライブラリをインポート
from tqdm.auto import tqdm
import time

# tqdm関数でプログレスバーを表示
for i in tqdm(range(100)):
        # この部分に実際の処理が入る
    time.sleep(0.1)

プログレスバー

このコードでは、0から99までのループを行い、各ステップで0.1秒待機します。この間、進捗バーが表示されます。進捗バーは以下のように読むことができます。

  • 72**%**: 現在の進捗をパーセンテージで表示します。
  • ██████████████: 完了した進捗を表すバーです。
  • 72/100: 処理が何回完了したかと、全体で何回の処理があるかを表示します。(画像では: 72回完了、全体は100 回)
  • 00:07<00:02: 経過時間と推定残り時間を表示します。(画像では: 経過7秒、残り**2**秒)
  • 9**.88s/it**: 1ループ処理にかかる平均時間を表示します。

様々な使い方

ネストされたループ

tqdmはネストされたループでも使えます。以下の例では、外側と内側の2つのループがあります。descオプションを使って、各プログレスバーに説明文('外側のループ''内側のループ')を追加しています。

# tqdmライブラリをインポート
from tqdm.auto import tqdm
import time

# descオプションで説明文を設定。
for i in tqdm(range(3), desc='外側のループ'):
    # descオプションで説明文を設定。
    for j in tqdm(range(3), desc=' 内側のループ', leave=False):
                # この部分に実際の処理が入る
        time.sleep(0.5)

コード内情報の表示

プログレスバーにはコード内の情報も表示できます。進捗情報だけでなく、現在の処理に関する追加の情報を表示するのに便利です。

# tqdmライブラリをインポート
from tqdm.auto import tqdm
import time

# postfixで初期の「現在の値」を0に設定
with tqdm(total=100, postfix={'現在の値': 0}) as pbar:
    for i in range(100):
                # この部分に実際の処理が入る
        time.sleep(0.1)
        # プログレスバーを1進める
        pbar.update(1)
        # プログレスバーの「現在の値」を更新
        pbar.set_postfix({'現在の値': i+1})

処理速度と残り時間

デフォルトで処理速度や推定残り時間も表示されます。これで処理がいつ頃終わるのかがわかりますね。

終わりに

tqdmは、コードに数行追加するだけでプログレスバーを表示することができ便利です。

バーのデザインやコード内の情報の可視化も**tqdm**のライブラリを用いることで実装できます。

是非Python機械学習などの時間がかかる処理が必要な際には、このtqdmライブラリも試してみてください!

株式会社フォトラクションでは一緒に働く仲間を募集しています