Starry

プログラミングやクラウドについて

ruby on rails コマンド

コマンド

appnameを作成

rails new appname

  

cd appname

 

dbを作成

rake db:create

 

rails generate系でコマンドが応答しない時があるのでその時使用

spring stop

 

controllernameのcontorollerを作成その中でindexメソッドを作成する。

rails generate controller controllername index

 

modelnameのmodelを作成nameはフィールド名。idなどは作ってくれるので必要なし。

その後のdb:migrate必要

rails generate model modelname name:text

rails db:migrate

rails db:seed(seedを作ってる場合)

 

 

 

 

設計 掲示板作り

ruby on railsで何かポートフォリオを作ろうかと掲示板を作ろうかと思ったのですが、色々詰まったりしたので設計というか計画というかまぁそんな感じのものやっていきます。

基本的には4画面でトピック一覧ページ,トピック作成ページ,書き込み一覧ページ,書き込み作成ページ。


画面的機能で言うと、
トピック一覧ページ
トピック一覧表示(リンク付き)
新規トピック作成
ページネーション

トピック作成
トピック送信

書き込み一覧ページ
トピック名表示
書き込み一覧表示
新規書き込み作成
ページネーション

書き込み作成
トピック表示
書き込み送信

コードベースで考えると、
コントローラー
topic_controller indexメソッド→トピック一覧ページ
topic_controller createメソッド→トピック作成ページ
topic_controller postcreateメソッド→トピック作成ページ結果を送信
post_controller indexメソッド→書き込み一覧ページ
post_controller createメソッド→書き込み作成ページ
post_controller postcreateメソッド→書き込み作成ページ結果を送信

モデル
topic
id :id
title :タイトル

post
id :id
post_id:1トピック内でのid
topic_id:topicのid
name:投稿者名
content:投稿内容
creationday:作成日時

備考
railsだとモデル作成時に作成日時と更新日時が作られるのでcreationdayはいらない気がする。

C# リフレクション

C#のリフレクションを最近触ったので少し復習がてら記事にしてみました。
まずはクラスを用意。

class Fruits
    {
        public int Apple { get; set; }
        public string Banana { get; set; }
        public int? Cherry { get; set; }
        public int Drian { get; } = 3;

        public int Sum()
        {
            return Apple + int.Parse(Banana) + (int)Cherry + Drian;
        }
    }


GetPropertiesでプロパティの情報を取り出せる。例えば.Nameでフィールド名を取り出せる。

class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruits();
            foreach (var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine(prop.Name);
            }
        }
    }

結果

Apple
Banana
Cherry
Drian


.canWriteでsetterを持っているか判断する。

class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruits();
            foreach (var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine(prop.Name + ":" + prop.CanWrite);
            }
        }
    }

結果

Apple:True
Banana:True
Cherry:True
Drian:False


.PropertyNameでフィールドの型名が取り出せる。

class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruits();
            foreach (var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine(prop.Name + ":" + prop.PropertyType);
            }
        }
    }

結果

