Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

LINQを学んでみよう

f:id:fa11enprince:20160131173315j:plain
最近、C#が好きになりかけています。
理由は楽ちんだから。
C#をやろうとすると避けて通れないものにLINQがあります。
別に使わなくてもかけるんだけど、
やっぱりLINQを知らないとほかのソースコードも読めないことがしばしば。
ちょっと勉強しないと使えるようにならないっぽい代物なので、
勉強しましょうってことでおすすめツールの紹介とプチ解説です。

LINQとは

まじめに解説しません。とりあえず、必要最低限でデータベースを使う気がないなら、
LINQ to ObjectとLINQ to XMLさえ学んでおけばOKでしょう。
今回はLINQ to Objectについて学びます。

必要なツール

Visual Studio!!
そりゃそうだって言われるので、今回はそれではなく、
https://www.linqpad.net/
LINQPadなるものがあるのでこれを使いましょう!

LINQ to Objectとは

C#のCollectionの処理ライブラリです。
ListやらDictionaryやらごにょごにょできます。
以上w
使うと便利になりますよってことで積極的に使いましょう。

ざっくり文法

省略できるのもいくつかありますが、まずはとりあえず基本形を。

var query = from [クラス名] 範囲変数名 in コレクション
    where [条件]
    select 範囲変数名

です。

LINQPadで書いてみます。

LINQPadをたちあげたら、上側のLanguageをC# Programに変えてあげて、
プログラムを打ち込みます。

public class 成績
{
    public string 学籍番号 { get; set; }
    public string 教科 { get; set; }
    public int    点数 { get; set; }
}

void Main()
{
    var 全成績 = new List<成績>() {
        new 成績 {学籍番号="S-0001", 教科="国語", 点数=90},
        new 成績 {学籍番号="S-0001", 教科="数学", 点数=80},
        new 成績 {学籍番号="S-0002", 教科="国語", 点数=70},
        new 成績 {学籍番号="S-0002", 教科="数学", 点数=70},
        new 成績 {学籍番号="S-0003", 教科="国語", 点数=20},
        new 成績 {学籍番号="S-0003", 教科="数学", 点数=50},
    };

    var query = from 成績 範囲 in 全成績
        where 範囲.点数 >= 80
        select 範囲;
    foreach (var v in query)
    {
        Console.WriteLine(v);
    }
}

実行ボタンを押すと、割とゴージャスな結果が出ます。
簡単だね!

f:id:fa11enprince:20160329021330p:plain

Listの初期化の書き方言語によって微妙に違うから間違えますね。

間違い例
var 全成績 = new List<成績> {
    new {"S-0001","国語", 90},
    ...
};

とか間違った書き方しててこれでいけないんだっけ???とか思いググってしまいました。
まだまだC#初心者ですね。

MVCとか3層アーキテクチャとか勉強しなおし

f:id:fa11enprince:20140517013817j:plain
ほとんど独り言のような記事です。
なんとなく理解して、なんとなく覚えるMVCとか3層アーキテクチャ
この2つ全く別物なんですが、ごっちゃにして覚えてる人多いですよね。
日本人だけかと思ったら、海外の人もそうみたい……。
正確ではないけどstackoverflowに書いてあった回答でわかりやすい回答がありました。
そもそもMVCと3層アーキテクチャはカテゴリーからして違うそうですよ。

MVCと3層アーキテクチャの違い

ハイパーざっくりかくと違いはこうです。いや、
MVCが明らかに違うじゃないか!!!って意見はあると思います。

3層アーキテクチャ
Client <-> Middle <-> Data
MVC
     Middle
     ^    |
     |    v
Client <- Data

これですね。3層アーキテクチャはわりと一言で表せて、
Middleの層を必ず介してClientとDataがやり取りされる。
正確に言うと、
プレゼンテーション層、ビジネスロジック層、データ層
で必ずビジネスロジック層を通じてデータをやり取りする
ということですね。

問題は、MVCのほう。これ一言で説明できる人いますか(;'∀')
なかなか一言で難しいうえに、私はまだ完全に理解してません。
そこでいろいろWebの情報漁って、Javaを例に書いてみました。
StrutsとかSpringの場合はこんな感じなのでしょう。
若干あってるか自信ありません。
f:id:fa11enprince:20160214085826p:plain
ざっくりいうと上のテキストで書いた図のように
3層アーキテクチャとの違いはModelとViewが関連しているところですね。
なんかこの辺をじっくり解説してくれてる書籍とかあるんだろうか?
使うフレームワークによってもちょっと違う仕組みの
MVC?になっているものもあったり……。
Document-Viewとかはわかりやすいんですが……。
今時それはないか……。
さらにMVVMとかもあったりカオスです。
読んでも違いが何なのかーってあたりが激しく混乱します……。
MVVMはWPFとか触れば理解できるようになるかもしれませんが……。

