Quantcast
Browsing Latest Articles All 4321 Live
Mark channel Not-Safe-For-Work? (0 votes)
Are you the publisher? or about this channel.
No ratings yet.
Articles:

テスト関連用語の英語表現

テスト関連用語(開発関連も含む)はそもそもカタカナ英語で既に使われている用語も多いので、
そんなものは除外し、よく使う用語だけピックアップ。
並び順はてきとー

日本語英語備考
テスト設計Test Designカタカナ英語の「デザイン」のイメージが強すぎて一瞬ピンとこない
テスト条件Test conditionsカタカナ英語の「コンディション」のイメージが強すぎて一瞬ピンとこない
テスト対象Test object
境界値分析Boundary Value Analysis略語はBVA
同値分割Equivalence Partitioning:
状態遷移State Transition
状態遷移図State transition diagram
状態遷移表State Transition Table
エラー推測Error Guessing
探索的テストExploratory Testing
回帰テストRegression Testing
再テストRe-Testing
非機能テストNon-functional testing「機能テスト」は「Non-」を外せばいいだけ
受け入れテストAcceptance testing
性能テストPerformance testingロードテスト(Load testing)とごっちゃになりやすいが、ロードテストは性能テストの中の一種
期待結果Expected result
実際の結果Actual resultsバグレポートの時につかうやつ
殺虫剤のパラドックスBeware of the pesticide paradoxソフトウェアテストの7原則に出てくるやつ
市販ソフトウェアCommercial off-the-shelf略語はCOTS
カンバンKanbanアジャイルな開発で使うフレームワークのやつ
本番環境Production environment.
セキュリティの脆弱性Security vulnerabilities
品質特性Quality characteristics
確認テスト/改修確認Confirmation testing:日本語の方は、現場によると思うが「確認テスト」という言い方より「改修確認」と言われている方が多い気がする・・・
動的テストDynamic testingカタカナ英語の「ダイナミック」のイメージが強すぎて、一瞬ピンとこない
振る舞いベースの技法Behavior-based techniques「振る舞いベースの技法」なんて回りくどい言い方はせず、普通にブラックボックステストと言えばいい
構造ベースの技法Structure-based techniques「構造ベースの技法」なんて回りくどい言い方はせず、普通にホワイトボックステストと言えばいい
開始基準Entry criteria「Start criteria」と言ってしまいそう。伝われば別にどっちもでいいのかも
終了基準Exit criteria「End criteria」と言ってしまいそう。伝われば別にどっちもでいいのかも
非機能特性Non-functional characteristics
再評価Re-evaluating
偽陽性False positives「偽陽性」という、人生のうちでたぶん数回しか使わない日本語・・・
再実行性Repeatability繰り返し実行する時のやりやすさ、みたいな時使うやつ

【1ヶ月で学ぶ!】Back-end Developperへの道 #11日目 : Web Security Kowledgeとは(後半)

下記の企画の11日目です。
【1ヶ月で学ぶ!】Back-end Developperへの道 #0:導入

下記を参考に項目を作成しました。
Roadmap to becoming a web developer in 2020

Web Security Kowledge

HTTPS

  • HTTPによる通信をより安全に(セキュアに)行うためのプロトコルおよびURIスキーム
  • SSL/TLSプロトコルを用いて、サーバの認証・通信内容の暗号化・改竄検出などを行う
  • これによって、なりすまし・中間者攻撃・盗聴などの攻撃を防ぐ

Content Security Policy

  • クロスサイトスクリプティング (XSS) やデータインジェクション攻撃などのような、特定の種類の攻撃を検知し、影響を軽減するために追加できるセキュリティレイヤー
  • サーバサイドからブラウザに対してコンテンツの使用ポリシーを伝えて各種攻撃を回避する
  • CSP を記述することで、コンテンツの提供元や取得方法(HTTPS経由のみ取得可能など)を制限することができ、コンテンツ提供者が意図しないコンテンツを読み込ませることを阻止することができる
  • コンテンツには実行可能なスクリプトも含まれているため、第三者による悪意のスクリプトの実行を制限することができる

CORS(Cross-Origin Resource Sharing)

  • あるオリジンで動いているアプリケーションに対して、別のオリジンのサーバーへのアクセスを安全に許可する仕組み
  • 同一オリジンポリシー下でも、異なるサイト間でリソースを共有(クロスサイトHTTPリクエスト)するためルール、手法

    • オリジン
      スキーム、ホスト、ポートの組み合わせ。いすれか1つでも異なるとオリジンが違うとみなす。
    • 同一オリジンポリシー(Same-Origin Policy)
      異なるオリジンのリソースへのアクセスに制約をかけるブラウザの機能

SSL/TLS(Secure Sockets Layer / Transport Layer Security)

  • ネットワークにおいてセキュリティを要求される通信を行うためのプロトコル
  • 通信相手の認証、通信内容の暗号化、改竄の検出を行う
  • HTTP以外にも多くのプロトコルにおいて採用され、クレジットカード情報や個人情報やその他の機密情報を通信する際など、様々なアプリケーションにおいて使われている

OWASP Security Risks(Open Web Application Security Project Security Risks)

  • OWASPとは、ソフトウェアのセキュリティ環境や、セキュリティを高めるための技術を共有・普及することを目的としたアメリカに本部を置くオープンコミュニティ
  • 以下の代表的なプロジェクトがある
    • OWASP ASVS
      Webアプリのセキュリティにおいて検証すべき事項を管理
    • OWASP ZAP
      安全性を分析できるWebアプリスキャナーを開発
    • OWASP OWTF
      効率的にセキュリティ検査するためのツールを開発
    • OWASP Testing Guide
      既知の脆弱性について内容・検査方法を管理
    • OWASP Top10
      開発者が優先して対処すべき脆弱性を共有

最新OWASP Top10(2017年)

  • インジェクション
    • 攻撃者がアプリケーションに攻撃用の文字列を注入(=インジェクション)すること
    • 例えば、Webアプリケーションのログイン用入力画面に、サーバのコマンドや、データベース操作言語であるSQLを注入する行為
  • 認証の不備
    • 認証とは、「正しいアクセス権をもつ人が、正しくアクセス権を得られる」ことであり、Webアプリケーションへのログイン等をする際に実施する行為
    • 認証の不備とは、正しく本人確認ができず、不正なアクセスを許してしまうこと。
    • 例えば、漏洩したパスワード等で第三者がWebアプリケーションなどにログインをしてしまう場合。
  • 機密データの露出
    • 意図せず重要なデータが第三者に見られてしまうこと
    • 例えば、クレジットカード番号などのような重要な個人情報が、暗号化されずにインターネット上を流れていると、盗聴がされていれば第三者に見られてしまう
    • また、クラウドなどではクラウドストレージ等に保存したデータを意図せず第三者に公開してしまっていた、というようなケース。
  • XML外部実体参照(XXE)
    • Webアプリケーションなどで多用されているXMLファイルの特徴を逆手に取った攻撃
    • Webアプリケーションはプログラミングを行い構築をするが、長文のプログラムは作成が大変なため「実体参照」といい、繰り返しを行うことができる仕組みになっている
    • この仕組みを悪用して、公開されていない外部のプログラムや機密情報を呼び込む
  • アクセス制御の不備
    • ユーザが与えられた権限以上の権限を持ってしまっている状態
    • 例えば、会社の平社員が、会社の役員レベルのみが参照できるファイルを見たり、操作できたりすることができる権限を持っているケース
  • 不適切なセキュリティ設定
    • いわゆる設定ミスや、知識不足による設定不備
    • 設定ミスはそれ自体がWebアプリケーションの脆弱性となってしまい、セキュリティ攻撃の格好の標的となる
  • クロスサイトスクリプティング(XSS)
    • あるWebアプリケーションにわなを仕掛けて、Webアプリケーション利用者を偽のWebアプリケーションに誘導させ、コンピュータウイルスを仕込んだり、ログイン情報を盗んだりする攻撃
    • 一般的に、Webアプリケーション利用者に被害が大きく出てしまう
  • 安全でないデシリアライゼーション
    • デシリアライゼーションとは、データ変換のこと
    • これが安全に行われない場合、攻撃者が悪意のあるプログラムを実行したりデータを抜き取ったりできてしまうことがある
  • 既知の脆弱性を持つコンポーネントの使用
    • Webアプリケーションが動くためのプログラミング言語、フレームワーク、サーバーといった部品は、セキュリティの穴である脆弱性が発見されるたびにアップデートやパッチが公開される
    • パッチを適用せずに脆弱性がある状態でアプリケーションを稼働させ続けると、セキュリティ攻撃の標的になることがあり危険
  • 不十分なロギングとモニタリング
    • 万が一攻撃をされてしまっても、きちんとモニタリングをしていれば早期発見をおこなうことで被害を最小限に食い止めることができる
    • またログをきちんと保管しておくことで、攻撃者に対し訴訟を起こすための証拠にもなる
    • 万が一に備え、十分にロギングとモニタリングを行う仕組みを用意することは大変重要である

参照

HTTPS - wikipedia
Transport Layer Security - wikipedia
Contents Security Policy(CSP)のお勉強 - Qiita
同一オリジンポリシーとCORS - Qiita
OWASPとは?開発者が注意すべきセキュリティリスクについて ...

Java SE 7/8 Bronze 合格体験記 ーオンライン受験verー

※2020年6月13日受験時の情報です。

2020年6月、外出自粛中にオンライン受験でJava SE 7/8 Bronzeに合格しました!
と、いうことで、オンライン受験の方法や勉強方法などについてまとめてみようと思います。

ちなみに勉強方法・受験方法の順で書くので、
受験方法だけ知りたい方は次のリンクをぽちっとどうぞ!
受験方法へGo

※まとめるために調べていたら、Java SE 7/8 Bronzeが配信されているのは2020年7月31日までなんですね!それ以降はJava SE Bronze (1Z0-818-JPN)が後継の資格になるようです。

Java SE 7/8 Bronzeとは

Oracle社が運営する認定資格試験のうちの一つで、言語未経験者向けの入門資格。
Javaプログラムの基本的な文法やオブジェクト指向の知識を持っているかが試される。

項目内容
出題形式選択問題
試験時間65分
出題数60問
合格ライン60%
受験料(税抜)¥13,600(税込み¥14,960)

試験詳細ページ

【個人的感想】
入門資格とはいえ、Java書けるし...と勉強しないで挑むのは危険です!
オブジェクト指向の概念と試験問題でひっかけてくる文法ルールを押さえるために試験対策の勉強は必要でしょう...。

私のスペック

  • 新卒2年目
  • 理系出身エンジニア
  • Javaの実務経験なし

研修等で触った経験はあるが1年のブランクで記憶があやsii...という状況でした。

なぜ受験しようと思ったか

  • オブジェクト指向に興味があった
  • 普段フロント周りの業務を行っているので、あえて別の資格に挑戦しようと思った
  • Javaの勉強をしたらサーバーサイドの知識も少しつくかなという期待

勉強方法

勉強時間

 勉強時間:25~30時間
 平日・休日何時間ときっちり決めず、約1か月間少しずつ勉強を進めていました。 

参考書

上記2冊の参考書で勉強しました。使い分けとしては、