Apple:System.Int32
Banana:System.String
Cherry:System.Nullable`1[System.Int32]
Drian:System.Int32


.SetValueメソッドでは値を入れることができる。
一つ目の引数は入れ物のオブジェクト。
二つ目の引数は入れ物に入れる値。

class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruits();
            var instance = new Fruits();
            foreach (var prop in fruit.GetType().GetProperties())
            {
                if (!prop.CanWrite) continue;
                if(prop.PropertyType == typeof(int))
                {
                    prop.SetValue(instance, 1);
                }
                else if(prop.PropertyType == typeof(int?))
                {
                    prop.SetValue(instance, 2);
                }
                else if(prop.PropertyType == typeof(string))
                {
                    prop.SetValue(instance, "3");
                }
            }

            Console.WriteLine("Apple = " + instance.Apple);
            Console.WriteLine("Banana = " + instance.Banana);
            Console.WriteLine("Cherry = " + instance.Cherry);
        }

結果

Apple = 1
Banana = 3
Cherry = 2


.GetValueで引数に入っている値を取り出すことができる。

class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruits();
            var instance = new Fruits();
            foreach (var prop in fruit.GetType().GetProperties())
            {
                if (!prop.CanWrite) continue;
                if (prop.PropertyType == typeof(int))
                {
                    prop.SetValue(instance, 1);
                    Console.WriteLine(prop.GetValue(instance));
                }
                else if (prop.PropertyType == typeof(int?))
                {
                    prop.SetValue(instance, 2);
                    Console.WriteLine(prop.GetValue(instance));
                }
                else if (prop.PropertyType == typeof(string))
                {
                    prop.SetValue(instance, "3");
                    Console.WriteLine(prop.GetValue(instance));
                }
            }
        }
    }

結果

1
3
2


他にも色々あるけど割とこの上記のものをよく使った。

C# Fileの読み書き

仕事で扱う機会があったのでこの機会に少しまとめてみようかな、と。
とりあえず基本的な事項のみで。


C#の現在のものだとopenとかcloseとかは気にしないですむ。
まずは普通にファイルの書き込み。

class Program
    {
        private static string path = "test.txt";
        static void Main(string[] args)
        {
            File.WriteAllText(path, "HelloWorld");
        }
    }

結果

HelloWorld


配列を入れてファイルの書き込みもできるらしい。
配列の要素ごとに改行を行う。

class Program
    {
        private static string path = "test.txt";
        static void Main(string[] args)
        {
            var array = new string[] {"apple", "banana", "cherry"};
            File.WriteAllLines(path, array);
        }
    }

結果

apple
banana
cherry


ファイルの読み込みも簡単に行える。
前提として上記のappleなどが書かれているファイルを読み込む。

class Program
    {
        private static string path = "test.txt";
        static void Main(string[] args)
        {
            var reader = File.ReadAllText(path);
            Console.WriteLine(reader);
        }
    }

結果

apple
banana
cherry


上記のWriteLinesと似たような感じでReadAllLinesメソッドを使用すると、行ごとの配列で結果が返ってくる。

class Program
    {
        private static string path = "test.txt";
        static void Main(string[] args)
        {
            var reader = File.ReadAllLines(path);
            foreach (var item in reader)
            {
                Console.WriteLine(item);
            }
        }
    }

結果

apple
banana
cherry


WriteLineのデメリットとして二回行ってしまうと結果が上書きされてしまう。

class Program
    {
        private static string path = "test2.txt";
        static void Main(string[] args)
        {
            File.WriteAllText(path, "HelloWorld");
            File.WriteAllText(path, "HelloWorld2");
        }
    }

結果

HelloWorld2


なので、AppendAllTextを使う。
なお、AppendAllLinesは配列やリストで渡すと行ごとに書き込みを行ってくれる。
というか、これだけは配列じゃなくてもいいらしい。

class Program
    {
        private static string path = "test3.txt";
        static void Main(string[] args)
        {
            File.AppendAllText(path, "HelloWorld");
            File.AppendAllText(path, "HelloWorld2");
            File.AppendAllLines(path, new string[] {"apple", "banana"});
            File.AppendAllLines(path, new List<string>() {"cherry","drian"});
        }
    }

結果

HelloWorldHelloWorld2apple
banana
cherry
drian

C# Environment

C#でfileの書き込みをちらほらやってた時に、Environment.NewLineというのを見たので、どんなものがあるのか見てみた。


NewLineは改行を行う。PCごとに改行文字は異なるがそういうものを気にしなくてもすむ。

Console.WriteLine("AAA" + Environment.NewLine + "BBB");

結果

AAA
BBB


MachineNameはmacだとmacではなくターミナルの名前の部分が表示された。

Console.WriteLine(Environment.MachineName);

結果

xxxxxxxxmacBook-Pro


OSVersionでOSのバージョンが取得できる。ただしToString()が必要。
OSVersion.ToString()

Console.WriteLine(Environment.OSVersion.ToString());

結果

Unix 18.6.0.0


スタックトレースの表示。

Console.WriteLine(Environment.StackTrace);

結果

at System.Environment.get_StackTrace()
   at Testapp2.Program.Main(String[] args) in /Users/******/Projects/Testapp2/Testapp2/Program.cs:line 16

見た所使いそうなのはこのあたり。
他にも、環境変数の取得や環境変数の設定などもすることができ
インストーラーを作ったりするのに使えそう。
コマンドライン関連のものもあったが使い道はあるのだろうか...


参考 

Environment Class (System) | Microsoft Docs

C# ref修飾子, out修飾子

C#のout修飾子、ref修飾子はメソッド使用時に参照を渡すことを目的としている。
いくつか例を示す。
まずはクラスの準備。

class Student
{
    public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber)
    {
        this.Id = Id;
        this.Name = Name;
        this.ScoreJapanese = ScoreJapanese;
        this.ScoreMath = ScoreMath;
        this.ScoreEnglish = ScoreEnglish;
        this.ClassNumber = ClassNumber;
     }
     public int Id { get; set; }
     public string Name { get; set; }
     public int ScoreJapanese { get; set; }
     public int ScoreMath { get; set; }
     public int ScoreEnglish { get; set; }
     public int ClassNumber { get; set; }
}


次にStudent型のの変数を用意し、メソッドに入れてstudentのみ値を変える。

static void Main(string[] args)
{
    var student = new Student(1, "taro", 82, 71, 75, 1);
    Console.WriteLine(student.Name + ":" + student.Id);
    classSub(student);
    Console.WriteLine(student.Name + ":" + student.Id);
}

public static void classSub(Student student)
{
    student.Id = 2;
}

結果はstudentのidは2に変わる。
このようにメソッドに値を渡し、その値を変更した時元の値にも
影響を及ぼすことを参照渡しという。
通常の引数となると、値は変わることはない。


例えば次のような例であればstudentの値は変わらない。

static void Main(string[] args)
{
    var student = new Student(1, "taro", 82, 71, 75, 1);
    Console.WriteLine(student.Name + ":" + student.Id);
    classSub2(student);
    Console.WriteLine(student.Name + ":" + student.Id);
}

public static void classSub2(Student student)
{
    student = new Student(2, "taro", 82, 71, 75, 1);
}


ここで無理やり参照渡しにするのがout修飾子とref修飾子だ。
以下のように使う。
ref修飾子。

static void Main(string[] args)
{
    var student = new Student(1, "taro", 82, 71, 75, 1);
    Console.WriteLine(student.Name + ":" + student.Id);
    refSub1(ref student);
    Console.WriteLine(student.Name + ":" + student.Id);
}

public static void refSub1(ref Student student)
{
    student = new Student(2, "taro", 82, 71, 75, 1);
}

out修飾子

static void Main(string[] args)
{
    var student = new Student(1, "taro", 82, 71, 75, 1);
    Console.WriteLine(student.Name + ":" + student.Id);
    outSub1(out student);
    Console.WriteLine(student.Name + ":" + student.Id);
}

public static void outSub1(out Student student)
{
    student = new Student(2, "taro", 82, 71, 75, 1);
}

違いは大してないような気がするがoutSub1で使ってるoutのついてる引数は
メソッド内で何かしらの値を割り当てられることが必要。
と、ここまで説明してきたけど、正直あまり使わない方がいいような修飾子ではある。


ただし、これを使ってるint.TryParseメソッドやDictionary.TryGetValueメソッドというものがあるので
ある程度は知っておいた方がいいかな、と。
int.TryParseメソッド

int.TryParse("123", out var number);
Console.WriteLine(number);

パースとはもちろんキャストのことだがこの場合はstringの123をintに変換する。
さらに第2引数にoutを入れることによってnumberという変数を宣言しつつ123をキャストした結果を格納できる。
キャストに成功すれば、Trueを返し失敗すれば Falseを返す。
Dictionary.TryGetvalueメソッド

dict.Add("田中", "たなか");
Console.WriteLine(dict.TryGetValue("鈴木", out var value));
Console.WriteLine(value);
Console.WriteLine(dict.TryGetValue("田中", out var value2));
Console.WriteLine(value2);

C#のDictionary型はkeyが存在しない場合例外が発生してしまう。
なので、TryGetValueによってkeyがあるか確かめつつ値を確認することが重要。
これも上のTryParseメソッドと同様にkeyがあるかを確認し、あった場合はvalueに格納。
さらに値があった場合はTrueを返す。なければFalseを返す。

参考URL
https://qiita.com/muro/items/f88b17b5fea3b4537ba7

C# Linq

C#LinqとはListの操作をSQLライクに書けるようにしたもの。
メソッドの書き方とキーワードを使う書き方の二つがあるが、今回はメソッドを使ったやり方を書く。
まずは準備としてクラスを用意する。

class Student
    {
        public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber)
        {
            this.Id = Id;
            this.Name = Name;
            this.ScoreJapanese = ScoreJapanese;
            this.ScoreMath = ScoreMath;
            this.ScoreEnglish = ScoreEnglish;
            this.ClassNumber = ClassNumber;
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public int ScoreJapanese { get; set; }
        public int ScoreMath { get; set; }
        public int ScoreEnglish { get; set; }
        public int ClassNumber { get; set; }
    }

次にリストに入れるデータの用意。
最後の一行がリンクを使うための準備である。

static void main(string[] args)
{
    var Students = new List<Student>();
    //ID,名前,国語の点数,数学の点数,英語の点数,クラス
    Students.Add(new Student(1, "taro", 92, 83, 81, 1));
    Students.Add(new Student(2, "hanako", 85, 38, 97, 1));
    Students.Add(new Student(3, "ryo", 92, 91, 95, 1));
    Students.Add(new Student(4, "ichiro", 61, 72, 45, 2));
    Students.Add(new Student(5, "runa", 52, 91, 38, 2));
    Students.Add(new Student(6, "akira", 82, 85, 77, 2));
    Students.Add(new Student(7, "yuka", 97, 24, 51, 3));
    Students.Add(new Student(8, "yoshiki", 51, 92, 73, 3));
    Students.Add(new Student(9, "arisa", 62, 73, 75, 3));
    IEnumerable<Student> Linq = Students;
}

Selectメソッド。
mainメソッドの最後に追加
実行すると、*名前*のように表示される。

foreach (var student in Linq.Select(x => "*" + x.Name + "*"))
{
    Console.WriteLine(student);
}

Whereメソッド
mainメソッドの最後に追加
実行するとIDが偶数のものが表示される。

foreach (var student in Linq.Where(x => x.Id % 2 == 0))
{
    Console.WriteLine(student.Name);
}

上記2つを組み合わせたWhereメソッドとSelectメソッド
mainメソッドの最後に追加。
実行するとIDが偶数のものが*名前*の形式で表示される。

foreach (var student in Linq.Where(x => x.Id % 2 == 0).Select(x => "*" + x.Name + "*"))
{
    Console.WriteLine(student);
}

OrderByメソッド
mainメソッドの最後に追加
実行すると順番が指定したものの昇順に並びかわる。

foreach (var student in Linq.OrderBy(x => x.ScoreJapanese))
{
    Console.WriteLine(student.Name + ":" + student.ScoreJapanese);
}

OrderByDescendingメソッド
mainメソッドの最後に追加
実行すると順番が指定したものの降順に並びかわる。

foreach (var student in Linq.OrderByDescending(x => x.ScoreJapanese))
{
    Console.WriteLine(student.Name + ":" + student.ScoreJapanese);
}

ThenByメソッド
並び替えを2回行う場合にはOrderByを2回使うのではなく2回目はThenByを使う。
mainメソッドの最後に追加。
実行すると順番がOrderByDescendingで指定したものの降順かつ
ThenByDescendingで指定したものの降順で並びかわる。

foreach (var student in Linq.OrderByDescending(x => x.ClassNumber).ThenByDescending(x => x.ScoreEnglish))
{
    Console.WriteLine(student.Name + ":" + student.ClassNumber + ":" + student.ScoreEnglish);
}

最後に全体を表示。

using System;
using System.Collections.Generic;
using System.Linq;

namespace TestApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("start");
            var Students = new List<Student>();
            Students.Add(new Student(1, "taro", 92, 83, 81, 1));
            Students.Add(new Student(2, "hanako", 85, 38, 97, 1));
            Students.Add(new Student(3, "ryo", 92, 91, 95, 1));
            Students.Add(new Student(4, "ichiro", 61, 72, 45, 2));
            Students.Add(new Student(5, "runa", 52, 91, 38, 2));
            Students.Add(new Student(6, "akira", 82, 85, 77, 2));
            Students.Add(new Student(7, "yuka", 97, 24, 51, 3));
            Students.Add(new Student(8, "yoshiki", 51, 92, 73, 3));
            Students.Add(new Student(9, "arisa", 62, 73, 75, 3));
            IEnumerable<Student> Linq = Students;
            //select
            foreach (var student in Linq.Select(x => "*" + x.Name + "*"))
            {
                Console.WriteLine(student);
            }
            //where
            foreach (var student in Linq.Where(x => x.Id % 2 == 0))
            {
                Console.WriteLine(student.Name);
            }
            //whereとselect
            foreach (var student in Linq.Where(x => x.Id % 2 == 0).Select(x => "*" + x.Name + "*"))
            {
                Console.WriteLine(student);
            }
            //orderby
            foreach (var student in Linq.OrderBy(x => x.ScoreJapanese))
            {
                Console.WriteLine(student.Name + ":" + student.ScoreJapanese);
            }
            //orderbyDescending
            foreach (var student in Linq.OrderByDescending(x => x.ScoreJapanese))
            {
                Console.WriteLine(student.Name + ":" + student.ScoreJapanese);
            }
            //ThenByDecending
            foreach (var student in Linq.OrderByDescending(x => x.ClassNumber).ThenByDescending(x => x.ScoreEnglish))
            {
                Console.WriteLine(student.Name + ":" + student.ClassNumber + ":" + student.ScoreEnglish);
            }


        }
    }

    class Student
    {
        public Student(int Id, string Name, int ScoreJapanese, int ScoreMath, int ScoreEnglish, int ClassNumber)
        {
            this.Id = Id;
            this.Name = Name;
            this.ScoreJapanese = ScoreJapanese;
            this.ScoreMath = ScoreMath;
            this.ScoreEnglish = ScoreEnglish;
            this.ClassNumber = ClassNumber;
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public int ScoreJapanese { get; set; }
        public int ScoreMath { get; set; }
        public int ScoreEnglish { get; set; }
        public int ClassNumber { get; set; }
    }
}