何人もの高専生を救ったあのサイトが閉鎖されていることを知り悲しみにくれる

Gakuです。

4年前まで高専生をやっていました。
その際にお世話になっていたあのサイトが閉鎖されていることを知り、少しだけ悲しみにくれております。
こちらのサイトです。

[blogcard url=”http://megalodon.jp/2015-0830-1401-44/www.geocities.jp/arrogant_give_and_take/”][/blogcard]

これはWeb魚拓から取ったもので現在はこのようになっております。

[blogcard url=”http://www.geocities.jp/arrogant_give_and_take/”][/blogcard]

Give and Takeという伝説のサイト

こちらのサイト、誰が作ったかは定かではありませんが、高専生なら一度はアクセスしたことがある程の有名なサイトでした。
どのようなサイトかというと、高専生が使用する数学の教科書「高専の数学」の解答例をpdfでダウンロードできるというそれだけのサイトです。

それだけのサイトなのに、なぜ、これ程までに有名なサイトだっかというと、この「高専の数学」という教科書は問題+答えしかないのです。
もうね。全くわかりません。解答例載せろよまじで!と何回思ったことか。。。

しかも、極め付けは「高専の数学」の難しさです。
「高専の数学3」にもなれば(高専生3年の数学の教科書)フーリエ変換・ラプラス変換あたりが平気で出ていたレベルだったと記憶してます。
もうね。大学の数学科先行レベルの問題を高校3年生の教科書に出すとかあほかと。

そういうレベルの問題がバンバン出ることから、高専生で留年していった人は数多くいたはずです。

ちなみに、年度末になると、なんとか留年にならないよう各教授に「お礼参り」するという習わしが私の高専にはあったのですが、「お礼参り」する教授Top1は数学か物理学の教授だった気がします。(「高専の数学」という教科書以外に「高専の物理」という教科書も存在していました。こちらも凶悪です。)

そんな中でのGive and Takeという神サイト

高専のテストは年間4回程あるのですが、テストの出題傾向は至極簡単です。

「たいていの教授は問題を考えるのが面倒くさいので、高専の数学の問題集からテストを出題します。」

はい。たったこれだけです。
たまに過去出題したテストをまるまる出してくれる神な教授もいましたが。。。

ただ、数が膨大なのです。
出題範囲は1試験でだいたい30p前後だったと思います。1pに最低5問程度はあったと思うので150問くらい丸暗記すれば100点です。
というわけで、解答例が載っている「Give and Take」を参照し、頭の悪い高専生は丸暗記をするわけです。(僕です)

サイトの衰退

高専で使用する教科書が「高専の数学」から新しい教科書に切り替わったので「Give and Take」は閉鎖になったようですね。
サイトの廃りは5年と良くいわれますが、その廃りを身を以て感じた午後の昼下がりでした。

今更ながらシェルスクリプトにはまる

Gakuです。

最近、dockerを良く触っており、環境構築自動化にはまっていました。
そこで、今まであまり使っていなかったシェルスクリプトにも触れたので、その所感を記述したいと思います。

シェルスクリプトってなんぞ?

Linux系OSで使用されるコマンドを1つのファイルに記述し、そのファイルを実行することでファイルに記述したコマンドを実行するものです。
Windows系で言えばbatファイルにあたります。

Hello Worldをシェルスクリプトで記述してみる

シェルスクリプトを作成するのはすごく簡単です。
拡張子.shでファイルを作成し、その中にいつも使っているコマンドを記述するだけです。
今回はHello Worldと出力するコマンドを記述したシェルスクリプトを作成します。

echo "Hello World"

これで準備完了です(´Д` )

作成したシェルスクリプトを実行していみる

シェルスクリプトを実行するのはすごく簡単です。
bashコマンドを用いて作成したシェルスクリプトを指定すれば、シェルスクリプト内に記述したコマンドが実行されます。

bash test.sh

スクリーンショット 2016-08-19 10.24.32

魅惑のシェルスクリプトの世界へようこそ( ^ω^ )

おわりに

シェルスクリプトを作成するのが最近すごく楽しいです。
一回書いちゃえば、もうその作業をする必要がなくなりますからね。
こういうことが好きってことはインフラエンジニアにも向いているのかもしれないと思っている今日この頃です。

ちなみに、私のGitHubリポジトリにvim環境構築用シェルスクリプトやrails5環境構築用シェルスクリプトなどを格納しております。
[blogcard url=”https://github.com/gaku3601/dotfile”][/blogcard]

よければ、参考にして下さい。でわでわ

システム開発における契約が120年ぶりに改正されるそうな

Gakuです。

昨日はてなブックマークを見ていたらこんな記事が上がっていました。

[blogcard url=”http://www.techvan.co.jp/media/quality/civil-code”][/blogcard]
この記事人気すぎてサーバー落ちているんですが。。。
いろいろ調べていたら、他サイトでも取り上げられていたのでそちらを参照。
[blogcard url=”http://oretore.com/minpoukaisei/”][/blogcard]
[blogcard url=”https://www.corporate-legal.jp/%E6%B3%95%E5%8B%99%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9/%E6%B3%95%E5%8B%99%E3%82%B3%E3%83%A9%E3%83%A0/1875″][/blogcard]

これまでの契約形態から見る今回の民法改正による影響

システム開発の契約形態は大きく分けてSES契約と請負契約に分かれるのだが、まず、これらの契約形態の知識を抑えておく必要があります。
SES契約と請負契約とはこんな感じです。

SES契約

人を貸してお金を貰う契約。システムの完成を完遂する義務はありません。お手軽ですが、あまりお金もらえません。弱い中小企業はこの契約がメインの生業となります。

請負契約

お客さんから頂くシステム作成依頼から、システムを作成し納品することでお金を貰う契約となります。
そのため、システムの完成を完遂する義務が発生します。SES契約と比べ完遂義務が生じるため、お金を多く載せることが多いです。(リスク分の上乗せなども混みで)
主に中小企業を脱しようとする中小企業から、最大手の企業(NTTデータなど)まで様々なシステム開発企業がこの契約でシステム開発を行っています。

まぁ、こんな感じです。
で、今回の民法改正で影響が出てくるのは請負契約の契約形態が変わってくる可能性があります。

何が変わるの

今回の民法改正で変わるのは大きく分けて下記2点です。

システム品質を担保する責任が1年から5年に延びる

これまでの契約ではシステムの欠陥が存在した場合や、その欠陥に伴い業務に支障が出た場合の賠償責任を保証する期間は1年でした。
しかし、今回の民法改正によりその責任期間が5年に延長されます。
この結果、システム開発屋さん一つの請負で5年間無償で品質担保をする必要があり、その分システム開発の金額が高くなる点が懸念されます。
(※また、5年間のシステム品質保証を見積もれない弱小企業は淘汰されるでしょう。)

プロジェクトが途中で中断されても請求可能

今までは請負ということで、システムが100%完成しないとシステム開発屋さんはお金を貰うことができませんでした。
しかし、民法が改正されることによって、システムの完成が50%であっても50%分のお金を貰うことができるようになります。
これはシステム開発屋さんにとっては朗報であります。
システムは様々な要因によって完成まで持っていくことができないことが多々あります。そのような場合でもお金をもらえるようになります。
(※まぁ、家で言うと3階建ての戸建てをお願いしたのに、1階しか作る事ができず、その分の1/3はお金を払え!というものなので、これをやっちゃうと信用は従来通り無くなりますが、リスクという面では低減しそうですね。)

システム開発の手法が変わってくる可能性がある

この民法改正を考えると従来の開発手法が変わってくる可能性があります。

システム開発の手法は様々あるのですが、請負契約での主流はウォーターフォール型開発でしょう。
2231
今まではシステム完成の完遂義務があったため、ウォータフォール型の開発手法でも大丈夫でした。しかし、民法改正で途中途中のシステム完成率を把握しておく必要があります。そうしないとプロジェクト中断で請求できませんからね。
ウォータフォール型ではシステム開発途中段階のシステム完成率が把握しにくいため、これからは廃れていくのではないかと予想します。
(※ウォータフォールなくなれぇええ!一開発者としてはあんなやりにくい手法はなくなればいいと思ってます!)

じゃあどうなるか。遂に日本の主流もアジャイル開発に移行していくのではないかと予想しております。
アジャイル化イメージ
アジャイル開発は例えば、プリンターの開発でコピーする機能、印刷する機能、両面印刷する機能の3つが存在した場合、初めにコピーする機能を作って、完成したら次は印刷する機能、それが完成したら両面印刷する機能を作ってシステムを完成させるといった手法です。
この手法の場合

コピーする機能 33%
印刷する機能 33%
両面印刷する機能 34%

の計100%でシステム完成率を把握することが明確化できます。また、お客さんにとってもコピーする機能と印刷する機能があれば、一応プリンターとして使用することができるので、もしプロジェクトが途中で中断したとしても信頼がそこまでなくならない可能性もあります。

みんなハッピーな手法なのですが、何故か日本のシステム開発屋さん(SIer)はウォータフォール型にこだわります。
様々な要因があるのですが、アジャイル開発が主流とならない一番の要因は日本の技術者レベルが低いからできないだけだと思ってます。
(※一度完成したシステムに機能を追加するといった改修を行うと、再度最初に作った部分を含めテストをする必要があります。その分、テスト期間が長くかかってしまうため金額が多くかかってしまいます。(テストを手動で行う場合))
(※最近ではテストさえも自動化する流れがあります。アジャイル手法ではテスト自動化ができないと上記で記述したように余計な工数が発生してしまいます。このテスト自動化ができるエンジニアが少ないこと少ないこと。だから日本ではアジャイル型手法が主流とならないのです。)

おわりに

と、まぁだらだら書いてきましたが、僕にとっては朗報でした。
あの腐ったSIer業界を打破してくれるのではないかと、少し期待しております。
エンジニアが真にエンジニアであり続けられ、かつ、お客さんにとっても利益があるシステムを開発できる!
今回の民法改正でそういった契約となることを期待しています。

docker-composeを使って複数コンテナの管理を簡易化する

Gakuです。

前回はdockerを使用し、railsコンテナとpostgreSQLコンテナを立ち上げ連携する方法を掲載しました。
[blogcard url=”http://160.16.72.126/?p=569″][/blogcard]

今回はdocker-composeなるものを導入し、複数コンテナの管理を簡易化したいと思います。

docker-composeとは何ぞ?

ここらへんの記事をみると幸せになれるかもしれません。
[blogcard url=”http://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce”][/blogcard]

複数コンテナを1コマンドで立ち上げたり、docker run時のめんどうなオプションを記述して管理できる仕組みです。

ファイル構成

ファイル構成は下記のような感じで構成します。

.
├── docker-compose.yml
└── rails
    └── Dockerfile

Dockerfileは前回と同様のDockerfileを使用しております。

docker-compose.ymlの編集

postgreSQLとrailsコンテナを管理するため、docker-compose.ymlを下記のように編集します。

postgres0:
  image: postgres:9.5.4
  ports:
    - 5432:5432
rails:
  build: rails
  ports:
    - 3000:3000
  volumes:
    - /Users/gaku/Documents/develop/projects:/usr/src/docker-rails-test
  links:
    - postgres0:postgres0
  tty: true

設定内容はdocker run時のオプションと似ているのでとっつきやすいかと思います。

これで準備完了です( ^ω^ )

実行してみる

実行はすごく簡単です。

docker-compose build //イメージの作成
docker-compose pull  //イメージのダウンロード
docker-compose up -d //コンテナの生成

たったこれだけです。
3コマンドで全てのコンテナのイメージ作成からコンテナ生成までやってくれます。
こ。。。これがdockerの強さか。。。

後片付けのコマンド

コンテナの後片付けもすごく簡単です。

docker-compose stop //全てのコンテナの停止
docker-compose rm   //全てのコンテナの削除

今まで一つ一つコンテナを削除していたのですが、これで一気に削除できます。
う〜ん。きもちぃε-(´∀`; )

/bin/bashが起動できない

今までdocker run -it コマンドでbashを立ち上げる設定をしていたのですが、docker-composeには-i相当の機能がないらしい。
(-tはdocker-composeのtty:trueの記述が該当している。)

なので、docker-composeで/bin/bashを立ち上げる場合、下記コマンドで実行してあげる必要がある。

docker exec -it <コンテナID> bash

おわりに

docker-composeを知るまで、

「dockerめんどくせぇな〜。vagrant+virtualBOXのが良いんじゃね(´q` )」
って思っていましたが、今回composeやってみて世界が変わりました。

dockerで設定すれば、もう環境構築ほとんどやらんでええやん!すばらしき世界!

2日間dockerを触ってきて、だいたいのことはできるようになりました。
今度はheroku上のdocker-herokuなるもので、herokuへのUPを試みたいと思います( *`ω´)

DockerでpostgreSQLを導入しrailsと連携する

Gakuです。

前回までで、Dockerfileからrails環境を構築する方法を掲載してきました。
[blogcard url=”http://160.16.72.126/?p=562″][/blogcard]

今回はpostgreSQLコンテナを作成し、railsコンテナと連携する方法を掲載したいと思います。

postgreSQLコンテナの準備

下記コマンドを実行することで、postgreSQLコンテナを作成できます。

docker pull postgres:9.5.4
docker run --name pos-con -p 5432:5432 -d postgres

簡単すぎる( ^ω^ )

railsコンテナの準備

下記コマンドを実行しrailsコンテナを作成します。

docker run -it -p 3000:3000 -v "$PWD":/usr/src/docker-rails-test --name railstest --link pos-con:pos-con  gaku/rails

(※–linkオプションが今回の肝です。)

で、仮想環境へアクセスされると思うので、対象のフォルダでrails newします。

rails new postgretest -d postgresql

これで準備完了です。

database.ymlを編集しpostgreSQLとコネクトする

railsのdatabase.ymlのdefault部分を下記のように編集し、postgreSQLコンテナとドッキングします。

default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: pos-con
  username: postgres

下記コマンドでエラーが出ずdatabaseが作成されれば完了です。

rails db:create

おわりに

案外簡単にpostgreSQLとrailsの連携が可能でした。
今までは単体で起動していた各コンテナを、まとめて立ち上げることが可能なdocker-composeなるものを触ってみようと思います。( ^ω^ )

Dockerでrails環境を構築する

Gakuです。

前回の記事で、Dockerfileを作成しrubyコマンドを実行するところまで備忘録として残しました。
[blogcard url=”http://160.16.72.126/?p=557″][/blogcard]

今回はそのDockerfileを編集し、rails環境を構築します。

Dockerfileを編集

Dockerfileを以下のように編集し、rails環境構築用Dockerfileを作成します。

vi Dockerfile
FROM ruby:2.3.1

ENV APP_ROOT /usr/src/docker-rails-test

#Workディレクトリの設定
WORKDIR $APP_ROOT

#apt-getでtoolのインストール
RUN apt-get update && \
        apt-get install -y nodejs && \
        apt-get install -y vim

#rails導入
RUN gem install --no-ri --no-rdoc rails -v 5.0.0.1

#docker runの-pのヒント これでポート解放されるわけではない
#あくまで道しるべ
EXPOSE 3000:3000

#bashの立ち上げ
CMD ["/bin/bash"]

これで準備完了です( ^ω^ )

railsコンテナを立ててみる

作成したDockerファイルをビルドしてイメージを作成します。

docker build -t gaku/rails .

作成したイメージからコンテナを作成する。

docker run -it -p 3000:3000 -v "$PWD":/usr/src/docker-rails-test gaku/rails

そしたら仮想環境へアクセスする形となるので、いつもどおりrailsアプリケーションを作成してアプリケーションを立ち上げる

rails new test1
cd test1
rails s -b 0.0.0.0

docker-machineのipを確認しておき、そのipでホストPCのブラウザよりアクセスする。
スクリーンショット 2016-08-16 10.21.42

おつかれさまでした〜( ^ω^ )

作成したコンテナを操作する

一旦exitコマンドでコンテナを抜けるとコンテナが終了してしまう。
その際はコンテナを起こしてあげて、アクセスする必要がある。
下記コマンドで上記操作は可能です。

docker start コンテナID
docker attach コンテナID

おわりに

完全にDockerfileのCMDコマンドではまりました。。。つらかった。
CMDでbashを立ち上げるように設定するのがミソですね。
また、docker run時にいろいろなオプションを付けるのですが、その点をミスらなければすんなりrailsの導入は可能です。
次回はDBをpostgreSQLへ変更した場合の対処法などを掲載したいと思ってます。

docker上のrubyでHello World出力してみる

rubyのベースイメージをダウンロードする

Docker上でrubyを実行するために、DockerHubからrubyのイメージをダウンロードします。
下記コマンドでダウンロード可能です。

docker pull ruby:2.3.1

で、プロジェクトフォルダを作成して遷移します。

mkdir docker-rails-test
cd docker-rails-test

test用にtest.rbを作成します。

vi test.rb
puts "Hello World☆*:.。. o(≧▽≦)o .。.:*☆"

これで準備完了です。

docker runコマンドでrubyコードを実行してみる

下記コマンドでdocker上のrubyで先ほど作成したtest.rbを実行してみます。

docker run --rm -v "$PWD":/usr/src/docker-rails-test -w /usr/src/docker-rails-test ruby:2.3.1 ruby test.rb

このコマンドでコンテナを作成することが可能です。
コンテナは作成すると永遠に残り続けるのですが、–rmをつけることで、コマンド実行後コンテナを削除することが可能です。(一時的にコンテナを作成したい時に有効なオプションですね。)
また、-vをつけることでホストコンピュータとdocker上のフォルダを共有フォルダとして設定することが可能です。
今回は
【”$PWD”:/usr/src/docker-rails-test】
としましたが、
【ホストマシンフォルダ:docker上のフォルダ】
でマウントしています。
-wはワーキングフォルダを設定するためのオプションでdocker上の/usr/src/docker-rails-testで作業をしたいため、このオプションをつけております。

その後ろに、イメージ名である「ruby:2.3.1」を記述し、その後ろにrubyの実行コマンドを記述しております。

docker run --rm -v "$PWD":/usr/src/docker-rails-test -w /usr/src/docker-rails-test ruby:2.3.1 ls -a
docker run --rm -v "$PWD":/usr/src/docker-rails-test -w /usr/src/docker-rails-test ruby:2.3.1 pwd

などのコマンドを実施すれば理解が深まるかもしれません。

Dockerfileからrubyファイルを実行してみる

dockerは先ほどダウンロードしたruby:2.3.1のイメージをベースにして、様々な環境をカスタマイズすることが可能です。
その設定をDockerfileというファイルに記述し作成するのですが、その作業を行ってみたいと思います。
とりあえず、Dockerfileを作成して、下記のように記述してみます。

vi Dockerfile
FROM ruby:2.3.1

はい。これでDockerFileの準備が完了しました。

Dockerfileをビルドして作成したイメージからrubyコマンドを実行してみる。

さきほど作成したDockerfileをビルドします。

docker build -t my-ruby-app .

これで、my-ruby-appという名前でimageが作成されました。
docker imagesとコマンドを実行すると作成したimageが存在しているのがわかります。

作成したimageからrubyコマンドを実行するために下記コマンドを実行してみます。

docker run --rm -v "$PWD":/usr/src/docker-rails-test -w /usr/src/docker-rails-test  my-ruby-app  ruby test.rb

簡単ですね☆*:.。. o(≧▽≦)o .。.:*☆

おわりに

なんとな〜くですが、Dockerさんと仲良くなれてきた気がします。
今度はDockerfileを編集してrailsを導入したいな〜っと思ってます。

docker-machineを自動起動するように設定する

dockerを起動する際、毎回毎回下記コマンドを実行するのはめんどうくさいです。

docker-machine start
eval "$(docker-machine env default)"

ってことで自動化します。

ホストマシン起動時にdocker-machineを自動起動する設定

~/Library/LaunchAgents以下に[com.docker.machine.default.plist]という名前でファイルを作成し、下記内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
        </dict>
        <key>Label</key>
        <string>com.docker.machine.default</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/docker-machine</string>
            <string>start</string>
            <string>default</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

これでホストマシン起動時に自動でdocker-machineが立ち上がります。
また、defaultとなっている部分を編集すれば、任意のdocker-machineを自動起動することが可能です。

環境変数の設定

下記コマンドを実行し、bash_profileに書き込みます。

echo 'eval "$(docker-machine env default)"' >> ~/.bash_profile

以上です。これでホストマシン起動時にdocker-machineを自動起動し、環境変数を設定してくれます。

注意点

ホストマシンを起動して、すぐにターミナルを起動するとdocker-machineが起動していない状態で環境変数を通しに行ってしまうためエラーが発生してしまいます。
スクリーンショット 2016-08-15 10.27.22

このエラーが発生した場合、少し待ってから再度ターミナルを起動すれば正常に環境変数が適用されます。

おわりに

こういうの楽しいね。好きだわ〜( ^ω^ )

「Cannot connect to the Docker daemon. 」と怒られる時の対処法

Gakuです。

docker runコマンドを実行しようとすると「Cannot connect to the Docker daemon. Is the docker daemon running on this host?」と出て怒られたのでその対処法を備忘録として残します。

そもそもこのエラーは何?

「Cannot connect to the Docker daemon. Is the docker daemon running on this host?」
日本語訳:Dockerが立ち上がってますか?dockerデーモンにconnectできないんだけど
って怒られる。

この症状は様々な要因が考えられるが、僕の場合、dockerをインストールしたユーザと別ユーザでdocker runコマンドを実行しようとしたため、エラーが発生した。

再度docker toolboxをインストールしてみる

この記事で書いたように、再度dockerをインストールしてみます。
[blogcard url=”http://160.16.72.126/?p=532″][/blogcard]

しかし、これだけではやはりさきほどのエラーが出力されてしまい解決できませんでした。

docker machineが立てられていない?

docker-machine start

を実行したところ、以下エラーが出力されました。

Error: No machine name(s) specified and no "default" machine exists.

「名前を指定しない場合はdefaultのマシンを立ち上げるけど、defaultのマシンは存在しないよ」
的なエラーが出力されました。
ここにピンときて、「docker-machineなるものが必要なのか?」
ってことで、調べて下記コマンドを実行してみました。

docker-machine create --driver virtualbox default
eval "$(docker-machine env default)"

これで再度「docker run hello-world」で正常に出力することが可能となりました。

おわりに

とりあえず解決しましたが、まだまだ理解力が足りないため、あらゆるところではまりそうです。
このエラーが出たら「docker-machine ls」でマシンが立ち上がっているかどうか確認するのは有効な手段であると思います。

macにdocker環境を構築する方法

Gakuです。

今まではvagrant+virtualBoxで仮想環境上で開発を行っていたのですが、macの初期化を行ったため、これを機会にdockerで開発環境構築を行ってみました。
その際の備忘録です。

そもそもdockerって何よ?

dockerが何者かわからない方は下記の記事を読めば幸せになれるかも。

[blogcard url=”http://paiza.hatenablog.com/entry/docker_intro”][/blogcard]

とりあえずmacにdockerをインストールしてみる

docker toolboxなるものをインストールすればOK
[blogcard url=”https://www.docker.com/products/docker-toolbox”][/blogcard]

インストールが完了したらLaunchpadでDocker Quickstart Terminal.appを実行ししばらく待つ
te

下記のアスキーアートが出力されれば成功です( ´ ▽ ` )ノ
スクリーンショット 2016-08-14 11.40.16
クジラたんだぉ(´Д` )かわいいぉ(´Д` )

とりあえずHello World!

さっきのターミナル上で下記コマンドを実行しHello Worldを出力してみる。

docker run hello-world

スクリーンショット 2016-08-14 11.45.19

Hello Worldが出力されて、正常にインストールが完了したことを確認できました。
☆*:.。. o(≧▽≦)o .。.:*☆

おわりに

これでmacにdockerをインストールするという最初のステップを完了しました。
ここからは具体的な使い方等を勉強し、有益な情報が得られ次第、またブログで報告させていただきたいと思います。