「スッキリ...」:基本的なオブジェクト指向とJavaの知識を勉強。(実践含む)
「徹底攻略...」:スッキリを解いた後に知識確認として問題を解く。+模擬問題集で試験問題の把握。

というように「勉強用」と「確認用」で参考書を分け、スッキリを解いて、問題集を解いて...と並行して使っていました。試験直前は模擬問題だけ何度か解いています。

【個人的感想】
時間がなく試験対策に特化したいなら「徹底攻略」のような参考書1冊でも十分対策ができると思います。
初めからまともに問題を解くと知識がなくてつまりますが、分からない部分はガンガン飛ばして答えを確認し、繰り返して解きなおすことで、問題傾向を知る+解説で学ぶ。ができます!

文字ばかりだと内容が頭に入らない。手を動かして学びたい人は「スッキリ」も読むことがお勧め!
イラストも多くオブジェクト指向の解説など、かなり分かりやすかったです!👏
(ただし試験対策本なしに「スッキリ」だけだと受験は難しそう...。)

受験方法

受験までには

 1. アカウント作成
 2. 受験申込
 3. 実際の受験

の流れがあります。

申し込みの手順にフォーカスして書かれる記事もあるなど、受験前の手順は少々ややこしいです。
受験日が決まってなくとも、まず初めに1. アカウント作成だけでも終わらせてしまいましょう!

1. アカウント作成

受験のために2つのアカウントが必要となります。
 1. Oracle.com アカウント
 2. ピアソンVUEアカウント

受験前に必要な手続きはもちろん公式ページにも書いてあるのですが、
下記の記事がスクショ付きで分かりやすかったので、スッと説明を譲ります...。

Java Bronze資格試験の申し込み手順がややこしすぎるぅぅぅぅ泣

アカウントがないと申し込みをしたいタイミングで申し込めないので、先に作っておくとよいと思います。
認証作業というものに少し時間がかかるのです。

2. 受験申込

受験の申込みはピアソンVUEから行うのですが、受験料の支払い方法には2通りの方法があります。

 1. 受験チケット(6ヶ月間有効)だけ先に買う。その後受験日直前にチケットを使って受験申込。
 2.受験申込時にクレジットカードで受験料を支払う。(オンラインの申込みの場合、申込み後48h以内の受験が必要)

支払いタイミングの違いですね。
また受験チケットだと場合によっては安く買えることもあるようです。(再販パートナーの割引?)

ただ、受験申込自体はどちらでも必要になるので、個人的には2がおススメです。

【受験チケット購入での失敗小話】

泣く泣く見送る「オラクル認定資格試験 再受験無料キャンペーン」...
2019年12月頃~2020年5月31日まで、1度受験失敗しても無料で再受験できるというオラクルのキャンペーンがありました。
(割と定期的に開催されているようです!)

-- 5月末日の3日前


「無料で再受験できるし、折角だから5月中に受験しよー」


Java SE 7/8 Bronze公式ページ


「ふんふん。支払い方法が2つあって、申込んだら2日以内に受験しないといけないのかー」
「じゃあ、チケット先買ってそれから申し込もう。早めの準備が大事だからね!(ドヤ)」


48394458-6751-4E25-A485-3FB8D0F8A95B.png


画面右の赤丸部分をぽちっと押してチケットを購入しました。


-- メール届く


01666C71-C71B-4EC1-9308-0B5D2AFC9DF6.png


「よし受付が完了...。いや、受付処理は終了してません...?あれ、チケットっていつ使えるようになるんだ?」


-- 受験チケットの購入前に必ずご確認くださいページを見る。


D69DE0E3-8A3D-4613-B0DC-FC93A1A8D3DA.png


「み、3営業日前後かかる...だと...!?」


-- 4日後
受付完了メールが届きました。
...うーん6月🙄


と、いうことで5月までのオラクルキャンペーンに間に合わなかったのでした。


オンラインのチケットだからすぐに届くわけではないのです...。
皆さんは注意書きをしっかり読みましょう。


やはり私のオススメはこちら。

 2.受験申込時にクレジットカードで受験料を支払う。(オンラインの申込みの場合、申込み後48h以内の受験が必要)


3. 実際の受験

スクショなどがなく詳細説明ができないのですが、アカウントページ(おそらくOracleの)からサクサク受験は始められます。

カメラで身分証明書を写して...なども特になく、模擬試験を受けるくらいの手軽さで受験できました。

逆に心の準備が間に合わず、しばらくドキドキしながら問題解いていました。
落ち着いて深呼吸してください。
 

結果

当日中に、試験結果が見れるようになった旨のメールが届きました。

-- 結果確認

合格!やったね!

最後に

受験しての感想をば...。

1問1分な問題数なのであまり回答時間の余裕はありません。
やはり、何かしらで模擬問題を解いて時間配分はつかんだ方が良いと思います。

冒頭の受験目的は果たせたのでしょうか?

  • オブジェクト指向に興味があった

→オブジェクト指向の考えは受験前より深まったと思います。

  • 普段フロント周りの業務を行っているので、あえて別の資格に挑戦しようと思った

→受験・合格したので、挑戦は無事果たせましたね!

  • Javaの勉強をしたらサーバーサイドの知識も少しつくかなという期待

→流石にサーバーサイドの知識はこれだけではつきませんでした...!
ただ少しは...という点では、今回勉強した知識を経て以前よりサーバーよりの事柄にも少しはとっつきやすくなった気がしています。

さて、ここまで読んでいただいた皆さん。ありがとうございます!

書き始めてから月末に試験配信が終了することを知るという出遅れ感のある記事でした...。なんだか申し訳ない...。

ただ、新しい試験も似たような形式のようなので(オンライン受験もあるし)そちらを受ける際にも多少参考にはなるかなと思っています...!

この記事が、何かのお役に立つと嬉しいです。

それでは!

Ransack Gemを用いた検索機能の実装(マイクロポスト編)

初めに

(前回に続く形になります。)
ここではRailsチュートリアルで作成したSample Appへのマイクロポスト検索機能の実装を目的としています。(Sample Appはtwitterライクなwebアプリケーションです。ユーザーやマイクロポスト、ログイン/ログアウトなどの認証機能を持っています。)

Rails チュートリアル
https://railstutorial.jp/

マイクロポスト検索

目標:ログイン時のホーム画面と各ユーザーのプロフィール画面で、マイクロポストコンテンツの検索、検索結果の表示を実現する。

・手順
開発環境は前回と同じ。まだransack gemを追加していない場合は追加する。
同様に、パーシャルに検索フォームを作成し、コントローラーに機能を加え、各ビューに反映させていく。

実装

app/views/shared/_microposts_search_form.html.erb
<%= search_form_for @q, url: @url do |f| %>
  <%= f.label :content_cont, 'Micoropost Search' %>
  <div class="input-group">
    <%= f.text_field :content_cont, placeholder: "Enter keyword...",
                      class: 'form-control' %>
    <span class="input-group-btn">
     <%= f.submit 'Go', class: "btn btn-primary" %>
    </span>
  </div>
<% end %>

検索条件にcontent_contとすることでMicropost(@qで定義)のcontentを検索します。
前回との大きな違いは、url: @urlの部分になります。search_form_forのデフォルトの送信先は検索モデルのindexアクションになるため、送信先を指定する必要があるからです。ここでは送信先が2つ(ホーム画面とプロフィール画面)あるため、インスタンス変数を用いています。

app/controllers/static_pages_controlle
defhomeiflogged_in?@micropost=current_user.microposts.buildifparams[:q]&&params[:q].reject{|key,value|value.blank?}.present?@q=current_user.feed.ransack(microposts_search_params)@feed_items=@q.result.paginate(page:params[:page])else@q=Micropost.none.ransack@feed_items=current_user.feed.paginate(page:params[:page])end@url=root_pathendend

@q = current_user.feed.ransack()と書くことで、モデルに記述されてあるfeedメソッド(ユーザーのステータスフィードを返す)を利用しています。
検索しない場合は@q = Model名.none.ransackとする必要があります(nilは使えない)。
フォームの送信先は@url = root_pathで指定。

app/controllers/users_controller
defshowredirect_toroot_urlandreturnunless@user.activated?ifparams[:q]&&params[:q].reject{|key,value|value.blank?}.present?@q=@user.microposts.ransack(microposts_search_params)@microposts=@q.result.paginate(page:params[:page])else@q=Micropost.none.ransack@microposts=@user.microposts.paginate(page:params[:page])end@url=user_path(@user)end

@urlにはuser_path(@user)を代入。

app/controllers/application_controller
privatedefmicroposts_search_paramsparams.require(:q).permit(:content_cont)end

microposts_search_paramsは、UsersControllerとStaticPagesControllerの両方から利用されるため、ApplicationControllerに記述。

また、MicropostControllerのcreateアクションの投稿が失敗した際の処理では、MicropostContorollerからホームのviewをrender(redirect_toではなく)しているため、@qが必要になります。そのため、そこだけ@q = Micropost.none.ransackと直しておく必要があります。

app/views/static_pages/_logged_in_home.html.erb
  ~
  <div class="col-md-8">
    <div class="col-md-4">
      <h3>Micropost Feed</h3>
    </div>
      <div class="search_form">
        <%= render 'shared/microposts_search_form' %>
      </div>
    <%= render 'shared/feed' %>
  </div>
  ~
app/views/users/show.html.erb
  ~
  <div class="col-md-8">
    <%= render 'follow_form' if logged_in? %>
    <% if @user.microposts.any? %>
      <div class="col-md-4">
        <h3>Microposts (<%= @user.microposts.count %>)</h3>
      </div>
      <div class="search_form">
        <%= render 'shared/microposts_search_form' %>
      </div>
      <ol class="microposts">
       <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
  ~

ビューに戻り、_microposts_search_form.html.erbをそれぞれに挿入したら実装完了。

最後に

参考にした記事は前回と同じです。
テストに関しては、統合テストに検索後に期待したマイクロポストが画面上に表示されているかを、ホーム画面とプロフィール画面の両方に行う形で記述すれば良いと思います。
最後まで閲覧いただいた方、ありがとうございます。ご指摘などあれば、ぜひコメントいただければと思います。

初心者のためのpandas基礎③matplotlibでヒストグラム作成

pandasとは

Pythonにて、構造化データを扱うためのデータフレームオブジェクトです。ファイルの読み込みやその後のSQL操作などを簡単に行うことができ、機械学習にてデータを加工し、計算、可視化する作業に必要となります。データ操作によく使う構文をメモ書き的にリストします。本項はデータの読み込み&加工です。

ヒストグラム

ヒストグラムは前準備の段階のデータ確認で多く使用します。今回はmatplotlibとうライブラリを使用します。Excelでやると面倒なヒストグラムが簡単に作成できます。データはおなじみのタイタニックのデータを利用しました。

ライブラリインポート&データ読み込み

pandasにpdという名前をつけてimportする。今回は、matplotlib.pyplotもpltという名前をつけてインポート。サンプルデータがタイタニックのもの利用

importpandasaspdimportmatplotlib.pyplotaspltdataframe=pd.read_csv('train.csv')dataframe.head()

ヒストグラム作成

年齢(column「Age」)にてヒストグラム作成します。dropna()にて欠損値をドロップします。

plt.hist(dataframe['Age'].dropna(),bins=10,range=(0,100),color='Blue')plt.show()

スクリーンショット 2020-07-09 14.29.30.png

