引き続きやってます。めでたくレベル2になりました。
Linqも、SelctManyやAggregateの使い方がわかってきた気がします。
一つわからないのが下の様なケース。TakeWhileやAggregateで出来そうな気もするんですが。どうするのがいいんだろう。
・合計がxを越えない範囲で列挙する。
あと、.NET Framework4でBigIntegerが追加されてることを知りました。便利。
#というか反則っぽいなぁ
技術ブログを始めたくてなんとなくスタートです。 たぶん長続きしないはず…
引き続きやってます。めでたくレベル2になりました。
Linqも、SelctManyやAggregateの使い方がわかってきた気がします。
一つわからないのが下の様なケース。TakeWhileやAggregateで出来そうな気もするんですが。どうするのがいいんだろう。
・合計がxを越えない範囲で列挙する。
あと、.NET Framework4でBigIntegerが追加されてることを知りました。便利。
#というか反則っぽいなぁ
Project Eulerなるものを知った。数学の問題をプログラムで解くらしい。
おもしろそうなので、登録してみた。
#そういえば、TopCoderに登録してそのままなことを思い出した。
http://projecteuler.net/
日本語のWikiもあり、問題も日本語化されているようだ。<やった。
http://odz.sakura.ne.jp/projecteuler/index.php?Project%20Euler
番号が若いうちは比較的簡単。出来るだけLinqを使って書くように心がける。
#でもLinqだと無駄が出やすい気がする。スピード重視なら、手続き指向になるのかなぁ。
とりあえず、今日は8問目まで。
いい加減、Azureへデプロイです。
プロジェクトを右クリックメニューより発行を選択。
表示されたダイアログで、「サービスパッケージだけを作成」を選択しOKをクリックします。
.cspkgファイルとcscfgファイルが作成されます。
これを、Azure環境にデプロイします。
まず、Windows Azure Developer Portal(http://windows.azure.com/)にアクセスします。その後、New Serviceをクリックします。
Hosted Servicesを選択します。
Service Labelと、Service Descriptionを入力します。適当でOK.
次にURLと、デプロイ場所を決定し、Createボタンをクリックします。
とりあえず、出来ました。そして、Deployボタンをクリック。
Application Packageに.cspkgファイルを、Configuration Settingsに.cscfgファイルを設定。Deployment Nameを入力したら、Deployボタンをクリック。
デプロイ完了です。最初は、Stoppedなので、Runボタンをクリックしアプリケーションを開始します。
しばらく、待つとデプロイが完了します。ステータスは次のように変更されます。
以上で、すべて完了。
油断すると、すぐ間隔が開いてしまって困ったことです。
前回の続きです。今回は、とりあえず実行するために、デフォルト設定で突き進みます。
まずは、プロジェクトの作成から。
VisualStudio2010を管理者モードで起動し(これ重要!いつも忘れます(^^;))、新しいプロジェクトの作成より、Windows Azure クラウドサービスを選択。
プロジェクトには、とりあえず、ASP.NET Webロールを一つだけ追加。
すると、ソリューションが作成されます。
その後、いきなりF5で実行。ASP.NETで作成されたテンプレートページが表示されます。一見、普通のWeb開発と変わりません。
違いはというと、タスクトレイのアイコンぐらい
右クリックメニューより、Development Fabric UIとDevelopment Storage UIを表示することが可能です。
まずは、Development Fabric UI。
続いて、Develpment Storage UI。
以上で、ローカルでのAzureプロジェクトの実行は完了です。 次は、ようやくデプロイ。
昨日、Azureの申し込みを完了したので、今日は環境の整備。
Windows Azure Toolsをインストールします。
ダウンロードは、下記から。
「Windows Azure Tools for Microsoft Visual Studio 1.2」
http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=2274a0a8-5d37-4eac-b50a-e197dc340f6f
リンク先ページにある、注意事項を参考にしつつインストールしました。
Windows7(x64)×VS2010なので、↓だけ追加でインストール。
http://code.msdn.microsoft.com/KB981002
というわけで、環境の準備は終了。そして今日の作業も終了。
明日はサンプル作りたいな。
MSDNサブスクリプションを利用中の方には特典が用意されています。詳しくは↓。
http://msdn.microsoft.com/ja-jp/subscriptions/ee461076.aspx
幸いにもPremiumの割り当てがあるので、申し込みを行ってみます。
入り口は、MSDNサブスクリプションのページから。
WIndows Azure プラットフォームのリンクをクリックすると、Microsoft Online Service カスターマー ポータルにサインインします。(アカウントがない場合は、ここで作成します。)
すると、ショッピングカートに商品が入っている状態に。あとは、同意するチェックボックスにチェックを入れて、購入手続きへ。(クレジットカード情報等を入力します。なぜか途中のValidationに引っかかって、何回か最初からやり直しましたが…)
あとは、サービスをアクティブにすれば終了。とりあえず、きょうはここまでか。
今更ですが、ダウンロード可能になってました。
http://www.microsoft.com/japan/products/expression/
さて試すか。
SQLServerCeで行ロックがかかっているかの実験。
using (var connection1 = new SqlCeConnection(Settings.Default.Setting))
using (var connection2 = new SqlCeConnection(Settings.Default.Setting))
{
connection1.Open();
connection2.Open();
var command1 = connection1.CreateCommand();
var command2 = connection2.CreateCommand();
using (var tran1 = connection1.BeginTransaction())
using (var tran2 = connection2.BeginTransaction())
{
command1.Transaction = tran1;
command2.Transaction = tran2;
command1.CommandText = "select * from table1 with (updlock) where id = 1";
command2.CommandText = "select * from table1 with (updlock) where id = 1";
using (var reader1 = command1.ExecuteReader())
using (var reader2 = command2.ExecuteReader())
{
while (reader1.Read() && reader2.Read())
{
Console.WriteLine(reader1.GetInt32(0));
Console.WriteLine(reader2.GetInt32(0));
}
}
}
}
確かに。
Visual Studio 2010 Pro Power Toolsをインストールしてみた。 http://visualstudiogallery.msdn.microsoft.com/en-us/d0d33361-18e2-46c0-8ff2-4adea1e34fef
など盛りだくさん。 あと、Alt+↑ とか Alt+↓とかで、コード移動が出来るみたいなのだが試してもよくわからなかった。
Entity Framework4では、外部キーをスカラプロパティーとして公開することが出来ます。
外部キーの使用 (Entity Framework)
http://msdn.microsoft.com/ja-jp/library/ee794150.aspx
でも、追加方法がよくわからずはまったので備忘録。
①追加からアソシエーションを選択すること。
(ツールボックスからではダメ。ここではまった。)
②外部キープロパティーの追加にチェックを付ける
③プロパティーが追加されます。
ところで、追加されたプロパティーが、どのアソシエーションに関連しているかを確認する方法がない?
長らくx64環境からMDBファイルにアクセスすることが出来なかった。
(正しくは、32bitアプリとしてWOW64上で動作する様に、ビルド構成としてx86を指定する必要があった。)
Office2010(x64)をインストールすることにより、64bitのアプリケーションでもMDBファイルにアクセスできるようになる。ConnectionStringで”Microsoft.ACE.OLEDB.12.0”するだけである。
データ接続コンポーネントも、今はベータがとれていないが、そのうちベータがとれるだろう。
(2010 Office system Beta ドライバ: データ接続コンポーネント)
http://www.microsoft.com/downloads/details.aspx?familyid=C06B8369-60DD-4B64-A44B-84B371EDE16D&displaylang=ja
これにより、32bitでは"Microsoft.JET.OLEDB.4.0"、64bitでは"Microsoft.ACE.OLEDB.12.0”と接続文字列を切り替えることにより、どちらの環境でも動作させることが可能になる。
※32bitでも下記ドライバをインストールすれば、"Microsoft.ACE.OLEDB.12.0”で接続が可能。
2007 Office system ドライバ: データ接続コンポーネント
http://www.microsoft.com/downloads/details.aspx?FamilyId=7554F536-8C28-4598-9B72-EF94E038C891&displaylang=ja
なお、32bitで動作しているか64bitで動作しているかは、IntPtr.Sizeで判定が可能だそうだ。
(とあるコンサルタントのつぶやき:Part 2. .NET Framework 2.0 アプリケーションの 64 ビット対応)
http://blogs.msdn.com/nakama/archive/2008/11/06/part-2-net-framework-2-0-64.aspx
なお、アプリケーションの内部から、現在自分が 64 ビット/32 ビットどちらで動作しているのかを知る一番簡単な方法は、IntPtr.Size プロパティをチェックするというものです。
- IntPtr.Size = 8 の場合は 64 ビットモードでプロセスが動作している。
- IntPtr.Size = 4 の場合は 32 ビットモードでプロセスが動作している。
週末を利用して、viliv S5にWindows7をインストールすることを画策中。
とりあえず、ブータブルのUSBメモリを作成中。
最近はMicrosoftがISOからブータブルUSBメモリを作成するツールを配布してるんですな。
ISOのダウンロード販売といい、便利な時代になったもんだ。
http://www.microsoftstore.jp/Form/Guide/downloadTool.aspx
Visual Studio 2010(.NET Framework 4)より、PLINQ (Parallel LINQ)が追加され、並列処理が簡単にできるようになっています。
10 行でズバリ !! 並列プログラミング - PLINQ (C#)より
PLINQ は LINQ によるデータ コレクションに対するクエリ処理を並列化するためのものであり、PLINQ を使用することで LINQ クエリの Select 句や Where 句で実行されるロジックを容易に並列処理化することが可能です。PLINQ の機能は ParallelEnumerable クラス (System.Linq.ParallelEnumerable) の拡張メソッドとして提供されており、LINQ クエリの処理対象データ コレクションに対して ParallelEnumerable クラスの拡張メソッドの呼び出しを追加するだけでデータ コレクションへの処理を並列化し、マルチプロセッサー/マルチコア CPU の処理能力を活用して処理時間を短縮することができます。
と言うわけで、先日の重いLinq構文を何とか出来ないかとあちこちにAsParallelを追加してみました。
が、Aggregate構文を途中で使用しているためか、追加前より速くなることはありませんでした。
残念。
というわけで、早速お試し。
気になる機能その1 Coded UI Test
なんと、GUIのUnitテストが出来るらしい。
①まずは、超簡単なWinFormアプリを作成
テキストボックスに文字列をいれて、ボタンを押下すると下記ダイアログを表示する
ただそれだけです。
②テストの追加
Testメニューから、NewTestを選択。そうすると下記ダイアログが表示されるので、Coded UI Testを選択する。
そうすると、どうやってUIテストを作成するかを聞いてくる。一番最初はテスト資産がないので、上を選択。
画面の右下に、小さなポップアップ?が表示されるので、準備OK。
ここからの正しい使い方がよくわかっていないので、適当に。
(i)テスト対象アプリの起動
とりあえず、テスト対象が起動していないことにはどうにもならないので、起動します。
(ii)赤いボタンを押下
操作記録が開始されます。
(iii)適当に操作
検証したいポイントの手前まで操作します。今回の場合、はテキストボックスに文字入力&ボタン押下。
(iv)一番右のボタン押下
行った操作に対するコードが生成されます。
(iv)照準アイコンを検証したいコントロールへD&D
対象コントロールのプロパティーが表示されます。
(v)検証したいプロパティーを選択し、Add Assertionをクリック
表示されるダイアログで、検証の条件を追加します。
(vi)再び、コードを生成
今度はAssertionコードが追加されます。
以上で、テストケースの作成は終わり。
③テストの実行
[TestMethod]
public void CodedUITestMethod1()
{
this.UIMap.RecordedMethod1();
this.UIMap.AssertMethod1();
}
気付き
IMEが有効になっていると、途中でテストが失敗する。
いまいち。自動テストとかできるんだろうか。。。
前々から欲しかったPocket Wifiを買ってしまった。
http://emobile.jp/pocketwifi/
買った後で、何なんですが、コース別の料金を比べてみた。
スーパーライトのライト加減がよくわかりますな。
どのコース従量の部分が狭いこと。。。
0~9までの数字のカードがN枚ある。同じ数字のカードは1枚とは限らない。
そこから、M枚使用しM桁の整数を作るとき、小さい方から数えi番目の数値は何か?
※先頭桁に0はこないものとする。
という問題が与えられた場合、これを効率よく説くにはどうすればよいか?
とりあえず、効率よくという部分は無視して、順列を作成して前から数えてみた。順列を作成するに当たりLinqを使用しているサイトが見つかったので、利用にさせていただいた。
http://d.hatena.ne.jp/taguo/20080722/1216745650
class Program
{
static void Main(string[] args)
{
int[] array = {0,0,1,2,2,3};
var result = array.GetPermutation(4)
.Where(x => x.ElementAt(0) != 0)
.Select(x => string.Join("", x.Select(i => i.ToString()).ToArray()))
.Distinct();
result = result.Skip(10).Take(1);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
}
public static class Util
{
public static IEnumerable<IEnumerable<T>> GetPermutation<T>(this IEnumerable<T> source, int count)
{
return Enumerable.Range(0, count)
.Select(_ => source)
.Select(et => et.Select((t, i) => new { t, i }))
.Aggregate(Enumerable.Repeat(Enumerable.Repeat(new { t = default(T), i = default(int) }, 0), 1)
, (ac, et) => from a in ac
from t in et
where !a.Contains(t)
select a.Concat(Enumerable.Repeat(t, 1)))
.Select(ea => ea.Select(a => a.t));
}
}
実は、delegateの非同期呼出は使ったことがなかったり…
というわけで、MultiCastDelegateといえどもターゲットが複数あるとダメなのは初めて知りました。
出来ても良さそうなのにね。
delegateは、メソッド情報(Methodプロパティー)を呼びメソッドの定義されるインスタンスの情報(Targetプロパティー)を持ち、それを同期または非同期に呼び出すことができる。
というわけで、まずは同期呼出から。とっても基本的な使い方。
delegate void Hoge(string str);
static void Main(string[] args)
{
Hoge hoge = null;
hoge = Console.WriteLine;
hoge("AAA");
hoge.Invoke("AAA");
}
delegateで宣言すると、MultiCastDelegateのサブクラスとなるので、常にInvocation Listを作ることが可能。
static void Main(string[] args)
{
Hoge hoge = null;
hoge = Console.WriteLine;
hoge += delegate(string str)
{
Console.WriteLine(str.ToLower());
};
hoge("AAA");
}
メソッドの引数は同じオブジェクトが順番に渡されるため、1番目のメソッドで行われた変更を2番目のメソッドへと引き継ぐ。MultiCastDelegateの場合、最後のメソッドの戻り値以外は捨てられるので、引数のオブジェクトを通してしか情報の伝達ができない。
class Program
{
//戻値の型 デリゲートの型名 引数の型
delegate void Hoge(Class c);
static void Main(string[] args)
{
Hoge hoge = null;
hoge += AAA;
hoge += AAA;
hoge += AAA;
hoge += AAA;
hoge(new Class());
}
static void AAA(Class c)
{
Console.WriteLine(c.MyProperty);
++c.MyProperty;
}
}
class Class : Interface
{
public int MyProperty { get; set; }
}
UIはどうも苦手。勉強しなきゃ何だけどなぁ。
後で読むようにまとめておく。
エンジニアにもわかる「ユーザーインターフェース設計」
http://techblog.yahoo.co.jp/cat207/how_to/post_12/
ソシオメディア:UIデザインパターン
https://www.sociomedia.co.jp/category/uidesignpatterns
インフラジスティックス:Quince
http://jp.quince.infragistics.com/
あと、WPF向けのコントロールとか欲しくなるなぁ。個人では絶対無理だけど。
http://jp.infragistics.com/dotnet/netadvantage/wpf.aspx#Overview
http://www.devcomponents.com/dotnetbar-wpf/
http://www.actiprosoftware.com/Products/DotNet/WPF/WPFStudio/Default.aspx
Interfaceは参照型だったよな。と思い確認。
class Program
{
static void Main(string[] args)
{
Struct s = new Struct();
s.MyProperty = 1;
Interface i = s;
i.MyProperty = 2;
Interface i2 = i;
i2.MyProperty = 3;
Console.WriteLine("s :{0}", s.MyProperty);
Console.WriteLine("i :{0}", i.MyProperty);
Console.WriteLine("i2:{0}", i2.MyProperty);
}
}
interface Interface
{
int MyProperty { get; set; }
}
struct Struct : Interface
{
public int MyProperty { get; set; }
}
正解。
つまり、Interface型に代入する際にボックス化が行われているということ。
class Program
{
static void Main(string[] args)
{
var val = new Struct();
var val2 = new Class();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000000; i++)
{
object obj = val;
}
Console.WriteLine("struct -> object :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
Interface obj = val;
}
Console.WriteLine("struct -> Interface:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val;
}
Console.WriteLine("struct -> struct :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
Interface obj = val2;
}
Console.WriteLine("class -> Interface:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
object obj = val2;
}
Console.WriteLine("class -> object :" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val2;
}
Console.WriteLine("class -> class :" + sw.Elapsed);
}
}
interface Interface
{
int MyProperty { get; set; }
}
struct Struct : Interface
{
public int MyProperty { get; set; }
}
class Class : Interface
{
public int MyProperty { get; set; }
}
以前のエントリで、Decimal型がDoubleに丸められてDBにInsertされることを書いた。
その後いろいろ調べた結果、フィールド型にNONEを指定していたのが原因だった。フィールド型をNONEで作成すると、NUMERICのaffinityが適用されるらしい。
http://www.sqlite.org/datatype3.html
Datatypes In SQLite Version 3 - 2.1 Determination Of Column Affinity
つまり、NONEのaffinityを適用されるためには、フィールドをBLOB型もしくは型指定なし(NONEの指定ではない)で作成しなくてはならないようだ。NONE指定すると、その他になり5番のNUMERICが適用されるわけだ。
ちなみに、↓がテーブルを作成する際に使用したSQLiteStudioのテーブル作成画面。
カラム追加のデフォルトデータタイプがNONEになっている。
そして、しっかりDDLにNONEと記載される。
引っかかった。
その後、データタイプをBlobで作成したところ、文字列として格納されることを確認した。
boxing(ボックス化)とは、値型を参照型であるobjectに変換する機能。
これにより、参照型であるobjectに値型を代入することができる。
ただし、パフォーマンス上の注意が必要。Generic型を使用することにより、boxingを防ぐことができる。
static void Main(string[] args)
{
var val = new Struct();
var val2 = new Class();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000000; i++)
{
object obj = val;
}
Console.WriteLine("struct -> object:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val;
}
Console.WriteLine("struct -> struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
object obj = val2;
}
Console.WriteLine("class -> object:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
var obj = val2;
}
Console.WriteLine("class -> class :" + sw.Elapsed);
var list = new List<Struct>(100000000);
var list2 = new List<Class>(100000000);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list.Add(val);
}
Console.WriteLine("generic list <- struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list2.Add(val2);
}
Console.WriteLine("generic list <- class :" + sw.Elapsed);
var list3 = new ArrayList(100000000);
var list4 = new ArrayList(100000000);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list3.Add(val);
}
Console.WriteLine("normal list <- struct:" + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000000; i++)
{
list4.Add(val2);
}
Console.WriteLine("normal list <- class :" + sw.Elapsed);
}
struct Struct
{
public int MyProperty { get; set; }
}
class Class
{
public int MyProperty { get; set; }
}