Skinny Controller, Fat Model

こんな言葉を聞いたことがあります。
僕が見てきたのはFat Controller, Skinny Model
というパターンが多かったです。
なんでもControllerでやりすぎ……。
ってのがありました。
それをデータの一貫性はModelになるべくさせて
Fat Modelにすべきみたいなのをどこかで読んだ気がします。
いい指針なのかなーと思いつつ、いろいろ調べると、
んーどうもどっちかに偏るのよくないみたいですね。
Fatなクラスは作るな的なことらしいです。
んー難しいですね。

でっていう……記事になってしまいました。

Cygwinにmonoをインストール

f:id:fa11enprince:20160208221718j:plain
今日もきれいなおねーさんです。結婚してください!!(*´ω`)
癒されますね。
話は変わり、mono使ってみたいなーと軽く調べてみると、
Macはもちろんのこと簡単にWindowsでもmonoが使えるようです。
ただ、Windowsでmonoってクロスプラットフォームなものを作る必要がないなら
いらね……Visual StudioでC#でいいじゃんなので
誰得?な感じはありますが、
コマンドラインで気軽に使えるっていうならいいかも!とおもい……(C#でもできるけど)
入れてみることにしました。
ただ、monoをコマンドプロンプトで使うのはいろいろ検閲により削除
なので、Cygwinで使ってみよーということで調べたらすぐに出てきました。
ちなみにですが、monoとは

MONOは99年、バンドをスタートした時は日本で認められずに、...

間違えました。

Mono(モノ)は、GNOMEプロジェクト創設者のミゲル・デ・イカザが開発した、Ecma標準に準じた.NET Framework互換の環境を実現するためのオープンソースのソフトウェア群、またそのプロジェクト名である。
現在はXamarin社が開発、販売、サポート業務を行っている。
共通言語基盤 (CLI) の実装やC#のコンパイラなどが含まれる。

Cygwin64bit版はいろいろ不備があるのであまり使っている人はいないと思いますが、
いちおう64bit版のやり方を書いておきます。
32bit版もほぼ同じ手順です。

Cygwin64bitのインストール

これは結構面倒です。
とりあえず落としましょう。
ここの説明は…割愛します。
https://www.cygwin.com/

64bit版の場合のmonoインストール

依存するモジュールのインストール

コマンドプロンプトを立ち上げます。
setup-x86_64.exeのあるディレクトリに移動します。
私の環境の場合はC:\CygwinLocalPackageなので

> cd C:\CygwinLocalPackage

Cygwinのインストールディレクトリ(rootになっているディレクトリ)を指定して次のコマンドを打ちます。
私の場合、C:\Cygwin64なので

> setup-x86_64.exe --root "C:\cygwin64" --quiet-mode --packages autoconf,automake,bison,gcc-core,gcc-g++,mingw-runtime,mingw-binutils,mingw-gcc-core,mingw-gcc-g++,mingw-pthreads,mingw-w32api,libtool,make,python,gettext-devel,gettext,intltool,libiconv,pkg-config,git,curl,libxslt

monoをダウンロード(今回はtar.bz2をダウンロードします)

Cygwinを立ち上げてサンプルコードを書きます。
wgetが入っていなければここからダウンロードしてください。
今回は現時点の最新版である4.4.2.30を使います。
Index of /sources/mono

$ wget http://download.mono-project.com/sources/mono/mono-4.2.2.30.tar.bz2

ところでみなさんこれなんて読みますか?僕はノリでウゲットですwww

解凍

最初の2行は変数を設定します。とりあえず公式の解説に合わせて、エンターを都度押してください。
解凍にものすごい時間がかかるのでカップ麺2杯くらいどうぞ(*´ω`)
気分だけ映画のハッカーですw

$ PREFIX=/usr/local
$ VERSION=4.4.2.30
$ tar xvf mono-$VERSION.tar.bz2

コンパイル

みなさん大好きconfigure & makeです。
configureの時間に気が遠くなります……。
カップ麺3杯くらいいけます。
そしてコンパイル・・・もう寝ていいですか(*´ω`)zZZ...

$ cd mono-4.2.2
$ ./configure --prefix=$PREFIX --host=i686-pc-mingw32
$ make
$ make install

--- 2 years later ---
ふぅ……これで環境構築は終わりです。

動作確認

ここでAtCoderの練習問題を解いてみます。

A - はじめてのあっとこーだー(Welcome to AtCoder)
高橋君はデータの加工が行いたいです。
整数 a,b,cと、文字列 s が与えられます。
整数 a+b+c と、文字列 s を並べて表示しなさい。

http://practice.contest.atcoder.jp/
using System;
using System.Linq;
using System.Collections.Generic;
namespace AtCoder
{
    class Program
    {
        public static void Main(string[] args)
        {
            var input = new List<int>();
            input.Add(int.Parse(Console.ReadLine()));
            input.AddRange(Console.ReadLine().Split(' ')
                .Select(int.Parse).ToList());
            string s = Console.ReadLine();
            Console.WriteLine(input.Sum() + " " + s);
        }
    }
}

コンパイル&実行&標準入力を与える…

$ mcs test.cs
$ mono test.exe
1
2 3
test

出力結果

6 test

めでたしめでたし(*´ω`)長かったー。
Cygwinだから異様に遅いんですね(;'∀')
決してPCは低スペックではないですが全部で3時間近くかかりました。
これだとプログラミングコンテストとかで気軽にC#を使えますね!
terminal+viでC#がかけて勉強ができます!
もちろん、特別なことをしない限りIntelliSenseの恩恵にあずかれませんが。
f:id:fa11enprince:20160209015552p:plain
……ここまで書いておいてVM上のLinuxで普通にmono入れりゃあいいだけかも……
なんて少しだけ思いましたw