bins(表示する瓶の数)、range(データの幅)、clor(色)を指定します。

ヒストグラム作成(正規化)

正規化し全体の合計が1になるようにします。

plt.hist(dataframe['Age'].dropna(),bins=20,range=(0,100),color='Blue',normed='true')plt.show()

スクリーンショット 2020-07-09 14.36.59.png

タイトル等追加

見やすい様にタイトル等を追加します。

plt.title('Age Histogram',fontsize=14)plt.xlabel('Age',fontsize=14)plt.grid(True)plt.hist(dataframe['Age'].dropna(),bins=20,range=(0,100),color='Blue')plt.show()

スクリーンショット 2020-07-09 14.57.21.png

.title(タイトル)、.xlabel(X軸ラベル)、.grid(グリッド)を追加します。

<応用>積み上げ表示

男性(male)と女性(femal)の内訳表示を積み上げ表示を使って表示します。プロットの準備として、malelist_mとmalelist_fをそれぞれ定義します。

malelist_m=dataframe['Sex']=='male'malelist_f=dataframe['Sex']=='female'plt.title('Age Histogram',fontsize=14)plt.xlabel('Age',fontsize=14)plt.grid(True)plt.hist([dataframe[malelist_m]['Age'],dataframe[malelist_f]['Age']],bins=20,range=(0,100),color=['Blue','Red'],label=['male','femal'],stacked=True)plt.legend(loc="upper right",fontsize=14)plt.show()

スクリーンショット 2020-07-09 15.59.04.png

複数積み上げたい場合は、hist([X1,X2])のように表記します。stackedをTrueにすると積み上げます。(Falseだと併記)labelにて凡例を定義します。.legendにて凡例を追加します。

【GAS & LINEWORKS】最寄駅を検索してくれる Bot を作ってみた

気づいたら異世界に召喚されていて見覚えのない場所に・・・なんて、よくある話ですよね!

お酒飲んだときに、気持ちよくなってお星さまを眺めてたらあっという間に朝になり、いつの間にか見知らぬ土地にワープさせられれてたり。
ちょっと気になる路地裏を見つけてふらりと入り込んでみたら、異界の街に辿り着いて帰り道がわからなくなったり。
ふと知らぬ駅に降りてみたら、お猫様が「ついてこいよ(イケメソ)」ってしっぽを振ってたからついていったら、たくさんのお猫様に囲まれて帰れなくなったり。

よくある話ですよね!(*‘∀‘)

そんなとき、妖精さん(Bot)に現在位置を送れば最寄駅の情報を教えてもらえるなら安心ですよねー。

ってなわけで、作ってみましたので紹介したいと思いまーす

どんな仕組み?

LINEWORKS のトーク画面から Bot に位置情報を送信すると、緯度経度から最寄りの駅を検索して教えてくれます。それだけ!

実際の画面

ss1

利用した技術

GAS は本当に便利。
LINEWORKS もトーク Bot は無料で使えるからとても便利。

HeartRails Express API は今回初めて使いました。
緯度経度から最寄り駅検索できるとか珍しい API があったので!
特に登録とかも必要なく、URL 叩けばデータをくれるのでとても使いやすかったです。

Bot を登録して使ってみる!

私が提供している GoogleAppsScripts のライブラリを使用して簡単に Bot を実装できるようにしました!

ってなわけで、使ってみたい方はまずは LINEWORKS ライブラリを GoogleAppsScripts に登録してくださいませ。

LINEWORKS ライブラリを登録する

ライブラリ名スクリプト ID
LINEWORKS1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod
  1. GoogleAppsScripts 画面上部の「リソース」-「ライブラリ」をクリック
  2. [Add a library] の欄に 1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod を入力して追加ボタンをクリック
  3. 「LINEWORKS」ライブラリが追加されるので、一番新しいバージョンを選んで保存ボタンをクリック

登録できたらコードを書いていきます。

GoogleAppsScripts にコードを書く

以下、コピペしてくださいな。

