- 投稿日:2020-07-31T23:11:58+09:00
LabelImgをMacにインストール
labelImgとは
無料のアノテーション(画像ラベリング)ツールで、物体検出の教師データ作成に使用する。VoTTと比較して、UIが初心者向けなので、採用しました。
今回はインストール手順を記載。
labelImgのGithub
https://github.com/tzutalin/labelImgインストール準備
brew更新(念のため)
brew updategitの更新
brew install git作業場所を作成
mkdir ~/Work cd ~/WorklabelImgのダウンロード
git clone git@github.com:tzutalin/labelImg.gitgitの設定エラーがでた場合
E-mailと名前の設定
git config --global user.email example@example.com git config --global user.name hogehogeインストール
cd ./labelImg brew install python3 pip3 install pipenv pipenv --three pipenv shell pip install pyqt5 lxml make qt5py3 rm -rf build dist python setup.py py2app cp -rf dist/labelImg.app /Applications exit参考
【labelImg:物体検出】公式READMEが当てにならない件
https://qiita.com/mdo4nt6n/items/46d53e19ed65c44c0eb7インストール完了
こんな画面が表示されたらOK
※画像の部分は何も表示されなくてOK
次回以降の起動方法
デスクトップにアイコンができるらしい。
- 投稿日:2020-07-31T12:48:54+09:00
LLDBでのデバッグまとめ
ある程度長いプログラムを書くようになってくると、エラーを探すのが難しくなってきます。
そんな時に必要となってくるのが「デバッガ」です。
多分これがないとやってられない、、???と思います。
ほぼ自分用ですが、LLDBの使い方まとめをやっていきます。
Macにはデフォルトで入っていそうな雰囲気なので、特に環境構築は必要ないかと思います。
今回、例として使うファイルはこんな感じです
test.c#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> void dainyu(int aa, int bb); int main(void) { double a = 3.0 ; double b = 5.0 ; double c = 7.0 ; dainyu(1,2); dainyu(2,3); } //-------------------------------------------------------- void dainyu(int aa, int bb){ const int num1 = aa ; static int num2 = 0; num2 = 0; num2 += 2; printf("aa(const) :%d, bb(static) : %d \n", num1, num2); }
const
とstatic
の違いを実験するプログラムです。ちなみに、出力は
aa(const) :1, bb(static) : 2 aa(const) :2, bb(static) : 2となります。
つまり、static
にしておくと、関数が終了した後もnum2
は値を保持し続けます。
つまり、static int num2 = 0;
の初期化が行われるのは、初めてdainyu()
が呼び出された際の一回のみです。前準備
デバッグをするためには、コンパイルの際に
-g
を指定する必要があります。gcc -g test.c
(蛇足ですが、最適化のための
-O3
と、警告をいっぱい出してくれるための-Wall
は毎回入れた方がいいでしょう)起動
先ほどのコンパイルで
test
という名前の実行ファイルが出たとします。起動するには
lldb [実行ファイル]
のコマンドを打ちます。lldb ./test (lldb) target create "./test" Current executable set to '/Users/K-eno/Scripts/test' (x86_64).よく使うコマンド一覧
[実行]
(lldb) rこれをやると、シンプルに実行できます。
(lldb) r Process 18038 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) aa(const) :1, bb(static) : 2 aa(const) :2, bb(static) : 2 Process 18038 exited with status = 0 (0x00000000)
[コードの表示]
(lldb) l数行ごとに
test.c
のコードの中身を見ることができます。[ブレイクポイントの設定]
行で指定
(lldb) b 15 Breakpoint 1: where = test`main + 32 at test.c:15:8, address = 0x0000000100000ec0これで、15行目にブレイクポイントを打つことができました。
b
の部分はbr
とかbreakpoint
でもいいです
その後実行するとこんな感じです。(lldb) r Process 18105 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) Process 18105 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000ec0 test`main at test.c:15:8 12 int main(void) 13 { 14 -> 15 double a = 3.0 ; 16 double b = 5.0 ; 17 double c = 7.0 ; 18 Target 0: (test) stopped.ちゃんと、15行目でストップできていますね。
関数名で指定
br set -n [funciton]
[function]
の所に関数名を入れます。実際に使ってみるとこんな感じです。
(lldb) br set -n dainyu Breakpoint 1: where = test`dainyu + 14 at test.c:27:22, address = 0x0000000100000f0e (lldb) r Process 18177 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) Process 18177 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000f0e test`dainyu(aa=1, bb=2) at test.c:27:22 24 } 25 26 void dainyu(int aa, int bb){ -> 27 const int num1 = aa ; 28 static int num2 = 0; 29 num2 = 0; 30 num2 += 2; Target 0: (test) stopped.関数の1行目まで入っていますね
その後ステップ実行すれば分かることですが、この場合、一つ目のdainyu(1,2)にブレイクポイントが打たれています。ちなみに、
breakpoint list
で設定したブレイクポイントを全て出力することができます。[ステップ実行]
ブレイクポイントを何処かに打った後に
s
もしくはn
(next)を打つとステップごとに実行することができます。
s -c <count>
のようにすると、ステップ回数を指定することができます。
その他のオプションはh s
と打てば出てきます。また、
c
(continue)を用いると、次のブレイクポイントまで(設定していない場合は最後まで)実行することができます。[変数の表示]
frame varuable
を使うと、変数の一覧とその中身を表示することができます。(lldb) frame variable実際にはこんな感じです。
(lldb) n Process 18352 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = step over frame #0: 0x0000000100000eca test`main at test.c:17:8 14 15 double a = 3.0 ; 16 double b = 5.0 ; -> 17 double c = 7.0 ; 18 19 //printf("re : 5.0 , w(3) : %lf , w(7) : %lf ", weight(a,b), weight(c,b)); 20 //printf("a : %lf, b : %lf, c : %lf \n",a,b,c); Target 0: (test) stopped. (lldb) frame variable (double) a = 3 (double) b = 5 (double) c = 0まだ、16行目までしか実行はされていないので、
c
には7.0が代入されていません。また、その後ろに変数を指定して見ることもできます。
(lldb) frame variable a (double) a = 3
- 変数の中身だけを見たい場合は
po
コマンドを使っても実行できます。(lldb) po b 5
- 構造体を出力する際には、
p
コマンドを使用します。(lldb) p *parameters (simulation_parameters) $6 = { DIM = 2 ParticleDistance = 0.025000000000000001 FluidDensity = 1000 KinematicViscosity = 9.9999999999999995E-7 GRAVITY_SWITCH = 1 DT = 0.001 FINISH_TIME = 2 OUTPUT_INTERVAL = 20 }(これは、全く別のコードで使っている構造体ですが、、、、)
- 配列の中身を見るときには少し特殊なコマンドを打つ必要があるようです。
(他にいいのがあったら教えて欲しい、、、)(lldb) p *(double (*)[10])Pressure (double [10]) $1 = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0, [8] = 0, [9] = 0)これだと、
Pressure
という配列のうち、先頭から10個の値を見ることができます。[終了]
q
もしくはquit
で終了することができます。後書き
参考記事に非常に似通ってしまったので、パブリックにするかは悩みどころではありますが、いいメモにはなりました。
適宜、便利なコマンドは追加していこうと思います。参考記事
- 投稿日:2020-07-31T12:48:54+09:00
LLDBでのデバッグ備忘録
ある程度長いプログラムを書くようになってくると、エラーを探すのが難しくなってきます。
そんな時に必要となってくるのが「デバッガ」です。
多分これがないとやってられない、、???と思います。
ほぼ自分用ですが、LLDBの使い方まとめをやっていきます。
Macにはデフォルトで入っていそうな雰囲気なので、特に環境構築は必要ないかと思います。
ちなみに、ファイルを実行するたびに動作が異なる、、、、、、とかバグの原因が特定できない、、、、、、という時は、Valgrindを使うと、一発でメモリリークが分かって最高なのでぜひ試してみてください。
(LLDBでもメモリ系のコマンドがあるのでもしかしたらLLDBでも分かるかも??)
今回、例として使うファイルはこんな感じです
test.c#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> void dainyu(int aa, int bb); int main(void) { double a = 3.0 ; double b = 5.0 ; double c = 7.0 ; dainyu(1,2); dainyu(2,3); } //-------------------------------------------------------- void dainyu(int aa, int bb){ const int num1 = aa ; static int num2 = 0; num2 = 0; num2 += 2; printf("aa(const) :%d, bb(static) : %d \n", num1, num2); }
const
とstatic
の違いを実験するプログラムです。ちなみに、出力は
aa(const) :1, bb(static) : 2 aa(const) :2, bb(static) : 2となります。
つまり、static
にしておくと、関数が終了した後もnum2
は値を保持し続けます。
つまり、static int num2 = 0;
の初期化が行われるのは、初めてdainyu()
が呼び出された際の一回のみです。前準備
デバッグをするためには、コンパイルの際に
-g
を指定する必要があります。gcc -g test.c
(蛇足ですが、最適化のための
-O3
と、警告をいっぱい出してくれるための-Wall
は毎回入れた方がいいでしょう)起動
先ほどのコンパイルで
test
という名前の実行ファイルが出たとします。起動するには
lldb [実行ファイル]
のコマンドを打ちます。lldb ./test (lldb) target create "./test" Current executable set to '/Users/K-eno/Scripts/test' (x86_64).よく使うコマンド一覧
[実行]
(lldb) rこれをやると、シンプルに実行できます。
(lldb) r Process 18038 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) aa(const) :1, bb(static) : 2 aa(const) :2, bb(static) : 2 Process 18038 exited with status = 0 (0x00000000)
[コードの表示]
(lldb) l数行ごとに
test.c
のコードの中身を見ることができます。[ブレイクポイントの設定]
行で指定
(lldb) b 15 Breakpoint 1: where = test`main + 32 at test.c:15:8, address = 0x0000000100000ec0これで、15行目にブレイクポイントを打つことができました。
b
の部分はbr
とかbreakpoint
でもいいです
その後実行するとこんな感じです。(lldb) r Process 18105 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) Process 18105 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000ec0 test`main at test.c:15:8 12 int main(void) 13 { 14 -> 15 double a = 3.0 ; 16 double b = 5.0 ; 17 double c = 7.0 ; 18 Target 0: (test) stopped.ちゃんと、15行目でストップできていますね。
また、複数ファイルをコンパイルしている場合は、
b main.c : 20
のようにすると、main.c
ファイルの20行目にブレイクポイントを打つというように指定することができます。関数名で指定
br set -n [funciton]
[function]
の所に関数名を入れます。実際に使ってみるとこんな感じです。
(lldb) br set -n dainyu Breakpoint 1: where = test`dainyu + 14 at test.c:27:22, address = 0x0000000100000f0e (lldb) r Process 18177 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64) Process 18177 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000f0e test`dainyu(aa=1, bb=2) at test.c:27:22 24 } 25 26 void dainyu(int aa, int bb){ -> 27 const int num1 = aa ; 28 static int num2 = 0; 29 num2 = 0; 30 num2 += 2; Target 0: (test) stopped.関数の1行目まで入っていますね
その後ステップ実行すれば分かることですが、この場合、一つ目のdainyu(1,2)にブレイクポイントが打たれています。ちなみに、
breakpoint list
で設定したブレイクポイントを全て出力することができます。[ステップ実行]
ブレイクポイントを何処かに打った後に
s
もしくはn
(next)を打つとステップごとに実行することができます。
s -c <count>
のようにすると、ステップ回数を指定することができます。
その他のオプションはh s
と打てば出てきます。また、
c
(continue)を用いると、次のブレイクポイントまで(設定していない場合は最後まで)実行することができます。[変数の表示]
frame varuable
を使うと、変数の一覧とその中身を表示することができます。(lldb) frame variable実際にはこんな感じです。
(lldb) n Process 18352 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = step over frame #0: 0x0000000100000eca test`main at test.c:17:8 14 15 double a = 3.0 ; 16 double b = 5.0 ; -> 17 double c = 7.0 ; 18 19 //printf("re : 5.0 , w(3) : %lf , w(7) : %lf ", weight(a,b), weight(c,b)); 20 //printf("a : %lf, b : %lf, c : %lf \n",a,b,c); Target 0: (test) stopped. (lldb) frame variable (double) a = 3 (double) b = 5 (double) c = 0まだ、16行目までしか実行はされていないので、
c
には7.0が代入されていません。また、その後ろに変数を指定して見ることもできます。
(lldb) frame variable a (double) a = 3
- 変数の中身だけを見たい場合は
po
コマンドを使っても実行できます。(lldb) po b 5
- 構造体を出力する際には、
p
コマンドを使用します。(lldb) p *parameters (simulation_parameters) $6 = { DIM = 2 ParticleDistance = 0.025000000000000001 FluidDensity = 1000 KinematicViscosity = 9.9999999999999995E-7 GRAVITY_SWITCH = 1 DT = 0.001 FINISH_TIME = 2 OUTPUT_INTERVAL = 20 }(これは、全く別のコードで使っている構造体ですが、、、、)
- 配列の中身を見るときには少し特殊なコマンドを打つ必要があるようです。
(他にいいのがあったら教えて欲しい、、、)(lldb) p *(double (*)[10])Pressure (double [10]) $1 = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0, [8] = 0, [9] = 0)これだと、
Pressure
という配列のうち、先頭から10個の値を見ることができます。[終了]
q
もしくはquit
で終了することができます。後書き
参考記事に非常に似通ってしまったので、パブリックにするかは悩みどころではありますが、いいメモにはなりました。
適宜、便利なコマンドは追加していこうと思います。参考記事
- 投稿日:2020-07-31T09:41:28+09:00
macOSでASP .NET Coreを使ってAPIサーバをHerokuにデプロイする
macOSで.NET Coreを使ってAPIサーバをHerokuにデプロイするまでの手順をまとめます。
前提条件
実行環境は macOS Catalina です。
以下のツールはインストール済みとします。
- VS Code
- Docker
何を作るの?
シンプルなTodo管理APIサーバを構築します。データはデータベースに保存します。
.NET Core macOS版のインストール
Microsoftのウェブサイトからダウンロードしてインストールします。
必要な.NETツールをインストール
dotnet tool install --global dotnet-aspnet-codegenerator dotnet tool install --global dotnet-efプロジェクトの作成
webapi
テンプレートを使ってプロジェクトを作成します。
--no-https
をつけないと、デフォルトでlocalhost
の証明書を作る流れになってややこしくなります。dotnet new webapi -o TodoApi --no-https初期パッケージのインストール
Entity Framework Coreを使って、データベースへの書き込みを実現するので、以下のようにパッケージをインストールします。
ただ、今回はSQLiteだけ使うので、Microsoft.EntityFrameworkCore.Sqlite
だけインストールしても問題ありません。cd TodoApi dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Sqlite dotnet add package Microsoft.EntityFrameworkCore.InMemory
初回起動
dotnet run
で起動できます。dotnet run info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /Users/XXXXX/TodoApiその後、
curl
を以下のように実行するとテンプレートの初期設定であるWeatherForecast
の情報が取得できます。curl http://localhost:5000/WeatherForecast次のようなJSONが返されます。
[ { "date" : "2020-08-01T08:48:53.47458+09:00", "summary" : "Mild", "temperatureC" : 39, "temperatureF" : 102 }, { "date" : "2020-08-02T08:48:53.474598+09:00", "summary" : "Mild", "temperatureC" : -20, "temperatureF" : -3 }, { "date" : "2020-08-03T08:48:53.474609+09:00", "summary" : "Scorching", "temperatureC" : 47, "temperatureF" : 116 }, { "date" : "2020-08-04T08:48:53.474619+09:00", "summary" : "Scorching", "temperatureC" : 54, "temperatureF" : 129 }, { "date" : "2020-08-05T08:48:53.474629+09:00", "summary" : "Sweltering", "temperatureC" : 39, "temperatureF" : 102 } ]モデルクラス TodoItem の追加
以下のように
TodoItem.cs
ファイルをModels
フォルダの下に作成します。TodoItem.cspublic class TodoItem { public long Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } }データベースコンテキストの追加
同様に
Models
フォルダの下にTodoContext.cs
を作成します。TodoContext.csusing Microsoft.EntityFrameworkCore; namespace TodoApi.Models { public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } } }Startup.cs を修正
Startup.cs
を以下のように修正します。ここで先ほど作成したモデルクラスやデータベースコンテキストを登録します。
今回は、SQLiteを使うのでそれ以外をコメントアウトしています。Startup.csusing Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; // 追加 using Microsoft.EntityFrameworkCore; using TodoApi.Models; namespace TodoApi { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext<TodoContext>(opt => //opt.UseInMemoryDatabase("TodoList")); opt.UseSqlite("Filename=db.sqlite3")); // 今回はこれを使う。 SQLiteのファイル名は db.sqlite3 //opt.UseNpgsql("Host=localhost;Database=mydb;Port=15432;Username=user;Password=password")); // PosgreSQL //opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // SQL Server services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }コントローラを生成
必要なパッケージを追加します。
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design dotnet add package Microsoft.EntityFrameworkCore.Designコントローラ
TodoItemsController
を生成します。dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllersこの状態で自動的に
TodoItem
のCRUD APIが実装されます。データベースマイグレーションとデータベースの更新
dotnet ef migrations add <どんな変更を加えたのかを表す任意の名称>
という形でマイグレーションを作成します。
dotnet ef database update
でデータベースを更新します。dotnet ef migrations add InitialCreate dotnet ef database updateAPIを試してみる
dotnet run
でサーバを起動します。POSTのテスト
curl -X POST \ -H "Content-Type:application/json" \ -d '{"Name":"Task 01", "IsComplete":false}' \ http://localhost:5000/api/TodoItems curl -X POST \ -H "Content-Type:application/json" \ -d '{"Name":"Task 02", "IsComplete":false}' \ http://localhost:5000/api/TodoItemsGETのテスト:一覧取得
curl http://localhost:5000/api/TodoItems [{"id":1,"name":"Task 01","isComplete":false},{"id":2,"name":"Task 02","isComplete":false}]PUTのテスト
curl -X PUT \ -H "Content-Type:application/json" \ -d '{"Id":2, "IsComplete":true}' \ http://localhost:5000/api/TodoItems/2GETのテスト:特定レコードの取得
curl http://localhost:5000/api/TodoItems/2 {"id":2,"name":"Task 02","isComplete":true}DELETEのテスト
curl -X DELETE \ -H "Content-Type:application/json" \ http://localhost:5000/api/TodoItems/2 {"id":2,"name":"Task 02","isComplete":true}TodoItemにカラムを追加
以下のように
TodoItem
にCreatedAt
を追加します。TodoItem.csusing System; // 追加 public class TodoItem { public long Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } public DateTime CreatedAt { get; set; } // 追加 }以下のようにマイグレーションを実行します。
dotnet ef migrations add AddDateColumn dotnet ef database updateデータベースが更新されたことを確認
sqlite db.sqlite3 sqlite> PRAGMA table_info('TodoItems'); 0|Id|INTEGER|1||1 1|Name|TEXT|0||0 2|IsComplete|INTEGER|1||0 3|CreatedAt|TEXT|1|'0001-01-01 00:00:00'|0 sqlite>Herokuへデプロイ
以下のような
Dockerfile
を作ります。DockerfileFROM mcr.microsoft.com/dotnet/core/aspnet COPY bin/Release/netcoreapp3.1/publish/ App/ WORKDIR /App CMD export ASPNETCORE_URLS=http://0.0.0.0:$PORT; dotnet TodoApi.dllデプロイファイルを生成します。
bin/Release/netcoreapp3.1/
配下にリリースようファイル群が生成されます。dotnet publish -c Release
Herokuのインスタンスを作成して、Dockerfileをpush & releaseします。
heroku create heroku container:login heroku container:push web --app <appName> heroku container:release web --app <appName>参考
チュートリアル: ASP.NET Core で Web API を作成する
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio-code#prerequisitesチュートリアル: 移行機能の使用 - ASP.NET MVC と EF Core
https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/migrations?view=aspnetcore-3.1チュートリアル: JavaScript を使用して ASP.NET Core Web API を呼び出す
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/web-api-javascript?view=aspnetcore-3.1ASP.NET Core を使って Web API を作成する
https://docs.microsoft.com/ja-jp/aspnet/core/web-api/?view=aspnetcore-3.1