Visual Studioのソリューション(プロジェクト)をコピーするプログラムを作りました。

f:id:fa11enprince:20160201022330j:plain
Visual Studioのソリューション(プロジェクト)をコピーするプログラムを作成しました。
Gitでブランチ分けてもいいんだけど、
大幅に試験的にプログラムを変えるときにプロジェクトを作り直してしまう
Git使い慣れてない私なんで、私には必要ですが、
ほかに需要があるかは謎です。
やっていることはプロジェクトを指定した名前で丸々コピーして
プロジェクト名を指定した名前に変えるのと、
ソリューションファイルとプロジェクトファイルの名前を書き換えて
GUIDを書き換えるといったそれだけのものです。
filterについては特に何もしてません。
GUID書き換えなくてよいという情報があったもので……。
また、RootNamespaceはよくわからなかったので指定先の名前で書き換えました。
そうするとソースコードにも影響が及ぶ気が若干しますが……。
十分にテストしていないので、人柱になりたい人はぜひ(^^)/!

中身は結構雑なプログラムでC#で組んでいます。
ソリューションファイルの構造大体わかったけれども
パーサを書くとそれなりに大がかりなので(なんでXMLでないんだよ……)
正規表現で力技で書き換えています。

GitHub

github.com
ライセンス入れておきました(MIT License)。
いつの間にかGitHubがライセンスと.gitignoreを自動で作れるようになってますね。

使い方

意図的にC++とC#だけ対応しています。
VBは滅びてください。
あっ、F#は入れるべきでした。
パスを通すか、使うところと同じディレクトリにおいて
コマンドプロンプトから使います。

> solcp [sol src path] [sol dst path]

例えばdemoというソリューションをdemoCopyでコピーするとこんな感じになります。

[コピー元]
demo
│  demo.sln
└─demo
        demo.vcxproj
        demo.vcxproj.filters
        Source.cpp
[コピー先]
demoCopy
│  demoCopy.sln
└─demoCopy
        demoCopy.vcxproj
        demoCopy.vcxproj.filters
        Source.cpp

参考にした情報(結構パクりました)

stackoverflow.com

C#楽ちんでいいです(*´ω`)

はてなブログに貼り付けた写真の話

f:id:fa11enprince:20160131173315j:plain
自分でホームページを作成するときなどは画像の大きさや容量を気にしていましたが、
ブログの時って実はあまり気にしていませんでした。
はてなブログの場合、
いいように勝手に圧縮してくれてるのかな?
と思ったらそんなことなかった(;´・ω・)
なので、ブログのトップの画像が1MB超えのものもある……
というありえない状況になっていました。
無駄なトラフィックを発生させてしまい、すみません。
今の時代1Mくらいなんて大したことないですが、
月々使用量が限られているところで契約している人にとっては
思いがけない巨大ファイルは死活問題。
ただでさえ画像貼るな原理主義の人もいるので、
真剣に考えなくてはなりませんね。

こんなことが起こらないようにするためには、
あらかじめ画像ファイルを横幅をせめて1024px以下にする、
できる限り300kB付近にするという対策が必要です。
そのうえでアップロードしましょう。

しかし、そんなことも気づかずに投稿してしまった過去の画像の場合は
正直つらい。
過去の画像を大量に貼り替える……なんてことは、
したくないのでその場合の簡易的な対処法を。
はてなブログの場合ははてなフォトライフに保存されます。
そこで画像の編集ボタンを押すと、
サイズが指定できますのでこれで圧縮をかけます。
画像によりますがおおむね効果があり1/2くらいにはなります。
f:id:fa11enprince:20160131172827p:plain
圧縮!
f:id:fa11enprince:20160131172843p:plain
まぁただこれは応急処置なので、皆さん気を付けましょう。
では(^_-)-☆

他で似たような内容を扱っているブログ

tomoyukitomoyuki.hateblo.jp
www.toritemi.com