app.gs
constobj={"apiId":"xxxxxxxxxx","consumerKey":"xxxxxxxxxxxxxxxx","serverId":"xxxxxxxxxxxxxxxxxxxxx","privateKey":"-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----","botNo":null};constadminId="xxx@yyy-zzz";constdomainId=xxxxxxxx;constcallbackURL="https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxx/exec"functionregBot(){LINEWORKS.regFindTheNearestStationBot(obj,adminId,domainId,)}functiondoPost(e){if(e==null||e.postData==null||e.postData.contents==null)return;constrequestObj=JSON.parse(e.postData.contents);constaccountId=requestObj.source.accountId;constx=requestObj.content.longitude// 経度consty=requestObj.content.latitude;// 緯度// HeartRails Express API// http://express.heartrails.com/api.htmlconsturi="http://express.heartrails.com/api/json?method=getStations&x="+x+"&y="+y;constoptions={"method":"get"};conststations=JSON.parse(UrlFetchApp.fetch(uri,options)).response.station;stations.forEach(station=>{LINEWORKS.sendMsg(obj,accountId,station["line"]+station["name"]+"駅まで"+station["distance"])});constitems=[{"action":{"type":"location","label":"位置情報を送信"}}];LINEWORKS.sendQuickReplyMsg(obj,accountId,"位置情報を送信すると最寄駅を検索します",items);}

以下の部分を自分の情報に書き換えます。
apiId などの LINEWORKS の情報は Developer Consoleで確認します。

変数名
apiIdDeveloper Console で API ID を確認
consumerKeyDeveloper Console で Server API Consumer Key を確認
serverIdDeveloper Console で Server List(ID登録タイプ)の ID を確認
privateKeyDeveloper Console で Server List(ID登録タイプ)の認証キーを確認
("-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9...\n-----END PRIVATE KEY-----" となるように \n と \n の間に認証キーを入れて一行で表記します)
botNoあとで記入します。今は null のまま
adminIdLINEWORKS の管理者権限を持つユーザ ID
callbackURLGoogleAppsScripts の「現在のウェブ アプリケーションの URL」を確認
(取得方法がわからない方はこちらを参照してください)

なお、LINEWORKS なんて初めて使うからわかんないよ!という方は公式をご確認いただくか、もしくはこちらの方の記事がわかりやすいと思います。
LINE WORKSで初めてのBot開発!(前編)

Bot を登録する

準備ができたら、GoogleAppsScripts 画面の上部にある「関数を選択」をクリックして regBotを選択し、隣の▶ボタンを押して実行します。

すると、LINEWORKS にトーク画面に登録が完了した旨のトークが届きます。
1594277788.png

ここで表示された botNo を先ほどスルーした変数 botNoに設定します。

設定したら画面上部メニューの [公開] - [ウェブアプリケーションとして導入] から、もう一度 Script を公開して完了です。
このとき、バージョンを NEWにするの、忘れないでくださいね~(*‘∀‘)

位置情報を送信!

位置情報を送信ボタンを押すと、地図画面に切り替わります。
1594278218.png

ss2

真ん中の 地図を添付 >を押すと位置情報が送信されて最寄り駅の情報が送られてきます。

ss1

これで完成です!

おわりに

ここまでお付き合いいただきありがとうございました。
LINE Bot で作ってる方がいたので見ながら作ってみました。

いやー、やっぱり動くもの作るのは楽しいですね~♪
位置情報を拾えるって面白いですよね。
迷子もそうですけど、落とし物拾った場所とか記録できますもんね。
何か面白い使い方ないかな~。

今回の Bot のためにライブラリにクイックリプライを追加してみました。
LINEWORKS.sendQuickReplyMsg

クイックリプライは便利なので今後も使っていこうと思います!

そう言えば Bot のアイコン LINEWORKS の公式の使っているのですが、何か味気ないですよね・・・種類が増えてきたからなおさらそう感じます。
自分で作れれば良いのですが、私のアイコンの通りの画力なので。。。誰か作ってくれるナイスガイがいらっしゃったら連絡いただけると大喜びしますw

次は何を書こうかな~。ではまた!(^^)/

参考にさせていただきましたm(_ _)m

GoogleAppsScript 公式サイト
LINEWORKS Developers
HeartRails Express API

【LINE bot】最寄駅検索bot
LINE WORKSで初めてのBot開発!(前編)

デザイン4つの基礎原則

 基礎原則

1 近接

 ・人間の心理で、近くに並べたものを無意識のうちにグループとしてみなす心理が働く。

 ・同じ要素のグループは近くに配置し、距離をとることによりグループの境界が明白になり、ハッキリとしたデザインになります。

2 整列

 ・デザインの要素を整列させることにより、見た目が整いすっきりしたデザインになります。
 
 左右整列例 : 右揃え 中央揃え 左揃え
上下整列例 : 上揃え 中央揃え 下揃え

 ・仕事でPowerPointなどでプレゼンの資料作成時に
整列するだけでも見やすさが変わり印象がよくなるので活用していきましょう。

3 強弱

 ・デザインで強弱をつけることにより、見た人が瞬時に理解できる早さが変わり、目で直感的に伝わるデザインになります。

 例として新聞などでも大きく見出しがあり、見て直感的にどんな内容なのかがわかり、瞬時に伝わってきます。

4 反復

 ・視覚的要素を繰り返し用いることにより、一貫性や統一感が出てまとまりのあるデザインになります。

参考サイト:https://webdesign-trends.net/entry/7810

”エンジニア”という仕事を辞めた話

私自身、過去に色々な記事(一例)を書いて来ましたが、今回で最後です。
この記事は、エンジニアを辞めようか悩んでいる人向けです。

私にとって、とてつもなく大きな転機でした。
様々な事情でキャリアチェンジを考えていらっしゃる方はぜひ読んで頂けると幸いです、きっと参考になると思われます。
逆に、ひたむきかつ順調に仕事に携わっていられる方には、合理的な理由ではありませんので納得出来ないしれません。

エンジニアを辞めた理由

まず前提として、プログラミングが嫌いで辞めた訳ではありません。
自画自賛のようで申し上げにくいのですが、適正はある上に周りの環境・人にも恵まれていたと実感しています。その事を前提に読んで頂けると幸いです。
私の性格と、会社構造の仕組みに悩み、色々考えた結果です。
以下にその要素を記述していきます。

①身近に死を体験し、考えを改めた

実家に大きな出来事がありました、実際に身内が亡くなった訳ではありませんでしたが、介護が必要となる事態でした。
ハイデッガーの実存哲学(死の哲学)ではありませんが、もし身内が急死した場合、私は後悔しないだろうかと思い詰めました。
また同様に、明日死ぬとしたら私はエンジニアという生涯で、何を残せて何を貢献出来るのだろうと考えました。
人生にブレイクポイントの設定はありませんしデバッグも出来ません、本当にどうしようも無い瞬間は突然来ます。

②完全リモート勤務が出来なかった

実家に大きな出来事があったり、地元が好きであるなどの理由から、地元に戻ろうと決意しました。
猶予はほとんどありませんでした。
地元にはIT企業はありません。あったとしても派遣会社の支店が市部に2社ほどあるだけでした。
完全リモートの会社を探したり、引き抜きの声をかけて頂いていた取引先ともお話させて頂きましたが、完全リモートは厳しく、少なくとも週に1日は出勤しなければいけない状況でした。今流行りのハンコ問題というのも少し関わっていたりします。

③好きではなかった。

ハンナ・アーレントの著書、人間の条件を読んでからずっと悩んでいました。
私は、死ぬまでこの仕事を続けて、何を得られるんだろうと考え続けていました。
プログラムを速く正確に書ける私にどんな意味があるんだろう。

今だからこそわかりますが、好みと適正の話で、単に好きではなかったんだと考えられます。

今の私と貴方へのアドバイス

私は今、子供と関わる仕事に携わろうと考え、最後をセンター試験を受験、無事に地元近辺の大学に通っています。
また、田舎なので周囲がITに疎く、入院患者の栄養管理アプリや、インフラ関係などを0円で手伝っています。
お金は学費と生活費でカツカツです...良心的な企業で、開発のお仕事があったら受けたいな、と探している最中です。
社会人時代と比べて、とても生活の質は下がりましたが私は今この上なく満足しています。

もし貴方が、エンジニアという仕事を辞めようと悩んでいられるのなら、周りが、そして貴方が明日死ぬとしたら?という事をぜひ考えてください。

死は突然来ますし、来てから対応出来るモノではありません。
貴方が本当にしたい事をすべきです。
コメント欄に相談や質問などがあればぜひ記入してください、返信させて頂きます。公開されたくないのでしたらメールアドレスを指定して頂ければより詳しくアドバイスさせて頂きます。

Vue.jsで超簡易的な映画検索アプリを作ってみた

はじめに

この記事は『2020年のフロントエンドマスターになりたければこの9プロジェクトを作れ』で紹介されていた

最初の
「Build a movie search app using React (with hooks)」 = Reactを使って映画検索アプリを作成する
というものをVue.js(Vue CLI)で簡易的に作ってみたものです。

完成したもの

search-movie.gif

この8ビット風のcssはNES.cssを利用させていただきました!

スクリーンショット 2020-07-09 22.28.38.png

APIについて

OMDb APIという映画検索APIを用いました。

https://www.omdbapi.com/?apikey=[yourkey]&s=hero

s=[検索したい文字列]で下記のようなjsonが返ってきます。

スクリーンショット 2020-07-09 22.22.28.png

※映画のポスター画像も取得できるのが便利です!

コード

Vue.js

vue-magic-gridと呼ばれる簡単にタイル状に並べてくれるライブラリを用います。

Movie.js
importMagicGridfrom'vue-magic-grid'importVuefrom'vue'letbaseUrl='https://www.omdbapi.com/?apikey=[yourkey]'exportdefault{name:'movie',data(){return{searchStr:'',results:[]}},methods:{// クリック時発火onClick:function(){// 何も入力されていない場合はAPI叩かないif(this.searchStr===''){return}// 検索用のURL作成baseUrl=baseUrl+'&s='+this.searchStr// axiosで非同期通信this.axios.get(baseUrl).then(response=>{this.results=response.data.SearchVue.use(MagicGrid)})}}}

HTML&CSS

v-modelを用いてテキストボックスの値(searchStr)を双方向データバインディングします。
ボタンでAPIを叩いて結果を表示してます。

<divclass="movie"><!-- 検索ボックス --><divclass="nes-field search-box"><inputtype="text"id="name_field"class="nes-input search-box__input"v-model="searchStr"placeholder="enter movie title"/><buttontype="button"class="nes-btn search-box__btn"@click="onClick">Search</button></div><magic-gridclass="posts-list"><!-- 単体 --><divclass="posts-item nes-container with-title is-centered"v-for="(post, index) in results":key="index"><pclass="title">{{post.Title}}</p><p>{{post.Year}}</p><img:src="post.Poster":alt="post.Title"></div></magic-grid></div>
.search-box{display:flex;&__input{width:80%;}&__btn{width:20%;}}.posts-list{margin-top:2.5rem;}.posts-item{img{width:100%;}}

終わり

こんな感じで映画のポスター付きで表示することができます!
コードはこちら

screencapture-localhost-8080-movie-2020-07-09-23_05_52.png

ステータスコードとポート番号がごっちゃになりそうだったので整理してみた

ステータスコードとは?

  • Webサーバーが、ブラウザからの要求に対して行うHTTPレスポンスの中に含まれる処理結果のこと。

  • 3桁の数字で構成されていて、最初の1桁目がカテゴリを表す。

※以下の表は代表的なステータスコードである。

ステータスコード意味説明
200OKリクエストが正常に完了したことを表す
302Foundリクエストされたリソースが一時的に別のURIに属していることを表す
401Unauthorizedユーザ認証に失敗したことを表す
403Forbiddenアクセス権限がないため、サーバーにリクエストの実行を拒否されたことを表す
404Not FoundリクエストURIに一致するリソースを見つけられなかったことを表す(ブラウザに入力したURIが誤っていたときのエラー)
500Internal Server ErrorCGIプログラムなど、サーバ内部のプログラム実行においてエラーが発生したことを表す

ポート番号とは?

  • コンピュータが提供するサービスを指定するための番号。

  • 代表的なプロトコルで使用されるポートは「ウェル・ノウン・ポート(well-known ports)」と呼ばれる。

※以下の表はウェル・ノウン・ポート番号である。

ポート番号プロトコル
20, 21FTP(ファイル転送)
22SSH(暗号化されたリモートコンピュータとの汎用通信)
23Telnet(リモートコンピュータとの汎用通信)
25SMTP(メール送信)
53DNS(ホスト名解決)
80HTTP(Webブラウジング)
110POP3(メール受信)
443HTTPS(暗号化されたHTTP)

【初心者でもわかる】デザインからコーディングする時の考え方(実践例あり)

どうも、7noteです。今回はデザインからコーディングに写すときのコーダーの頭の中を解説。

ところで「YOASOBI 夜に駆ける」はやってますね。私も1日中ループで「夜に駆ける」を聞いています。
(あ、雑談なので内容を知りたい人は次の見出しまで読み飛ばしてください。)

なんかいろいろな人が歌ってみたとかYoutubeとかで上げているので、自分も何かできないかなと考えたときにふと「夜に駆ける」のCDジャケットをみて、「これ、背景CSSで再現できるんじゃね?」と思って・・・作っちゃいました(笑)。

・・・と言うわけで、今回は流行りに便乗してCDジャケットを参考にして、CSSで再現してみました!

でも真面目な話、これ意外と練習になるんですよ。
まだコーダーの経験が浅い頃、休日のカフェでipadを使って注文カウンター上の掲示板メニューをCSSで再現したりして遊んでいました。

なぜこれが練習になるかと言うと、いままでならさらっとしか見たことないものでも、再現するとなると細かい部分まで見なければ作れません。
文字の大きさや色使い。余白の取り方など細部のデザインに気づくことができます。

またデザインからタグの組み方をああしようかなこうしようかなと構成を考えられるので、コーディングの作業スピードを上げることができます。

初心者の人向けに、まずはそのタグの構成の分け方や考え方からいっしょに見ていきましょう。
コーディングができる人の考え方や頭の中の構造や構成が参考になれば嬉しいです!

完成予定図

YOASOBI.png
※amazonより引用

デザインをタグレベルに分解

最初にも書きましたが、流行りに便乗して YOASOBI 「夜に駆ける」 のCDジャケットを作っていきたいと思います。
まずはこのデザインを見た目から分解していきます。いくつか重なっているところも考えて重なっている後ろのパーツから考えていきます。

これは人によって若干違いはあると思いますが、今回はこのように分解してみました。

  • 一番背景にある赤
  • 赤背景の上に乗っている網のような模様
  • 網模様の下の薄茶色いブロック
  • その薄茶色い下にある床?っぽいデザインのとこ
  • 人の絵(ここだけ画像予定)
  • 左の文字(YOASOBI)
  • 右の文字(夜に駆ける)

全部で7種類に分けました。これはデザインを分解しただけなので、
これをタグに置き換えて考えていきます。
HTMLのタグに置き換えるとこんな感じかな?

index.html
<divclass="jacket"><divclass="building"><!-- ビルの上っぽそうなのでそのパーツを1まとまりにしました --><divclass="ami"></div><!-- 網っぽいところ --><divclass="block"></div><!-- ブロックっぽいところ --><divclass="tile"></div><!-- 床っぽいところ --></div><pclass="left_text">YOASOBI</p><!-- 左の文字 --><pclass="right_text">夜に駆ける</p><!-- 右の文字 --><figure><imgsrc="hito.png"alt="人のイラスト"></figure><!-- ここだけ画像。好きな画像を入れてね。 --></div>

では一つずつCSSを書いていきたいと思います!

.jacketの大きさを決めて、赤背景を入れる

今回は(横500px × 縦500px)で作っていきたいと思います。

style.css
.jacket{width:500px;height:500px;background:#F35975;position:relative;}

buildingを下寄せに配置する

style.css
.building{width:100%;position:absolute;left:0;bottom:0;}

amiを入れる

まずは網のぶんの高さを確保します。
作戦としては斜線背景を2種類重ねて網を表現します。
背景は複数指定できるので、やり方もいっしょに確認していきます。

style.css
.building.ami{width:100%;height:95px;background-color:#fff;background:linear-gradient(-45deg,#4960765%,transparent5%,transparent45%,#49607645%,#49607655%,transparent55%,transparent95%,#49607695%),linear-gradient(45deg,#4960765%,transparent5%,transparent45%,#49607645%,#49607655%,transparent55%,transparent95%,#49607695%);background-size:10px10px;}

backgroundが長く書いてますが、「linear-gradient(↘︎向きの斜線), linear-gradient(↙︎向きの斜線)」の2種類を書いているだけです。
「-45deg」が、背景の角度を変更。「#496076 5%」など書いているのが、0%から5%までは#496076色にしなさいと言う指示が書いてあります。これをつなげて書いているので、0~5%までは青色。5%~45%までは透明。45%〜55%までは青色・・・みたいに書いて、線を表現しています。

ブロックを配置

ブロック分の高さを確保。
グラデーションが少しついているので、背景色にはlinear-gradientを指定。

style.css
.building.block{width:100%;height:20px;background:linear-gradient(#b78d9760%,#99899380%,#838190);}

床を再現

床もグラデーションがかかっているので背景色にlinear-gradientを指定。
また上にはボーダーを引いて、斜めの線は疑似要素(::beforeと::after)で再現します。

style.css
.building.tile{width:100%;height:130px;border-top:solid5px#415971;background:linear-gradient(#707c8e2%,#5369805%,#536980);position:relative;}.building.tile::before{content:'';width:90px;height:90px;background:linear-gradient(-45deg,transparent,transparent49.3%,#41597149.3%,#41597150.7%,transparent50.7%,transparent);position:absolute;top:0;left:0;display:block;}.building.tile::after{content:'';width:90px;height:90px;background:linear-gradient(45deg,transparent,transparent49.3%,#41597149.3%,#41597150.7%,transparent50.7%,transparent);position:absolute;top:0;right:0;display:block;}

左右の文字を配置

writing-modeを使って縦書きにします。英語は縦書き指定をすると90度回転した文字で縦書きになります。
font-famiryを指定していますが、ブラウザやデバイスにフォントがないと再現されないので、あってもなくてもいいと思います。

style.css
.left_text{color:#04274B;font-size:28px;font-family:"HG創英角ゴシックUB","HG創英角ゴシック","他のゴシック系フォントなど";/* ※基本的にブラウザではこのフォントでは表示されません */letter-spacing:1.35em;line-height:1;writing-mode:vertical-rl;position:absolute;top:90px;left:0;margin:0;}.right_text{color:#04274B;font-size:50px;font-family:"游明朝",YuMincho,"游教科書体","他の明朝系フォントなど";line-height:1;letter-spacing:0.5em;writing-mode:vertical-rl;position:absolute;top:0;right:0;margin:0;}

人の画像を配置

好きな横顔の写真を配置します。

style.css
figure{position:absolute;left:25%;bottom:0;margin:0;}

完成!

YOASOBI_ok.png

どうでしょう。自分で言うのもあれですが、なかなかの完成度かなと思います。
本物と見比べると、文字が違ったり微妙な表現の違いがわかるかなと思います。
YOASOBI_比較.png
(網の線太かった・・・)

各所で疑似要素や背景のグラデーションを使っているので、このあたりの使い方がまだあやふやな人は過去の記事を参考にしていただければ嬉しいです。

疑似要素について↓↓
【初心者でもわかる】擬似要素(::before,::after)でサンドイッチを作る方法

グラデーションについて↓↓
【初心者でもわかる】グラデーションをつかって、コップに好きなジュースを注ぐ方法

コピペして遊びたい人はこちらをどうぞ!

index.html(コピペで作れる用)
<div class="jacket">
    <div class="building"> <!-- ビルの上っぽそうなのでそのパーツを1まとまりにしました -->
        <div class="ami"></div> <!-- 網っぽいところ -->
        <div class="block"></div> <!-- ブロックっぽいところ -->
        <div class="tile"></div> <!-- 床っぽいところ -->
    </div>
    <p class="left_text">YOASOBI</p> <!-- 左の文字 -->
    <p class="right_text">夜に駆ける</p> <!-- 右の文字 -->
    <figure><img src="hito.png" alt="人のイラスト"></figure> <!-- ここだけ画像。好きな画像を入れてね。 -->
</div>




<style>
    .jacket {
        width: 500px;
        height: 500px;
        background: #F35975;
        position: relative;
    }

    .building {
        width: 100%;
        position: absolute;
        left: 0;
        bottom: 0;
    }

    .building .ami {
        width: 100%;
        height: 95px;
        background-color: #fff;
        background: linear-gradient(-45deg, #496076 5% ,transparent 5%, transparent 45%, #496076 45%, #496076 55%, transparent 55%, transparent 95%, #496076 95%),linear-gradient(45deg, #496076 5% ,transparent 5%, transparent 45%, #496076 45%, #496076 55%, transparent 55%, transparent 95%, #496076 95%);
        background-size: 10px 10px;
    }

    .building .block {
        width: 100%;
        height: 20px;
        background: linear-gradient(#b78d97 60%, #998993 80%, #838190);
    }

    .building .tile {
        width: 100%;
        height: 130px;
        border-top: solid 5px #415971;
        background: linear-gradient(#707c8e 2%, #536980 5%, #536980);
        position: relative;
    }

    .building .tile::before {
        content: '';
        width: 90px;
        height: 90px;
        background: linear-gradient(-45deg, transparent, transparent 49.3%, #415971 49.3%, #415971 50.7%, transparent 50.7%, transparent);
        position: absolute;
        top: 0;
        left: 0;
        display: block;
    }

    .building .tile::after {
        content: '';
        width: 90px;
        height: 90px;
        background: linear-gradient(45deg, transparent, transparent 49.3%, #415971 49.3%, #415971 50.7%, transparent 50.7%, transparent);
        position: absolute;
        top: 0;
        right: 0;
        display: block;
    }



    .left_text {
        color: #04274B;
        font-size: 28px;
        font-family: "HG創英角ゴシックUB", "HG創英角ゴシック", "他のゴシック系フォントなど"; /* ※基本的にブラウザではこのフォントでは表示されません */
        letter-spacing: 1.35em;
        line-height: 1;
        writing-mode: vertical-rl;
        position: absolute;
        top: 90px;
        left: 0;
        margin: 0;
    }

    .right_text {
        color: #04274B;
        font-size: 50px;
        font-family: "游明朝", YuMincho, "游教科書体", "他の明朝系フォントなど";
        line-height: 1;
        letter-spacing: 0.5em;
        writing-mode: vertical-rl;
        position: absolute;
        top: 0;
        right: 0;
        margin: 0;
    }

    figure {
        position: absolute;
        left: 25%;
        bottom: 0;
        margin: 0;
    }

</style>

まとめ

結構時間かかった。けど楽しかった!
身の回りの物をコーディングするの、結構楽しいからやってみてね!

素材データ配布

真似して作りたい人はこの画像をダウンロードして使ってね!
hito.png

おそまつ!

(コメント・質問・ソースの指摘等なんでもウェルカムです!初心者の方でも気軽に質問ください!)

TeXの導入

はじめに

自分用メモです。
デスクトップPCにtexを入れました。
windows10です。

いろいろなサイトをみてみたのですが、TeX Liveを入れました。
TeX インストーラ3
を使ったり、
Visual Studio Code
も一緒にインストールしたりしてる人もいたんですけど、
texとlatexの違いもいまいちわからんので (;^_^A)
まあとりあえずtex liveだけ入れます。

インストールの仕方

以下のURLからinstall-tl-windows.exeを選択します。
http://www.tug.org/texlive/acquire-netinstall.html

保護がどうたらって警告がでたけど気にせず進みます。

インストールします
image.png

かわいいଘ(੭ˊᵕˋ)੭*
image.png

高度な設定も一応見てみたけどまあそのままインストールでおけ。
image.png

とおもったらウイルス対策ソフトに止められました。
image.png

許可したつもりなんだけどインストール止まっちゃったので不安になり、
C直下のtexliveのファイルを消してもう一回入れなおしました。

インストールに一時間ぐらいかかるらしいのでお出かけしました。
帰ってきたらインストール終わってました。

image.png

さて使えるようになってるといいんですが。

よくわからんけどエディタが入ったのでこれでなにかを書いてみます。

image.png
こんな感じで書くと下の出力になる。
上の方のdocumentclassとかusepackageとかはよくわからんでござるwww

image.png
コンパイルできたしpdfにもできそうですね。

texworks editorはシンプルだけど微妙かも。
{を1コ開いたらもう一コ自動で出たりしたり、行番号あったらいいなって思いました。
あと記号とかマウスで選択できると楽かなあ。

この辺は要検討です。
TeXStudioがいいっぽいとかどうとか。

まあ赤ちゃんなのでよくわかりませんが、とりま今日はこの辺で。

初心者向け!JavaScriptの演算子について解説! byウェブカツ

JavaScriptに限らず、どのプログラミング言語でも共通する基礎には
「演算子」「条件文」「繰り返し」「変数」「関数」
などがあり、まずはこの基礎中の基礎の理解が必要となる。

今回はその中から「JavaScript」での「演算子」について解説します。

「演算子」とは?

演算子とは主に「データの代入・計算・比較」を担当する様々な記号のこと。

演算子の種類と解説

初心者は最初から全部を網羅する必要はないので、基本的な内容をピックアップしました。

代入演算子

「代入演算子」とは?

簡単に言うと、データを変数に代入するためのものです。
最もよく使用されるのが「=」記号。

学生時代にやった算数や数学では、「=」は「等しい」という意味で使っていたので、慣れるまで違和感があると思うが、プログラミングでは「等しい」ではなく「代入する」という意味で使われます。

代入:(=)記号

さきほども説明したように、代入演算子は「代入」をします。
「=」の右側と左側にわけて見ていただきたいのですが、「右側を左側に代入」します。

x=5;//xに5を代入します。 この時点でxは5です。y=x;//yにxの値である5を代入します。 この時点でyは5です。y=y+8;//(左側の)yには(右側の)yに8を加えた値を代入します。 この時点で(左側の)yは13となります。 //2行目の時点でyは5でした。//3行目の右辺「y+8」では、中身が5だったyに、さらに8を加えました。//それを左辺のyに代入しなおしています。//yの中身を上書きしているというイメージがわかりやすいでしょう。//なので、3行目で(左側の)yは13になるのです。

繰り返しますが、「等しい」ではなく「右側から左側への代入」です。

加算代入:(+=)記号

加算代入では、左側の変数に右側の値を加えた値で上書きします。

先ほどの例で

y=y+8;

と出てきましたが、これを省略する書き方ができるのが加算代入です。

y=5;//yに5を代入します。この時点でyは5です。 y+=8;//y=y+8と同じことを意味します。 この時点でyは13となります。

プログラミングをする際には「元々の変数の値に何かの値を足して上書きしたい」ということが頻繁にでてきます。
その場合に少しでも簡潔にコードをかけるように作られたのがこの代入演算子ですね。
少しややこしいかもしれませんが、これが理解できると、この後に紹介する減算代入・乗算代入・除算代入も同じ理屈ですのですぐ理解できます。

減算代入:(-=)記号

減算代入では、左側の変数に右側の値を引いた値で上書きします。

x=5;//xに5を代入します。 この時点でxは5です。x-=3;//x=x-3と同じことを意味します。 この時点でxは2となります。

乗算代入:(*=)記号

乗算代入では、左側の変数に右側の値をかけ算した値で上書きします。
(後ほどご紹介しますが「*」記号は「かける」を意味します。)

x=8;//xに8を代入します。 この時点でxは8です。x*=6;//x=x*6と同じことを意味します。 この時点でxは48となります。

除算代入:(/=)記号

乗算代入では、左側の変数に右側の値をかけ算した値で上書きします。
(後ほどご紹介しますが「/」記号は「割る」を意味します。)

x=20;//xに20を代入します。 この時点でxは20です。x/=5;//x=x/5と同じことを意味します。 この時点でxは4となります。

算術演算子

算術演算子は数値を計算する際に使用します。

加算:(+)記号

足し算です。

x=y+z;//「y+z」は「yにzを加える」という意味です。//例y=17;x=y+8;//xは25となります。

減算:(-)記号

引き算です。

x=y-z;//「y-z」は「yからzを引く」という意味です。//例y=15;x=y-8;//xは7となります。

乗算:(*)記号

かけ算です。

x=y*z;//「y*z」は「yにzをかける」という意味です。//例y=7;x=y*8;//xは56となります。

除算:(/)記号

割り算です。

x=y/z;//「y/z」は「yをzで割る」という意味です。//例y=48;x=y/6;//xは8となります。

剰余:(%)記号

割った際の余りです。

x=y%z;//「y%z」は「yをzで割った際の余り」という意味です。//例y=7;x=y%3;//xは1となります。

インクリメント演算子:(++)記号

変数の値を1増やします。

//例y=7;y++;//yは8となります。

デクリメント演算子:(--)記号

変数の値を1減らします。

//例x=6;x--;//xは5となります。

比較演算子

比較演算子は2つの値が比較して、true(真)もしくはfalse(偽)を返します。
通常これらはif分の条件判定で使います。

厳密等価演算子:3つのイコール記号(===)

記号の左側と右側の値が「等しい、かつ、同じ型かどうか」を判定します。

判定の結果、
等しい、かつ、同じ型であれば「true」を返します。
等しい、かつ、同じ型でなければ「false」を返します。

//例x=6;y=6;z="6";result=x===y;//変数resultの中身は「true」result=x===z;//変数resultの中身は「false」//2行目、3行目の6は「数値型」として扱います。//4行目の"6"は「""」で囲んでいるので、「文字列型」として扱います。//7行目では、同じ6ですが型が異なると判定されます。//変数の値には「型」があることを覚えておきましょう。

厳密不等価演算子:2つの等号の前にエクスクラメーション記号(!==)

記号の左側と右側の値が「等しい、かつ、同じ型ではないどうか」を判定します。

判定の結果、
等しい、かつ、同じ型でなければ「true」を返します。
等しい、かつ、同じ型であれば「false」を返します。

//例x=6;y=6;z="6";result=x!==y;//変数resultの中身は「false」result=x!==z;//変数resultの中身は「true」//「厳密等価演算子(===)」とは真逆ですね。

等価演算子:2つのイコール記号(==)

記号の左側と右側の値が「等しいかどうか」を判定します。型は判定しません。

判定の結果、
等しければ「true」を返します。
等しくなければ「false」を返します。

//例x=6;y=6;z="6";result=x==y;//変数resultの中身は「true」result=x==z;//変数resultの中身は「true」//「厳密等価演算子」とほぼ同じ例ですが、こちらは型が異なっても等しいと判定されます。

型が異なっても「等しい」と判定してしまうのは思わぬバグの原因となることがあります。ですので、特別な理由がない限り「等価演算子」ではなく「厳密等価演算子」を使用するようにするべきですね。

不等価演算子:等号の前にエクスクラメーション記号(!=)

記号の左側と右側の値が「等しいかどうか」を判定します。

判定の結果、
等しければ「false」を返します。
等しくなければ「true」を返します。

//例x=6;y=8;z="6";result=x!=y;//変数resultの中身は「true」result=x!=z;//変数resultの中身は「false」//「等価演算子(==)」と逆ですね。

こちらも「等価演算子」と同じ理由ですが、特別な理由がない限り「厳密不等価演算子」を使用するようにしましょう。

小なり演算子(より小さい):小なり記号(<)

記号の左側が右側の値よりも「小さいどうか」を判定します。
判定の結果、
小さければ「true」を返します。
そうでなければ「false」を返します。

小なりイコール演算子(より小さいまたは等しい):小なりイコール記号(<=)

記号の左側が右側の値よりも「小さい、もしくは等しいかどうか」を判定します。

判定の結果、
小さい、もしくは等しければ「true」を返します。
そうでなければ「false」を返します。

大なり演算子(より大きい):大なり記号(>)

記号の左側が右側の値よりも「大きいどうか」を判定します。

判定の結果、
大きければ「true」を返します。
そうでなければ「false」を返します。

大なりイコール演算子(より大きいまたは等しい):大なりイコール記号(>=)

記号の左側が右側の値よりも「大きい、もしくは等しいかどうか」を判定します。

判定の結果、
大きい、もしくは等しければ「true」を返します。
そうでなければ「false」を返します。

まとめ

JavaScriptの学習を始めたばかりの初心者であれば、まずはこの演算子をマスターしてください。
他にもいろいろありますが、それは後から少しずつ覚えればOKです。


かずきち

プログラミング学習サイト「ウェブカツ!!」の顧問。
不動産、保険の営業マンから、エンジニアへ転身。
「HTMLって何?」という状態から3ヶ月の独学のみでエンジニアへ転職し、1年で年収1千万を稼ぐエンジニアへ。
独学時代のプログラミング学習の分かりにくさや、「技術しか出来ずに稼げていないエンジニア」の現状を変えるため「ウェブカツ」を立ち上げ運営している。

【ウェブカツ公式WEBサイト】
https://webukatu.com/

Laravel クエリビルダを駆使する

目的

  • クエリビルダを用いたDBのデータ取得方法とテーブル結合を用いたデータん取得方法をまとめる

実施環境

  • ハードウェア環境
項目情報
OSmacOS Catalina(10.15.5)
ハードウェアMacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ2 GHz クアッドコアIntel Core i5
メモリ32 GB 3733 MHz LPDDR4
グラフィックスIntel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目情報備考
PHP バージョン7.4.3Homwbrewを用いて導入
Laravel バージョン7.0.8commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン8.0.19 for osx10.13 on x86_64Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提環境

  • 先に記載した実施環境が構築されていること。
  • 実施環境にて何かしらのLaravelアプリが作成されていること。
  • Laravelアプリ用のDBが作成され.envファイルに必要情報が記載され、マイグレーションなどが行えること。

前提情報

  • contentsテーブルとstatusesテーブルを新たに作成し、テーブル内に格納されているデータをクエリビルダを用いて取得する。
  • コードの解説は本記事の下部の「ミニ解説」にてちょっとだけ解説している。

読後感

  • contentsテーブルの内容をクエリビルダを用いて取得する。
  • contentsテーブルとstatusesテーブルを結合し内容をクエリビルダを用いて取得する。

クエリビルダとは?

  • LaravelのDBアクセスの手法の一つである。
  • クエリ文を先に組み立ててからDBにアクセスする方法である。
  • 使用する句はSQLと共通であるが記載方法に若干のクセがある。

概要

  1. contentテーブルの作成
  2. statusesテーブルの作成
  3. ルーティングの記載
  4. コントローラの作成と記載(クエリビルダの記載)
  5. ビューの作成と記載
  6. データの格納
  7. クエリビルダ単体の確認
  8. JOIN句の確認

詳細

  1. contentテーブルの作成

    1. アプリ名ディレクトリで下記コマンドを実行してモデルファイルとマイグレーションファイルを作成する。

      $php artisan make:model Content --migration
    2. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。

      $vi database/migrations/YYYY_MM_DD_XXXXXX_create_contents_table.php
      
    3. 開いたマイグレーションファイルを下記の様に追記修正する。

      アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_contents_table.php
      <?phpuseIlluminate\Database\Migrations\Migration;useIlluminate\Database\Schema\Blueprint;useIlluminate\Support\Facades\Schema;classCreateContentsTableextendsMigration{/**
           * Run the migrations.
           *
           * @return void
           */publicfunctionup(){Schema::create('contents',function(Blueprint$table){$table->id();//下記を追記$table->string('content');$table->integer('status_id');//上記までを追記$table->timestamps();});}/**
           * Reverse the migrations.
           *
           * @return void
           */publicfunctiondown(){Schema::dropIfExists('contents');}}
    4. アプリ名ディレクトリで下記コマンドをジックしてマイグレーションを実行する。

      $php artisan migrate
      
  2. statusesテーブルの作成

    1. アプリ名ディレクトリで下記コマンドを実行してモデルファイルとマイグレーションファイルを作成する。

      $php artisan make:model Status --migration
    2. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。

      $vi database/migrations/YYYY_MM_DD_XXXXXX_create_statuses_table.php
      
    3. 開いたマイグレーションファイルを下記の様に追記修正する。

      アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_contents_table.php
      <?phpuseIlluminate\Database\Migrations\Migration;useIlluminate\Database\Schema\Blueprint;useIlluminate\Support\Facades\Schema;classCreateContentsTableextendsMigration{/**
           * Run the migrations.
           *
           * @return void
           */publicfunctionup(){Schema::create('contents',function(Blueprint$table){$table->id();//下記を追記$table->string('status_name');$table->timestamps();});}/**
           * Reverse the migrations.
           *
           * @return void
           */publicfunctiondown(){Schema::dropIfExists('contents');}}
    4. アプリ名ディレクトリで下記コマンドをジックしてマイグレーションを実行する。

      $php artisan migrate
      
  3. ルーティングの記載

    1. アプリ名ディレクトリで下記コマンドを実行してルーティングファイルを開く。

      $vi routes/web.php
      
    2. 下記の一行を追記する。

      アプリ名ディレクトリ/routes/web.php
      Route::get('/output','ContentController@output');
  4. コントローラの作成と記載(クエリビルダの記載)

    1. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを作成する。

      $php artisan make:controller ContentController
      
    2. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $vi app/Http/Controllers/Controller.php
      
    3. 下記の様にoutputという名前のアクションを追加する。

      アプリ名ディレクトリ/app/Http/Controllers/Controller.php
      <?phpnamespaceApp\Http\Controllers;useIlluminate\Http\Request;//下記を追記useApp\Content;classContentControllerextendsController{//下記を追記publicfunctionoutput(){$contents_query=Content::select('*');$contents=$contents_query->get();returnview('contents.output',['contents'=>$contents,]);}//上記までを追記}
  5. ビューの作成と記載

    1. アプリ名ディレクトリで下記コマンドを実行してビューファイルを格納するディレクトリを作成する。

      $mkdir resources/views/contents
      
    2. アプリ名ディレクトリで下記コマンドを実行してビューファイルを作成して開く。

      $vi resources/views/contents/output.blade.php
      
    3. ビューファイルに下記を記載する。

      アプリ名ディレクトリ/resources/views/contents/output.blade.php
      @foreach ($contents as $content)
          <hr>
          <p>{{$content['content']}}</p>
          <p>{{$content['status']}}</p>
      @endforeach
      
  6. データの格納

    1. アプリ名ディレクトリで下記コマンドを実行してtinkerを開く。

      $php artisan tinker
      
    2. tinkerにて下記を実行してcontentsテーブルにデータを追加する。

      useApp\Content;$a=newContent();$a->content='test';$a->status_id=1;$a->save();
    3. tinkerにて下記を実行してstatusesテーブルにデータを追加する。

      useApp\Status;$b=newStatus();$b->status_name='good'$b->save();$c=newStatus();$c->status_name='bad'$c->save();
  7. クエリビルダ単体の確認

    1. アプリ名ディレクトリで下記コマンドを実行しローカルサーバを起動する。

      $php artisan serve
      
    2. 下記にアクセスし、ブラウザから当該アプリを確認する。

    3. 下記の様にブラウザで表示されることを確認する。

      127_0_0_1_8000_output.png

  8. JOIN句の確認

    1. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $vi app/Http/Controllers/Controller.php
      
    2. 開いたコントローラファイルのoutputアクション内部を下記の様に修正する。

      アプリ名ディレクトリ/app/Http/Controllers/Controller.php
      <?phpnamespaceApp\Http\Controllers;useIlluminate\Http\Request;useApp\Content;classContentControllerextendsController{publicfunctionoutput(){$contents_query=Content::select('*');//下記を追記$contents_query->join('statuses','contents.status_id','=','statuses.id');$contents=$contents_query->get();returnview('contents.output',['contents'=>$contents,]);}}
    3. アプリ名ディレクトリで下記コマンドを実行してビューファイルを開く。

      $vi resources/views/contents/output.blade.php
      
    4. ビューファイルに下記を下記の様に修正する。

      アプリ名ディレクトリ/resources/views/contents/output.blade.php
      @foreach ($contents as $content)
          <hr>
          <p>{{$content['content']}}</p>
          <!-- 下記を追記 -->
          <p>{{$content['status_name']}}</p>
      @endforeach
      
    5. 下記にアクセスし、ブラウザから当該アプリを確認する。

    6. 下記の様にブラウザで表示されることを確認する。

      127_0_0_1_8000_output.png

ミニ解説

「クエリビルダ単体の確認」のアクション内のコードについて

  • 下記にコントローラのアクションのコードを記載する。

    アプリ名ディレクトリ/app/Http/Controllers/Controller.php
    publicfunctionoutput(){//DBにアクセスするためのクエリ文を組み立てている//Contentというモデルファイルに紐づいたテーブルの全てのカラムを取得する(SQL文のselect *と同じ)クエリ文を変数$contents_queryに格納している$contents_query=Content::select('*');//先に組み立てたクエリ文を実行して取得したデータを変数$contentsに格納している。$contents=$contents_query->get();returnview('contents.output',['contents'=>$contents,]);}

「JOIN句の確認」のアクション内のコードについて

  • 下記にコントローラのアクションのコードを記載する。

    アプリ名ディレクトリ/app/Http/Controllers/Controller.php
    publicfunctionoutput(){//DBにアクセスするためのクエリ文を組み立てている//Contentというモデルファイルに紐づいたテーブルの全てのカラムを取得する(SQL文のselect *と同じ)クエリ文を変数$contents_queryに格納している$contents_query=Content::select('*');//テーブルの結合を行う//クエリ文が格納されている変数->join('結合するテーブル名', '結合元テーブル名.結合するカラム名', '=', '結合先テーブル名.リンクするカラム名')$contents_query->join('statuses','contents.status_id','=','statuses.id');//先に組み立てたクエリ文を実行して取得したデータを変数$contentsに格納している。$contents=$contents_query->get();returnview('contents.output',['contents'=>$contents,]);}

Laravel ビューファイルで作成する画面にYoutubeの動画を埋め込む

目的

  • Youtubeの再生画面をLaravelのビューファイルに埋め込む方法をまとめる。

実施環境

  • ハードウェア環境
項目情報
OSmacOS Catalina(10.15.5)
ハードウェアMacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ2 GHz クアッドコアIntel Core i5
メモリ32 GB 3733 MHz LPDDR4
グラフィックスIntel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目情報備考
PHP バージョン7.4.3Homwbrewを用いて導入
Laravel バージョン7.0.8commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン8.0.19 for osx10.13 on x86_64Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

  • 実施環境のLaravelアプリ動作環境が構築できていること。

前提情報

  • 特になし

読後感

  • Laravelのビューファイルを用いた画面の表示にYoutubeの再生ウインドウを埋め込むことができる。

概要

  1. 埋め込みリンクのコピー
  2. ビューファイルの記載

詳細

  1. 埋め込みリンクのコピー

    1. ブラウザにてYoutubeのページを開く。
    2. 埋め込みたい動画の「共有」をクリックする。

      Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube.png

    3. 「埋め込む」をクリックする。

      Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube_🔊.png

    4. 表示されたhtml形式のリンクをコピーする。

      Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube-2.png

  2. ビューファイルの記載

    1. Youtubeを埋め込みたいビューファイルを開き、埋め込みたい箇所に先にコピーしたリンクを貼り付ける。

Uncaught Error: Cannot find module 'bootstrap-form'と出た場合はコメントアウト

自分用忘備録

環境

  • macOS Catalina
  • ruby 2.6.6
  • Rails 6.0.3.2
  • gem 'bootstrap_form'
  • Google chrome

管理者一覧画面から管理者を削除
すると以下のエラーがブラウザ上に出現。

Unknown action
The action 'show' could not be found for Administrator::AdminsController

と出る。
destroy actionのはずが何故show??

controller,view,pathの確認をするも異常なし。

web developer consoleでerror logを確認すると、

Uncaught Error: Cannot find module 'bootstrap-form'
    at webpackMissingModule (application.js:1)
    at Module../app/javascript/packs/application.js (application.js:1)
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

bootstrap-formのmoduleでエラーが発生していることを確認。

app/javascript/packs/application.jsの
import 'bootstrap-form';
をコメントアウト。

動作確認すると無事削除出来た。

"Kill sticky headers"の動作解説 ーWebサイト閲覧を快適にー

はじめに

はじめまして、@wa-cordと申します。

"Kill sticky headers"というブックマークレットをご存知でしょうか。Webサイト閲覧時、サイト上部に固定されているヘッダーなどを消してくれるものです。Alisdair McDiarmid氏が2013年に公開しました。

公式ページ:
https://alisdair.mcdiarmid.org/kill-sticky-headers/

私は愛用しています。非常に便利なものだと感じています。このブックマークレットのおかげでWebサイト閲覧が快適になりました。
Javascriptを学び、動作を理解することができたので、解説したいと思います。公式ページにも解説がありますが、初心者でも分かりやすいように丁寧に説明していきます。なお、Alisdair McDiarmid氏本人から紹介の許可を得ております。

使用方法

動作の解説の前に使用方法を説明します。簡単です。

  1. 公式ページの"Kill Sticky"という青いボタンを、ブックマークバーにドラッグ&ドロップする。(Google Chromeの場合)
  2. 追加されたブックマークレットをクリックする。

こうすると、公式ページの上部にあるヘッダーが消えます。ブックマークレットをクリックするだけで、他のWebページでも同様に動作します。消したヘッダーなどを元に戻したいときは、そのページをリロードします。

動作解説

ブックマークレットとは

ブックマークレットについて簡単に説明します。

ブックマークレット (Bookmarklet) とは、ユーザーがウェブブラウザのブックマークなどから起動し、なんらかの処理を行う簡易的なプログラムのことである。(Wikipediaより)

Wikipediaにある説明のとおりです。"Kill sticky headers"では、Javascriptで処理が記載されています。

"Kill sticky headers"の動作解説

"Kill sticky headers"のソースコードはこちらです。

1(function(){2vari,elements=document.querySelectorAll('body *');34for(i=0;i<elements.length;i++){5if(getComputedStyle(elements[i]).position==='fixed'){6elements[i].parentNode.removeChild(elements[i]);7}8}9})();

2行目で、elementsという変数を定義しています。querySelectorAllメソッドによって、HTMLファイルのbody要素の中にあるすべての要素を取得し、配列の形でelementsに代入しています。(作成者は、このquerySelectorAllをawesomeと表現しています。私も同意です。)
続いて、4行目から8行目にかけてです。すべてのelementsに対して、「Styleのpositionがfixed」となっているものに6行目の処理をさせています。6行目は、対象となったelments要素をremoveChildメソッドにより削除するという処理です。

おわりに

"Kill sticky headers"というBookmarkletを紹介し、その動作を解説しました。短いコードでこんなにも便利なものが作れるということに感動します。作成者のAlisdair McDiarmid氏を尊敬します。最後までお読みいただき、ありがとうございます。

謝辞

紹介を快諾していただいたAlisdair McDiarmid氏に感謝申し上げます。

参考

公式ページ:https://alisdair.mcdiarmid.org/kill-sticky-headers/
querySelectorAll:https://www.w3.org/TR/selectors-api/#examples
https://gigazine.net/news/20170629-kill-sticky-headers/

【1ヶ月で学ぶ!】Back-end Developperへの道 #12日目 : Testingとは、CI/CDとは

下記の企画の6日目です。
【1ヶ月で学ぶ!】Back-end Developperへの道 #0:導入

下記を参考に項目を作成しました。
Roadmap to becoming a web developer in 2020

Testingとは

Integration Testing

  • 結合テストとは、システム開発におけるプログラムの検証作業の中でも、手続きや関数といった個々の機能を結合させて、うまく連携・動作しているかを確認するテスト
  • 個々の機能を果たすためのプログラム部品(プログラムモジュール)を組み合わせて、データの受け渡しがうまく行われているか、コードの記述様式は揃っているか、データを授受するタイミングはずれていないか、といった点が確認される
  • サブシステム内の機能連携を検証する内部結合テストと、サブシステム間や他システムとの機能連携を検証する外部結合テストに分かれる

Unit Testing

  • 単体テストとは、個々のプログラムモジュールが問題なく機能するかを確認するテスト
  • プログラムを手続きや関数といった個々の機能ごとに分割し、そのそれぞれについて動作検証を行う
  • ロジックの条件分岐を網羅するホワイトボックステストを実施する

Functional Testing

  • 機能テストとは、ユーザー側から要求された機能をシステムが満足しているかどうかを検証するテスト
  • 機能テストで確認すべき機能要件とは、クライアントが要望する必ず搭載すべき機能を指す
  • 入力されたテストデータと出力結果を比較検証するブラックボックステストが用いられる

CI/CDとは

  • 継続的インテグレーション(Continuous Integration)とは、ソフトウェア開発において定期的にビルド、テストされ、共通リポジトリに統合されるような自動化プロセスのこと
  • 継続的デリバリー(Continuous Delivery)とは、バグがないか自動的にテストし、リポジトリ (GitHub やコンテナレジストリなど) にアップロードすること
  • 継続的デプロイメントとは、開発者による変更をリポジトリから本番環境に自動的にリリースすること
  • バグを素早く発見したり、手動プロセスを自動化し素早くリリースすることができる

参照

単体テスト・結合テスト・総合テストの違い、観点や注意点を簡単に説明する
CI/CD とは-継続的インテグレーション/継続的デリバリー|Red Hat

AOJ 「ITP1_11」をpythonで解く(サイコロのクラスを作る)

初めに

AOJでITPを解いていたら、たまたま「【競プロ初心者向け】AOJ 「ITP I」40問をpythonで解いてみた」という記事を見つけ、せっかくだし補完と記録的な意味合いで書くことにしました。(この記事は41~44問目にあたる)

自分なりに汎用性を持たせることをイメージしてクラスを書きましたが、もっと効率的な書き方や怪しい記述があれば指摘していただきたいです。(筆者は初心者なので一般的な書き方をしていない可能性があります...)

今回作ったサイコロ

classDice:def__init__(self,ary):# [top, front, right, left, back, bottom]
self.__top=ary[0]self.__fro=ary[1]self.__rit=ary[2]self.__lft=ary[3]self.__bak=ary[4]self.__btm=ary[5]defturn_e(self):# 右に転がる
self.__top,self.__lft,self.__btm,self.__rit= \
        self.__lft,self.__btm,self.__rit,self.__topdefturn_s(self):# 手前に転がる
self.__top,self.__fro,self.__btm,self.__bak= \
        self.__bak,self.__top,self.__fro,self.__btmdefturn_w(self):# 左に転がる
self.__top,self.__lft,self.__btm,self.__rit= \
        self.__rit,self.__top,self.__lft,self.__btmdefturn_n(self):# 奥に転がる
self.__top,self.__fro,self.__btm,self.__bak= \
        self.__fro,self.__btm,self.__bak,self.__topdefspin_r(self):# 右回転 
self.__rit,self.__fro,self.__lft,self.__bak= \
        self.__bak,self.__rit,self.__fro,self.__lftdefspin_l(self):# 左回転
self.__rit,self.__fro,self.__lft,self.__bak= \
        self.__fro,self.__lft,self.__bak,self.__ritdefis_same_setting(self,ary):# 同じように置いているか
ifself.__top==ary[0]andself.__fro==ary[1]andself.__rit==ary[2]and \
            self.__lft==ary[3]andself.__bak==ary[4]andself.__btm==ary[5]:returnTruedefis_same_dice(self,ary):# 回転させて同じダイスになるか
is_same=Falsefor_inrange(2):for_inrange(3):for_inrange(4):ifself.is_same_setting(ary):is_same=Trueself.spin_r()self.turn_n()self.spin_r()self.turn_s()returnis_samedefshow_top(self):# 上面の値を表示
returnself.__top

機能の説明

コンストラクタ

# from class Dice
def__init__(self,ary):# [top, front, right, left, back, bottom]
self.__top=ary[0]self.__fro=ary[1]self.__rit=ary[2]self.__lft=ary[3]self.__bak=ary[4]self.__btm=ary[5]

各面の値の配列を引数にとります。例えば、普通のサイコロなら [1, 2, 3, 4, 5, 6]です。
インスタンス生成時の引数は必ず、[top, front, right, left, back, bottom]の順にしてください。

転がし方*4

# from class Dice
defturn_e(self):# 右に転がる
self.__top,self.__lft,self.__btm,self.__rit= \
        self.__lft,self.__btm,self.__rit,self.__top

4つあります。
転がしたときの値を入れ替えて状態を変えています。
turn_〇〇」となっていますが、〇〇には方角の頭文字が入ります。奥方向なら「n」です。

  

回転*2

# from class Dice
defspin_r(self):# 右回転 
self.__rit,self.__fro,self.__lft,self.__bak= \
        self.__bak,self.__rit,self.__fro,self.__lft

2つあります。
実は今回の問題では直接使わないんですが、いずれ他の問題で使うかもしれないと思って一応実装してます。

  

同じように置かれているか

# from class Dice
defis_same_setting(self,ary):ifself.__top==ary[0]andself.__fro==ary[1]andself.__rit==ary[2]and \
            self.__lft==ary[3]andself.__bak==ary[4]andself.__btm==ary[5]:returnTrue

2つのサイコロを比較して、各面の値がすべて一致しているかの判定をしてくれます。
向きも一致していないといけないので、同じサイコロを同じ置き方(6がbottomで、5がfrontになるように置く、など)をしたときのみTrueを返します。

実行するときは、

dice=Dice([1,2,3,4,5,6])dice.is_same_setting([6,5,4,3,2,1])

のように使います。下で引数になっているのが、比較したいサイコロです。

  

回転させて同じダイスになるか

# from class Dice
defis_same_dice(self,ary):is_same=Falsefor_inrange(2):for_inrange(3):for_inrange(4):ifself.is_same_setting(ary):is_same=Trueself.spin_r()self.turn_n()self.spin_r()self.turn_s()returnis_same

今度は、2つのサイコロを比較して、各面の値が回転して一致するかの判定をしてくれます。
インスタンスで作ったサイコロを実際に回転させて、与えた引数(比べたいサイコロ)と一致していれば、Trueを返します。

この関数で行っている処理は、置き方の全列挙です。
サイコロの置き方は24通りしかないので、上のfor文のループ回数2 * 3 * 4 = 24ですべてカバーできています。
また、サイコロの回転を複数回行っていますが、この処理の前後でサイコロの置き方は変化しません。
ただ、このfor文をbreakしたりすると、breakした点での置き方に変わってしまうので編集するときは注意してください。

実行するときは、

dice=Dice([1,2,3,4,5,6])dice.is_same_dice([6,2,4,3,5,1])# True

のように使います。
 

出目の表示

# from class Dice
defshow_top(self):# 上面の値を表示
returnself.__top

みたまんまです。他の面を表示したいときは各自でお願いします。
今回の問題はこれしか使いません。

 

それでは、実際に解いていきます。

ITP1_11_A サイコロ1

サイコロを指示された通り転がし、転がし終えた後の上面の値を答える問題です。

解答
surfaces=list(map(int,input().split()))instructions=list(input())dice=Dice(surfaces)forinstininstructions:ifinst=="E":dice.turn_e()ifinst=="N":dice.turn_n()ifinst=="S":dice.turn_s()ifinst=="W":dice.turn_w()print(dice.show_top())

言われた通り実装します。

ITP1_11_B サイコロ2

サイコロを回転させた後のtopfrontの値が与えられるので、その時のrightを出力する問題です。

この問題は置き方の全列挙を使えば、簡単に右側面の値が求まるはずです。
なので、is_same_dice(self)を少し変更してあげればよさそうです。

# def is_same_dice(self)を一部変更
deftop_fro_right(self,ary):+++right=0+++for_inrange(2):for_inrange(3):for_inrange(4):ifself.is_same_top_fro(ary):+++right=self.__rit+++self.spin_r()self.turn_n()self.spin_r()self.turn_s()returnright+++defis_same_top_fro(self,ary):+++ifary[0]==self.__topandary[1]==self.__fro:+++returnTrue+++

この問題に合わせた条件式を新たに作っています。
この条件式はtopfroが一致したときにTrueを返すだけです。

解答
surfaces=list(map(int,input().split()))q=int(input())dice=Dice(surfaces)for_inrange(q):top_fro=list(map(int,input().split()))right=dice.top_fro_right(top_fro)print(right)

こんな感じでよさそうです。
このように、条件式を工夫すれば色々な問題に対応できると思います。

ITP1_11_C サイコロ3

2つのサイコロが一致していればYes、不一致ならNoを出力する問題です。
回転させて同じかどうかは一発で求められます。

解答
surfaces1=list(map(int,input().split()))surfaces2=list(map(int,input().split()))dice=Dice(surfaces1)ifdice.is_same_dice(surfaces2):print('Yes')else:print('No')

簡単!

ITP1_11_D サイコロ4

サイコロがn個与えられるので、それらがすべて異なるサイコロならYes、一つでも同じサイコロがあればNoを出力する問題です。

n <= 100なので、愚直に全組み合わせについて調べても間に合いそうです。

解答
n=int(input())surfaces_stack=[None]*nforiinrange(n):surfaces_stack[i]=list(map(int,input().split()))foriinrange(n-1):forjinrange(i+1,n):dice=Dice(surfaces_stack[i])ifdice.is_same_dice(surfaces_stack[j]):print('No')breakelse:continuebreakelse:print('Yes')

こんな感じでしょうか。
同じサイコロがあれば、Noを出力してすべてのfor文からbreakし、一度もbreakしなければYesを出力します。

 

これですべての問題が終わりました。

最後に

ここまで読んでくださってありがとうございました。

以前某サイトで初めてサイコロの問題を解いたときに、回転をどう表せばいいのか非常に悩んだ覚えがあります。
やってることは単純なのですが、4方向の回転の処理を書いていくのはなかなか骨が折れます。
なにかテンプレート的なものがあれば簡単に解けるのにな、ということで考えてみました。

pythonでこのようにサイコロを扱った記事は、ぱっと見た感じでは無かったと思います。(多分)
このテンプレートの差別化点としては、
・自分で目を設定できる
・置き方全列挙がある
ぐらいでしょうか。
なんにせよ、これでサイコロ転がす系の問題は楽勝です!(サイコロの問題そんなに多くない気もしているんですけどね!)

至らないところも多かったと思いますが、少しでも誰かの参考になれたらうれしいです。

Javaのラムダ式

ラムダ式とは

Java8で導入された記述方法です。
同じくJava8で導入されたStream API1はラムダ式を使うことが前提とされているため、ラムダ式を学んでおくとメリットがありそうです。

また、ラムダ式を使うと、「匿名クラスを使った関数型インターフェースの記述」を簡潔にできるというメリットもあります。

ラムダ式の書き方

引数が複数ある時

インターフェース名 オブジェクト名 = (引数1, 引数2, ...) -> { return 処理内容 };

コンパイラが型推論してくれるので、引数の型は指定する必要はありません。

引数が1つしかない時

インターフェース名 オブジェクト名 = 引数 -> 処理;

引数が1つしかない時は、returnや引数を囲む()、処理を書く{}等は要りません。

ラムダ式を読む時はシンプルにこの形式を覚えておいて、書く時は引数の数によって記述を気をつければいいと思います。

匿名クラスを使った実装

匿名(無名)クラスとは、インターフェースを実装したローカルクラスの、宣言部分を省略したものです。
ラムダ式を使えば、匿名クラスを使わずに簡潔にわかりやすく書くことができます。

たとえば以下のような匿名クラスがあったとします。

main.java
interfaceInterfaceTest{// 抽象メソッドpublicStringname(Stringname);}publicclassMain{publicstaticvoidmain(String[]args){// 匿名クラスを使った書き方InterfaceTestgreeting=newInterfaceTest(){// オーバーライドpublicStringname(Stringname){return"Hello "+name;}};System.out.println(greeting.name("momoji"));}}

上記では、インターフェースのインスタンスを生成しているように見えますが、実際はインターフェースをもった、無名クラスのインスタンスを生成しています。

実行結果↓

Hello momoji

ラムダ式での実装

これをラムダ式で書き換えてみます。

main.java
interfaceInterfaceTest{// 抽象メソッドpublicStringname(Stringname);}publicclassMain{publicstaticvoidmain(String[]args){// ラムダ式を使った書き方InterfaceTestgreeting=(name)->{return"Hello "+name;};System.out.println(greeting.name("momoji"));}}

{}の中にはgreetingメソッドで行う処理内容が書かれています。
短くなった上、何をしているかが分かりやすくなりました。また、引数の型指定をしなくてよくなりました。

実行結果↓

Hello momoji

forEach文をラムダ式を使ってもっと短く書く

Javaにはfor-each文と同じ性質を持ったもので、拡張for文というものがあります。配列やリストの全ての要素に指定した処理を行うという性質を持ちます。

拡張for分の書き方

for (データ型 変数名: listや配列){
  処理;
  ...
}

リストの要素を全て順番に出力するには、拡張for文だと以下のように書きます。

main.java
main.javaclassMain{publicstaticvoidmain(String[]args){List<String>list=newArrayList<>();list.add("a");list.add("b");list.add("c");// 拡張for文for(Stringl:list){System.out.println(l);}}}

上記の例では、
①String型のリスト「list」を定義する
②addメソッドでlistに"a","b","c"の要素をひとつずつ詰めていく
③拡張for文を使ってlistの要素をひとつずつ出力していく。

ということをしています。

実行結果は以下のようになります。

a
b
c

これを、ラムダ式とforEach文を使うともっと短くすることができます。

main.java
classMain{publicstaticvoidmain(String[]args){List<String>list=newArrayList<>();list.add("a");list.add("b");list.add("c");// 拡張for文// for(String l : list) {//  System.out.println(l);// }// ラムダ式を使ったforEach文list.forEach(l->System.out.println(l));}}

実行結果↓

a
b
c

3行使って書いていたところを、1行に収めることができました。
これを「メソッド参照」を使うともっと短くすることができます。

メソッド参照とは

これもJava8から導入された記法になります。
メソッド参照とは、メソッドの引数としてメソッドを参照できる仕組みのことです。
定義済みのメソッドを引数なしで呼び出すことができます。

メソッド参照は以下のように書きます。

クラス名 :: メソッド名

クラス名の後に「::」、呼び出したいメソッド名を書きます。メソッド名に()は不要です。

さっそくラムダ式と組み合わせてみます。

main.java
// メソッド参照を使ったラムダ式list.forEach(System.out::println);

実行結果↓

a
b
c

ラムダ式とメソッド参照の合わせ技で、ずいぶん短く書けるようになりました。


  1. 配列やリストなどのコレクションを扱う為のもので、値の集計やデータを使った処理を分かりやすいコードで実装することができるAPI。 

Browsing Latest Articles All 4321 Live