スマホアプリのアイデアを出す
世の中には普通に思いつきそうなアイデアや、誰も思いつかないようなアイデアを実現したスマホアプリがたくさんあります。 そこで、自分も何かアイデアを形にしたいと思ったので、実際にアプリを開発することにしました。
しかし、普段からあまり自分のアイデアを考えることがなかったので、何を作れば良いのか思いつきませんでした。 ですので、まずは世の中のアプリにはどういうジャンルがあってどんなことが出来るのかというのを自分なりにまとめてみました。
目次
- アプリのジャンル
- どんなアプリを作ればいいか
- アプリの操作対象
- 世の中のアプリの例
アプリのジャンル
- 健康
- 音楽
- 料理 グルメ
- 植物
- 写真 動画 (加工、管理)
- 教育 学習
- 育児
- 生活
- 地図
- 情報収集 (ニュース、天気、交通状況等)
- 情報整理 (見る予定のアニメ、待ち合わせの時間、持ってる本)
- エンタメ
- ファッション
- ビジネス
- 仕事効率化 (電卓、メモ帳、TODOリスト、リマインダー)
- 会計 (お小遣い帳、家計簿)
- コミュニケーション (SNS)
- デジタルアート
- 災害時用
- クリエイティブ (作曲、小説、プログラミング)
- ゲーム
どんなアプリを作ればいいか
- 現実の物(行為)をアプリに置き換え (タイマー、塗り絵、じゃんけん、読書)
- 流行を取り入れたもの (ポケモンがいる場所がわかるマップ)
- 面倒なものを楽にしてくれる (自動化アプリ)
- 悩みを解消してくれる (物を無くす、電車を乗り過ごす)
- 知りたい情報が得られる (天気、電車の時刻、ファッション、マナー、SNS通知)
- 時間が潰せる物 (単純なゲーム)
- 決められた目標を達成する (スコアやレベル)
- 欲求が満たせる (破壊欲求、自己顕示欲、女の子に会いたい欲求)
アプリの操作対象
ゲームのようにスマホ内だけで完結するものもあれば、センサ等で取得した現実の情報とスマホアプリが連動しているものも多くあります。 アプリの操作対象というのは、現実とスマホのどちらからインプットし、どちらにアウトプットするのかということです。
世の中のアプリの例
自分が便利だなーと思ったアプリです、3種類あげていますが特に関連性はありません。
まとめ
世の中のアプリはジャンルや操作対象が違うだけで、大半は似たようなものばかりだと思います。 ですので、何を作るか迷ったらジャンルや操作対象を何にするか考えてみると良いかもしれません。
当たり前のことを書き連ねましたが、何かの参考になればと思います。
学生プログラマはプログラミングバイトをしよう
今回の記事に出てくる「学生プログラマ」には高校生は含まれておりません。高校生は労働基準法で勤務時間が制限されてしまう為、プログラミングバイトが難しいと思われるからです。
しかし、100%不可能であるとは断言出来ないので、メンタルの強い方は挑戦してみてもいいかもしれません。(責任は取れません)
独学には限界がある
プログラミングをしている学生さんは、独学や学校の授業でプログラミングを学んだことでしょう。自分で処理を考えて思った通りに動作した時は、何よりも気分が良い物だと思います。
しかし学生でプログラミングの勉強をしていると、下記のことに悩んだりしたことがあると思います。
- 実際のシステムがどうコーディングされているのか
- チームで開発をするときはどのように進めればよいのか
- 自分のコードの書き方は本当に正しいのか
- 今の技術レベルは、業界的に見たらどれくらいなのか
そんな時は実際にIT企業にインターンやアルバイトに行き、現場のシステムやプロジェクトに触れてみることが良いと思います。
自分の中の勝手なイメージですが、学生プログラマの方々は勉強会やコンテスト等には参加していても、プログラミングバイトをしている方は少なく思います。
勉強会へ行くことは確かに大切ですが、実際に利益を生んでいるシステムの開発に関わることはより価値のある経験だと考えています。
プログラミングバイトはどうやって探す?
プログラミングのバイトは「バイト探しはan」「マイナビバイト」等の普通のアルバイト求人サイトで応募しても、学生である以上ほとんど受かりません。
自分は高校三年の冬に三社のIT企業に応募しましたが、悲しいことに三社とも面接さえ受けさせてもらえませんでした。常識的に考えれば、高校生が業務で役に立つとは思えないので正しい判断であると言えますが。
完全に心が折れていましたが、Twitter で上記の経験を嘆いていると優しいフォロワーさんが素晴らしいサイトを教えてくれました。
そのサイトは Wantedly というもので、学生プログラマのアルバイトやインターンを募集している企業が多く集まっているそうです。
早速このサイトである企業に応募してみました。すると、その企業の方は自分と会って話がしたいと言って下さったのです。学生というだけで話させて貰えない経験を3回もしていたので、すごく嬉しかったです。
面接は新宿のカフェで行われ、IT関係で働いているプロの方といろいろなお話をしました。結果的に不採用となってしまいましたが、プロの方とカフェでお話するのはとても貴重な経験で楽しかったです。
その後立て続けに7社の企業に応募し、2社から内定を頂くことが出来ました。このような経緯を経て、自分は現在web系の企業でアルバイトとして働いています。
学校に行きながらいつ働いているのか
自分は平日週5日、放課後の 18:00 - 23:00 に働いています。また、自宅での作業も許可されているので、働くのが苦だと感じたことは一度もありません。
全ての企業がこうであるとは言えませんが、Wantedly に登録している企業のほとんどは相談してみれば遅い時間帯であっても働かせてもらうことが出来ると思います。
まとめ
ホリエモンやビル・ゲイツも、学生時代はプログラミングバイトをしていたそうです。プログラミングバイトは技術に関してだけではなく、仕事に対する姿勢やエンジニアとしての物の考え方を身につけることもできます。また、周りの人が大人ばかりなので、人間的にも大きく成長出来ます。
今の自分よりも更に上を目指したいと思っている学生プログラマの皆さんは、是非一度プログラミングバイトを経験してみると良いでしょう。
JQuery との別れ
こんにちは、専門学校に通いながらwebエンジニアのバイトをしている者です。
普段考えていることや、新しく知ったこと等を適当にブログに書いています。
今回は JQuery についてです。
自分は趣味でwebページを作ることがあり、ページ内のロジックに JavaScript を使用しています。(当たり前ですが)
その際に自分は JQuery を使用していたのですが、 最近 JQuery はあまり使うべきではないという話をよく耳にしており、何故ダメなのか疑問に思っていました。 そこで、JQuery のデメリットや、JQuery を使わない場合等をネットで調べたり、会社の先輩に聞いてみたりしました。
また、今回の記事は私見が多く含まれているので、あくまで考え方の一つとして捉えていただけたらと思います。
JQuery はスコープがでかい
JQuery を使うとDOM全体を操作出来てしまう為、JavaScript の長いコードを修正する際にコード全体を読まなければならないそうです。 また、対象の要素の親要素を操作出来る .parent() 等のメソッドを使用してしまうと、コードの修正がとても大変になってしまうみたいです。
これらの原因は、JQuery のスコープが大きいことにあります。 ですので、本来webページのロジックを記述する時はページ内のコンポーネントごとに行うことが理想です。 もちろん JQuery でもコンポーネントごとにコードを書くことも出来ますが、 全体を操作出来るメソッドが存在する以上、見づらいコードが生まれてしまう可能性は潰せないようです。
じゃあどうすればいいのか
生の JavaScript か、フレームワークを使うと良いとのことでした。
生の JavaScript は面倒なことが多いですが、可読性は高いようです。
また、フレームワークを使用すれば、ページ内のパーツをコンポーネントに分けて開発できるので、 スコープを縮めることが出来ます。
JavaScript のフレームワークは一度も使ったことが無かったので、現在開発しているwebアプリケーションに組み込んでみようと思っています。
まとめ
JQuery さよなら。
ある男の為に自作楽曲配布サイトを作る
Googleアドセンスの申請を通したくて久しぶりに記事を書きました。
自分は現在、IT系の専門学校に通いながらIT系のアルバイトをしています。 もちろん趣味でもプログラミングをしており、最近はアルバイトの影響でweb系の勉強を多くしています。 アルバイトではバックエンドの仕事が中心ですが、趣味ではバックもフロントもやってます。 しかし、勉強するだけでは本質的な技術は身につかないと思ったので、実際にwebサービスを作ることにしました。
webサービスを趣味で作った経験はまるで無いので、とりあえず簡単なサービスから作りたいなと思っていました。 そんな時、高校の頃の同級生が学校にも行かずにひたすら曲を自作しているというので、まずはそいつの為のサイトを作ろうと思いました。
サイトの機能は、楽曲再生・ダウンロード・コメント の3つが中心です。 たったこれだけなのかと思うかもしれないですが、 データベースを使ったり、動的にサイトを書き換えたりという処理をしたのは人生で初めてだったので苦労しました。
バックエンドは FuelPHP というフレームワークを使用し、フロントでは当然ながら JavaScript を使用しています。 バックエンドに Rails ではなく PHP を選んだ理由は、環境構築が圧倒的に楽だったからです。 Rails が強力なフレームワークであることは理解していますが、趣味で使うにはまだ知識が足りないなぁという印象でした。
公開するためのレンタルサーバは、Xサーバ の一番安いプランを利用しています。 一番安いとは言っても、個人が趣味で作った小さなwebサービスを公開する分には十分使えます。 料金の支払いは高校の同級生と割り勘です。
このサイトは8割近く完成しているので、今月中には公開出来るだろうと思います。 公開しましたら、是非曲を聴いてくださると嬉しいです。
ある男の Twitter → @k_t_mejohn
ある男が作った曲 → 作った曲
セキュリティ・キャンプ 2016 選択問題解答
ブログでセキュキャンの解答を晒している方が何人かいらっしゃったので、自分も晒してみようと思います。 ここ違くね?とかここは同じだ!とか思っていただければ幸いです。
選択問題1
実行結果のアドレスのサイズを見る限りですと、上記のプログラムは64bit の OS で実行されているのではないかと考えました。
理由は、32bit の OS で上記のプログラムを実行した際は上記の実行結果よりも小さなサイズであり、 64bit の OS で実行した際は上記の実行結果に近いアドレスとなったからです。
32bit の OS で実行した結果は下記の通りです。
hoge address = 0019F824 fuga address = 002D3208
他に感じたことは、スタックとヒープのおおよその先頭アドレスがわかるので、上記のアドレスの差から これら2つの領域に割り当てられているアドレス領域のサイズがわかるのでは無いかということです。 「おおよその」というのは、ヒープに OS の管理領域がある為、正確な位置がわからないという意味です。
選択問題3
パソコンの電源が入るとまず、システムBIOSがハードウェアを初期化して記憶装置からブートローダを読み出します。 そして読み出されたブートローダはMBRに記録されているプログラムを呼び出し、呼び出されたプログラムはOSを読み込んで起動します。
OS起動後に何かプログラムを実行させる時は、補助記憶装置に書き込まれたプログラムを実行することになります。 しかし問題文にあるようにCPUは主記憶上のプログラムしか実行できないので、 プログラムローダと呼ばれるものが必要に応じて、補助記憶装置に書き込まれているプログラムを主記憶装置に読み出しています。
その後、プログラムローダは読み出したプログラムの先頭アドレスに飛ぶことで、目的のプログラムが実行されています。 以上の処理が行われているため、私たちは補助記憶装置に書き込んだプログラムを実行することが出来ています。
選択問題4
プログラムは Windows Vista 32bit版 で Microsoft Visual C++ 2010 Express で作成・実行しました。 最初はこの問題を解こうとは思っていなかったのですが、チノちゃんが目に入ってきて問題を解くことを決意しました。 ソースコードは下記の通りです。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define TRUE 1 #define FALSE 0 #define MAX_MAGIC 2 #define MAX_SOURCE 20 #define MAX_DESTINATION 20 /* バイトオーダーの違いを吸収する */ typedef union{ unsigned int byte_4; char byte_1[4]; }byte_union; /*------------ | その他関数 | ------------*/ /* 文字列を小文字に変換 */ void str_to_lower(char *str,int size){ int i; for( i=0 ; i<MAX_SOURCE+1 ; i++ ) str[i] = tolower(str[i]); } /* バイトオーダー変換 */ void change_byte_order(byte_union *data){ const int INT_SIZE = sizeof(int) - 1; byte_union tmp_data; // バイトオーダー変換 int i; for( i=0 ; i<4 ; i++ ) tmp_data.byte_1[i] = data->byte_1[INT_SIZE-i]; // 代入 data->byte_4 = tmp_data.byte_4; } /*------- | 条件 | ------- */ /* Magicの検証 */ int Condition1(char *data){ if( strcmp(data,"RH") == 0 ) return TRUE; else return FALSE; } /* Sourceの検証 */ int Condition2(char *data){ str_to_lower(data, MAX_SOURCE); if( strcmp(data,"rise-san") == 0 || strcmp(data,"cocoa-san") == 0 ) return TRUE; else return FALSE; } /* Destinationの検証 */ int Condition3(char *data){ str_to_lower(data, MAX_DESTINATION); if( strcmp(data,"chino-chan") == 0 || strcmp(data, "chino") == 0 ) return TRUE; else return FALSE; } /* data に valid_order_brand が含まれているか検証 */ int Condition4(char *data){ const char *valid_order_brand[3] = { "BlueMountain", "Columbia", "OriginalBlend" }; int i=0; for( i=0 ; i<3 ; i++ ) if( strstr(data,valid_order_brand[i]) != NULL ) return TRUE; return TRUE; } /* data に invalid_order_brand が含まれていないか検証 */ int Condition5(char *data){ const char *invalid_order_brand[2] = { "DandySoda", "FrozenEvergreen" }; int i=0; for( i=0 ; i<2 ; i++ ) if( strstr(data,invalid_order_brand[i]) != NULL ) return FALSE; return TRUE; } /*----------- |メイン関数 | -----------*/ int main(void) { // 変数宣言(ファイルからデータを読み込む変数は、読み込んだデータを文字列として扱うために \0 の領域分を確保している) char Magic[MAX_MAGIC+1]; char Source[MAX_SOURCE+1]; char Destination[MAX_DESTINATION+1]; byte_union DataLength; char *Data; int byte_count = 0; int pass_flag = 0; int loop_count = 0; // ループ回数を出力するためのもので、ループ処理には使用されない // 条件が全て通ったときの pass_flag の値 const int PASS_FLAG_COUNT = 4; //ファイル読み出し FILE *fp; fp = fopen("pyonpyon.rh","rb"); if(fp == NULL){ printf("ファイル読み込み失敗\n"); exit(0); } // ファイルサイズ取得 fpos_t fsize = 0; fseek(fp,0,SEEK_END); fgetpos(fp,&fsize); fseek(fp,0,SEEK_SET); // ファイル終端まで読み出す while( byte_count < fsize ){ // データ読み込み変数初期化 memset(Magic,'\0',sizeof(Magic)); memset(Source,'\0',sizeof(Source)); memset(Destination,'\0',sizeof(Destination)); // 一連のファイルを読み出す fread(Magic,sizeof(char),MAX_MAGIC,fp); fread(Source,sizeof(char),MAX_SOURCE,fp); fread(Destination,sizeof(char),MAX_DESTINATION,fp); fread(&DataLength.byte_4,sizeof(int),1,fp); // pyonpyon.rh はビッグエンディアンだが、windowsはリトルエンディアンなので変換する change_byte_order(&DataLength); Data = (char *)calloc(DataLength.byte_4+1,sizeof(char)); fread(Data,DataLength.byte_4,1,fp); // バイトカウントに読み込んだバイト数加算 byte_count += MAX_MAGIC + MAX_SOURCE + MAX_DESTINATION + sizeof(int) + DataLength.byte_4; // 判定 if( Condition1(Magic) ) pass_flag++; if( Condition2(Source) ) pass_flag++; if( Condition3(Destination) ) pass_flag++; if( Condition4(Data) && Condition5(Data) ) pass_flag++; // ループカウント更新 loop_count++; // 結果出力 if( pass_flag == PASS_FLAG_COUNT ) printf("%2d回目:PASS\n",loop_count); else printf("%2d回目:REJECTED\n",loop_count); // メモリ開放 & paa_flag初期化 free(Data); pass_flag = 0; } fclose(fp); return 0; }
実行結果
1回目:PASS 2回目:PASS 3回目:PASS 4回目:PASS 5回目:PASS 6回目:PASS 7回目:PASS 8回目:PASS 9回目:PASS 10回目:REJECTED 11回目:PASS 12回目:PASS 13回目:PASS 14回目:REJECTED 15回目:REJECTED 16回目:PASS 17回目:PASS 18回目:PASS 19回目:REJECTED 20回目:REJECTED 21回目:REJECTED 22回目:PASS 23回目:PASS 24回目:PASS 25回目:REJECTED 26回目:REJECTED 27回目:REJECTED 28回目:REJECTED 29回目:PASS 30回目:PASS 31回目:PASS 32回目:REJECTED 33回目:REJECTED 34回目:REJECTED 35回目:REJECTED 36回目:REJECTED 37回目:PASS 38回目:PASS 39回目:PASS 40回目:REJECTED 41回目:REJECTED 42回目:REJECTED 43回目:REJECTED 44回目:REJECTED 45回目:REJECTED
選択問題6
まず簡単なシステム構成の前提ですが、ユーザ認証等の処理に使用する言語は PHP で、ユーザ情報を保存するデータベースは MySQL です。
上記の構成でユーザ認証のWebアプリを構築した場合、自分が一番最初に行うセキュリティテストは「SQLインジェクション」の対策が行われているかどうかのテストです。 SQLインジェクションを選択した理由は、攻撃者が手軽に実行できる攻撃でありながら、 開発者はフレームワーク等を使用していない場合は自ら対策を行う必要があるからです。
また開発者側がSQLインジェクション攻撃の存在を認識していても、サニタイズを忘れてしまう可能性もあります。 以上のような理由から、私は最初のセキュリティテストに「SQLインジェクション」の対策を行うことを選択しました。
FuelPHP でカラムを追加した時にやり忘れたこと
現在使用しているテーブルに新しくカラムを追加したのですが、 何故かコントローラからモデルオブジェクトを呼び出してカラムを使おうと思っても上手くいかなかったので、 同じ事象に遭遇した人の為に記事を書きました。
この問題はモデルのprotected static $_properties
がカラム追加をしても更新されない為に起こる問題でした。
protected static $_properties
はコマンドラインでモデルを作成すると自動的に作られます。
下記のように新規に追加したカラムをprotected static $_properties
に追加することで解決しました。
例
protected static $_properties = array( 'id', 'カラム名', 'created_at', 'updated_at' );
↓
protected static $_properties = array( 'id', 'カラム名', 'created_at', 'updated_at', '新規カラム名' );
無料サーバ Hostinger で FuelPHP を動作させる
Hostingerは無料で使用できるレンタルサーバです。
このサイトの他にもいくつか無料のレンタルサーバは存在しますが、大抵は広告がついていたりデータベースが使えなかったりと制限が多くあります。
しかし、このサイトにはそのような制限はありません。なおかつ、使いやすいダッシュボードに充実したサポートもついているのですごく気に入っています。 ただし、無料なのでページが表示される速度は物凄く遅いです。まぁ、お金を払えば100倍早く出来ますが。
もちろん、PHPも動作するので今回はこのレンタルサーバで FuelPHP を動作させてみようと思いました。 なお、FuelPHP のプロジェクトは実際に動作する状態になっていると想定します。
関係無いですが、Hostinger は残念ながら Ruby on Rails には対応していないようです。。。
まずはアカウント取得
1.まずはトップページにアクセスして、アカウント取得。
2.登録したメールアドレスに登録完了メールが来るので、アカウントを認証。
3.次に、表示されているページで一番左の Free コースを注文し、適当に設定。
4.これでサーバが使えるようになった、試しに登録したドメインにアクセスしてみる。(登録に時間がかかる場合もある)
ローカルの DB を Hostinger に移行する
Hostinger 上ではマイグレートをすることが出来ないので、ローカルでマイグレートしておいて DB をエクスポートします。
1.ローカルで phpMyAdmin を開き、プロジェクトに使用しているデータベースを選択して出てきたメニューから「エクスポート」をクリック。
2.デフォルトの設定のまま「実行」をクリックすると、SQLファイルがダウンロードされます。
3.Hostinger のダッシュボードから「MySQLデータベース」を選択し、適当な名前でデータベースを作成します。
4.データベースが作成できたらダッシュボードから「データベースの読み込み」を選択し、先ほどエクスポートしたSQLファイルを読み込ませます。
これで、データベースの移行は完了しました。
FuelPHP の環境設定をステージング環境に変更しておく
FuelPHP には下記の4つの環境が設定されています。
- 開発環境
- ステージング環境
- テスト環境
- 本番環境
ステージング環境とは本番環境でテストする時に使い、テスト環境は自動化テストを走らせる時に使うって考えています。 環境を変更するメリットは、環境ごとに DB に関する設定をする必要が無いからです。
詳しくは、ウェブ開発で大切な3つの環境を見てみると良いかも。
今回の場合はステージング環境だと判断したので、FuelPHPの環境をステージング環境に切り替えます。
切り替えるにはfuel/app/bootstrap.php
のFuel::DEVEROPMENT
をFuel::STAGING
に変更。
すると、下記のようになるはずです。
\Fuel::$env = (isset($_SERVER['FUEL_ENV']) ? $_SERVER['FUEL_ENV'] : \Fuel::STAGING);
ステージング用の DB 設定を編集
環境をステージングに変更しただけでは何も意味無いので、ステージング用の DB 設定ファイルを編集していきます。
fuel/app/config/staging/
にあるdb.php
の内容を、Hostinger で作成した DB の設定に変更しま。
なお、作成した DB の設定はダッシュボードの「MySQLデータベース」から確認できます。
FuelPHP のプロジェクトを Hostinger に移行する
FuelPHPに限った話ではないですが、フレームワークを使用したwebサイトは全体の容量が大きくなります。
ですので、Hostinger に FuelPHP のプロジェクトをアップロードするためにはサイトのファイルマネージャーでは無理なので、FTPクライアントを使用する必要があります。
今回私が使ったのは、FileZillaです。
使い方は超初心者向け!FileZilla(ファイルジラ)の使い方を参照してください。
FTPアクセスに関する情報は、ダッシュボードの「FTPアクセス」に記載されています。
アップロードするディレクトリは、public_html
です。
これで FuelPHP を動作させることが出来ると思われます。
何かわからないことや、間違っていることがあれば是非コメント下さい。
最後に気がついたのですが、本番環境にアップロードする時はpublic
以下をドキュメントルートに設定しましょう。