tag:crieit.net,2005:https://crieit.net/tags/%E9%80%A3%E8%BC%89/feed 「連載」の記事 - Crieit Crieitでタグ「連載」に投稿された最近の記事 2023-03-15T23:42:14+09:00 https://crieit.net/tags/%E9%80%A3%E8%BC%89/feed tag:crieit.net,2005:PublicArticle/18405 2023-03-11T21:18:58+09:00 2023-03-15T23:42:14+09:00 https://crieit.net/posts/Unity-640c71b2ace84 Unity練習 セーブデータを作ろうぜ(^~^)? <h1 id="セーブデータの作り方調べ"><a href="#%E3%82%BB%E3%83%BC%E3%83%96%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9%E8%AA%BF%E3%81%B9">セーブデータの作り方調べ</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/kazuki_kuriyama/items/20847a040d5f52835ba6">Unityでセーブデータを作る方法まとめ</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 Unity でセーブデータを作る方法を調べようぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 JSONファイルでいいんじゃないか?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Unity にファイルチューザーが あんの?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://docs.unity3d.com/ja/current/ScriptReference/JsonUtility.html">JsonUtility</a><br /> 📖 <a target="_blank" rel="nofollow noopener" href="https://docs.unity3d.com/ja/current/ScriptReference/EditorJsonUtility.ToJson.html">EditorJsonUtility.ToJson</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 ユーティリティーが2種類あるらしい。使ってみようぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 サンプルが無くて 分からんな」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://logicalbeat.jp/blog/8195/">【Unity】JsonUtilityを触ってみた</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 セーブファイルを 100個ぐらい分けたいとき どうするんだぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 1つのJSONファイルに すべて詰め込むんじゃないか?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 容量は 何バイトまで 保存できるんだぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 移植先にもよるんじゃないの?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 Webブラウザーの上で実行するアプリだったら、どこへ保存される?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 それも含めて調査しろだぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://blog.unity.com/ja/technology/persistent-data-how-to-save-your-game-states-and-settings">永続データ ― ゲームの状態と設定を保存する方法</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 保存先の設定をプログラムしないといけないらしいぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://github.com/UnityTechnologies/UniteNow20-Persistent-Data">UnityTechnologies/UniteNow20-Persistent-Data</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 サンプル・プログラムは これらしいぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 ソース読んだが 使い方 分からん。<br /> どうやって クロス・プラットフォーム のセーブデータを作れる?<br /> Windows を想定して ファイルパス書いていいのか?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://magnaga.com/2016/04/25/unity-save2/">PlayerPrefsと同様な使い勝手で独自クラスもセーブできる機能実装【Unity】【セーブ】【Json】</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 これを真似てみるかだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 なんだこのクラスは。真似たくない書き方だな」</p> <h1 id="セーブボタンを置こう"><a href="#%E3%82%BB%E3%83%BC%E3%83%96%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%92%E7%BD%AE%E3%81%93%E3%81%86">セーブボタンを置こう</a></h1> <p><a href="https://crieit.now.sh/upload_images/e4257f7c7fa838934b0e7872bd1e8a03640c7bc3cdad4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e4257f7c7fa838934b0e7872bd1e8a03640c7bc3cdad4.png?mw=700" alt="202303_unity_11-2200--saveDataManager-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 とりあえず マネージャー・クラスを作る 鉄板のやり方で サンプルを書き直そう」</p> <p><a href="https://crieit.now.sh/upload_images/9a772f1c008ffd1d8cd102bbfca6878e640c7e2c2fd3c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9a772f1c008ffd1d8cd102bbfca6878e640c7e2c2fd3c.png?mw=700" alt="202303_unity_11-2211--onSave-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 <code>OnSave</code> という Publicメソッドを作って」</p> <p><a href="https://crieit.now.sh/upload_images/ea6bc8e52d8e3c6380c649d8dd603506640c7fc19b479.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ea6bc8e52d8e3c6380c649d8dd603506640c7fc19b479.png?mw=700" alt="202303_unity_11-2211--saveButton-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 <code>Save</code> ボタンをクリックしたら、 <code>SaveDataManager</code> クラスの <code>OnSave</code> メソッドを呼び出すところまで<br /> 作るのは 鉄板だぜ」</p> <h1 id="マウスで動かせるオブジェクトを置こう"><a href="#%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%9B%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E7%BD%AE%E3%81%93%E3%81%86">マウスで動かせるオブジェクトを置こう</a></h1> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://futabazemi.net/notes/unity-mouse_drag">オブジェクトを掴んで動かす</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 上のリンク先の、他人の記事を読めだぜ。<br /> マウスで動かせるオブジェクトを画面上に置こうぜ?」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://hakase0274.hatenablog.com/entry/2019/11/12/200000">Unity マウスからRayを打つ ~可視化もするよ~</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 別の記事も読まないと コードがおかしいぜ」</p> <p><a href="https://crieit.now.sh/upload_images/00e9629b65a49f0d5deaa5b759b87a80640c9156da8e5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/00e9629b65a49f0d5deaa5b759b87a80640c9156da8e5.png?mw=700" alt="202303_unity_11-2333--inputManager-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/2830c4ae2e78f66fa1074ea64efa4156640c905f83bd0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2830c4ae2e78f66fa1074ea64efa4156640c905f83bd0.png?mw=700" alt="202303_unity_11-2326--script.png" /></a></p> <pre><code class="csharp">using System.Collections; using System.Collections.Generic; using UnityEngine; public class InputManager : MonoBehaviour { /// <summary> /// レイを描く距離 /// </summary> float DebugDrawRayDistance = 15.0f; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { // マウス右ボタン 押しっぱなし時 if (Input.GetMouseButton(0)) { // レイ(見えない光線のようなもの)を飛ばす var ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out var hit)) { // レイが当たったオブジェクト string goName = hit.collider.gameObject.name; Debug.Log("右クリック:" + goName); // そのオブジェクトの中心位置を、クリックした場所へ移動(カクカクした動き) GameObject.Find(goName).transform.position = new Vector3(hit.point.x, hit.point.y, 0); } else { Debug.Log("右クリック 外れ"); } // レイを描く Debug.DrawRay(ray.origin, ray.direction * DebugDrawRayDistance, Color.green, 5, false); } } } </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 カクカクしてるが、とりあえず これで 箱は動くぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>Update()</code> じゃなくて、 <code>LateUpdate()</code> にすりゃいいんじゃないかだぜ?」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 うまくやってくれだぜ」</p> <h1 id="まず、 PlayerPrefs を練習しようぜ?"><a href="#%E3%81%BE%E3%81%9A%E3%80%81+PlayerPrefs+%E3%82%92%E7%B7%B4%E7%BF%92%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%9F">まず、 PlayerPrefs を練習しようぜ?</a></h1> <p><a href="https://crieit.now.sh/upload_images/33f01c48d2ec58268bc1932413f76681640c98527113f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/33f01c48d2ec58268bc1932413f76681640c98527113f.png?mw=700" alt="202303_unity_12-0002--loadButton-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 セーブボタンだけあっても練習できない。ロードボタンも追加するぜ」</p> <p><code>SaveDataManager.cs</code> :</p> <pre><code class="csharp">using System.Collections; using System.Collections.Generic; using UnityEngine; public class SaveDataManager : MonoBehaviour { // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } // - イベントハンドラ public void OnSave() { Debug.Log("セーブします"); var goCube = GameObject.Find("Cube"); PlayerPrefs.SetFloat("x", goCube.transform.position.x); PlayerPrefs.SetFloat("y", goCube.transform.position.y); PlayerPrefs.SetFloat("z", goCube.transform.position.z); } public void OnLoad() { Debug.Log("ロードします"); var goCube = GameObject.Find("Cube"); var x = PlayerPrefs.GetFloat("x"); var y = PlayerPrefs.GetFloat("y"); var z = PlayerPrefs.GetFloat("z"); goCube.transform.position = new Vector3(x, y, z); } } </code></pre> <p>📺 <a target="_blank" rel="nofollow noopener" href="https://twitter.com/muzudho1/status/1634576987200294912?s=20">開発中画面</a></p> <p>📅 2023-03-12 sun 00:29</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 これで 思ってるように セーブとロードは でけた」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 バカでかい容量のセーブをしたいとき こんなシンプルな構造で 対応しきれるのかだぜ?<br /> クラスを シリアライズ/デシリアライズ して 投げ込めないの?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 <code>String</code> 型のセッターに JSON を投げ込めだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 そんなこと していいのかな……」</p> <h1 id="まず、セーブ・スロットを3つにしようぜ?"><a href="#%E3%81%BE%E3%81%9A%E3%80%81%E3%82%BB%E3%83%BC%E3%83%96%E3%83%BB%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88%E3%82%92%EF%BC%93%E3%81%A4%E3%81%AB%E3%81%97%E3%82%88%E3%81%86%E3%81%9C%EF%BC%9F">まず、セーブ・スロットを3つにしようぜ?</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 セーブ・ファイルって 複数個 持ちたいよな」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 自分用、弟用、クリアー・データ用よね」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://xr-hub.com/archives/12118">【Unity uGUI】ドロップダウン(Dropdown)を使用してオプションを選択する方法</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 とりあえず ドロップダウン の作り方を調べるか」</p> <p><a href="https://crieit.now.sh/upload_images/6619beb770fc600aaac4306532da6a40640d48ef7f139.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6619beb770fc600aaac4306532da6a40640d48ef7f139.png?mw=700" alt="202303_unity_12-1235--dropdown-1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 さて、何を どうすればいいのか?」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 UI は、スクリプトから 操作したいよな」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://www.ame-name.com/archives/12633">【Unity】ドロップダウンの表示テキストを変える</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 何かをやろうとしても、はて、と分からんことばっかりで つらい。調べる」</p> <p><a href="https://crieit.now.sh/upload_images/703c29c8ddd6fae41458a81f8cf5c3f5640d6d9f90a70.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/703c29c8ddd6fae41458a81f8cf5c3f5640d6d9f90a70.png?mw=700" alt="202303_unity_12-1513--saveSlot.png" /></a></p> <p>📅 2023-03-12 sun 15:14</p> <p><code>SaveDataManager.cs</code> :</p> <pre><code class="csharp">using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class SaveDataManager : MonoBehaviour { TMP_Dropdown dropdown; // Start is called before the first frame update void Start() { dropdown = GameObject.Find("Save Slot Dropdown").GetComponent<TMP_Dropdown>(); // ドロップダウンリストのラベル dropdown.options[0].text = "Save Data 1"; dropdown.options[1].text = "Save Data 2"; dropdown.options[2].text = "Save Data 3"; // コンボボックスのラベル // // - 最初に選択されている項目に合わせないと挙動がおかしくなる dropdown.captionText.text = dropdown.options[0].text; } // Update is called once per frame void Update() { } // - フィールド string[] gameObjectNamesToSave = new string[] { "Red Cube", "Green Cube", "Blue Cube", }; // - イベントハンドラ public void OnSave() { Debug.Log($"{(dropdown.value)}+1番へ、セーブしたい"); foreach (var gameObjectName in gameObjectNamesToSave) { var gameObject = GameObject.Find(gameObjectName); // ゲームオブジェクトの名前には、いろんな文字が使えるので、区切りなるような文字がない。とりあえずドット区切りにする var nameSpace = $"Slot{dropdown.value}.{gameObjectName}"; PlayerPrefs.SetFloat($"{nameSpace}.x", gameObject.transform.position.x); PlayerPrefs.SetFloat($"{nameSpace}.y", gameObject.transform.position.y); PlayerPrefs.SetFloat($"{nameSpace}.z", gameObject.transform.position.z); } } public void OnLoad() { Debug.Log($"{(dropdown.value)}+1番から、ロードしたい"); foreach (var gameObjectName in gameObjectNamesToSave) { var gameObject = GameObject.Find(gameObjectName); // ゲームオブジェクトの名前には、いろんな文字が使えるので、区切りなるような文字がない。とりあえずドット区切りにする var nameSpace = $"Slot{dropdown.value}.{gameObjectName}"; gameObject.transform.position = new Vector3( PlayerPrefs.GetFloat($"{nameSpace}.x"), PlayerPrefs.GetFloat($"{nameSpace}.y"), PlayerPrefs.GetFloat($"{nameSpace}.z")); } } } </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 よし、ドロップ・ダウン・リストの使い方を覚えたぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 やったぜ!」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 やったわね!」</p> <h1 id="📅 2023-03-15 wed 19:18"><a href="#%F0%9F%93%85+2023-03-15+wed+19%3A18">📅 2023-03-15 wed 19:18</a></h1> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 次は、XML 形式で保存できるように改造しようぜ」</p> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://nekosuko.jp/1893/">【Unity】JsonUtilityを使ったJson化</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 分からんことがいっぱいなので調べるぜ」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 よし、簡単なとこだけ つかんだので そこだけやろ」</p> <p><a href="https://crieit.now.sh/upload_images/f7576d2ceeffbae78410f7f6a56d7fc06411a7a2c30ee.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f7576d2ceeffbae78410f7f6a56d7fc06411a7a2c30ee.png?mw=700" alt="202303_unity_15-2009--tree.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 階層構造はこうなるぜ。<br /> 関係あるところを見ていこう」</p> <p><a href="https://crieit.now.sh/upload_images/3d89644f2ed4362581661d90cc031bbd6411a81bdde58.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3d89644f2ed4362581661d90cc031bbd6411a81bdde58.png?mw=700" alt="202303_unity_15-2012--gameObject.png" /></a></p> <p><code>Assets.Scripts.Models.SaveData.GameObject.cs</code>:</p> <pre><code class="csharp">namespace Assets.Scripts.Models.SaveData { using UnityEngine; /// <summary> /// UnityのGameObjectをラッピング /// </summary> [System.Serializable] public class GameObject { // -^ その他 /// <summary> /// 生成 /// </summary> /// <param name="gameObject"></param> /// <returns></returns> internal static GameObject FromGameObject(UnityEngine.GameObject gameObject) { return new GameObject { name = gameObject.name, x = gameObject.transform.position.x, y = gameObject.transform.position.y, z = gameObject.transform.position.z }; } // - フィールド public string name; public float x; public float y; public float z; // - メソッド internal Vector3 ToPosition() { return new Vector3(this.x, this.y, this.z); } } } </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 <code>GameObject</code> と同名で、保存したいところだけ作ったクラスを用意するぜ。<br /> クラス名の上の行に <code>[System.Serializable]</code> が付いているのを忘れるなだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/3a9a03cb8ea9ff6f5feadab6e7a90cfb6411a8dbcb934.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3a9a03cb8ea9ff6f5feadab6e7a90cfb6411a8dbcb934.png?mw=700" alt="202303_unity_15-2015--init.png" /></a></p> <p><code>Assets.Scripts.Models.SaveData.Init.cs</code>:</p> <pre><code class="csharp">namespace Assets.Scripts.Models.SaveData { using System.Collections.Generic; using ModelOfSaveData = Assets.Scripts.Models.SaveData; /// <summary> /// セーブ・データ /// </summary> public class Init { // - その他 internal Init() { this.gameObjects = new List<ModelOfSaveData.GameObject>(); } // - フィールド // JsonUtilクラスは、Dictionary型には対応していない public List<ModelOfSaveData.GameObject> gameObjects; // - メソッド /// <summary> /// ゲームオブジェクトの追加 /// </summary> /// <param name="item"></param> public void AddGameObject(ModelOfSaveData.GameObject item) { this.gameObjects.Add(item); } } } </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 <code>SaveData.Init</code> クラスが、セーブデータ・クラス階層構造のトップ・レベルのクラスだぜ。<br /> セーブスロット1個分のデータが全部入ってると思えだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/808bfacf3c7c040f3a39d15bd0525bf86411acdf6c81e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/808bfacf3c7c040f3a39d15bd0525bf86411acdf6c81e.png?mw=700" alt="202303_unity_15-2032--saveDataManager.png" /></a></p> <p><code>Assets.Scripts.SaveDataManager.cs</code>:</p> <pre><code class="csharp">using TMPro; using UnityEngine; using ModelOfSaveData = Assets.Scripts.Models.SaveData; public class SaveDataManager : MonoBehaviour { TMP_Dropdown dropdown; // Start is called before the first frame update void Start() { dropdown = GameObject.Find("Save Slot Dropdown").GetComponent<TMP_Dropdown>(); // ドロップダウンリストのラベル dropdown.options[0].text = "Save Data 1"; dropdown.options[1].text = "Save Data 2"; dropdown.options[2].text = "Save Data 3"; // コンボボックスのラベル // // - 最初に選択されている項目に合わせないと挙動がおかしくなる dropdown.captionText.text = dropdown.options[0].text; } // Update is called once per frame void Update() { } // - フィールド string[] gameObjectNamesToSave = new string[] { "Red Cube", "Green Cube", "Blue Cube", }; // - イベントハンドラ public void OnSave() { // セーブデータ・モデルの作成 var saveDataModel = new ModelOfSaveData.Init(); // 記憶したいゲームオブジェクトを格納 foreach (var gameObjectName in gameObjectNamesToSave) { var gameObject = GameObject.Find(gameObjectName); var gameObject2 = ModelOfSaveData.GameObject.FromGameObject(gameObject); saveDataModel.AddGameObject(gameObject2); } // JSON文字列化(シリアライズ) var jsonText = JsonUtility.ToJson(saveDataModel); // 保存 Debug.Log($"{(dropdown.value)}+1番へ、セーブしたい。 Json:{jsonText}"); PlayerPrefs.SetString($"Slot{dropdown.value}", jsonText); } public void OnLoad() { // 読取(JSONテキスト取得) var jsonText = PlayerPrefs.GetString($"Slot{dropdown.value}"); Debug.Log($"{(dropdown.value)}+1番から、ロードしたい。 Json:{jsonText}"); // セーブデータ・モデルへ復元 var saveDataModel2 = JsonUtility.FromJson<ModelOfSaveData.Init>(jsonText); if (saveDataModel2==null) { // 復元できません Debug.Log($"{(dropdown.value)}+1番 ロードできませんでした。 Json:{jsonText}"); return; } // 記憶されているゲームオブジェクトを取出し foreach (var gameObject2 in saveDataModel2.gameObjects) { var gameObject = GameObject.Find(gameObject2.name); gameObject.transform.position = gameObject2.ToPosition(); } } } </code></pre> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 セーブデータを読み書きするクラスだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 これで ゲームをセーブできるな」</p> <h2 id="WebGL"><a href="#WebGL">WebGL</a></h2> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 WebGL 形式で出力して、ブラウザで動かしても セーブ/ロード できんの?」</p> <p><a href="https://crieit.now.sh/upload_images/2fe31c2e365587ab82c25629e47267996411c119e67fb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2fe31c2e365587ab82c25629e47267996411c119e67fb.png?mw=700" alt="202303_unity_15-2158--webGL.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 よっしゃ、実験してみるかだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/6cc90dea46920ae4e274d4d3be6a5e5c6411c1c29798f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6cc90dea46920ae4e274d4d3be6a5e5c6411c1c29798f.png?mw=700" alt="202303_unity_15-2201--saveLoad.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 できたり、できなかったりするな、ちょっと 調べるか」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 気になったのは、 <strong>デバッグ・ログ</strong> そのまんま出てくるのか 整えないと カッコ悪いな」</p> <p><a href="https://crieit.now.sh/upload_images/24becbe9afe4833b908b46a09f0145656411c9bace1fb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/24becbe9afe4833b908b46a09f0145656411c9bace1fb.png?mw=700" alt="202303_unity_15-2235--test.png" /></a></p> <p>📅 2023-03-15 wed 22:38</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 よし、動いていることもあるし 完成とするかだぜ」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 わらう」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 Unity のサイトにアップロードしましょう!」</p> <h2 id="Unity Play"><a href="#Unity+Play">Unity Play</a></h2> <p>📖 <a target="_blank" rel="nofollow noopener" href="https://play.unity.com/">Unity Play</a></p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 アップロード後に ゲーム画面上の×ボタンを押して ブラウザの戻るボタンを押したら<br /> 画面が真っ白になった!」</p> <p><a href="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/beaf94b260ae2602ca8cf7f5bbc769c261daf8686dbda.png?mw=700" alt="kifuwarabe-futsu.png" /></a><br /> 「 一度 間違った操作を行うと 続けて 間違った操作を行ってしまう。<br /> わらう」</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 何もできん」</p> <p><a href="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96fb09724c3ce40ee0861a0fd1da563d61daf8a09d9bc.png?mw=700" alt="ohkina-hiyoko-futsu2.png" /></a><br /> 「 今日は終わりかしらねえ」</p> <p>📺 <a target="_blank" rel="nofollow noopener" href="https://play.unity.com/mg/other/save-data-practice">Save Data Practice</a></p> <p>📅 2023-03-15 wed 23:41</p> <p><a href="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d27ea8dcfad541918d9094b9aed83e7d61daf8532bbbe.png?mw=700" alt="ramen-tabero-futsu2.png" /></a><br /> 「 👆 1時間放置したら アクセスできるようになった。アップロードした。<br /> もう終わり!」</p> <p><おわり></p> むずでょ tag:crieit.net,2005:PublicArticle/15808 2020-04-03T19:27:48+09:00 2020-04-04T09:09:10+09:00 https://crieit.net/posts/1-AI 01.人間がAIに支配される未来が来る? <p>※こちらは「ひとりぼっちPython」連載記事です。<a href="https://crieit.net/magazines/massasquash/%E3%81%B2%E3%81%A8%E3%82%8A%E3%81%BC%E3%81%A3%E3%81%A1Python">連載一覧はコチラ</a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>今回は「人工知能」「AI」について触れてみます。</p> <p>(本記事は概念やイメージを掴むための入門向けのお話のため、Pythonのコードや技術的な内容はありませんのでご了承ください…!)<br />  <br />  <br /> 人工知能とかAI、この数年くらいで急によく聞くようになったワードかなと思います。どんどん新製品や新サービスが出てきたりニュースにも登場したりしていて、進歩が激しい分野なんだなっていうのがわかります。</p> <p>僕も普段家でAmazonでのネットショッピングやGoogleスマートスピーカーを使うことが多いのですが、これらもAIが活用されているのですよね。<br /> 知らず知らずのうちにAIの便利な機能を使っていたり、AIによってオススメ商品を買わされていたりします(クレカの請求が怖い)。</p> <p>そんな感じで身近なところでも使われていて、とにかく頻繁に人工知能やAIという言葉は聞くけれど、じゃあ</p> <p><strong>「AIってズバリ、何?」</strong></p> <p>という単純で素朴な質問に対して、明快に答えられないな…と思ったのです。</p> <p><strong>「うーん、なんか良くわからないけど、色々できてしまうスゴイやつ…?」</strong></p> <p>僕の語彙力の引き出しを全力で引っ張ってみても、そんな程度の回答で悲しくなりました…。</p> <p>皆さんはどう答えますかね?</p> <p>いろんな観点がありそうですが、自分なりの解答を得たいと思い、人工知能・AIの入り口を紐解いてみます。</p> <h2 id="AIと聞いて抱くイメージ"><a href="#AI%E3%81%A8%E8%81%9E%E3%81%84%E3%81%A6%E6%8A%B1%E3%81%8F%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8">AIと聞いて抱くイメージ</a></h2> <p>「AIって何?」っていう直接的な疑問は一旦置いておいて、まずはAIと聞いてどんなイメージを思い浮かべるでしょうか?</p> <ul> <li>便利ロボット?学習して成長していくやつ?</li> <li>人間より上位の存在? 下位の存在?</li> <li>ポジティブな印象? ネガティブな印象?</li> </ul> <p>なんとなく僕は、人類が支配されてしまいそうな怖いイメージを持っています。AIが人類を支配するというよりは、AIを活用して色々やっている上位の人達が大規模にデータを集めていて、僕たち下々の人間は知らないうちに彼らに支配されてゆく…そんなイメージです(ネガティブ思考全開)。</p> <p>身近には便利になっている気がするけど、実はそれは甘い汁を吸わされているんじゃないか…と、考えすぎると疑心暗鬼の闇に沈んでしまうので、あまり考えないようにして生活しています。<br />  <br />  <br /> <strong>「シンギュラリティ」</strong> という言葉があります。</p> <p>想像上の未来のお話で、 <strong>「AIなどの技術が、自ら人間より賢い知能を生み出すことが可能になる時点」</strong> を指す言葉のようです。<br /> 人工知能が進歩しすぎて人間の能力を超えてしまう時、と考えるとわかりやすいかもしれないです。<br /> そんな時代がいつしか来る、と言われています。</p> <p>「自分で考えて仕事ができるAIロボットに僕らの仕事が奪われるんじゃないか」</p> <p>とか、そんな言葉も聞きますよね。</p> <p>その真偽は僕ら常人に想像がつかない範囲だと思います。<br /> まだ見ぬ未来に不安を覚えるより、今存在している現実的なAIについて考えてみることで、僕らの生活を便利で豊かなものにしてくれるAIさんに寄り添ってみることにします。<br /> そうすることで、仮にそんなファンタジーな世界が訪れた時でも対策ぐらいは立てられそうですよね。</p> <h2 id="想像上のAIと現実的なAI"><a href="#%E6%83%B3%E5%83%8F%E4%B8%8A%E3%81%AEAI%E3%81%A8%E7%8F%BE%E5%AE%9F%E7%9A%84%E3%81%AAAI">想像上のAIと現実的なAI</a></h2> <p>どこかの偉い人が定義した「強いAI」と「弱いAI」という言葉があります。<br /> 「AI・人工知能」という大きなくくりの中には2種類があって、それらを分けている分類です。</p> <p>まず <strong>「強いAI」</strong> とは「汎用人工知能」とも呼ばれて、 <strong>「自意識を持った人間同様の知能を持つ存在」</strong> を指す言葉のようです。<br /> つまり、人間のように自ら考えて、行動することができるAIのこと。よくターミネーターといった例えが登場します。ドラえもんもこの分類に入るのでしょうか。<br /> こちらは今は想像上の存在で、本当にこのようなAIができるかどうかもよくわかりません。<br /> 上のシンギュラリティは、このような人間以上の知性を持った「強いAI」が登場した世界、と置き換えるとわかりやすいのかなと思います。</p> <p>一方で <strong>「弱いAI」</strong> とはもっと現実的かつ実用的なもので、 <strong>「特定の機能に特化したAI」</strong> のことを指します。<br /> 人間の機能の一部分のみにフォーカスして、その処理をすることに特化したもの、と考えて良いかなと思います。</p> <p>そんな訳で、今はまだ全知全能な「強いAI」が存在しない(できるかもわからない)現状、僕らが普段関係しているのはこの「弱いAI」に分類されているもの、と考えて良さそうですね。</p> <p>(強い・弱いという区別も素人目からしたら何か違和感があるなと思ってしまうのですが、この辺りは色々議論されている部分でもあるようですね)</p> <h2 id="どんなAIが今は実用化されているだろうか"><a href="#%E3%81%A9%E3%82%93%E3%81%AAAI%E3%81%8C%E4%BB%8A%E3%81%AF%E5%AE%9F%E7%94%A8%E5%8C%96%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A0%E3%82%8D%E3%81%86%E3%81%8B">どんなAIが今は実用化されているだろうか</a></h2> <p>そんなこんなで漠然としたイメージだけ抱いてネガティブ思考に堕ちていても仕方がないので、もうちょっと地に足をつけて考えてみます。<br /> まずは具体的に、実用化されているAIとして思いつくものを挙げてみました。</p> <ul> <li>将棋や囲碁のプロ棋士に勝てる人工知能</li> <li>ペッパー君に代表されるAIロボット</li> <li>AIによって無人でチャット対応ができる、企業のカスタマーサポート</li> <li>スマートスピーカーに使われている音声アシストなど。声を認識してインターネットを介して調べ物やお店の予約、買い物など秘書的な活躍をしてくれる</li> <li>Web広告やネットショッピングでオススメ商品を提供してくれる</li> </ul> <p>他にもたくさんあると思うんですが、何か思い着くのはありますかね?<br />  <br />  <br /> 自動運転技術なんかも今は研究が進んでいますよね。<br /> 聞くところによると、海外のUber社は今はタクシーのシェアリングサービスですが、それによって人間様の行動のデータを集めて自動運転のための情報を集めている…だとか(正確な情報かは知りません)。</p> <p>余談ですが、Uberは僕もアメリカに行った時に乗ってみました。すごく便利ですねあれ。<br /> クレジットカードを登録しておくことで現金での支払いは不要。タクシーに乗りたい時にスマホアプリで予約すると、ほんの数分でお迎えが来てアプリに通知が入ります。<br /> 僕が経験したのは、本当は自分が乗るはずじゃないタクシーに載っちゃって途中で間違いに気づいた運転手さんにその場で放り出されたり、<br /> 町を案内してくれた友人がUber運転手をやっていて突然「ちょっと1時間稼いでくる」と出て行って数時間戻ってこなかったり、<br /> おそらくUber社は、そんな人間らしさをデータとして集めて心温まるAIを作ろうとしているのでしょう…。</p> <p>余談でした。</p> <h2 id="AIは何でも出来る訳じゃない?"><a href="#AI%E3%81%AF%E4%BD%95%E3%81%A7%E3%82%82%E5%87%BA%E6%9D%A5%E3%82%8B%E8%A8%B3%E3%81%98%E3%82%83%E3%81%AA%E3%81%84%EF%BC%9F">AIは何でも出来る訳じゃない?</a></h2> <p>先ほど挙げたものはどれも、その特定の分野では優れているのですが、実は万能なものではありません。<br /> 例えば将棋や囲碁が強い人工知能は人生ゲームやモノポリーでは勝てないし、例えば洋服屋のカスタマーサポートのチャットボットが急に自動車業界に部署異動させられてしまったら、お客さんがマフラーの交換の見積もりを尋ねた時になんか上司に怒られる事態が発生してしまいそうです。</p> <p>このように、 <strong>現実的なAIとは 「何か特定の機能・分野に特化したもの」</strong> であり、 <strong>AIにも「出来ること」と「出来ないこと」がある</strong> 訳です。</p> <p>人間で考えても、誰しも得意不得意ってありますよね。<br /> それがAIだと極端になっていて、得意なものはとことん得意だけど、自分の習熟していない分野になるとからっきしダメになってしまうのです。</p> <p>AIではその得意不得意が特にデータに依存してきます。<br /> 基本的に積み重ねられた文字や画像などのデータを学習することで識別したり分析したりしていて、それも学習のためには大量のデータが必要になってくるのです。<br /> 特定の分野に強いAIは、その分野について大量のデータをもとに学習しているのです(詳細は省きますが「強化学習」とか必ずしもそうじゃないようですが)。</p> <p>Amazonや楽天市場は大量のお客さんがいて大量の購入履歴があるため、「◯◯代の✖︎✖︎県在住の男性。こういう商品をよく買っているので、こんなのをお勧めしたら買ってくれるかも」とピンポイントで商品を勧める(レコメンドする)ことができるのですが、</p> <p>それを一個人が販売システムから作ったとしても、お客さんが少ないので学習するデータが少なく、その人が買わなさそうなトンチンカンな商品を勧めてしまったりするのです。</p> <p>…それはそれで作ってみたい。<br /> (絶対その人が興味なさそうな本とか音楽、動画を勧めてくるサービスが1つくらいあってもいい)</p> <p>一例としてデータの必要性を挙げましたが、まだまだ今のAIの制約はたくさんありそうです。<br /> この辺り、もうちょっと具体的に紐解いてみたいのですが今回はこの辺までとして、次回は「AIに出来ること・出来ないこと」あたりにフォーカスしてまとめてみたいなって思います。</p> <p>今回はおしまい。</p> <h2 id="今回のまとめ"><a href="#%E4%BB%8A%E5%9B%9E%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81">今回のまとめ</a></h2> <p>「AIって何?」という疑問に対しての明確な答えにまでは辿り着くことができませんでしたが、<br /> ひとまずのところ「万能でなんでもできるもの」ではなくて「人間の機能の一部分を代替してくれるもの」と考えることができそうですね。</p> <h3 id="用語"><a href="#%E7%94%A8%E8%AA%9E">用語</a></h3> <ul> <li>人工知能(AI)</li> <li>シンギュラリティ</li> <li>「強いAI」と「弱いAI」</li> </ul> <h3 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/4797370262">絵でわかる人工知能 明日使いたくなるキーワード68 (サイエンス・アイ新書) | 三宅 陽一郎, 森川 幸人, 森川 幸人 |本 | 通販 | Amazon</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/4797391693">人工知能解体新書 ゼロからわかる人工知能のしくみと活用 (サイエンス・アイ新書) | 神崎 洋治 |本 | 通販 | Amazon</a></p> Massa tag:crieit.net,2005:PublicArticle/15780 2020-03-27T21:45:06+09:00 2020-04-02T03:05:14+09:00 https://crieit.net/posts/Python-5e7df55255160 序章「ひとりぼっちPython」 <h2 id="雑記"><a href="#%E9%9B%91%E8%A8%98">雑記</a></h2> <p>巷で話題のPython。<br /> 言語別エンジニアの年収グラフでは1位を獲得しており(どっかで見た気がする)、近年話題の飛び交う「機械学習」「AI」「ブロックチェーン」にもよく活用されている言語ということで、とても人気なのが伺えます。<br /> 寝る前のお供に時々「日経ソフトウェア」という雑誌を購入しているのですが、ここ最近の表紙を見るとほとんどPythonという文字で埋め尽くされています。</p> <p>ただ、その人気の裏側というか、実際にどうなのかというのがわからないのが正直なところです。安易に個人で初心者が手を出して痛い目を見るんじゃないのかなあとか。正直ちょっとPythonって敷居が高い印象があります(言語的には比較的取り組みやすそう?)。</p> <p>で、まあ好奇心に負けて(?)Pythonに少し取り組んでみた訳です。いろんな言語に取り組むのはベストプラクティスでないと怒られそうですが、都合の悪いことは聞かないこととします!!!!!</p> <p>実際に「機械学習」の基礎の基礎みたいな部分をUdemyで学習してみました。回帰分析を学んでみたのですが、やっぱり面白いのですね。<br /> もともと数学的な分野は好きな部類なので、もうちょっと勉強してみたいなって思いました。</p> <p>そんなこんなで <strong>「ノンプログラマ」で本業の傍ら趣味と実益を兼ねて学習をしながら 「ひとり開発」 に取り組んでいる人間</strong> が、<strong>Pythonについて取り組んでみたことや興味のあるトピックについて</strong> 知識を広げてみたいと思っているのがこの連載です。</p> <h2 id="この連載で取り上げたいこと"><a href="#%E3%81%93%E3%81%AE%E9%80%A3%E8%BC%89%E3%81%A7%E5%8F%96%E3%82%8A%E4%B8%8A%E3%81%92%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8">この連載で取り上げたいこと</a></h2> <p>(1)Pythonでどんなツールが作れるの?どんな身近な課題が解決できるの?<br /> (2)Pythonといえばよく聞く、機械学習・AI・IoT・ブロックチェーンなどの現代の気になるワードについて<br /> (3)個人レベルでどうこれらに取り組める?</p> <p>これらについて調べたこと、考えたこと、実際に取り組んでみたことを取り上げてトピックにしてみたいなーって。</p> <h2 id="この連載の目標"><a href="#%E3%81%93%E3%81%AE%E9%80%A3%E8%BC%89%E3%81%AE%E7%9B%AE%E6%A8%99">この連載の目標</a></h2> <p>pythonに限らずプログラミング自体そうなんですが</p> <p>「なんとなくできるとカッコいい!」<br /> 「とにかくPCに触れているのが好き!」</p> <p>というだけで学習を続けるのも限界があります。</p> <p>20代で若ければそれで技術をつけて就職!転職!というストーリーは全然ありで良いのかもしれないのですが、30代に入ってある程度人生が固まってきている自分自身の現状、漫然とやっても限界があるしなあ。と、そんな思いがどうしても出てきてしまいます。</p> <p>好きでやる、だけじゃ続けられない。<br /> やるからには何か意義のあることをしたいな、って思う訳です。</p> <p>そうなると大事なのは「出口」かなって思っています。<br /> 「Pythonに取り組むことで何ができるんだろう?」<br /> 「どんな身近な課題が解決できるようになるのだろう?」</p> <p>そういうのを模索する過程で、世の中のニュースやよく知らない技術についてもっと理解しつつ、実際に意義のあるものを作れるようになろう、と取り組んでみるのがこの連載の目標です。</p> <p>読んでくれた方と一緒に勉強していくような、そんな感じを目指しています。</p> <p>…と、何かちゃんとしたことを言ってしまったのですが<br /> 企画倒れになる気がするのでまあ気ままにやりましょう…。</p> Massa tag:crieit.net,2005:PublicArticle/15175 2019-06-29T22:19:48+09:00 2019-07-01T21:40:30+09:00 https://crieit.net/posts/3bd18b4f821a3db5a62911485d650080 のんびりアルジェブラをやろうぜ☆(^~^)<その4> <p><前回の続き></p> <h2 id="またまたまた次の日"><a href="#%E3%81%BE%E3%81%9F%E3%81%BE%E3%81%9F%E3%81%BE%E3%81%9F%E6%AC%A1%E3%81%AE%E6%97%A5">またまたまた次の日</a></h2> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 ほんとは 10240進数 があると 見やすいと思うんだが、<br /> そんな進数変換プログラムを書こうと思うと 数年間 休みが欲しいぐらいなんで 省く☆」</p> <pre><code>2^10 * 10 = 10240 </code></pre> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 どんどん省いていこう☆」</p> <p><a href="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif?mw=700" alt="OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif" /></a><br /> 「 話が脱線しているけど、家屋を退き倒したところが 道よね」</p> <p><a href="https://crieit.now.sh/upload_images/ee2899fccd8a21d57e027a5dcf093a915d1766eaf0af7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ee2899fccd8a21d57e027a5dcf093a915d1766eaf0af7.png?mw=700" alt="20190629math114a1b1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 きふわらべの質問は、九九の対角線の1桁目は なぜ ラウンド・トリップ(往復)<br /> しているのか? だった☆」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 それだけじゃないけどな☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 わたしの回答は カンタンなものだが、説明がいる☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 nの2乗 1、4、9、16、……というやつは どんどん大きくなっていき、<br /> それが10個のなんとか倍 続いたときに 10進数というのは<br /> 10のn乗というやつで 10、100、1000、……と 速く大きくなっていって、<br /> 増え方の速さの噛み合わせが ラウンド・トリップするグループに あるからだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 お父んの しゃべりが下手くそで さっぱり分からん☆」</p> <p><a href="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif?mw=700" alt="OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif" /></a><br /> 「 緑のたぬき でか盛り できたわよ!」</p> <p><a href="https://crieit.now.sh/upload_images/e22f6f1c539456b4a1294ff6a12943545d19fc2a405f0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e22f6f1c539456b4a1294ff6a12943545d19fc2a405f0.png?mw=700" alt="20190701math1a1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 例えば 白玉と 赤玉 が交互に並んでるとするだろ☆」</p> <p><a href="https://crieit.now.sh/upload_images/34837c642050d176d602c16dd5f0728d5d19fc52b827a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/34837c642050d176d602c16dd5f0728d5d19fc52b827a.png?mw=700" alt="20190701math1a2.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 2個ずつ おまとめ すれば……☆」</p> <p><a href="https://crieit.now.sh/upload_images/6fa780ccd610bedf36b5396dfdeca51b5d19fc6ac49f6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6fa780ccd610bedf36b5396dfdeca51b5d19fc6ac49f6.png?mw=700" alt="20190701math1a2b1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 紅白饅頭が5箱できる☆」</p> <p><a href="https://crieit.now.sh/upload_images/dc461e3699fba9e0c39b37a2e8b5250f5d19fc86f3cf4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/dc461e3699fba9e0c39b37a2e8b5250f5d19fc86f3cf4.png?mw=700" alt="20190701math1a3.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 3個ずつ おまとめ すれば……☆」</p> <p><a href="https://crieit.now.sh/upload_images/bd2930351e7a7ba6a1497b7df7d565895d19fc9ba56fe.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bd2930351e7a7ba6a1497b7df7d565895d19fc9ba56fe.png?mw=700" alt="20190701math1a3b1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 セットが 2パターンになるな☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 このような 数の 模様 のようなものを見ているだけで、数に違いはない☆<br /> しかし こんな ざっくりした説明で 満足できるわたしたちでは ないだろう☆」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 満足した☆ もう寝ろ☆」</p> <p><a href="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif?mw=700" alt="OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif" /></a><br /> 「 お湯を入れた 緑のたぬき でか盛り の麺が伸びてるんだけど!<br /> 食べないの?」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> (ずるるる……☆)</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 伸びてるのに……☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 少しずつ 数の仕組みを見ていこうぜ☆<br /> 記事が <その4> になったせいで、気にくわないが 再掲する☆」</p> <pre><code> 10進数 80進数 80進数10進表記 x^2 xa ax a^2 ------ ------ ------------ --------------------- 0^2 = 0 0 [ ][ ][ 0] [ ][ ][ ][ 0] 1^2 = 1 1 [ ][ ][ 1] [ ][ ][ ][ 1] 2^2 = 4 4 [ ][ ][ 4] [ ][ ][ ][ 4] 3^2 = 9 9 [ ][ ][ 9] [ ][ ][ ][ 9] 4^2 = 16 g [ ][ ][16] [ ][ ][ ][ 16] 5^2 = 25 p [ ][ ][25] [ ][ ][ ][ 25] 6^2 = 36 A [ ][ ][36] [ ][ ][ ][ 36] 7^2 = 49 N [ ][ ][49] [ ][ ][ ][ 49] 8^2 = 64 # [ ][ ][64] [ ][ ][ ][ 64] 9^2 = 81 11 [ ][ 1][ 1] [ ][ ][ ][ 81] 10^2 = 100 1k [ ][ 1][20] [ 100][ ][ ][ 0] 11^2 = 121 1F [ ][ 1][41] [ 100][ 10][ 10][ 1] 12^2 = 144 1# [ ][ 1][64] [ 100][ 20][ 20][ 4] 13^2 = 169 29 [ ][ 2][ 9] [ 100][ 30][ 30][ 9] 14^2 = 196 2A [ ][ 2][36] [ 100][ 40][ 40][ 16] 15^2 = 225 2$ [ ][ 2][65] [ 100][ 50][ 50][ 25] 16^2 = 256 3g [ ][ 3][16] [ 100][ 60][ 60][ 36] 17^2 = 289 3N [ ][ 3][49] [ 100][ 70][ 70][ 49] 18^2 = 324 44 [ ][ 4][ 4] [ 100][ 80][ 80][ 64] 19^2 = 361 4F [ ][ 4][41] [ 100][ 90][ 90][ 81] 20^2 = 400 50 [ ][ 5][ 0] [ 400][ ][ ][ 0] 21^2 = 441 5F [ ][ 5][41] [ 400][ 20][ 20][ 1] 22^2 = 484 64 [ ][ 6][ 4] [ 400][ 40][ 40][ 4] 23^2 = 529 6N [ ][ 6][49] [ 400][ 60][ 60][ 9] 24^2 = 576 7g [ ][ 7][16] [ 400][ 80][ 80][ 16] 25^2 = 625 7$ [ ][ 7][65] [ 400][100][100][ 25] 26^2 = 676 8A [ ][ 8][36] [ 400][120][120][ 36] 27^2 = 729 99 [ ][ 9][ 9] [ 400][140][140][ 49] 28^2 = 784 9# [ ][ 9][64] [ 400][160][160][ 64] 29^2 = 841 aF [ ][10][41] [ 400][180][180][ 81] 30^2 = 900 bk [ ][11][20] [ 900][ ][ ][ 0] 31^2 = 961 c1 [ ][12][ 1] [ 900][ 30][ 30][ 1] 32^2 = 1024 c# [ ][12][64] [ 900][ 60][ 60][ 4] 33^2 = 1089 dN [ ][13][49] [ 900][ 90][ 90][ 9] 34^2 = 1156 eA [ ][14][36] [ 900][120][120][ 16] 35^2 = 1225 fp [ ][15][25] [ 900][150][150][ 25] 36^2 = 1296 gg [ ][16][16] [ 900][180][180][ 36] 37^2 = 1369 h9 [ ][17][ 9] [ 900][210][210][ 49] 38^2 = 1444 i4 [ ][18][ 4] [ 900][240][240][ 64] 39^2 = 1521 j1 [ ][19][ 1] [ 900][270][270][ 81] 40^2 = 1600 k0 [ ][20][ 0] [1600][ ][ ][ 0] </code></pre> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> (ずるる……☆)</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 わたしが 緑のたぬき を食べ終わるまで 上の表でも 眺めておいてくれだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> (ずるる……☆)</p> <p><a href="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif?mw=700" alt="OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif" /></a><br /> 「 80進数って 何なのよ!」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 10進数の ノッテイションを変えただけだぜ☆<br /> 左の箱は要らなかったか☆ 真ん中の箱に80を、右の箱に1を掛けて足せだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 nの2乗を 何進数 で書いても 1桁目がラウンド・トリップして見えるが、<br /> 数自体は ただ増えてるだけ というのが 感じられたかだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 これは 波の見え方 のようなものだと感じられてきただろうか☆」</p> <p><a href="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/058791c2dd4c1604ce1bd9ec26d490ae5d17653182de5.gif?mw=700" alt="OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif" /></a><br /> 「 もう寝なさい!」</p> <h2 id="まーたまたまーたまた次の日"><a href="#%E3%81%BE%E3%83%BC%E3%81%9F%E3%81%BE%E3%81%9F%E3%81%BE%E3%83%BC%E3%81%9F%E3%81%BE%E3%81%9F%E6%AC%A1%E3%81%AE%E6%97%A5">まーたまたまーたまた次の日</a></h2> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 波を説明するために道具がいるだろ☆ 道具を説明する☆ のんびり行こう☆」</p> <p><a href="https://crieit.now.sh/upload_images/a658ee481b213086c19b197ce248d7875d17f08db7ec4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a658ee481b213086c19b197ce248d7875d17f08db7ec4.png?mw=700" alt="20190630math115a1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 これデカルト座標☆<br /> ルネ・デカルトが デカルト座標を使っているところを知らないが その業績の大きさから<br /> みんなのよく使う直交座標に デカルトの名前を残している☆」</p> <p><a href="https://crieit.now.sh/upload_images/24b6e24628ddb35331ed1497394b0ce85d17f3191200e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/24b6e24628ddb35331ed1497394b0ce85d17f3191200e.png?mw=700" alt="20190630math115a2.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 何が デカルト っぽいかと言うと、<br /> xアクシズと yアクシズが 直角に交わっていることを デカルトっぽいと言っている☆」</p> <p><a href="https://crieit.now.sh/upload_images/ce86ed9721df20ea5ad1725d0c6a56cc5d17fb68a609b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ce86ed9721df20ea5ad1725d0c6a56cc5d17fb68a609b.png?mw=700" alt="20190630math116a1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 次に ポラー☆ 極座標だぜ☆<br /> xアクシズの代わりに アングル だな☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 デカルト座標に比べて4倍ぐらいでかくなるので<br /> ブログで描くには でかすぎる かわいいやつだぜ☆(*^~^*)」</p> <p><a href="https://crieit.now.sh/upload_images/39162723a44f892c3359a75e7b446c695d17fd60a2205.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/39162723a44f892c3359a75e7b446c695d17fd60a2205.png?mw=700" alt="20190630math115a3.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 ポラーは 横が ひとかたまり しかなくて 隣がないことと、<br /> タテが0のとき アングルがなくなってしまうことに 注意してくれだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/96dbb1aac3fd45947c4a7df9715d871c5d18001f5c21c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/96dbb1aac3fd45947c4a7df9715d871c5d18001f5c21c.png?mw=700" alt="20190630math117a2.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 じゃあ まず x=1,y=1 のところに 赤い箱を置くぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 あんまり でかい画像を 連続して貼り付けると 追い出されるぜ☆?」</p> <p><a href="https://crieit.now.sh/upload_images/d5b3ee5e57f2e8b4c008f6238d39f8ea5d18019487af2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d5b3ee5e57f2e8b4c008f6238d39f8ea5d18019487af2.png?mw=700" alt="20190630math117a2b1.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 1分経つごとに 隣に 赤い箱がコピーされると思ってくれだぜ☆<br /> 10分経つと デカルト座標では 水平な直線、<br /> ポラーでは 円になるな☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 物理は さっぱり知らないが、これを 等速直線運動、<br /> タテ幅は 速度で 1、<br /> コピーしたとき箱はタテに増減してないので 加速度は 0、<br /> 箱を全部足して 10 になったこれを 移動した距離 だと思ってくれだぜ☆」</p> <h2 id="またまーたまた次の日"><a href="#%E3%81%BE%E3%81%9F%E3%81%BE%E3%83%BC%E3%81%9F%E3%81%BE%E3%81%9F%E6%AC%A1%E3%81%AE%E6%97%A5">またまーたまた次の日</a></h2> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 計算サイトを使って 資料を作っていたんだが、数が まるまっている ことに気づいて おじゃんになった……☆」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 それを資料ではなく、ゴミという☆ 捨てろだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 累乗を計算できるプログラムを自作するかだぜ☆?」</p> <p><a href="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5ac9fa3b390b658160717a7c1ef5008a5d1765137b853.gif?mw=700" alt="KIFUWARABE_80x100x8_01_Futu.gif" /></a><br /> 「 自作せず、Python 3 を使えだぜ☆」</p> <p><a href="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3da2d4690cf2c3f101c5cbc0e48729f55d1764bd74445.gif?mw=700" alt="KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif" /></a><br /> 「 …………☆」</p> <p><書きかけ></p> むずでょ tag:crieit.net,2005:PublicArticle/15168 2019-06-26T09:51:09+09:00 2019-06-26T09:51:09+09:00 https://crieit.net/posts/WPF-PostgreSQL-5d12c17d61f60 【WPF】PostgreSQL に接続してデータを操作(登録、更新、削除)してみる <p>おはようございます。</p> <p>前回に引き続き PostgreSQL を使って、登録、更新、削除をしてみたいと思います。</p> <p>前回の記事はこちら。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/08/08/post-1948/" target="_blank" rel="noopener noreferrer" data-blogcard="1">【WPF】PostgreSQL に接続してデータを取得して表示する</a></p> <h2 id="プログラムの修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BF%AE%E6%AD%A3">プログラムの修正</a></h2> <h3 id="追加処理の修正"><a href="#%E8%BF%BD%E5%8A%A0%E5%87%A6%E7%90%86%E3%81%AE%E4%BF%AE%E6%AD%A3">追加処理の修正</a></h3> <p>MainWindow.xaml.cs</p> <pre><code> /// <summary> /// 追加ボタンクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void add_button_Click(object sender, RoutedEventArgs e) { logger.Info("追加ボタンクリック"); // データを追加する // PgDbContext に変更 //using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) using (var context = new PgDbContext()) { // データ作成 // テーブルはコンテキスト経由でアクセスする //var table = context.GetTable<Cat>(); Cat cat = new Cat(); cat.No = 5; cat.No = 5; cat.Name = "こなつ"; cat.Sex = "♀"; cat.Age = 7; cat.Kind = "01"; cat.Favorite = "布団"; // データ追加 // コンテキスト経由でエンティティを追加 //table.InsertOnSubmit(cat); context.Cats.Add(cat); // DBの変更を確定 // メソッド変更 //context.SubmitChanges(); context.SaveChanges(); } // データ再検索 searchData(); MessageBox.Show("データを追加しました。"); } </code></pre> <h3 id="更新処理"><a href="#%E6%9B%B4%E6%96%B0%E5%87%A6%E7%90%86">更新処理</a></h3> <p>MainWindow.xaml.cs</p> <pre><code> /// <summary> /// 更新ボタンクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void upd_button_Click(object sender, RoutedEventArgs e) { logger.Info("更新ボタンクリック"); // 選択チェック if (this.dataGrid.SelectedItem == null) { MessageBox.Show("更新対象を選択してください。"); return; } // データを更新する // PgDbContext に変更 //using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) using (var context = new PgDbContext()) { // 対象のテーブルオブジェクトを取得 // テーブルはコンテキスト経由でアクセスする //var table = context.GetTable<Cat>(); var table = context.Cats; // 選択されているデータを取得 Cat cat = this.dataGrid.SelectedItem as Cat; // テーブルから対象のデータを取得 var target = table.Single(x => x.No == cat.No); // データ変更 target.Favorite = "高いところ"; // DBの変更を確定 // メソッド変更 //context.SubmitChanges(); context.SaveChanges(); } // データ再検索 searchData(); MessageBox.Show("データを更新しました。"); } </code></pre> <p> </p> <h3 id="削除処理"><a href="#%E5%89%8A%E9%99%A4%E5%87%A6%E7%90%86">削除処理</a></h3> <p>MainWindow.xaml.cs</p> <pre><code> /// <summary> /// 削除ボタンクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void del_button_Click(object sender, RoutedEventArgs e) { logger.Info("追加ボタンクリック"); // 選択チェック if (this.dataGrid.SelectedItem == null) { MessageBox.Show("削除対象を選択してください。"); return; } // データを削除する // PgDbContext に変更 //using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) using (var context = new PgDbContext()) { // 対象のテーブルオブジェクトを取得 // テーブルはコンテキスト経由でアクセスする //var table = context.GetTable<Cat>(); var table = context.Cats; // 選択されているデータを取得 Cat cat = this.dataGrid.SelectedItem as Cat; // テーブルから対象のデータを取得 var target = table.Single(x => x.No == cat.No); // データ削除 // メソッド変更 //table.DeleteOnSubmit(target); table.Remove(target); // DBの変更を確定 context.SaveChanges(); } // データ再検索 searchData(); MessageBox.Show("データを削除しました。"); } </code></pre> <p> </p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>サクッとした記事になりましたが、ひとまず PostgreSQL はここまでとして次回は Oracle を試してみたいと思います。</p> <p>ソースはこちら</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/doraxdora/SampleWpfPostgreSQL1" target="_blank" rel="noopener noreferrer">GitHub</a></p> <p>ではでは。</p> doraxdora tag:crieit.net,2005:PublicArticle/15166 2019-06-25T10:05:02+09:00 2019-06-25T10:05:02+09:00 https://crieit.net/posts/WPF-PostgreSQL 【WPF】PostgreSQL に接続してデータを取得して表示する <p>おはようございます。</p> <p>今回は、PostgreSQLを使ってデータを検索、データグリッドに表示してみます。<br /> お決まりですが、プログラムは前回までのものを流用します。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/07/28/post-1873/" target="_blank" rel="noopener" data-blogcard="1">【WPF】ProgressRingを使って時間のかかる処理を分かりやすくする</a></p> <p>また、PostgreSQLをインストールしていない場合は次の記事を参照して、パソコンにインストールしてください。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/07/25/post-1748/" target="_blank" rel="noopener" data-blogcard="1">PostgreSQL 9.6.3 をインストールしてテーブルを作成する</a></p> <h2 id="Nuget でパッケージをダウンロード"><a href="#Nuget+%E3%81%A7%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89">Nuget でパッケージをダウンロード</a></h2> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/08/WpfPostgreSQL000.jpg" alt="NuGetパッケージ管理を開く" /></p> <p>ソリューションエクスプローラーからプロジェクトを選択、右クリックし<br /> 「Nuget パッケージの管理」を選択</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/08/WpfPostgreSQL001.jpg" alt="NuGetパッケージ管理" /></p> <p>Nuget パッケージ管理画面が表示されるので、<br /> 検索窓に「Npgsql 6」を入力し、「EntityFramework6.Npgsql」を選択、<br /> インストールボタンをクリックします。</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/08/WpfPostgreSQL002.jpg" alt="プレビュー画面" /></p> <p>プレビュー画面が表示される場合は「OK」ボタンをクリックします。</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/08/WpfPostgreSQL003.jpg" alt="出力ビュー" /></p> <p>出力ビューに「終了」が表示されれば完了です。</p> <h2 id="スキーマの作成"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%81%AE%E4%BD%9C%E6%88%90">スキーマの作成</a></h2> <p>PostgreSQL ではスキーマ単位の管理をしておかないと困ることになります。</p> <p>スキーマ指定しないでテーブル作成すると「public」スキーマに作成されるのですが、<br /> C#からの接続時には必ず(やってみた限りでは)スキーマ指定しないといけないので、まずはスキーマを作成しておきます。</p> <pre><code>CREATE SCHEMA dora; </code></pre> <h2 id="テーブルの作成"><a href="#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90">テーブルの作成</a></h2> <p>作成したスキーマににテーブルを作成<br /> SQLite の時と同じテーブル、データを用意します。</p> <p>このとき、テーブル名やカラム名は小文字にしておくこと。</p> <pre><code>CREATE TABLE IF NOT EXISTS dora.mstkind ( kind_cd CHAR(2) NOT NULL , kind_name VARCHAR(20) , primary key (kind_cd) ); CREATE TABLE IF NOT EXISTS dora.tblcat ( no INTEGER NOT NULL , name VARCHAR(20) NOT NULL , sex CHAR(3) NOT NULL , age INTEGER DEFAULT 0 NOT NULL , kind_cd CHAR(2) DEFAULT '00' NOT NULL , favorite VARCHAR(40) , PRIMARY KEY (no) ); INSERT INTO DORA.MSTKIND VALUES ('01', 'キジトラ'); INSERT INTO DORA.MSTKIND VALUES ('02', '長毛種(不明)'); INSERT INTO DORA.MSTKIND VALUES ('03', 'ミケ(っぽい)'); INSERT INTO DORA.MSTKIND VALUES ('04', 'サビ'); INSERT INTO DORA.MSTKIND VALUES ('09', 'その他'); INSERT INTO DORA.TBLCAT VALUES('1','そら','&#x2642;','6','01','犬の人形'); INSERT INTO DORA.TBLCAT VALUES('2','りく','&#x2642;','5','02','人間'); INSERT INTO DORA.TBLCAT VALUES('3','うみ','&#x2640;','4','03','高級ウェットフード'); INSERT INTO DORA.TBLCAT VALUES('4','こうめ','&#x2640;','2','04','横取りフード'); </code></pre> <h2 id="設定ファイルの修正"><a href="#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BF%AE%E6%AD%A3">設定ファイルの修正</a></h2> <p>次のようにします。<br /> 重要な部分は、「entityFramework」タグと「system.data」タグ。</p> <p>App.config</p> <pre><code><?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v13.0" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" /> </providers> </entityFramework> <system.data> <DbProviderFactories> <remove invariant="Npgsql" /> <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" /> </DbProviderFactories> </system.data> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Npgsql" publicKeyToken="5d8b90d52f46fda7" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-3.2.5.0" newVersion="3.2.5.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> </code></pre> <h2 id="プログラム修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E4%BF%AE%E6%AD%A3">プログラム修正</a></h2> <h3 id="新規クラスの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E8%BF%BD%E5%8A%A0">新規クラスの追加</a></h3> <p>DbContextを継承したクラスを作成します。<br /> このクラスでデータベースへの接続、Entityへのマッピングなどを行います。<br /> デフォルトのスキーマを変更する場合、「OnModelCreating」メソッドにて設定可能です。</p> <p>PgDbContext.cs</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.Entity; using Npgsql; namespace WpfApp1 { class PgDbContext : DbContext { private const string ConnectionString = "Server=localhost;User ID=USER01;Password=USER01;Database=DB01;port=5432"; // コンストラクタにて接続文字列を設定 public PgDbContext() : base(new NpgsqlConnection(ConnectionString), true) { } public DbSet<Kind> Kinds { get; set; } public DbSet<Cat> Cats { get; set; } // スキーマを変更する場合にはここに設定 protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("dora"); } } } </code></pre> <h3 id="Entityクラスの修正"><a href="#Entity%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E4%BF%AE%E6%AD%A3">Entityクラスの修正</a></h3> <p>アノテーションが今までのとちょっと違うので修正します。</p> <p>Kind.cs</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace WpfApp1 { [Table("mstkind")] class Kind { [Key] [Column("kind_cd")] public String KindCd { get; set; } [Column("kind_name")] public String KindName { get; set; } } } </code></pre> <p>Cat.cs</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace WpfApp1 { [Table("tblcat")] class Cat { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] [Column("no")] public int No { get; set; } [Column("name")] public String Name { get; set; } [Column("sex")] public String Sex { get; set; } [Column("age")] public int Age { get; set; } [Column("kind_cd")] public String Kind { get; set; } [Column("favorite")] public String Favorite { get; set; } } } </code></pre> <h3 id="宣言の追加"><a href="#%E5%AE%A3%E8%A8%80%E3%81%AE%E8%BF%BD%E5%8A%A0">宣言の追加</a></h3> <p>MainWindow.xaml.cs</p> <pre><code>using Npgsql; using System.ComponentModel; </code></pre> <h3 id="接続処理の変更"><a href="#%E6%8E%A5%E7%B6%9A%E5%87%A6%E7%90%86%E3%81%AE%E5%A4%89%E6%9B%B4">接続処理の変更</a></h3> <p>テーブル作成以外、全ての箇所を変更します。</p> <p>MainWindow.xaml.cs</p> <pre><code>//using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) using (var context = new PgDbContext()) </code></pre> <p>テーブル作成は今まで通りコマンドで行います。<br /> (また別途、DbContext でのやり方は紹介します)</p> <h3 id="テーブル作成クエリの変更"><a href="#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E4%BD%9C%E6%88%90%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E5%A4%89%E6%9B%B4">テーブル作成クエリの変更</a></h3> <p>SQLite とは微妙に違うところ(型、長さ)を変更。</p> <p>MainWindow.xaml.cs</p> <pre><code>// テーブルが存在しなければ作成する // 種別マスタ StringBuilder sb = new StringBuilder(); sb.Append("CREATE TABLE IF NOT EXISTS mstkind ("); sb.Append(" kind_cd CHAR(2) NOT NULL"); sb.Append(" , kind_name VARCHAR(20)"); sb.Append(" , PRIMARY KEY (kind_cd)"); sb.Append(")"); command.CommandText = sb.ToString(); command.ExecuteNonQuery(); // 猫テーブル sb.Clear(); sb.Append("CREATE TABLE IF NOT EXISTS tblcat ("); sb.Append(" no INTEGER NOT NULL"); sb.Append(" , name VARCHAR(20) NOT NULL"); sb.Append(" , sex CHAR(3) NOT NULL"); sb.Append(" , age INTEGER DEFAULT 0 NOT NULL"); sb.Append(" , kind_cd CHAR(2) DEFAULT '00' NOT NULL"); sb.Append(" , favorite VARCHAR(40)"); sb.Append(" , PRIMARY KEY (no)"); sb.Append(")"); command.CommandText = sb.ToString(); command.ExecuteNonQuery(); </code></pre> <h3 id="検索処理の修正"><a href="#%E6%A4%9C%E7%B4%A2%E5%87%A6%E7%90%86%E3%81%AE%E4%BF%AE%E6%AD%A3">検索処理の修正</a></h3> <p>MainWindow.xaml.cs</p> <pre><code> /// <summary> /// 検索処理(非同期) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SearchProcess(object sender, DoWorkEventArgs e) { // 猫データマスタを取得してコンボボックスに設定する //using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) // PgDbContext に変更 using (var context = new PgDbContext()) { String searchName = this.search_name.Text; String searchKind = (this.search_kind.SelectedValue as Kind).KindCd; // データを取得 // context から DbSet を取得 //Table<Cat> tblCat = con.GetTable<Cat>(); var tblCat = context.Cats; // サンプルなので適当に組み立てる IQueryable<Cat> result; if (searchKind == "") { // 名前は前方一致のため常に条件していしても問題なし result = from x in tblCat where x.Name.StartsWith(searchName) orderby x.No select x; } else { result = from x in tblCat where x.Name.StartsWith(searchName) &amp; x.Kind == searchKind orderby x.No select x; } this.dataGrid.ItemsSource = result.ToList(); } } </code></pre> <h3 id="コンバーターの修正"><a href="#%E3%82%B3%E3%83%B3%E3%83%90%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E4%BF%AE%E6%AD%A3">コンバーターの修正</a></h3> <p>データグリッドに表示する際に値を変換している箇所も、DB接続しているため変更します。</p> <p>KindConverter.cs</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.Linq; using System.Data.SQLite; using System.Data.SQLite.Linq; // Converter 用 // IValueConverter、CultureInfo using System.Windows.Data; using System.Globalization; namespace WpfApp1 { /// <summary> /// 種別コンバータークラス. /// </summary> public class KindConverter : IValueConverter { /// <summary> /// データ変換処理 /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { //using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite")) // PgDbContext に変更 using (var context = new PgDbContext()) { // データを取得 //Table<Kind> tblCat = con.GetTable<Kind>(); //Kind k = tblCat.Single(c => c.KindCd == value as String); var kind = context.Kinds.SingleOrDefault(c => c.KindCd == (String)value); if (kind != null) { return kind.KindName; } return ""; } } /// <summary> /// データ復元処理 /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { using (var context = new PgDbContext()) { // データを取得 //Table<Kind> tblCat = con.GetTable<Kind>(); //Kind k = tblCat.Single(c => c.KindCd == value as String); var kind = context.Kinds.SingleOrDefault(c => c.KindName == value as String); if (kind != null) { return kind.KindCd; } } return ""; } } } </code></pre> <p> </p> <h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/08/WpfPostgreSQL004.jpg" alt="検索結果" /></p> <p>無事に起動、検索することができました。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>ひとまず、元々の処理(SQLite、MySQL)とあまり変更せずに実装することができました。</p> <p>ちょっと長くなってしまったので、<br /> 登録、更新、削除はまた次回とさせていただきます。</p> <p>ではでは。</p> <p> </p> doraxdora tag:crieit.net,2005:PublicArticle/15153 2019-06-23T07:08:50+09:00 2019-06-23T07:08:50+09:00 https://crieit.net/posts/77ac240e0c4b0d0f48ea6ae891149a4c 僕がプロダクト開発を続ける理由 <p><a href="https://crieit.now.sh/upload_images/97bc8faa28e4b6dbc434fa8c0d605f7f5d0d6d25f3d54.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/97bc8faa28e4b6dbc434fa8c0d605f7f5d0d6d25f3d54.png?mw=700" alt="reason.png" /></a></p> <p>ちょうど一週間くらい前。「プロダクト開発について整理しよう!」と思い立って、はじめたブログですが、これで一旦、最終回とします。やっぱり、無理に書こうとすると、良いものってできない。。だから、また学んだことがあったときに綴っていければと!</p> <p>毎日ブログを更新するたびに、リツイートやいいね!、リプをくれた方々、読んでくれた人たち、すごく励みになりました。ありがとうございます!ちょっと、本気でブロガーもありかなって思いました。そんなブログにハマりつつあった僕がやっぱりプロダクトを開発し続ける理由をシメとして共有していきます。</p> <p>これまでのことを読んで、プロダクト開発をやってみたいという人が増えたり、最近やってなかったけど、またプロダクト開発を再開してみるかという人が一人でも増えたら。すごく嬉しいですね。</p> <p>今はプロダクトとして、<a target="_blank" rel="nofollow noopener" href="https://devtalk.jp/">開発会議</a>と、<a target="_blank" rel="nofollow noopener" href="https://devmart.jp/">個人開発のフリマ</a>を運営しています。そこに、明日からEast Hackersというオンラインサロンを追加します。どうしてこれらを始めるに至ったか、そして運営していて思ったことなど、赤裸々に綴っていきたいと思っています。</p> <h2 id="開発会議について"><a href="#%E9%96%8B%E7%99%BA%E4%BC%9A%E8%AD%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">開発会議について</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://devtalk.jp/"><a href="https://crieit.now.sh/upload_images/323e17384a22413c40aa3fb187947b535d0d6c9ad4dd2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/323e17384a22413c40aa3fb187947b535d0d6c9ad4dd2.png?mw=700" alt="スクリーンショット 2019-06-21 16.46.56.png" /></a></a></p> <p><a target="_blank" rel="nofollow noopener" href="https://devtalk.jp/">開発会議</a>は、プロダクト開発のノウハウや知見を共有できるコミュニティサイトです。もともと、Indie Hackersというサイトが大好きで、これをローカライズするような形でリリースに至りました。本当に最初は同じようなものを作っていこうという気持ちでやってみたのですが、<a target="_blank" rel="nofollow noopener" href="https://qiita.com/svfreerider/items/def03b636df78eeea0e6">Qiitaでトレンド入りしたり</a>、多くの開発者の方々に気にかけてもらうようになってから、気を取り直してリニューアルしたりもしました。</p> <p>なので、アイデアに散々書いてきた僕ですけど、開発会議に関しては、かなり趣味的に作ったのがキッカケでした。運営し始めてきてから、サイトに気付かされたことの方が大きいです。今では、日本のモノづくりや、個人開発をする人たちを全面的に応援できるサイトになれるよう日々、改善をしながら運用をしています。</p> <h2 id="個人開発のフリマについて"><a href="#%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA%E3%81%AE%E3%83%95%E3%83%AA%E3%83%9E%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">個人開発のフリマについて</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://devmart.jp/"><a href="https://crieit.now.sh/upload_images/27defec124e587f81c7c4d74fffcd94a5d0d6cc105e2c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/27defec124e587f81c7c4d74fffcd94a5d0d6cc105e2c.png?mw=700" alt="スクリーンショット 2019-06-21 16.47.06.png" /></a></a></p> <p>開発会議でインタビューをしているうちに、「いつかサービスを売却してみたい!」という声もよく聞くようになってきました。サービス売却というと、数千万円、数億円のイメージがありますが、もっと小規模で売買をできるようになってもいいんじゃないか?という仮説のなかで、小規模M&Aサイト「<a target="_blank" rel="nofollow noopener" href="https://devmart.jp/">個人開発のフリマ</a>」を作りました。</p> <p>僕の中では、開発会議と個人開発のフリマに関しては変わらず、個人開発をメジャーなものにしていきたいという思いで続けています。それは、自身が一人で続けてきて失敗を共有できる場所がなかったり、評価される場所がなかったことに課題を感じていたことにありますし、僕は何よりもモノづくりが大好きなので、もっとモノづくりに加わる人たちが増えれば良いなと心から思っているのでやっています。</p> <p>大前提として、慈善活動してやるつもりはないので、ちゃんと自分がいなくても回るくらいの仕組みにするまでプロダクトを成長させていきたいと思っています!</p> <h2 id="プロダクト開発を続ける理由"><a href="#%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E9%96%8B%E7%99%BA%E3%82%92%E7%B6%9A%E3%81%91%E3%82%8B%E7%90%86%E7%94%B1">プロダクト開発を続ける理由</a></h2> <h3 id="面白いから"><a href="#%E9%9D%A2%E7%99%BD%E3%81%84%E3%81%8B%E3%82%89">面白いから</a></h3> <p>プロダクト開発って、プログラミング、セールス、マーケティング、その他諸々なビジネスのエッセンスが詰まっています。その一つ一つを試行錯誤で学んで、実践に移していくのってすごく面白いです。そして、全てのアクションに対して結果がついて回ります。僕は何かを学びたいと思って、プロダクト開発をやっているわけではありませんが、プロダクト開発をやったことで次や他のことに生かせることはたくさんあります。</p> <h3 id="お金を稼げるから"><a href="#%E3%81%8A%E9%87%91%E3%82%92%E7%A8%BC%E3%81%92%E3%82%8B%E3%81%8B%E3%82%89">お金を稼げるから</a></h3> <p>モチベーション高く維持していくために必要な要素だと思います。まだまだプロダクト開発で食べていけるほどではないですが、ちゃんとビジネスモデルを仕込めば、お金を稼ぐこともできます。自分のプロダクトでキャッシュを生むって世の中に価値を出している感が半端ないし、当たれば額も大きくなっていくのを夢見てるのはありますね!</p> <h3 id="やりたいから"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%8B%E3%82%89">やりたいから</a></h3> <p>僕がやりたいのは、スタートアップや開発者の方々のように何かを作ってみたいと思っている人たちのためにプロダクトを作ることです。何かを作ってみたいと一緒にいると勇気が湧いてきて、そういう気持ちがちゃんと世の中を良くしていくと信じています。だから、そういう人たちに価値を見出しているもらえる何かをこれからも作っていきたいです!</p> <p>そして、もう一つが日本のためにできることをやっていきたいです。移住し始めてから、自分が日本人として何ができるのかについてすごく考えるようになりました。このモノづくりの領域から、自分が貢献できることを考えやっていきたいです。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>そして、しつこいくらいに宣伝してきた、<a target="_blank" rel="nofollow noopener" href="http://easthackers.com">East Hackers</a>です。これをなぜやるかについては、別の視点からお話する必要があると思ったので、珍しく長文を用意させていただきました!モノづくりに関わっていない人でも読み物として楽しめるかなと思い、noteで書いてみました。</p> <p>友人の少ない日本人がアメリカに移住して6ヶ月経った結果<br /> <a target="_blank" rel="nofollow noopener" href="https://note.mu/svfreerider/n/n2f57ac648d54">https://note.mu/svfreerider/n/n2f57ac648d54</a></p> <p>アナザーストーリーとして楽しんでいただければ嬉しいですね!これからEast Hackersにはリソースを割いていくことになりますが、開発会議も個人開発のフリマも疎かにならないよう頑張っていきたいと思ってます!もう僕の人生でプロダクトを開発する、成長させる以外にやることないんですよね。そして、これをやってる時が一番幸せってことも分かってます。より良いプロダクトを生み出し、挑戦する人たちに勇気を与えられるよう頑張りましょう!</p> <p><a target="_blank" rel="nofollow noopener" href="http://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0d6cf6910e4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0d6cf6910e4.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15144 2019-06-22T05:47:53+09:00 2019-06-22T05:47:53+09:00 https://crieit.net/posts/FREERIDER FREERIDERのチートコード <p><a href="https://crieit.now.sh/upload_images/b512ef0c2e34734aef723b50d7cc079c5d0c490c4ab02.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b512ef0c2e34734aef723b50d7cc079c5d0c490c4ab02.png?mw=700" alt="cheatcode.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>ちょっと番外編的な感じになってしまうかもしれないですが、今回はプロダクト開発や、それ以外の場面で個人的に意識しているコツとかを話していければと思っています!ちなみに、チートコード(Cheat Code)は、Kiipという会社を作ったBrian Wong氏の<a target="_blank" rel="nofollow noopener" href="https://www.amazon.com/Cheat-Code-Script-Shortcut-Success/dp/1101904968">書籍</a>のタイトルから取ってきました。</p> <p>まず、大前提として僕はプロダクト開発をやりながらも、幾つか日本のクライアントさんからお仕事をもらいながら、リモートワーク+フリーランス的に生計を立てています。あと、アメリカに在住しています。つまり、ちょっと特殊なバックグラウンドかもしれないので、これらのコツが合わないという方かもいるかもしれないので、参考程度にしていただければなと思っています!</p> <h2 id="チートコード紹介"><a href="#%E3%83%81%E3%83%BC%E3%83%88%E3%82%B3%E3%83%BC%E3%83%89%E7%B4%B9%E4%BB%8B">チートコード紹介</a></h2> <h3 id="やりたいことは先にやる!"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8%E3%81%AF%E5%85%88%E3%81%AB%E3%82%84%E3%82%8B%EF%BC%81">やりたいことは先にやる!</a></h3> <p>小さい頃にお母さんから、「宿題してから遊びなさい!」と教育された方も多いはず。ですが、フリーランスと個人開発を両立する上で僕は「遊んでから宿題する」ようなスタイルに変えました。大抵、フリーランスとか仕事が延々に続くことをやってると、忙しくて個人開発の時間を作れないと思うんですよね。僕もそうでした。で、全部仕事終わってから、よし個人開発するかと思うと、疲れてやらないなんて感じになるんですね。。</p> <p>だから、僕は先にやりたいことをやってから仕事するやり方に変更しました。好きなこと先にやった方が効率良いんですよね!じゃあ、仕事やれなくなったらどうするんだよ!ってなるじゃないですか。やるんですよね、仕事は。どんなに時間が足りなくなっても仕事は責任があるのでやります。でも、プロダクト開発は責任がないからやらなくなる。だったら、どうせやる方を後回しにするようにしました!</p> <p>ラッキーなことに、僕はいまアメリカにいるので、クライアントから連絡が来始めるのは夕方以降です。まさに理想なスタイルが築けています!</p> <h3 id="自己主張しない"><a href="#%E8%87%AA%E5%B7%B1%E4%B8%BB%E5%BC%B5%E3%81%97%E3%81%AA%E3%81%84">自己主張しない</a></h3> <p>議論する時もそうですが、プロダクト開発の場面でもあまり自己主張をしないようにしています。これはPGの有名なエッセイ<a target="_blank" rel="nofollow noopener" href="http://www.paulgraham.com/identity.html">Keep Your Identity Small</a>にならっているんですけど、話し合いのなかで自分がどうのこうのって要素が入ると、毎回こじれてしまうんですよね。感情をなるべく出さずに、客観的にみてどうなのかという視点を常に磨くようにしています。この客観的視点というのは経験や知見を学べば学ぶほど育まれていくものなので、意識してみると良いと思います!</p> <h3 id="プルよりもプッシュする"><a href="#%E3%83%97%E3%83%AB%E3%82%88%E3%82%8A%E3%82%82%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%81%99%E3%82%8B">プルよりもプッシュする</a></h3> <p>押してダメなら引いてみろ。だいたい、上手くいくケースって経験上プルの方が多いと思っています。仕事がない時に、いろんな求人サービスに登録したり、「仕事ください!」って言って回るよりも、プロダクト開発に専念したりして、それをSNSとかで発信したりしてる時の方が良い案件の相談がきたりすることが多いように思います!</p> <p>プッシュって、「お願いします」ベースになりがちなので、足元見られやすいんですよね。その分、案件の質も落ちるんですよね。だから、いろんな人にお願いメールを送るよりも、ブログ書いたり、SNSで発信したりして、向こうから来るのを待った方が良い結果になりがちだったりします。プロダクト開発の時もそうですね。</p> <h3 id="紹介よりもDM"><a href="#%E7%B4%B9%E4%BB%8B%E3%82%88%E3%82%8A%E3%82%82DM">紹介よりもDM</a></h3> <p>一方で、プッシュしなければ勝ち得ない場面もあります。相手と自分の接点がまるでない場合や、確実に伝えたい相手が決まっているときには、プルよりもプッシュの方が効率は良いです!例えば、どうしても会いたい相手がいるとして、その人と繋がるためにはプッシュするしかありません。</p> <p>その時に緩い繋がりを使って、やんわり紹介してもらうよりも、自分から直接DMした方がよほど効果的であるケースが多いです。実際に、日本にいるときは、海外の著名なIT起業家が訪日するたびに、TwitterでDMやリプを送って「会ってくれ!」と言ってました。</p> <p>実際に会ってくれて、今でも続いている仲の人もいます。彼らは日本のイベントとかに登壇しに来てたりもするんですけど、そういう場で会うよりも1対1で会えた方が絶対有意義です。あえて、イベントには行かず、いつもそういうやり方を取っていました。</p> <p>ここに補足すると、僕みたいに会ってくれとDMする人たちはたくさんいると思うんです。そうなるとライバルを出し抜いて会ってもらうために、自分がその人に提供できる価値を出すといいと思います。カフェをするのは、あまり相手に価値はないです。ですが、その人を空港まで迎えに行って、ホテルを案内して、観光地も案内するとかなら、カフェするよりよほど相手に価値があると思いませんか?そういうテクニックも織り交ぜていくと良いと思います!</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>時間は平等ですが、時間の使い方って人それぞれだし、使い方によっては普通の何倍も価値を出せるようになってくると思います!だから、生産性については常に意識して行動してみるのが良いと思います。またどこかで紹介してみたいなと思いますが、結構いろんなツールを使ってなるべく生産的な働き方を意識するようにはしています。している方だと思います!</p> <p><a target="_blank" rel="nofollow noopener" href="https://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0c48632438e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0c48632438e.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15137 2019-06-21T09:19:22+09:00 2019-06-21T09:19:22+09:00 https://crieit.net/posts/edd895a564afd55b508a930f06637630 化けるアイデアを生み出すための仮説 <p><a href="https://crieit.now.sh/upload_images/e907e0efb5d7f4980a6d19d0bc2714e55d0c2238c93c3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e907e0efb5d7f4980a6d19d0bc2714e55d0c2238c93c3.png?mw=700" alt="idea.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>先日、<a href="https://crieit.net/posts/a79d49290e0b849d68cae28b74c1f285">公開しましたアイデアに関する記事</a>がけっこう好評だった?ので、もう少し僕なりにアイデアについて書くことがありそうだと思ったので、補足的に今日はやろうかなと思います。決して、ネタ切れとかではないです(笑)</p> <p>まあ、ざっくり言うと、プロダクト開発のアイデアは作り手、もしくは作り手の周りにいる人たちの抱える課題から生まれるのが正攻法だよね!という話をしました。もちろん、そうなんですけど、じゃあ抱えている課題に対する解決策であれば何でもアイデアとして正しいかどうかといえば、そうではない気がしていて。</p> <p>例えばですけど、僕は昔シェアハウスの検索サイトのようなものをしていました。具体的には、シェアハウス事業者と契約的なのを交わして、サイトから誘客して、入居が決まったらお金をシステム利用料として支払ってもらうものです。不動産屋っぽいですね。</p> <p>このアイデアは確かに、シェアハウスの事業者と、シェアハウスを探している人たちが抱えている課題を解決しているかもしれません。ですが、これから大きくスケールしていくような見込みはありません。年間数百万の規模まではすごく頑張れば望めるかもしれませんが、それ以上は厳しいと思ってしまいます。</p> <p>別の観点から考えてみると、普段受託の仕事をしています。外注先の企業の課題を解決しています。普段会社で働いている人たちは、自分を雇用している会社、また、会社のクライアントの課題を解決していると思います。課題を解決しているからといって、プロダクト開発のアイデアにはなり得ません。</p> <p>課題を解決する、あるいは人が欲しがるものを作るというのは、プロダクト開発のアイデアとしては不十分であって、本当に化けるアイデアを生み出すためには、既存のサービスの10倍以上優れたサービスもしくは、今までとはまったく違うサービスを作る必要があります。</p> <p>いま開発しているプロダクトは、Google 翻訳よりも、1%くらい精度が高く翻訳することができる。これからリリースしようと思っているシェアハウスの検索サイトは、他の検索サイトと違って、位置情報からも調べられるんだ。これらは本当に既存のサービスよりも10倍優れた製品でしょうか?その一機能が、キラーな要素で、ユーザーの体験をまるで変えてしまうものであれば別ですが。</p> <p>10倍を定義するのは難しいですが、具体的な事例をあげるとこんな感じです。Uberは普通のタクシーを捕まえるよりも10倍早く目的地にたどり着ける。Slackは既存の社内チャットの10倍自由に楽しくやり取りができるようになった。ICOは既存の10倍以上、資金調達を楽にしてくれました。</p> <p>じゃあ、こういうアイデアをどうやって生み出すのか。課題から始まるのは勿論ですが、化けるアイデアにはどんな特徴があるのでしょうか。これから紹介する仮説はアイデアを生み出す方法というよりは、アイデアの特徴を示しているに過ぎません。しかも、僕の仮説です。なんで、参考程度に「そうかも!」と思ってもられば良いなと思います。</p> <h2 id="マイノリティを見つける"><a href="#%E3%83%9E%E3%82%A4%E3%83%8E%E3%83%AA%E3%83%86%E3%82%A3%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%82%8B">マイノリティを見つける</a></h2> <p>アイデアの定説として、「未来に生きて欠けてるものを作る」があります。じゃあ未来のヒントはどこにあるのかというのを考えてみます。僕はマイノリティにあると思っています。</p> <p>電話はもともと、家庭や会社に一台とかしかありませんでした。マイノリティでした。ですが、今や電話を持ち歩いていない人はいないほどに普及しました。タクシーを日常的に使えるのはビジネスマンや、限られたケースだけでした。ですが、Uberがあることで、誰もが普通にタクシーのような体験を簡単にできるようになっています。</p> <p>マイノリティはただ人数が少ないということを指しているのではなくて、正しいことを知っていて、それを信じている人たちです。今でいう代表的なマイノリティは、フリーランスやリモートワーカーかなと思っています。フリーランスと、そうでない人にはどのような違いがあるのか、フリーランスになりたい人がいるとして、それができていないなら、何が足りていないのか、それを補完できるプロダクトはきっと化けるアイデアになると思います!</p> <h2 id="プライバシーを破壊する"><a href="#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%90%E3%82%B7%E3%83%BC%E3%82%92%E7%A0%B4%E5%A3%8A%E3%81%99%E3%82%8B">プライバシーを破壊する</a></h2> <p>インターネットの世界で成功したサービスの多くは、これまでプライバシーを破壊してきた傾向にあります。これは、Angel Listの創業者であるNaval Ravikantが提唱していたことなのですが。</p> <p>Flickrは、写真をデフォルトでカメラロールにしまい非公開にしている状態を破壊することで成功しました。<br /> LinkedInは、普通履歴書は誰にも公開しないのが普通だった状態を破壊することで成功しました。<br /> Foursquareは、位置情報、あなたがどこにいるかを非公開にしていた状態を破壊しました。<br /> Twitterは、心の中に閉まっておく、メモしておく個人的な気持ちが非公開になっている状態を破壊しました。</p> <p>こんな感じで、プライベートになっているものを公開にしてみることで爆発的に伸びたサービスというのがあったんですね。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>いろいろと仮説を書いてみましたが、なかなか後付け的な理論ばかりなので最終的にはやった後にしか、それが正しいかどうかなんて分からないのかもしれません。でも、いろいろと考えていくとプロダクト開発ってやっぱり奥が深い。。</p> <p><a target="_blank" rel="nofollow noopener" href="https://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0c227e02c65.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0c227e02c65.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15132 2019-06-20T11:42:02+09:00 2019-06-20T11:42:02+09:00 https://crieit.net/posts/daa3bda358cd32be7c35e156b9d70431 チーム開発をやってみた気づきと反省 <p><a href="https://crieit.now.sh/upload_images/663ae4f562314c209d4c8abc16fe39c15d0af1e1bbbfc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/663ae4f562314c209d4c8abc16fe39c15d0af1e1bbbfc.png?mw=700" alt="team.png" /></a></p> <p>かれこれ何年も個人開発に打ち込んでいるわけですが、個人でなくてチームでやっていた時期も結構ありました。最初にプロダクトをリリースしていた頃、エンジニアでもなかったので、結果的にさまざまな立場でプロダクト開発に関わっていることになります。</p> <p>今は個人で開発をしていることに落ち着いているのですが、機会があればまた誰かと何かを作ってみたい!と思っていますし、自分の主要なプロダクトが市場の波に乗ってきたら会社化して体勢を整えていくことも視野に入れています。</p> <p>サービスの開発に関わる人を増やすって、会社で言えば採用なわけですが、売上も出ていない個人開発だとなかなか人を採用するまでの余裕って生まれないんですよね。僕も以前、受託で稼いだお金でプロダクトのマーケティングや、一部の開発を友人などに外注したこともあるのですが、やっぱり上手くいくかどうか分からないプロダクトで何十万円とかコストがかかってくるのは、精神的にも経済的にも好ましくないです。</p> <p>それでも、誰かと一緒にやるのであれば、レベニューシェアみたいなやり方があります。株式に似ていて、売上が出たり、売却できた時に報酬を山分けしようぜ!というやつです。お互い負担なくスタートできるので、より良いやり方ではあるものの、大抵のプロダクトは途中で上手くいかなかったりするので、その時が辛いです。</p> <p>だいたい、最初は開発者が労力をかけてサービスを作り始めるので、実際に出して上手くいかなかったら、開発者の方がコストが多大で終わってしまうのが多いのです。僕は、どちらの立ち位置でも関わったことがあるので、両方の辛みが分かります。頑張って開発してくれたけど振るわず、サービスを広められなかった自責もあれば、頑張って開発してるけど、この人は何をしてくれるんだろう・・と思ったことも正直あります。</p> <p>僕が関わったことのあるチーム開発での経験と、反省。それから、結局どういうやり方がいいのかなということを書いていきたいと思います。</p> <h2 id="チーム開発での経験"><a href="#%E3%83%81%E3%83%BC%E3%83%A0%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%AE%E7%B5%8C%E9%A8%93">チーム開発での経験</a></h2> <h3 id="AI系サービス"><a href="#AI%E7%B3%BB%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9">AI系サービス</a></h3> <p>学生時代に、10才年上のデザイナーさんと、さらに10才年上のエンジニアさんと、3人でプロダクトを開発することになりました。まず、それだけバラバラの世代がどこで知り合ったかといえば、確か何かのワークショップ?アイデアソン?みたいなので同じグループでした。その時に出したアイデアをイベント後も一緒にやろうということになりました。</p> <p>アイデアは、ボットの質問に答えながら自分の分身のようなAIを育てていくものだったのですが、毎月ミーティングや、開発を進めながら半年くらいやっていたと思います。僕はプロダクトそのものを作ることに関しては何もできなかったので、ユーザーとなりうる人のヒアリングや、サービスを広めるための施策を考えたりしてました。</p> <p>結局、チームは風化していきました。イベントで出会ったということもあって、多少関心の接点はあったものの、お互いの生活風景がまったく異なっていたので、何も分かり合えませんでした。でも、この時、初めてプロダクトを作るということを経験して、しかも組んだ2人が業界に長い方だったので、色々と1から教えてもらったのはラッキーでした!チーム開発では、誰かの仕事っぷりを直に感じることができるので、自分よりスキルが高いという人と組んだ方が絶対良いなとその時思いました。</p> <h3 id="インターンシップメディア"><a href="#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2">インターンシップメディア</a></h3> <p>アメリカに滞在している時に、語学学校が一緒だった友人と、シリコンバレーで働きたいけどその機会を見つけられない人向けに、現地の情報や、インターンできるスタートアップを紹介するインターンシップメディアを作りました。二人で記事を作ったり、取材をしたりするのはとても楽しかったです。しかし、やっていくうちに、自分はここに優先度を高く、比重を置いていたのに対して、相手がそうでなかったことで熱量の違いを感じて、あまり良くない別れかたをしてしまいました。その時は相手の気持ちを汲み取れず、一方的に自分のやる気を押しつけてしまったことに反省していて、今後チームでやる時は絶対に険悪な形で終わらないようにしようと決意しました。</p> <h3 id="共同創業"><a href="#%E5%85%B1%E5%90%8C%E5%89%B5%E6%A5%AD">共同創業</a></h3> <p>アメリカでルームシェアをしていた友人と一緒に、日本で会社を立ち上げました。一年以上寝食を共にしてきた仲だったので、この人とならどんな苦難も乗り越えていくと信じ、さまざまなプロダクトを一緒に立ち上げてきました。この時も彼がエンジニアで、僕はコードを書いていなかったので、彼がコードを書いている間に集客用のオウンドメディアを作ったりと、少しでもプラスになることを探していて頑張っていました。</p> <p>結果、売上も見えないまま、余裕がない中でのスタートアップで関係も険悪になり、最終的に相手が会社を去りました。プライベートでは仲良くなれても、ビジネスでも良好で進められるとはまた別なんだなと思いました。会社を去った後も、彼とは連絡を取り合っていますし、飲みにいったりもしてます。一緒にプロダクトを作った仲間って、例え失敗しても、その期間一緒に夢を追った仲間なわけですから、最高ですよね。</p> <h3 id="Twitterカード系サービス"><a href="#Twitter%E3%82%AB%E3%83%BC%E3%83%89%E7%B3%BB%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9">Twitterカード系サービス</a></h3> <p>前回と結構時間が空いて、1年半以上ぶりにチーム開発をしたのが、Twitterカードを使ったミニアプリです。一緒にやることになった人とは、コワーキングスペースで出会いました。文字通り、意気投合して、出会ってから3週間とかでサービスリリースしてました。この時こそ、僕がメイン開発で、相手がマーケティングを担当してくれました。サービスはリリース初日からバズって、すごいアクセスがある中で夜通し通話と繋いで、バグを直したり、どういう動きをするのか話し合うのは良き思い出ですね。結構、マーケ、開発と役割をきっちり分けてしまったがゆえに、お互いがその役割に干渉しづらい空気になったのが良くなかったですね。</p> <h3 id="予定調整アプリ"><a href="#%E4%BA%88%E5%AE%9A%E8%AA%BF%E6%95%B4%E3%82%A2%E3%83%97%E3%83%AA">予定調整アプリ</a></h3> <p>Googleカレンダーとシンクして、予定調整ができるサービスを作りました。一緒に作った人とは、共通の友人経由で出会って、一緒に仕事するよりも、どちらかといえば飲み友達でした。ですが、彼の腕前と仕事での評判は予々聞いていたので、なんか一緒にできないかなとタイミングを伺っていました。そこで、サービスのアイデアを考えて、一緒にやらないかと提案してみました。作り始めてからは、僕がバックエンド、彼がフロントエンドでやる予定だったのですが、結局、開発で自分が足を引っ張ってしまい、両方彼が実装することになりました。その時は、本当に申し訳なかったですが、二人でファミレスオールして開発したのは、プロダクト開発をしてきた人生で選り取りにエキサイティングな思い出です。サービスは上手くいきませんでしたが、今でもサービスの相談に乗ってもらっています。やっぱり、自分が非開発のポジションで入ってしまうと、リリースまで手薄になるし、リリースしてからも上手くいかなかったら自責が半端ないので、もっと、MVPから一緒にやっていった方がいいかもしれませんね。</p> <h2 id="チーム開発に対する見解"><a href="#%E3%83%81%E3%83%BC%E3%83%A0%E9%96%8B%E7%99%BA%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E8%A6%8B%E8%A7%A3">チーム開発に対する見解</a></h2> <p>結果、一緒にプロダクト開発をしてくれた人たちにはすごく感謝しています。プロダクト開発にはビジネスのエッセンスが込められていて、他の人がどのような想いやモチベーションでやるのかから、自分には思いつかないマーケティング的視点まで、なかなか学ぶ点がたくさんあるのです!</p> <p>もちろん、そういう意味では誰と組むかが大事だったりもするのですが。結論的に、個人開発なら失敗も成功も全部自分のものになるわけですが、チーム開発だと失敗しても成功しても、その人と組んだことで得られるものがあると判断できた場合にのみやってみるのが良いんじゃないかなと思います!</p> <p>あとは持分ですよね、どういう条件でやるのかは最初のうちからちゃんと(できれば契約も混みで)決めておくのが良いと思います。必ずしも、均等が良いわけではないですし。でも、この人とビジネスやってみると面白そうだなって人に気軽に、なんかやりましょ!って声かけてみればよいと思います。</p> <p><a target="_blank" rel="nofollow noopener" href="https://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0af2621caee.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0af2621caee.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15127 2019-06-19T10:56:53+09:00 2019-06-19T11:01:46+09:00 https://crieit.net/posts/d5ab9cccde272b3d40b8adc641c59048 プロダクトを閉じる時。ピボットで成功しよう <p><a href="https://crieit.now.sh/upload_images/49e8d0999f611650ddf9ee75141fc60c5d09965da619d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/49e8d0999f611650ddf9ee75141fc60c5d09965da619d.png?mw=700" alt="pivot.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>プロダクトを閉じるときほど、開発者にとって辛いことはないかもしれませんね。よく、開発会議のインタビューで「最初に開発したプロダクトは何ですか?」と尋ねさせていただいてるのですが、おそらく個人開発者の多くが今日に至るまで一つ以上のプロダクトを作ってきたし、きっと閉じたり、運営を続けたりを繰り返していると思います。</p> <p>僕自身も<a href="https://crieit.net/posts/2-7">本当にたくさんのプロダクトを閉じてきた</a>し、たまに、あれってこういうやり方でやれば、もっと上手くできたんじゃないかなと思い起こしたりすることもあります。今も幾つかプロダクトを運営していますが、何らかの理由で閉じてしまう可能性もあるかもです。</p> <h2 id="なぜプロダクトは死ぬのか?"><a href="#%E3%81%AA%E3%81%9C%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%81%AF%E6%AD%BB%E3%81%AC%E3%81%AE%E3%81%8B%EF%BC%9F">なぜプロダクトは死ぬのか?</a></h2> <p>よく競合に食われたとか、法規制がどうのっていう問題も挙げられますが、だいたいのプロダクトは他殺ではなく、自殺です。だから、プロダクトを作っている時に、類似サービスが出てきてもそんなに気にする必要はないんじゃないかなと思いますね。</p> <p>要は、開発者がこのプロダクトはやりようがない、やっていても楽しくないってなった瞬間にプロダクトは閉じられていきます。あんまりユーザーがいるかいないかのような成績は関係なくても、ユーザーがついていても閉じる時は閉じるし、ユーザーがいなくてもやり続ける人はいます。</p> <p>続けるか、続けないかは開発者次第ですが、個人的にはどんなに続けたくても、無理だという理由に納得できるなら、キッパリ閉じた方が生産的かなと思っています。アイデアに盲信して、一年くらいのめり込んでしまい、お金も時間も無駄になってしまった経験があるので、あくまで成功することを前提にするなら、見極めはすごく大事です!</p> <p>一方で、Airbnbのように一年くらいしてからやっと芽が出てくるパターンもあるので、続けるか、続けないかの基準はここでは書き切れなさそうだなと思っています。ただ、プロダクトは死んでも、開発者が死ななければまだこれからめちゃくちゃ良いプロダクトを生み出せる可能性は残っています。</p> <h2 id="ピボット後に成功したプロダクトたち"><a href="#%E3%83%94%E3%83%9C%E3%83%83%E3%83%88%E5%BE%8C%E3%81%AB%E6%88%90%E5%8A%9F%E3%81%97%E3%81%9F%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%81%9F%E3%81%A1">ピボット後に成功したプロダクトたち</a></h2> <p>今では誰もが知っているプロダクトで方向転換して成功した事例を幾つか見ていきましょう!</p> <h3 id="Twitter"><a href="#Twitter">Twitter</a></h3> <p>みんな大好きTwitterも最初は、Twitterではありませんでした。もともと、Odeoというポッドキャストのプラットフォーム(iTunesのような)を作っていた会社の中における社内ベンチャー的にはじまりました。確かに、Twitterは創業者のジャックドーシーが5年前から温めていたアイデアとしても有名ですが、Odeoが上手くいっていないときにTwitterのプロジェクトをスタートし、今ではここまで大きくなったのです。</p> <h3 id="Youtube"><a href="#Youtube">Youtube</a></h3> <p>こちらも面白いのが、Youtubeって最初は出会い系サイトだったんです!ユーザーは自己紹介のビデオをアップロードして、理想の相手を探せる動画を使った出会い系だったのですが、ユーザーが理想の相手を探すことよりも動画をアップロードしておくことに価値を感じていたのを発見し、現在のYoutubeへとピボットを果たしました。</p> <h3 id="Slack"><a href="#Slack">Slack</a></h3> <p>Slackは、Slackを作る会社の社内ツールとして開発されてきました。表向きはゲーム会社でした。創業者のスチュワートバターフィールドは、その以前、写真共有サービスFlickrを立ち上げた起業家でもあります。ちなみに、その時も表向きはゲームを作っていたという。。</p> <h3 id="Pinterest"><a href="#Pinterest">Pinterest</a></h3> <p>Pinterestも何回も失敗しながら、今のサービスに着地していることを創業者本人が<a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=KYQHPHYs2Os">こちらの動画</a>で語っています。ちなみに、Pinterestの前はToteというショッピングアプリを作っていたそうです。ユーザーはそこそこついていたみたいですが、アプリ上でユーザーは購入せず、お気に入りをするだけだったそうです。そこから、お気に入りしておくことに特化したPinterestが生まれたんですね。</p> <h3 id="Instagram"><a href="#Instagram">Instagram</a></h3> <p>ティーンズに大人気のInstagramもリリース当初は、こんなにスタイリッシュではありませんでした。最初はBurbnという、位置情報や写真を共有できるソーシャルチェックインとして始まりました。確かにInstagramに似通った部分もあって、ユーザーの動きを見ながら、本当に大切な機能だと判断した写真投稿の機能だけが残り、今のInstagramになりました。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>もう世界中の知らない人がいないレベルのプロダクトを作る開発者でも、プロダクトを閉じて作り直すという経過を経て、それを作り上げているんです。そう考えると、プロダクトを閉じるなんて全然恥ずかしいことじゃないと思います。</p> <p>でも、プロダクトを閉じるためにプロダクトを作る人なんていないわけですから、閉じると決断するまでは、ずっと続けられるプロダクトを作ることに精一杯尽くしていかなきゃですね。</p> <p><a target="_blank" rel="nofollow noopener" href="https://easthackers.com/"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0995c95393f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d0995c95393f.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15126 2019-06-19T09:36:38+09:00 2019-06-19T09:36:38+09:00 https://crieit.net/posts/WPF-5d0983964473b 【WPF】自作カレンダー その2(動的生成) <p>自作カレンダーその2です。<br /> 今回は、Xamlではなくコードからカレンダーを生成します。</p> <p>最終的に年間カレンダー的なものにしようと思うので、<br /> Xamlで定義すると Grid だらけになってしまうし、色々やろうと思ったらやっぱり動的に生成した方がやりやすいような気がするので。</p> <p>前回のプログラムはこちら。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/10/15/post-2760/" target="_blank" rel="noopener noreferrer" data-blogcard="1">【WPF】自作カレンダー その1(とりあえず当月を表示)</a></p> <h2 id="スタイル定義の変更"><a href="#%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E5%AE%9A%E7%BE%A9%E3%81%AE%E5%A4%89%E6%9B%B4">スタイル定義の変更</a></h2> <p>まずはスタイルの外出しをします。</p> <p>StyleDic.xaml</p> <pre><code><br /> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:local="clr-namespace:CalendarSample.Style"> <!-- グループ:通常--> <Style x:Key="gp-normal" TargetType="GroupBox" > <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="Background" Value="#FFFFFFFF" /> <Setter Property="Foreground" Value="#FF777777" /> <Setter Property="Height" Value="300" /> <Setter Property="Width" Value="500" /> <Setter Property="Margin" Value="10, 10, 0, 0" /> </Style> <!-- グリッド:カレンダー用 --> <Style x:Key="grid-calendar" TargetType="Grid" > <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="Background" Value="#FFFFFFFF" /> <Setter Property="Height" Value="258" /> <Setter Property="Width" Value="450" /> <Setter Property="Margin" Value="0, 0, 0, 0" /> </Style> <!-- テキストブロック:日付セル(通常) --> <Style x:Key="txb-date" TargetType="TextBlock"> <Setter Property="FontSize" Value="12" /> <Setter Property="Foreground" Value="Black" /> <Setter Property="Padding" Value="0, 10, 10, 0" /> <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="HorizontalAlignment" Value="Right" /> </Style> <!-- テキストブロック:日付セル(土曜) --> <Style x:Key="txb-date-sat" TargetType="TextBlock" BasedOn="{StaticResource txb-date}"> <Setter Property="Foreground" Value="Blue" /> </Style> <!-- テキストブロック:日付セル(日曜) --> <Style x:Key="txb-date-sun" TargetType="TextBlock" BasedOn="{StaticResource txb-date}"> <Setter Property="Foreground" Value="Red" /> </Style> <!-- 四角形:外枠用 --> <Style x:Key="rec-border" TargetType="Rectangle"> <Setter Property="Stroke" Value="Black" /> <Setter Property="StrokeThickness" Value="1" /> <Setter Property="Grid.ColumnSpan" Value="7" /> <Setter Property="Grid.RowSpan" Value="7" /> </Style> <!-- 四角形:下線用 --> <Style x:Key="rec-underlining" TargetType="Rectangle"> <Setter Property="Stroke" Value="Black" /> <Setter Property="StrokeThickness" Value="1" /> <Setter Property="Height" Value="1" /> <Setter Property="VerticalAlignment" Value="Bottom" /> <Setter Property="Grid.ColumnSpan" Value="7" /> </Style> <!-- 四角形:曜日 --> <Style x:Key="rec-week" TargetType="Rectangle"> <Setter Property="Fill" Value="#FF8000" /> <Setter Property="VerticalAlignment" Value="Stretch" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="Grid.Row" Value="0" /> <Setter Property="Margin" Value="1, 1, 0, 0" /> <Setter Property="Panel.ZIndex" Value="0" /> </Style> <!-- 四角形:曜日 --> <Style x:Key="rec-week-sat" TargetType="Rectangle" BasedOn="{StaticResource rec-week}"> <Setter Property="Margin" Value="1, 1, 1, 0" /> </Style> <!-- 四角形:日付セル(通常) --> <Style x:Key="rec-date" TargetType="Rectangle"> <Setter Property="VerticalAlignment" Value="Stretch" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="Fill" Value="Transparent" /> <Setter Property="Margin" Value="0, -1, -1, 0" /> <!-- トリガーを使ってマウスオーバーで背景色を変更する --> <Style.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Trigger.Setters> <Setter Property="Margin" Value="0, 0, 0, 0" /> <Setter Property="Fill" Value="#60d0ff" /> <Setter Property="Opacity" Value="0.1"/> </Trigger.Setters> </Trigger> </Style.Triggers> </Style> <!-- 四角形:日付セル(土曜) → 最後の列を微調整--> <Style x:Key="rec-date-sat" TargetType="Rectangle" BasedOn="{StaticResource rec-date}"> <Setter Property="Margin" Value="0, -1, 0, 0" /> </Style> <!-- 四角形:日付セル(選択) --> <Style x:Key="rec-date-selected" TargetType="Rectangle"> <Setter Property="VerticalAlignment" Value="Stretch" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="Stroke" Value="Black" /> <Setter Property="StrokeDashArray" Value="1 1" /> <Setter Property="StrokeThickness" Value="1"/> <Setter Property="Fill" Value="#007acc" /> <Setter Property="Opacity" Value="0.2"/> </Style> <!-- ラベル:曜日ヘッダ--> <Style x:Key="lb-week" TargetType="Label"> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="Grid.Row" Value="0" /> <Setter Property="FontSize" Value="11" /> <Setter Property="Padding" Value="0" /> </Style> </ResourceDictionary> </code></pre> <p>ポイントは、日付セルの上をマウスオーバーした際と、クリックして選択した際に背景色を変更するところですかね。</p> <h2 id="画面の変更"><a href="#%E7%94%BB%E9%9D%A2%E3%81%AE%E5%A4%89%E6%9B%B4">画面の変更</a></h2> <p>画面に年月を選択するコンボボックスと、選択された日付を表示するラベルを追加しました。<br /> 後は カレンダー用の Grid がなくなってすっきりしました。</p> <p>MainWIndow.xaml</p> <pre><code><br /><Mah:MetroWindow x:Class="CalendarSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:CalendarSample" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" GlowBrush="{DynamicResource AccentColorBrush}" mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="カレンダーサンプル" Height="400" Width="525"> <Window.Resources> <ResourceDictionary Source="/Style/StyleDic.xaml"/> </Window.Resources> <Grid x:Name="MainContainer"> <Label x:Name="lbYearMonth" Content="年月:" HorizontalAlignment="Left" Margin="10,20,0,0" VerticalAlignment="Top" /> <ComboBox x:Name="cbYearMonth" HorizontalAlignment="Left" Margin="61,20,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="cbYearMonth_SelectionChanged"/> <Grid x:Name="CalendarContainer" HorizontalAlignment="Left" Height="317" Margin="0,53,0,0" VerticalAlignment="Top" Width="517"/> <Label x:Name="lbDate" Content="選択された日付:" HorizontalAlignment="Left" Margin="222,20,0,0" VerticalAlignment="Top"/> <Label x:Name="lbSelectedDate" Content="" HorizontalAlignment="Left" Margin="333,20,0,0" VerticalAlignment="Top"/> </Grid> </Mah:MetroWindow> </code></pre> <h2 id="プログラム修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E4%BF%AE%E6%AD%A3">プログラム修正</a></h2> <h3 id="新規クラス追加"><a href="#%E6%96%B0%E8%A6%8F%E3%82%AF%E3%83%A9%E3%82%B9%E8%BF%BD%E5%8A%A0">新規クラス追加</a></h3> <p>新規で、年月コンボボックス用と、日付セル用のクラスを追加します。</p> <p><span class=" author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z9z84zrpz78zez89zz80zz74zz70ziz73z2qz76zgqnz66z0uyz82zz89zz78zz83zhjez73zj">MonthInfo.cs<br /> </span></p> <pre><code><br />using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CalendarSample { /// <summary> /// 年月情報 /// </summary> public class MonthInfo { /// <summary> /// コンストラクタ /// </summary> /// <param name="yearMonth"></param> public MonthInfo(String yearMonth) { this.YearMonth = yearMonth; this.YearMonthWithKanji = getYear() + "年" + getMonth() + "月"; } /// <summary> /// 年月 /// </summary> public String YearMonth { set; get; } /// <summary> /// 年月(YYYY年MM月) /// </summary> public String YearMonthWithKanji { set; get; } /// <summary> /// 年を返します. /// </summary> /// <returns></returns> public String getYear() { if (String.IsNullOrEmpty(YearMonth)) return ""; return YearMonth.Substring(0, 4); } /// <summary> /// 月を返します. /// </summary> /// <returns></returns> public String getMonth() { if (String.IsNullOrEmpty(YearMonth)) return ""; return YearMonth.Substring(4, 2); } } } </code></pre> <p>DateInfo.cs</p> <pre><code><br />using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CalendarSample { /// <summary> /// 日付情報 /// </summary> public class DateInfo : MonthInfo { /// <summary> /// コンストラクタ /// </summary> /// <param name="yearMonth"></param> /// <param name="day"></param> public DateInfo(String yearMonth, String day) : base(yearMonth) { this.YearMonthDay = yearMonth + day; this.Date = new DateTime(int.Parse(getYear()), int.Parse(getMonth()), int.Parse(day)); } public DateTime Date { set; get; } /// <summary> /// 年月日 /// </summary> public String YearMonthDay { set; get; } /// <summary> /// 年月日(YYYY年MM月DD日) /// </summary> public String getYearMonthDayWithKanji() { return String.Format("{0:yyyy年MM月dd日(ddd)}", Date); } /// <summary> /// 日を返します. /// </summary> /// <returns></returns> public String getDay() { if (String.IsNullOrEmpty(YearMonthDay)) return ""; return YearMonthDay.Substring(6, 2); } } } </code></pre> <h3 id="コードビハインドの修正"><a href="#%E3%82%B3%E3%83%BC%E3%83%89%E3%83%93%E3%83%8F%E3%82%A4%E3%83%B3%E3%83%89%E3%81%AE%E4%BF%AE%E6%AD%A3">コードビハインドの修正</a></h3> <p>年月コンボボックスの項目設定と、カレンダーの生成メソッドを追加したりしました。</p> <p>MainWindow.xaml.cs</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using MahApps.Metro.Controls; namespace CalendarSample { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : MetroWindow { private Rectangle selectedRec; private Style selectedRecStyle; public MainWindow() { InitializeComponent(); // 前月から6カ月分のリストを作成し、当月を選択させる List<MonthInfo> list = new List<MonthInfo>(); DateTime now = DateTime.Now; DateTime dt = now.AddMonths(-1); for (int i = 0; i < 6; i++ ) { list.Add(new MonthInfo(String.Format("{0:yyyyMM}", dt))); dt = dt.AddMonths(1); } this.cbYearMonth.ItemsSource = list; this.cbYearMonth.DisplayMemberPath = "YearMonthWithKanji"; this.cbYearMonth.SelectedIndex = 1; createCalendar(this.cbYearMonth.SelectedItem as MonthInfo); } /// <summary> /// 年月コンボの選択変更イベントハンドラー. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void cbYearMonth_SelectionChanged(object sender, SelectionChangedEventArgs e) { createCalendar(cbYearMonth.SelectedItem as MonthInfo); } /// <summary> /// 指定された年月のカレンダーを作成 /// </summary> /// <param name="monthInfo"></param> private void createCalendar(MonthInfo monthInfo) { CalendarContainer.Children.Clear(); // グループボックス GroupBox calendarGroup1 = new GroupBox(); calendarGroup1.Header = monthInfo.YearMonthWithKanji; calendarGroup1.Style = FindResource("gp-normal") as Style; // グリッド Grid calendarGrid1 = new Grid(); calendarGrid1.Style = FindResource("grid-calendar") as Style; calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(20) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); calendarGrid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); // グリッド枠線 Rectangle border = new Rectangle(); border.Style = FindResource("rec-border") as Style; calendarGrid1.Children.Add(border); for (int col = 0; col < 7; col++) { Rectangle week = new Rectangle(); week.Style = (col == 6) ? FindResource("rec-week-sat") as Style : FindResource("rec-week") as Style; week.SetValue(Grid.ColumnProperty, col); calendarGrid1.Children.Add(week); Label lbWeek = new Label(); lbWeek.Style = FindResource("lb-week") as Style; lbWeek.Content = ("日月火水木金土").Substring(col, 1); lbWeek.SetValue(Grid.ColumnProperty, col); calendarGrid1.Children.Add(lbWeek); } // ヘッダ行下線 Rectangle underlining = new Rectangle(); underlining.Style = FindResource("rec-underlining") as Style; calendarGrid1.Children.Add(underlining); // グループボックスにグリッドを追加 calendarGroup1.Content = calendarGrid1; CalendarContainer.Children.Add(calendarGroup1); // 当月の月初を取得 var firstDate = new DateTime(int.Parse(monthInfo.getYear()), int.Parse(monthInfo.getMonth()), 1); // 曜日番号の取得 int dayOfWeek = (int)firstDate.DayOfWeek; // 月末を取得 int lastDay = firstDate.AddMonths(1).AddDays(-1).Day; // 1日から月末までを走査 for (int day = 1; day <= lastDay; day++) { // セル位置 int index = (day - 1) + dayOfWeek; // 横位置 int x = index % 7; // 縦位置 int y = index / 7; // テキストブロックを生成してグリッドに追加 var tb = new TextBlock(); tb.Text = string.Format("{0}", day); // 土日は文字色を変更する if (x == 0) { tb.Style = FindResource("txb-date-sun") as Style; } else if (x == 6) { tb.Style = FindResource("txb-date-sat") as Style; } else { tb.Style = FindResource("txb-date") as Style; } calendarGrid1.Children.Add(tb); tb.SetValue(Grid.ColumnProperty, x); tb.SetValue(Grid.RowProperty, y + 1); // 四角形を生成してグリッドに追加 // セルの枠線などを表示し、イベントをハンドリングする用 var rec = new Rectangle(); DateInfo dt = new DateInfo(monthInfo.YearMonth, string.Format("{0:00}", day)); rec.DataContext = dt; // 枠線を調整 rec.Style = (x == 6) ? FindResource("rec-date-sat") as Style : FindResource("rec-date") as Style; // イベント設定 rec.MouseLeftButtonDown += date_MouseLeftButtonDown; calendarGrid1.Children.Add(rec); rec.SetValue(Grid.ColumnProperty, x); rec.SetValue(Grid.RowProperty, y + 1); } } /// <summary> /// セル(日)をクリックした際のイベントハンドラ. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void date_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 既に選択されたセルがある場合はスタイルを戻す if (selectedRec != null) { selectedRec.Style = selectedRecStyle; } // 選択されたセルの取得 Rectangle rec = sender as Rectangle; // 選択セルの保持 selectedRec = rec; selectedRecStyle = rec.Style; // 選択時のスタイルに変更 rec.Style = FindResource("rec-date-selected") as Style; // ラベルに日付をセット lbSelectedDate.Content = (rec.DataContext as DateInfo).getYearMonthDayWithKanji(); } } } </code></pre> <p> </p> <h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/10/WpfCalendar2_000.jpg" alt="起動後画面" /></p> <p>起動後は当月を表示するようにしました。</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/10/WpfCalendar2_001.jpg" alt="日付選択時" /></p> <p>日付を選択すると、選択箇所の背景色が変わり、選択された日付が右上に表示されます。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>なんとなく使えそうな気がしてきました。<br /> バインディングなんかがうまく利用できていませんが、それは追々ということで。</p> <p>次回は、年間カレンダーにしようかと思います。</p> <p>ではでは。</p> <p> </p> doraxdora tag:crieit.net,2005:PublicArticle/15123 2019-06-18T13:31:11+09:00 2019-06-18T13:31:11+09:00 https://crieit.net/posts/4006643be56ab8a75076facb12c28473 ユーザーヒアリングのすすめ <p><a href="https://crieit.now.sh/upload_images/36beacce711c05863c9275ba71ac49975d0868de021a4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/36beacce711c05863c9275ba71ac49975d0868de021a4.png?mw=700" alt="usehearing.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>より良いプロダクトづくりをするために、ユーザーヒアリングはすごく大事だと言われています。ユーザーヒアリングをしていると思わぬ見落としに気づくことができたりして、例えば、Twitchは初期に相当数のユーザーにヒアリングをしたそうですが、その中でユーザーにとってもっとも深刻なことはTwitchが「Team Liquid Star Craft」のファンサイトで掲載されていないことだったとか。そんなコアなこと自分たちでやっていたら分かるはずもなくて、ユーザーにヒアリングして初めて理解できることもあるってわけです。</p> <p>じゃあ、ユーザーヒアリングってどうすれば良いのでしょうか?個人開発を初めてすぐの時は、ユーザーヒアリングが大事であるだけを鵜呑みにして、とにかく登録してくれたユーザーにアポイントを取って、できるだけ対面で会うようにしました。それを一年続けた結果、Facebookの友達数が増えただけで、代わりに生き残ったサービスは一つもありませんでした。</p> <p>実際のところ、周りの話を聞いてもまともなユーザーヒアリングをするのは大概難しいように思います。まず、プロダクトがない状態だったら、ユーザーがいないので(ユーザー)ヒアリングになります。もちろん、ユーザー、それもただ登録しているだけの人ではなく、ヘビーユーザーに意見を聞けることが一番理想です。しかし、プロダクトを作ったり、ユーザーがつく前からヒアリングってしておきたいものですよね。</p> <h2 id="どんな人がヒアリングの対象になりうるのか?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E4%BA%BA%E3%81%8C%E3%83%92%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AE%E5%AF%BE%E8%B1%A1%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%86%E3%82%8B%E3%81%AE%E3%81%8B%EF%BC%9F">どんな人がヒアリングの対象になりうるのか?</a></h2> <p>ヘビーユーザーがいない場合のヒアリング対象は、3パターンあるかなと思ってます。分かりやすい例があるといいと思うので、Airbnbを取ってみましょ。一応説明すると、Airbnbは、自分の家で空いている部屋を宿泊施設に旅行客に貸し出すことができるシェアリングエコノミー です。</p> <h3 id="競合他社のプロダクトを使ってる"><a href="#%E7%AB%B6%E5%90%88%E4%BB%96%E7%A4%BE%E3%81%AE%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%8B">競合他社のプロダクトを使ってる</a></h3> <p>Airbnbがスタートする4年前から、似たようなサービスでCouchSurfingというのがありました。CouchSurfingとAirbnbの違いは、取引に際して金銭のやり取りがあるかどうかだけで、基本的に空いている部屋を旅行者に明け渡すという意味ではほぼ同じユーザー体験を提供していたといえます。CouchSurfing人は、すでに知らない人の家に泊まる/知らない人を泊めるのハードルをクリアしていて、Airbnbのユーザーにもなる可能性が高いですよね。じゃあ、「どうやったら、乗り換えてくれますか」って聞けば良さそう。</p> <h3 id="すでに代替手段を用いて、行為を習慣化している"><a href="#%E3%81%99%E3%81%A7%E3%81%AB%E4%BB%A3%E6%9B%BF%E6%89%8B%E6%AE%B5%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E3%80%81%E8%A1%8C%E7%82%BA%E3%82%92%E7%BF%92%E6%85%A3%E5%8C%96%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B">すでに代替手段を用いて、行為を習慣化している</a></h3> <p>少し競合の部分に被るところもあるかもしれませんが、Airbnbが始まる前からAirbnbぽいことをしている人たちはいました。Craiglistは、中古家具の売買や、部屋探しなど生活にいまつわる掲示板として有名なのですが、要するに人と人で自由に取引を行ってたのですね。そこで、Airbnbのように知らない人の家に数日間宿泊するようなことも行われていました。彼らは専用プラットフォームがないから、仕方なく、別のサイト(今回でいうCraiglist)や方法(代替手段)で補完していたわけですね。そういう人なら自分のサイトのユーザーにもなってくれそうですよね。</p> <h3 id="プロダクトによって解決される問題を抱えている"><a href="#%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%81%AB%E3%82%88%E3%81%A3%E3%81%A6%E8%A7%A3%E6%B1%BA%E3%81%95%E3%82%8C%E3%82%8B%E5%95%8F%E9%A1%8C%E3%82%92%E6%8A%B1%E3%81%88%E3%81%A6%E3%81%84%E3%82%8B">プロダクトによって解決される問題を抱えている</a></h3> <p>プロダクトがなぜ成立しているのかといえば、何かしらの問題を解決しているからです。Airbnbでいえば、住んでいる家にいらない空きスペースがあるけど、有効活用できないという問題(ホスト視点)を解決していることになります。こうした家に過剰スペースを持っていて、「どうするか・・・」と考えている人たちにヒアリングしても何か見えてくるものがありそうですね。</p> <h2 id="どんなことを聞けば良いのか?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%81%93%E3%81%A8%E3%82%92%E8%81%9E%E3%81%91%E3%81%B0%E8%89%AF%E3%81%84%E3%81%AE%E3%81%8B%EF%BC%9F">どんなことを聞けば良いのか?</a></h2> <p>ユーザーと話すときに勘違いされがちになっているのが、アイデアを検証するために色々と用意してしまうことです。「これはしますよね?」、「あれはしますか?」とまるで誘導尋問のように質問をして、YESと答えれば、「よし、仮説は検証された!」と思ってはりきってしまうパターンです。ユーザーと話す最大の目的とは、そこからアイデアを得ることです。話していくなかで、もっと使ってもらえそう、改善した方が良いなと思うことを書き留めていくのです。</p> <p>実際に会う場合には、質問事項とかを用意しなきゃ失礼かと思うかもしれませんが、大事なのはユーザーがどんな人なのかを知ることだったりもして、雑談をしているくらいの方が良いアイデアを思い浮かぶかもしれません。ユーザーがどんな生活をしているか聞いて、この隙間の時間ならサービスを使ってもらえるかもしれないと、相手の話をヒントに組み立てていくんです。</p> <h2 id="もう普通の人ヒアリングはやめよ"><a href="#%E3%82%82%E3%81%86%E6%99%AE%E9%80%9A%E3%81%AE%E4%BA%BA%E3%83%92%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AF%E3%82%84%E3%82%81%E3%82%88">もう普通の人ヒアリングはやめよ</a></h2> <p>アンケート的なものと、ヒアリングは別物ですね。アンケートって、何万何十万の意見を集計して少しは説得力が出てくるかもですが、周りの友達数人に聞いたことってアンケートでも何でもなくて、もちろんヒアリングでもありません!</p> <p>一度、友人にペットのSNSを作るからヒアリングに乗ってくれと言われたのですが、ペットを飼っていない僕にそれを聞いても何にも参考にならないですよね。というか、むしろ雑音が反映されてしまうので、かえってマイナス効果が強いんだと思います。</p> <p>一般的な機能や、パッとした見た目について聞くぐらいは良いと思いますが、サービスの根幹に関わるところを普通の人に聞くのは危険です!万人受けするサービスを作るのは後で良いので、まずは最初の100人に愛されるサービスを作っていきましょ。</p> <h2 id="一番のユーザーはあなたであるべきかも"><a href="#%E4%B8%80%E7%95%AA%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AF%E3%81%82%E3%81%AA%E3%81%9F%E3%81%A7%E3%81%82%E3%82%8B%E3%81%B9%E3%81%8D%E3%81%8B%E3%82%82">一番のユーザーはあなたであるべきかも</a></h2> <p>Aribnbの例に戻ると、彼らはサンフランシスコという立地で高い家賃を払うことに苦しんでいました。だったら、「ロフトの空きスペースにマットレスを敷いて、お金を稼げるんじゃないか?」と思いつき、実際にそれで人を募集したところ、泊まる人が現れたことからサービスをスタートしました。</p> <p>まずは、自分が緊急性の高い問題を抱えていて、他のやり方で何とか補完しているけど、これでは不足だと感じていることがないか考えてみませんか。それを解決するプロダクトを作るなら、ユーザーヒアリングは最初のうちは自問自答すれば良いわけですからね。モチベーションも高まりながら、プロダクト開発を続けられるはず!</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>ちょっと今日の記事は「こうすべき!」みたいな強調が多くなってしまったかもしれません。。僕自身がこれまでユーザーヒアリングに失敗してきたので、ちゃんと失敗から学ばなきゃなとずっと思ってきた分、そういう口調になってきたかもです。どのパターンが正解かどうかは、それぞれのケースにもよると思うので、参考程度にしていただければと思います!</p> <p><a target="_blank" rel="nofollow noopener" href="http://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d08690390837.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d08690390837.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15122 2019-06-18T10:06:23+09:00 2019-06-18T10:07:06+09:00 https://crieit.net/posts/WPF 【WPF】自作カレンダー その1(とりあえず当月を表示) <p>WPFには、カレンダーコントロールが標準であるんですが、<br /> スケジューラ-みたいなことはできないし、あくまで選択された日付を取得するためのものになっています。</p> <p>常に表示して、カレンダーに対してアクションするようなコントローラーも<br /> 需要はあると思うので、標準で使えるようにしてくれればいいのにと思いながらちょっと自作してみます。</p> <p>今回は新規で専用にプロジェクトを作成します。</p> <h2 id="プロジェクト作成"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E4%BD%9C%E6%88%90">プロジェクト作成</a></h2> <p>VisualStudio2017を起動し、<br /> 新規プロジェクトを作成、名前を「CalendarSample」とします。</p> <p>作成方法などは下記の記事を参考にしていただければ。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/05/02/post-453/" target="_blank" rel="noopener noreferrer" data-blogcard="1">Visual Studio 2017 Community のインストールから Hello World</a></p> <p>また、スタイルに「MahApps.Metro」を利用するので、<br /> 分からなければこちらの記事を参考にしてください。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/07/27/post-1871/" target="_blank" rel="noopener noreferrer" data-blogcard="1">【WPF】MahApps.Metro で見た目をスタイリッシュにしてみる</a></p> <h2 id="プログラム実装"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E5%AE%9F%E8%A3%85">プログラム実装</a></h2> <h3 id="スタイルの設定"><a href="#%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A">スタイルの設定</a></h3> <p>App.xaml</p> <pre><code class="xml"><Application x:Class="CalendarSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CalendarSample" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> <!-- Accent and AppTheme setting --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application> </code></pre> <p>MahApps.Metroのスタイル設定を記述します。</p> <p>StyleDic.xaml</p> <pre><code class="xml"><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:local="clr-namespace:WpfApp1.Style"> <!-- グループ:通常--> <Style x:Key="gp-normal" TargetType="GroupBox" > <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="Background" Value="#FFFFFFFF" /> <Setter Property="Foreground" Value="#FF777777" /> </Style> </ResourceDictionary> </code></pre> <p>プロジェクト直下に「Style」ディレクトリを追加し、上記ファイルを作成します。</p> <h3 id="画面の作成"><a href="#%E7%94%BB%E9%9D%A2%E3%81%AE%E4%BD%9C%E6%88%90">画面の作成</a></h3> <p>MainWindow.xaml</p> <pre><code class="xml"><Mah:MetroWindow x:Class="CalendarSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:CalendarSample" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" GlowBrush="{DynamicResource AccentColorBrush}" mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="カレンダーサンプル" Height="350" Width="525"> <Window.Resources> <ResourceDictionary Source="/Style/StyleDic.xaml"/> </Window.Resources> <Grid> <GroupBox x:Name="CalendarGropu1" Header="" HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" Style="{StaticResource gp-normal}"> <Grid x:Name="CalendarGrid" HorizontalAlignment="Left" Height="258" Margin="10,10,0,0" VerticalAlignment="Top" Width="467"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="20" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> </Grid.RowDefinitions> <Rectangle Stroke="Black" StrokeThickness="1" Grid.ColumnSpan="7" Grid.RowSpan="7"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0" /> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="2" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="3" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="4" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="5" VerticalAlignment="Stretch" Margin="1 1 0 0" Panel.ZIndex="0"/> <Rectangle Fill="#ff8000" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="6" VerticalAlignment="Stretch" Margin="1 1 1 0" Panel.ZIndex="0"/> <Rectangle Height="1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Bottom" Grid.ColumnSpan="7"/> <Label Content="日" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="月" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="火" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="水" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="木" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="4" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="金" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="5" VerticalAlignment="Center" FontSize="11" Padding="0"/> <Label Content="土" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="6" VerticalAlignment="Center" FontSize="11" Padding="0"/> </Grid> </GroupBox> </Grid> </Mah:MetroWindow> </code></pre> <h3 id="コードビハインドの実装"><a href="#%E3%82%B3%E3%83%BC%E3%83%89%E3%83%93%E3%83%8F%E3%82%A4%E3%83%B3%E3%83%89%E3%81%AE%E5%AE%9F%E8%A3%85">コードビハインドの実装</a></h3> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using MahApps.Metro.Controls; namespace CalendarSample { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : MetroWindow { private Rectangle selectedRec; public MainWindow() { InitializeComponent(); CalendarGropu1.Header = String.Format("{0:yyyy年MM月}", DateTime.Now); // 当月の月初を取得 var firstDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); // 曜日番号の取得 int dayOfWeek = (int)firstDate.DayOfWeek; // 月末を取得 int lastDay = firstDate.AddMonths(1).AddDays(-1).Day; // 1日から月末までを走査 for (int day = 1; day <= lastDay; day++) { // セル位置 int index = (day - 1) + dayOfWeek; // 横位置 int x = index % 7; // 縦位置 int y = index / 7; // 土日は文字色を変更する Color color = Colors.Black; if (x == 0) { color = Colors.Red; } else if (x == 6) { color = Colors.Blue; } // テキストブロックを生成してグリッドに追加 var tb = new TextBlock() { Text = string.Format("{0}", day), FontSize = 12, Foreground = new SolidColorBrush(color), Padding = new Thickness(0, 10, 10, 0), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top }; this.CalendarGrid.Children.Add(tb); tb.SetValue(Grid.ColumnProperty, x); tb.SetValue(Grid.RowProperty, y + 1); // 四角形を生成してグリッドに追加 // セルの枠線などを表示し、イベントをハンドリングする用 var rec = new Rectangle(); rec.HorizontalAlignment = HorizontalAlignment.Stretch; rec.VerticalAlignment = VerticalAlignment.Stretch; // 背景色を設定しないとイベントを検知できないらしいので透過色を設定 rec.Fill = Brushes.Transparent; // 枠線を調整 rec.Margin = (x == 6) ? new Thickness(0.0, -1.0, 0.0, 0.0) : new Thickness(0.0, -1.0, -1.0, 0.0); // イベント設定 rec.MouseLeftButtonDown += date_MouseLeftButtonDown; this.CalendarGrid.Children.Add(rec); rec.SetValue(Grid.ColumnProperty, x); rec.SetValue(Grid.RowProperty, y + 1); } } /// <summary> /// セル(日)をクリックした際のイベントハンドラ. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void date_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 既に選択されたセルがある場合は初期化 if (selectedRec != null) { selectedRec.StrokeDashArray = null; selectedRec.StrokeThickness = 0; } // 枠線に点線をセット Rectangle rec = sender as Rectangle; rec.Stroke = Brushes.Black; DoubleCollection dbc = new DoubleCollection(); dbc.Add(1); dbc.Add(1); rec.StrokeDashArray = dbc; rec.StrokeThickness = 1; // 選択セルの保持 selectedRec = rec; } } } </code></pre> <p>ポイントは、<br /> 「Grid」を使い枠組みを作成してセルに日付用の「Rectangle」、「TextBlock」を配置することです。</p> <h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/10/WpfCalendar000.jpg" alt="image" /></p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/10/WpfCalendar001.jpg" alt="image" /></p> <p>日付セルをクリックすると、枠に点線が表示されるようにしました。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>今回はここまでとなります。</p> <p>次回以降、このカレンダーを使って色々試してみたいと思います。</p> <p>ではでは。</p> doraxdora tag:crieit.net,2005:PublicArticle/15115 2019-06-17T08:38:32+09:00 2019-06-17T08:45:58+09:00 https://crieit.net/posts/a25f333c2170dd797dfbfe0308335d9d 作って終わらない!スケールしないことをしよう! <p><a href="https://crieit.now.sh/upload_images/cccef3be44c0107231dad681112a13d25d06d08d3664b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cccef3be44c0107231dad681112a13d25d06d08d3664b.png?mw=700" alt="scale.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>プロダクトを作るのって楽しいですよね。で、いよいよリリースってなるとワクワクします!でも、リリースして1,2人がサインアップして使われない、みたいな状態になると、本当ショックでそのまま放置・・・。このサイクルを何巡もしちゃってませんか?そうならないためにも、確かに最初のアイデアはすごく大事なんですけど、出してすぐに使われなかったからといって、それがダメなアイデアであるとは限らないです。</p> <p>今や知らない人がいない民泊サービスのパイオニアAirbnbも、最初の一年は泣かず飛ばずで、クレジットカードで資金調達をしていたというエピソードもあるほどです。(笑)リリースしてまずやらなければいけないことって何でしょうか?それを考えないまま、リリースすると結局、「ダメだった。。」と気落ちしてしまうわけですね。</p> <p>リリースしてから(もしくは、リリース前でもOK)、僕たちがやることはズバリ「スケールしないこと」が良いとされています。Y Combinatorという、AirbnbやStripe、Dropboxを輩出したアクセラレーターでは、この「<a target="_blank" rel="nofollow noopener" href="https://postd.cc/do-things-that-dont-scale/">スケールしないことをしよう</a>」を第一のアドバイスとして起業家に伝えています。</p> <p>スケールしないことというのは、その言葉の通り、ユーザーが爆伸びするようなことを狙ってやるのではなく、その行為をしたことでユーザーが一気に増えることはないけど、プロダクトそのものを改善する一助になることを指してます。</p> <p>ユーザーヒアリングとかそうじゃないですかね。使っているユーザーに、なぜ使っているのか、どうすればお金を払ってくれるのかを聞くみたいな。ユーザーヒアリングについては、また次回とかに詳しく書こうかなと思っています!</p> <p>で、スケールしないことってどんなこと?って思いますよね。こういうのは具体例をいっぱい見た方が参考になると思うので、いくつかスケールしないことの事例を紹介していこうかなと思います!</p> <h2 id="スケールしないことの事例"><a href="#%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%97%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%AE%E4%BA%8B%E4%BE%8B">スケールしないことの事例</a></h2> <h3 id="Stripe"><a href="#Stripe">Stripe</a></h3> <p>一番有名な事例から紹介します。Stripeといえば、決済のAPIを提供しているスタートアップですね。パトリックコリソンと、ジョンコリソンの双子が作ったんですけど、YCに伝わる有名な諺に「コリソンインストレーション」があります。これは、コリソンが実際に会って誰かにStripeの紹介をした時に、相手が「良いサービスだね、使ってみるよ!」と答えると、「ありがとうございます。では、パソコンを貸してください。」と言って、その場でパソコンにStripeをインストールしたやり方です。</p> <p>普通だったら、「ありがとうございます。じゃあリンク送っておきますね。」ですよね。その場でインストールしてもらうという一見強引だけど、確実にユーザーに使ってもらえる方法をやっていたわけです。</p> <h3 id="Airbnb"><a href="#Airbnb">Airbnb</a></h3> <p>Airbnbは典型的な「スケールしないこと」をして這い上がったスタートアップの一つです。リリースして当初、創業者たち自らがホストをしてる家に宿泊しに行き、写真を撮影して回っていったのです。一軒、一軒訪れて。YCではプログラムが行われている時に、週一で会食があったそうですが、いつも彼らはスーツケースをガラガラ引いて会合に参加していたそうです。また、ブライアンチェスキーはいつもヘッドセットを着用して自らがカスタマーサポートを担当していたそうです。素晴らしい。</p> <h3 id="Pinterest"><a href="#Pinterest">Pinterest</a></h3> <p>お気に入りの画像やアイデアをピンで保存しておけるサービス、Pinterest。彼らが最初にしたことは、デザイナーたちの会合に出かけて自分たちのサービスを広めることでした。また、自らが運営で写真のミートアップを開くなど、Webのサービスだけど、現実世界でユーザーを増やしていきました。特に好きなエピソードが、ベンシルバーマンが毎日Appleストアに赴いて、怒られるまで、置いてあるPCのスタート画面をPinterestに変え続けたことですw</p> <h3 id="Meraki"><a href="#Meraki">Meraki</a></h3> <p>Merakiはルーターの会社で、やがてCiscoに買収されました。彼らはルーターをいきなり外注で依頼することなく、最初は自分たちの手づくりでルーターを作って売っていました。また、これに続いてスマートウォッチのPebbleも最初の100台を自分たちで作って売っていたそうです。ハードウェアってビジネスにするの大変そうですが、最初は自分たちで作って売ればコストは抑えてスタートできそうですね!</p> <h3 id="Tinder"><a href="#Tinder">Tinder</a></h3> <p>ホットオアノットで、男女の出会いを実現してくれるTinderは、最初大学のサークル一つ一つずつ営業をかけて、アプリをダウンロードしてくれるように促進したそうです。使ってくれそうなユーザーに対して直談判して進んでいくやり方ですね。</p> <h3 id="Wufoo"><a href="#Wufoo">Wufoo</a></h3> <p>このエピソードがすごく好きです。Wufooは、Googleフォームのようなフォームを簡単に作成できるツールを作っていました。(Survey Monkeyが買収)彼らは最初に使ってくれたユーザーに対して一人一人手書きの感謝状を書いて送っていたのです。結構、USのサービスはこういうやり方をする企業が増えてますが、その先駆けがWufooでした!</p> <h2 id="スケールすることもしよう"><a href="#%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E3%81%97%E3%82%88%E3%81%86">スケールすることもしよう</a></h2> <p>スケールしないことをすることは、すごく大事ですが、同時並行もしくは、遅れてスケールをすることも仕込んでいくのが良いかなと思います。いわゆる、グロースハックというやつですね。多くのハックは、技術を伴うので、開発者には有利な戦法かなと!</p> <h3 id="Dropbox"><a href="#Dropbox">Dropbox</a></h3> <p>リファラルキャンペーンを大々的にやり始めた、最初の会社です。今や当たり前になったリファラルキャンペーン(友達を紹介するとクーポンがもらえる、無料になるみたいな)。Dropboxはこのやり方で、15ヶ月で400万人のユーザーを獲得しました。</p> <h3 id="Airbnb"><a href="#Airbnb">Airbnb</a></h3> <p>Airbnbは、民泊の物件を投稿する際にクラシファイドサイトのCraiglistにも同時投稿する機能を加えました。Craiglisthは、Airbnbが誕生するずっと前から存在する何でも屋のようなサイトで、実際にAirbnbと似たような掲示板(ホームスワッピング)のようなのがありました。後からこれがバレて、Craiglistにバンされたそうですが、工夫を凝らしたやり方ですよね!</p> <h3 id="Pinterest"><a href="#Pinterest">Pinterest</a></h3> <p>「Pin it Forward」キャンペーンを実施して、ユーザーを増やすことに成功しました。ピンタレストは、著名なブロガーとパートナーを組み、ブロガーコミュニティの中でピンタレストを紹介するような運動を扇動しました。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>サービスの育て方を知らない僕たちは作って終わりになりがちです、運が良ければバズって終わり。でも、僕たちがやれることってまだまだ残されているっていうのが、こうした事例を見ている勇気が湧いてきませんか?今や世界中のユーザーに使われているあんな企業や、こんな企業も最初はこんなにも地道に頑張ってたわけです。</p> <p>そして、マーケットハックはそれはそれで面白そうだし。熱中しているあいだに、新しいツールとかも思いつきそうですよね!そんなわけで、こういうマーケティング事例とか、<a target="_blank" rel="nofollow noopener" href="easthackers.com">アイデアをお互いに密にシェアできるオンラインサロン</a>をやってくので、よろしくお願いします!(さりげなく宣伝するのムズイ!)</p> <p><a target="_blank" rel="nofollow noopener" href="http://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d2caae42d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d2caae42d.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15110 2019-06-16T08:21:10+09:00 2019-06-17T08:40:46+09:00 https://crieit.net/posts/MVP プロダクト開発におけるMVPをちゃんと考える <p><a href="https://crieit.now.sh/upload_images/de08736b9fba0dce0cc8fe076e898b1b5d057d5d61810.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/de08736b9fba0dce0cc8fe076e898b1b5d057d5d61810.png?mw=700" alt="mvp.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>MVPって知ってますか?バスケや野球で選手が表彰される方じゃなくて、スタートアップやプロダクト開発の場面でよく言われる方です。MVPは、Most Viable Productの略で、実用最低限に実装されたプロダクトのことを言います。2010年あたりに、エリックリースが「<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B00F3UTIQY/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1">リーンスタートアップ!</a>」という本の中で、まずプロダクトの工数を見積もって開発を進める前に、このプロダクト本当にいけるんか?!っていうところをちゃんと検証してから、プロダクト開発に着手しようという理論です。</p> <p>分かりやすく言えば、プロダクトがいけるかどうかを確かめるために、コードなんて書く必要がないってことです。いけるならやればいいし、いけそうにないなら止める。普通、アプリ作ろうと思ったら、何ヶ月もかかるし、お金も時間も奪われますよね。それでダメだって分かったら、これまでのコスト(涙)ってなる。だから、これを最低限に抑えようぜっていうのが、MVP。スタートアップや個人開発のように、リソースが限られている僕らには知って損はないやり方なのかなって思います。</p> <h2 id="どんなのがMVPっていうのか?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%81%AE%E3%81%8CMVP%E3%81%A3%E3%81%A6%E3%81%84%E3%81%86%E3%81%AE%E3%81%8B%EF%BC%9F">どんなのがMVPっていうのか?</a></h2> <p>主に海外の事例になりますが、「これぞ!MVP」というものを幾つか紹介していきますね。</p> <h3 id="Dropbox"><a href="#Dropbox">Dropbox</a></h3> <p><a href="https://crieit.now.sh/upload_images/9a62bbf803b9b3be5f218f044e83fbb65d057c19b0b2e.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9a62bbf803b9b3be5f218f044e83fbb65d057c19b0b2e.jpg?mw=700" alt="dropbox.jpg" /></a><br /> MVPの事例を探したとき、一番初めにヒットするのがDropboxですね。Dropboxはプロダクト開発をしている最中に、デモンストレーションのビデオを作り、HackerNewsに投稿したことで75,000の事前登録者を獲得することに成功します。サービスを出す前にこれだけ登録者を得られるってすごいですよね。やる気上がりそう。</p> <h3 id="ProductHunt"><a href="#ProductHunt">ProductHunt</a></h3> <p><a href="https://crieit.now.sh/upload_images/76660b7f2f7c65a434411fe9143435d75d057c25c0058.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/76660b7f2f7c65a434411fe9143435d75d057c25c0058.png?mw=700" alt="producthunt.png" /></a><br /> 今や開発者コミュニティの代表的サイトとなった、ProductHunt。実は創業者のRyanは開発者でもなければ、共同創業者も持たないというバックグラウンド。彼が最初に始めたのはニュースレターでした。投資家や創業者に対して、自分が探したプロダクトの最新情報をメールで送っていたのですね。</p> <h3 id="Buffer"><a href="#Buffer">Buffer</a></h3> <p><a href="https://crieit.now.sh/upload_images/ed911ec77c7ec1332f5d1c89a1bb2fed5d057c3874f33.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ed911ec77c7ec1332f5d1c89a1bb2fed5d057c3874f33.jpg?mw=700" alt="buffer.jpg" /></a><br /> Bufferは、SNS予約投稿ツールとして不動の地位を築いています。彼らはリリース前に、こういうサービスを作ろうと思っているよ!というランディングページを用意し、事前登録者を誘いました。登録者が増えるたびに、幾らだったら払うかみたいな検証も少しずつ加えていって、プロダクトの検証を進めました。(LPは会議のアイデア機能でも作れるのでぜひ!)</p> <h3 id="Zappos"><a href="#Zappos">Zappos</a></h3> <p><a href="https://crieit.now.sh/upload_images/23e3e9158a37f6454b69fdae7832fc185d057c621c7f3.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/23e3e9158a37f6454b69fdae7832fc185d057c621c7f3.jpg?mw=700" alt="zappos.jpg" /></a><br /> カスタマーサポートの神として崇められているオンライン靴ECのZapposも、最初はコストを欠けずに経営していました。彼らは、簡単なホームページを作成し、靴の写真を並べて、在庫は持ちませんでした。ページ上で靴が売れたら、経営者本人が靴を買いにいって配送するという仕組み。</p> <h3 id="Uber"><a href="#Uber">Uber</a></h3> <p><a href="https://crieit.now.sh/upload_images/879e801a7ad436c3dfd4606d7e76166a5d057c755286f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/879e801a7ad436c3dfd4606d7e76166a5d057c755286f.png?mw=700" alt="uber.png" /></a><br /> 最近上場した白タクサービスのUberも、リリース時はあんなに立派な位置情報は用いておらず、SMSで近くの車を呼ぶ仕組みでサービスを成立させていました。また、最初は創業者たち自らが車を控えていて、運転手をやっていたそうです。</p> <p>MVPは、有名サイトのURLをアーカイブで検索して、リリース頃まで巻き戻れば見れるので結構勉強になりますよ〜。</p> <h2 id="ちゃんと考える"><a href="#%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E8%80%83%E3%81%88%E3%82%8B">ちゃんと考える</a></h2> <p>Facebookのマークザッカーバーグも「完璧よりも、まず終わらせろ!」って言ってるし、Linkedinのリードホフマンも「v1.0は恥ずかしいくらいで良い」って言ってます。もうまさに世の中MVP万歳!みたいな空気になってるけど、果たしてそうなんでしょうか。</p> <p>これだけMVPの良さや事例を書いてきたのですが、僕個人としてはMVPの考えに対して半分賛成、半分懐疑的に受け止めています。どうしてかという理由は2つあって、1つはMVPでダメだったからといって諦めるべきなのかと、MVPでうまくいったら本当にうまくいくかどうか、です。</p> <p>MVPでダメだったからといって諦める理由になり得ないという点から話していきましょう。ランディングページを出した時点では、そんなに人を集められることができなくても、実際にアプリを出してみたら、バズって多くの人に使ってもらえることになったというのもなくはないのではないでしょうか。</p> <p>例えば、<a target="_blank" rel="nofollow noopener" href="https://devmart.jp/">フリマ</a>もTwitterで事前登録を募集した際にはそんなに良き反応なかったんですけど、えいやで作ってみたら、出して初週から成約したり、多くの開発者の方々に出品をしていただけることになった。もちろん、まだまだ成功といえるには程遠いんですが、事前登録を出した時とは思いもよらぬ結果になったのは事実です。</p> <p>Bufferや、Dropboxの例は興味深いんですけど、LPのようなものを出す場合にはMVPよりもマーケティング的な要素が強いんじゃないかなとも思っています。ただ、そこから事前登録したユーザーの声とか聞いていくと、だんだん検証が取れていくのかもしれませんが。</p> <p>もう一つの点が、MVPでうまくいったら本当にうまくいくかどうかという点です。いいね!と、本当にお金払うは全然気持ちが違います。無料だったら使う人や、事前登録だったら登録する人はいても、実際にお金を払ってまで使うという人の属性とは違うと思うのです。1000いいね!をもらって誰もお金を払わないプロダクトよりも、0いいね!で10人の顧客がいる方がうまくいっているように思いませんか?</p> <p>つまり、この2点に対しての僕なりの答えは、MVPは完成品の延長線上にあるべきということです。もし、ECだったらMVPの段階からモノを売るべきだし、SaaSだったら最初からお金を払って使ってもらうべきだと思います。フリーミアムって考え方はあんまり好きじゃないんですよね。MVPのVは、顧客から実用(Viable)ですが、開発者からすると検証可能(Validatable)っていうことです。</p> <h2 id="もっとちゃんと考える"><a href="#%E3%82%82%E3%81%A3%E3%81%A8%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E8%80%83%E3%81%88%E3%82%8B">もっとちゃんと考える</a></h2> <p>ここまでは理論の話でした。コストを最低限に抑えて、いけるかどうかの検証ができるのがMVPです。ですが、顧客からしたら「知らねーよ」って話ってわけです。自分が顧客だったら、不完全なものよりも完全なものを使いたがるだろうし、開発者側のテストに付き合うつもりは毛頭ないのです。だから、MVPの段階からちゃんと顧客の欲しいものを作る必要があります。<br /> <a href="https://crieit.now.sh/upload_images/b5c55578618abff087b601b2c7a418715d057d04a0349.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b5c55578618abff087b601b2c7a418715d057d04a0349.jpg?mw=700" alt="how-to-build-a-minimum-viable-product.jpg" /></a><br /> ここでいうスケートボードを目指したいですよね。スケートボードを使えば、歩くよりも早く移動できるし、車よりも使い方もシンプルで分かりやすい。もちろん、作るにあたっても車よりずっとコストは削減できる。<br /> MVPは、ちゃんと顧客が使う一番の理由を抑えつつ、それをいかに最低コストで開発できるかを考えて開発することなんですね、多分。</p> <p>少し自分のことを補足すると、冒頭でコードを書かないってことを書いたのですが、そこは本質ではないので無視しても良いと思ってます。僕も開発者なので、むしろコードを書いた方が早い時の方がMVPを素早く作れたりすることの方が多いですし。だいたい、一週間で作れるかどうかをMVPになり得るかどうかで判断していますね。</p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>ちょっと最後無理やりまとめた感もありますが、結構海外には成功したスタートアップの創業者たちが、唸るレベルの記事をたくさん残してくれていて参考になるし、勇気が湧いてきます。そういう記事をたくさんシェアしていこうと思っているのが、<a target="_blank" rel="nofollow noopener" href="http://easthackers.com">世界中のユーザーに愛されるプロダクトを作るオンラインサロン「East Hackers」</a>です。6/24にスタートするので、ぜひ事前登録お待ちしてます!(これはMVP!そして宣伝!!)</p> <p><a target="_blank" rel="nofollow noopener" href="https://easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d358cd934.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d358cd934.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15108 2019-06-15T10:56:51+09:00 2019-06-17T08:39:18+09:00 https://crieit.net/posts/a79d49290e0b849d68cae28b74c1f285 個人開発でアイデアを出す方法 <p><a href="https://crieit.now.sh/upload_images/e907e0efb5d7f4980a6d19d0bc2714e55d044fa75e48e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e907e0efb5d7f4980a6d19d0bc2714e55d044fa75e48e.png?mw=700" alt="idea.png" /></a></p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>個人開発のアイデアを出すのって難しいですよね。厳密に言えば、正しいアイデアを出すのがすごく難しいと思います!「これは絶対イケる!」と思って、今まで散々プロダクトを出してきた人も、期待はずれの結果に苦しめられてきたかと。大丈夫です、僕もその一人です。</p> <p>デザインや、細かい機能部分については後からでも変えられますが、根っことなるアイデア部分って取り返しがつかないやつです。だからこそ、ヒットするプロダクトを作るためにはアイデア出しがすごく大切なんですよね。<br /> でも、無理やり出そうとすると、決して良いものは出てこないし、自然に出てきたアイデアがベターだと思うんです。</p> <p>Y CombinatorをつくったPGも「<a target="_blank" rel="nofollow noopener" href="http://www.paulgraham.com/startupideas.html">正しいアイデアを出そうとするんじゃなくて、正しいアイデアを出せる人物になれ</a>」とか無茶振りを言っています。(このエッセイはなんども読み返す価値ありです!)今回は、僕が失敗や、上手くいった人たちの経験談を読んで、「確かに。これは当たってそう!」と感じたアイデアを得る方法を紹介していければなと。</p> <h2 id="自分自身が望むモノを作る"><a href="#%E8%87%AA%E5%88%86%E8%87%AA%E8%BA%AB%E3%81%8C%E6%9C%9B%E3%82%80%E3%83%A2%E3%83%8E%E3%82%92%E4%BD%9C%E3%82%8B">自分自身が望むモノを作る</a></h2> <p>鉄板ですよね。自分が欲しいから作る理論。でも、気をつけなければならないのが殆どの開発者が「自分が作りたいものを作ってしまっている」点ですね。React Native使ってみたいからスマホアプリ!Solidity触ってみたいからブロックチェーンのサービス作ってみるぞ!これは、自分が欲しいからではなく、作りたいから作っているわけですね。</p> <p>別に作ること自体が悪いわけではないですし、勉強として個人開発をやるには凄く良いモチベーションかと思います!ただ、他の人に作ったサービスを提供しても、使う理由があまりないです。。だから、ちゃんと自分が欲しいものを作りましょう!</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B07DXKCR83/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1">エンジェル投資家</a>のジェイソン氏は、欲しいものの例を分かりやすく「ビタミン」と、「鎮痛剤」と比喩してました。これは何かというと、ビタミンは毎日食べてると体が良くなるもの、アイデアのジャンルでいうと、メディアとか、ミニアプリ系がこれに当たりそう。Youtubeとかまさにじゃないですかね。なくて生活困るわけじゃないけど、あると毎日ハッピーになるみたいな!(Youtuberにとっては稼ぎ口なのでなくてはならないものかもしれませんが)鎮痛剤は、言葉通り、痛みに効くアイデアですね。何か困っていることがあって、これを解決するために作るようなイメージですね。Dropboxとか、Gmailとか始めツール系はその性質が強いぽいです。ちなみに、Dropboxは、創業者のドリューヒューストン宿題の論文をUSBに入れて大学でプリントアウトしようと思った時に、家にUSBを忘れたことに気づき、「ファイルはクラウド上にあるべきだ!」と痛みを感じて作り始めたそうです。彼は一人でDropboxの原型を作ったので個人開発の鏡です!</p> <p>つまりは、自分が困っていたり、あると良いなと思うものを、もっと言えば<strong>お金を払ってもよいかどうか</strong>を考えて、YES!というものを作る方法です。あんまり技術どうこうは考えなくても良いと思います。</p> <h2 id="身近な人が困っている課題を解決する"><a href="#%E8%BA%AB%E8%BF%91%E3%81%AA%E4%BA%BA%E3%81%8C%E5%9B%B0%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E8%AA%B2%E9%A1%8C%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B">身近な人が困っている課題を解決する</a></h2> <p>ただ、課題!課題!ってなってると、課題って見つからないんですよね。世の中、特に日本ってすごく便利な国で、たいていのものは既に解決されてるんです。自分で課題が見つけられない場合は、身の回りの人が困っていることを解決しあげるというのはどうでしょうか?</p> <p>これの良いところは、1つめで話したような「欲しいものではなく、作りたいものを作ってしまう」症候群を避けることができる点です。身近な人は近ければ、近いほど良いと思っています。そして、もっと言えば専門的であればあるほど良いですよね。</p> <p>例えば、看護師をやっている友だちのスケジュール調整の問題を解決するとか、Youtubeで動画投稿をはじめた友だちがもっと簡単に動画編集できるソフトを作るとか。ただ、自分の問題ではない分、どこまで続けていくモチベーションを保てられるかが勝負になってくると思われます。。</p> <h2 id="誰かにやって欲しい面倒事に取り組む"><a href="#%E8%AA%B0%E3%81%8B%E3%81%AB%E3%82%84%E3%81%A3%E3%81%A6%E6%AC%B2%E3%81%97%E3%81%84%E9%9D%A2%E5%80%92%E4%BA%8B%E3%81%AB%E5%8F%96%E3%82%8A%E7%B5%84%E3%82%80">誰かにやって欲しい面倒事に取り組む</a></h2> <p>個人的には、これが一番好きです。これまた、<a target="_blank" rel="nofollow noopener" href="http://www.paulgraham.com/schlep.html">PGのエッセイ</a>から引用したものなのですが。みんながやりたくないことを進んでやる、つまり自分はやりたくないから誰か他の人にやってもらいたいなというアイデアを選ぶ方法です。</p> <p>典型例が、Stripeです。Stripeは、開発者ならご存知な方も多いと思いますが、決済の仕組みをAPIで提供しているサービス。今でこそ、当たり前になっている決済サービスづくりですが、Stripeがなければ個人開発で決済導入なんて面倒な極みです。その面倒を買って出てくれたのが、Stripeだったわけです。実際、作るのは面倒臭かったらしく、いろんな金融とか決済の会社にアポ取って、赴いて許可もらって、APIを実装していくみたいに進めていったそうです。</p> <p>個人開発のレベルでそのようなリソースを多分に使うことは難しいかもですが、ヒントとしては頭に入れておいても良いような気がします。日常で生きていると、結構ありませんか?「あ、この問題誰か解決してくれないかなー。」とか思うことって。行列に並んだり、レシートの整理だったり。</p> <h2 id="別の目標を設定して足りないモノを補完する"><a href="#%E5%88%A5%E3%81%AE%E7%9B%AE%E6%A8%99%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%A6%E8%B6%B3%E3%82%8A%E3%81%AA%E3%81%84%E3%83%A2%E3%83%8E%E3%82%92%E8%A3%9C%E5%AE%8C%E3%81%99%E3%82%8B">別の目標を設定して足りないモノを補完する</a></h2> <p>問題がないなら、問題を作れば良いのです!今の自分に満足していなければ、それって理想に対して何かが問題で満足していないということですよね。月収100万円だの、ダイエットでマイナス10キロとか、なんでも良いので目標を設定してみましょう。そこに辿り着くために、一番最適な方法を取ってみて、それができないなら何かが問題になっているはずです!これで、問題が生まれるわけです。</p> <p>月収100万円とか、ダイエットでマイナス10キロとかの目標って、個人的な目標というよりは、広く一般的にも望んでいる人が多そうじゃないですか?もし、こうした目標に対して、それを実現できるサービスを作ることができれば、それを目標にしている多くの人が使ってくれるという理論になりますね!</p> <h2 id="他のサービスを試してみる"><a href="#%E4%BB%96%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">他のサービスを試してみる</a></h2> <p>僕は、いつもこのやり方を取るようにしてます。他のサービスを使っていて不足だなとか、もっとこうできるんじゃないかなという形で自分のプロダクトを作る方法です。この発想を幅広で考えていくと、極論インターネットを使ったことがない人がインターネットのサービスを作ることってできないですよね。スマホも然り。</p> <p>僕らが普段使っているサービス、失敗や脅威を乗り越えて愛されている答えなわけです。そして、次のサービスって今のサービスの補完や、改善から生まれているように感じています。今までホテルっていう便利なサービスを使ってたけど、安くて、楽しく過ごせるなら人の家でもいいじゃんっていうのがAirbnbで、Uberをタクシーに対して同じことを行ないました。</p> <p>だから、今自分たちが常日頃から使っているサービス(Webサービスやアプリだけでなく)を本当にこれが最適解なの?って疑問を呈してみることで、新しいアイデアが生まれるんじゃないかなと思っています。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>「これがアイデアを出す方法や!」と書きましたが、ぶっちゃけ自分も上手いアイデアを出せたことはありません。だから、自分が気づいたことまでを紹介したって感じです!開発会議のインタビューとかで、開発者の方がどんなところからアイデアを思いついたか聞いているのですが、やっぱり身近なところを解決しようとするケースが多いかなって思います。</p> <p>今日から、24日まで学んだことをガンガン共有していきたいと思います!こんな感じでプロダクト開発のノウハウをぶつけ合いたいという方や、お前のアイデア出す方法甘い!俺はこんな感じで出してるぜ!って方は、<a target="_blank" rel="nofollow noopener" href="http://easthackers.com">世界中で愛されるプロダクトを作るためのオンラインサロン「East Hackers」</a>を始めるので、ぜひ覗きにいっていてくれると嬉しいですね!(これは宣伝!)</p> <p><a target="_blank" rel="nofollow noopener" href="easthackers.com"><a href="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d31e75563.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5244895fc48a7ddf0d45ea8d210cfab65d06d31e75563.png?mw=700" alt="og.png" /></a></a></p> FREERIDER tag:crieit.net,2005:PublicArticle/15062 2019-06-06T02:40:29+09:00 2019-06-06T02:42:32+09:00 https://crieit.net/posts/1-5cf7fe8d65c49 アニメーションについて1 <h2 id="前置き"><a href="#%E5%89%8D%E7%BD%AE%E3%81%8D">前置き</a></h2> <p>Unityを触る上でアニメーションはとても大事。らしい。<br /> <strong>ま僕アニメーション部分担当した事ないですがw</strong><br /> なので先ずはアニメーションの基礎知識を学ぶのが必要らしいので↓のサンプルを元に勉強して行く。<br /> (動作させた動画も撮ったけどどこにあげていいものかよく分からんので一旦保留。)</p> <h2 id="3DRunゲーム"><a href="#3DRun%E3%82%B2%E3%83%BC%E3%83%A0">3DRunゲーム</a></h2> <p><a href="https://crieit.now.sh/upload_images/51c1291d585b4555565f2d721e894d975cf7f6d608113.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/51c1291d585b4555565f2d721e894d975cf7f6d608113.png?mw=700" alt="スクリーンショット 2019-06-06 1.56.00.png" /></a><br /> (これ画像サイズ調節できる機能ないんか・・?)</p> <p>障害物をぴょんぴょん乗り越えて行くオートスクロール系の3Drun。<br /> これにはどんな技術が使われてるんだろうか。</p> <h2 id="Unityアニメーション基礎知識"><a href="#Unity%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98">Unityアニメーション基礎知識</a></h2> <h3 id="Mecanim(メカニム)"><a href="#Mecanim%EF%BC%88%E3%83%A1%E3%82%AB%E3%83%8B%E3%83%A0%EF%BC%89">Mecanim(メカニム)</a></h3> <p>・UnityにはMecanimと呼ばれるアニメーションシステムがある。<br /> ・Unity 4.0から導入されたアニメーションの機能。(ちなみに今はUnityの最新は2019)<br /> ・これ、スクリプト書かずにアニメーションが作れる(!?)らしい。</p> <h2 id="閑話"><a href="#%E9%96%91%E8%A9%B1">閑話</a></h2> <p>という事でMecanimを利用する事でプログラマーに頼らずアニメーション担当のスタッフだけでアニメーション部分の作成が可能なのだ!素晴らしい。分担って最高。</p> <p>という事で<strong>アニメーションについて</strong>では基本的にコードは書かず、<br /> Unityの機能Mecanimと仲良くなって行こうと思います。<br /> 本格的にUnityのAnimetorコンポーネントとか触って行くのはまた次回。</p> <p>Mecanimについての詳しい説明は<a target="_blank" rel="nofollow noopener" href="https://shade3d.jp/training/unity/tips_2.html">参考サイト</a>の方を見てください。ここに限らずググれば色々出てきます。多分触って覚えた方が分かりやすい感じですが。<br /> <strong>ってあれ?この参考サイトにアニメーションの作り方書いてある?w</strong></p> <p>^o^・・・</p> <p>ま、まぁ僕の方でもある程度掻い摘んで載せて行きます。<br /> 了</p> <h3 id="参考サイト"><a href="#%E5%8F%82%E8%80%83%E3%82%B5%E3%82%A4%E3%83%88">参考サイト</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://shade3d.jp/training/unity/tips_2.html">Mecanimについて</a></p> じょんむる tag:crieit.net,2005:PublicArticle/15060 2019-06-05T02:03:50+09:00 2019-06-05T02:14:48+09:00 https://crieit.net/posts/Unity-5cf6a4765192f Unityでゲーム作る(方針のみ) <h2 id="Unityでゲーム作りたい"><a href="#Unity%E3%81%A7%E3%82%B2%E3%83%BC%E3%83%A0%E4%BD%9C%E3%82%8A%E3%81%9F%E3%81%84">Unityでゲーム作りたい</a></h2> <p>「ゲーム作るかー」と思ってても中々やらんし、ゲーム案件最近触ってないんで勉強がてらやっていきます。<br /> 先ずは記事だけ。明日から触って行く。<br /> 暇があったら別記事でhtml5ゲームの方も作ります。今はunity。</p> <h2 id="技術とか知見になる予定のもの"><a href="#%E6%8A%80%E8%A1%93%E3%81%A8%E3%81%8B%E7%9F%A5%E8%A6%8B%E3%81%AB%E3%81%AA%E3%82%8B%E4%BA%88%E5%AE%9A%E3%81%AE%E3%82%82%E3%81%AE">技術とか知見になる予定のもの</a></h2> <ul> <li>Unity</li> <li>UniRx</li> <li>2D/3D</li> <li>AR/VR</li> </ul> <h2 id="閑話"><a href="#%E9%96%91%E8%A9%B1">閑話</a></h2> <blockquote> <p><strong>俺の考えてるゲーム絶対面白いのに作る時間ないが?</strong><br /> <strong>作り方わからんが?</strong></p> </blockquote> <p>と多少プログラム触ってきたけど「おし、作るか!」から「はい完成!」とはいかないゲーム。<br /> WebGL?iOS?Android?Steam?とかプラットフォーム選別から始めちゃうと「あ、だり」となってやらない事も多い。<br /> <strong>「Unityのチュートリアル一通りやったぞwふんw」</strong><br /> って人には不要な記事かもしれない。</p> <p>基本参考書の順番で作って行く。<br /> 2Dアクションゲームが本当は作りたいけど参考書の順番で作って行く。</p> <h2 id="参考書"><a href="#%E5%8F%82%E8%80%83%E6%9B%B8">参考書</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://www.borndigital.co.jp/book/6633.html">Unityゲーム プログラミング・バイブル</a></p> じょんむる tag:crieit.net,2005:PublicArticle/14739 2019-01-22T08:36:53+09:00 2019-01-22T08:36:53+09:00 https://crieit.net/posts/GatsbyJS-Markdown-5c465795f18c3 GatsbyJSでMarkdownの記事を表示させよう <h2 id="GatsbyJSでMarkdownの記事を表示させよう"><a href="#GatsbyJS%E3%81%A7Markdown%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%95%E3%81%9B%E3%82%88%E3%81%86">GatsbyJSでMarkdownの記事を表示させよう</a></h2> <p>Markdownファイルをそのまま表示させることは出来ません。<br /> そこで、Markdownファイルを表示するページを動的に生成する必要があります。<br /> Gatsbyでそのようなことをする場合はgatsby-node.jsを使います。<br /> やることは2つです。<br /> + onCreateNode<br /> + createPage<br /> onCreateNodeでslugを動的に生成します。(xxx.com/my1stpost/のmy1stpostにあたる部分)<br /> そのslugを元にtempleteファイルを作成し、createPageでpageを生成します。</p> <h2 id="gatsby-node.js"><a href="#gatsby-node.js">gatsby-node.js</a></h2> <pre><code>const path = require(`path`) const { createFilePath } = require(`gatsby-source-filesystem`) exports.createPages = ({ graphql, actions }) => { const { createPage } = actions return new Promise((resolve, reject) => { const blogPost = path.resolve(`./src/templates/blog-post.js`) // graphqlからデータの取得 resolve( graphql( ` { allMarkdownRemark( sort: { fields: [frontmatter___date], order: DESC } limit: 1000 ) { edges { node { fields { slug } frontmatter { title } } } } } ` ).then(result => { if (result.errors) { console.log(result.errors) reject(result.errors) } // 投稿ページの生成 const posts = result.data.allMarkdownRemark.edges posts.forEach((post, index) => { const previous = index === posts.length - 1 ? null : posts[index + 1].node const next = index === 0 ? null : posts[index - 1].node createPage({ path: post.node.fields.slug, component: blogPost, context: { slug: post.node.fields.slug, previous, next, }, }) }) }) ) }) } // slugの生成 exports.onCreateNode = ({ node, actions, getNode }) => { const { createNodeField } = actions if (node.internal.type === `MarkdownRemark`) { const value = createFilePath({ node, getNode }) createNodeField({ name: `slug`, node, value, }) } } </code></pre> <p>次にblog-post.jsを作っていきます。</p> <pre><code>import React from 'react' import { Link, graphql } from 'gatsby' import Layout from '../components/Layout' import SEO from '../components/seo' class BlogPostTemplate extends React.Component { render() { const post = this.props.data.markdownRemark const siteTitle = this.props.data.site.siteMetadata.title const { previous, next } = this.props.pageContext return ( <Layout location={this.props.location} title={siteTitle}> <SEO title={post.frontmatter.title} description={post.excerpt} /> <h1>{post.frontmatter.title}</h1> <p> {post.frontmatter.date} </p> <div dangerouslySetInnerHTML=<span>{</span><span>{</span> __html: post.html <span>}</span><span>}</span> /> <hr/> <ul> <li> {previous && ( <Link to={previous.fields.slug} rel="prev"> ← {previous.frontmatter.title} </Link> )} </li> <li> {next && ( <Link to={next.fields.slug} rel="next"> {next.frontmatter.title} → </Link> )} </li> </ul> </Layout> ) } } export default BlogPostTemplate export const pageQuery = graphql` query BlogPostBySlug($slug: String!) { site { siteMetadata { title author } } markdownRemark(fields: { slug: { eq: $slug } }) { id excerpt(pruneLength: 160) html frontmatter { title date(formatString: "MMMM DD, YYYY") } } } ` </code></pre> <p>これで準備が出来ました。</p> <h2 id="確認作業"><a href="#%E7%A2%BA%E8%AA%8D%E4%BD%9C%E6%A5%AD">確認作業</a></h2> <p>それでは確認作業をしてみましょう。<br /> <code>gatsby develop</code>でサーバーを立ち上げ<br /> <code>http://localhost:8000/a</code>にアクセスしてみましょう。<br /> <a href="https://crieit.now.sh/upload_images/cae4883c933fdf71d219e166f5abeec35c465767715ee.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cae4883c933fdf71d219e166f5abeec35c465767715ee.jpg?mw=700" alt="013.jpg" /></a><br /> 404と表示されますが上記のようにディレクトリが分かれているのがわかります。ちゃんと/my1stpost/があります。<br /> 早速、アクセスしてみましょう!<br /> <a href="https://crieit.now.sh/upload_images/ac6d362013e534c167c6333b6a3c25135c46578d1f79e.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ac6d362013e534c167c6333b6a3c25135c46578d1f79e.jpg?mw=700" alt="0131.jpg" /></a><br /> ちゃんと表示されていますね!お疲れ様でした。</p> aocory