- 1. AtCoder Beginner Contest 189のメモ
- 2. GolangでGoogle Calender APIを使って日本の祝日情報を取得する
- 3. go言語学習雑記2
- 4. AWS Translateを使ってGo言語で翻訳するサンプル
- 5. go module のバージョニング
- 6. Gormの1.9と1.20で失敗したお話
- 7. GinでBodyを取得する際の最大サイズについて
- 8. 自宅内の見守りカメラをアップデートした:④実装編:Go言語の基本を駆使してラズパイ制御&HTTPサーバー
- 9. 自宅内の見守りカメラをアップデートした:③構成を変更しよう編:ラズパイカメラモジュールのマニュアル撮影を極める…!
- 10. [Go] データをファイルに書き込む方法をまとめる
- 11. golangでFargate運用を想定したDockerfile作成(Alpineベース)
- 12. GCPのSpannerで allow_commit_timestamp = true のフィールドに現在時刻を入れてはいけない
- 13. [追記]Go言語でチャンネル書込がブロックされるのを無理矢理解決した話
- 14. sdk-goでdynamoDBの複雑なstructの値をupdateする
- 15. Azure FunctionsとGoでZoom会議参加者を取得する
- 16. RcppKagome – Rcpp経由でGoのライブラリを呼んで形態素解析するRパッケージ
- 17. 【自己学習用】はじめてのGo2
- 18. Goの複数バージョン管理をanyenv+goenvで行う
- 19. Golangでのゼロ埋め
- 20. Goでスライス内の最大値・最小値を抽出する関数
AtCoder Beginner Contest 189のメモ
# 前置き
Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。# 問題
https://atcoder.jp/contests/abc189
# A
“`Q_A.go
package mainimport (
“fmt”
“strings”
)func main() {
var C string
fmt.Scanf(“%s”, &C)
s := strings.Split(C, “”)var flag bool = true
var c string = s[0]
for i:=1; i<3; i++{ if c != s[i]{ flag = false } } if flag{ fmt.Printf("Won\n") } else { fmt.Printf("Lost\n") } } ``` # B ```Q_B.go package mai
GolangでGoogle Calender APIを使って日本の祝日情報を取得する
祝日の一覧が欲しいなと思った時にGoogle Calendarから取得する方法を調べたので
まとめておきたいと思います。
GolangでGoogle Calender APIを使って取得します。## はじめに
[google calender api ドキュメント](https://developers.google.com/calendar/quickstart/go?hl=ja)
にgolangで利用する時のクイックスタートが乗っているので、参考に進めていきます。#### 1. 作業ディレクトリの作成
“`
$ mkdir google_calender
$ cd google_calender/
“`#### 2. Google APIを利用するためのcredentialsを取得
![スクリーンショット 2021-01-22 21.18.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6510/6bfc8ca5-4322-2282-025a-ec93703183d4.png)
go言語学習雑記2
go言語の勉強雑記その2
今回は文法# for文
goの言語は他の言語と比べて非常に柔軟性があります。
まずは普通のfor文“`go
for i := 0; i < 10; i++ { sum += i } ``` この条件式をいじるとwhile文のような挙動を実現できます ```go sum1 := 1 for sum < 1000 { sum1 += sum } ``` これで条件式を満たさなくなるまで処理を続けます。 さらにいじると無限ループができます。 ```go for {} ``` # if文 ```go if x>0 {}
“`
シンプルにifを書くだけ、 但し評価を()でくくる必要はないですまた、その場で変数を代入して比較を行うこともできます
“`go
if i:=3; i<4 { // 処理 } ``` # switch文 switch文は評価される変数を省略できる。 ```go t := 11 switch { case t < 12: fmt.Println
AWS Translateを使ってGo言語で翻訳するサンプル
タイトルの通りですが、[公式ドキュメント](https://docs.aws.amazon.com/sdk-for-go/api/service/translate/)にサンプルが含まれていなかったので記事にしました。
サンプルソースはGithubにも置いてあります。
https://github.com/yuukimiyo/go-aws-translate簡単なコードですが、[73言語](https://docs.aws.amazon.com/translate/latest/dg/what-is.html#what-is-languages.html)(2021年1月現在)の双方向翻訳が可能な簡易ツールとして使えます。
Public Domainですので、コピペなどご自由に。“`golang
package mainimport (
“flag”
“fmt”“github.com/aws/aws-sdk-go/aws”
“github.com/aws/aws-sdk-go/aws/session”
“github.com/aws/aws-sdk-go/
go module のバージョニング
# はじめに
自身で作った go package を公開し、別のプロジェクトで利用されるというケースで、バージョンがどのように扱われるのか調べました。
# バージョン指定なし
githubに`hello`というリポジトリを作り、そこにパッケージを作成します。
“`go.mod
module github.com/username/hello
go 1.15
“`“`go:hello.go
package hello
import “fmt”
func Hello() {
fmt.Println(“this is version v0.0.0”)
}
“`#### パッケージを呼び出す
パッケージを呼び出すためのクライアントを用意します。
“`
$ go mod init hello_client
$ go get -u github.com/username/hello
“`以下のようなgo.modができます。バージョン(v0.0.0)と参照しているコミット(40fe1c06b3a8)がわかります。
“`go.mod
module
Gormの1.9と1.20で失敗したお話
#最初に
2021年1月23日時点で、GORMの最新版はv1.20.11ですが、Qiitaや巷の記事はv1.9.xの物が多く(特に日本語)
公式ドキュメントは、基本v1.20がヒットするのでGorm初心者の私は混乱したというお話です。##バージョンはよく確認しよう
当たり前のことですが、パッケージのバージョンと参考記事のバージョンはよく確認しましょう。##GORMのバージョン
“`
v1.9.x系
import (
“github.com/jinzhu/gorm”
_ “github.com/jinzhu/gorm/dialects/mysql”)
“`“`
v1.20.11
import (
“gorm.io/gorm”
“gorm.io/driver/mysql”
)
“`
1.9系と1.20系でインポートするパッケージが異なります。
ネットの記事をそのままに、「go get github.com/jinzhu/gorm」すると1.9系がインストールされます。## 変更点
ほかに記事を上げてくださっている方がいらっしゃるので、すべては
GinでBodyを取得する際の最大サイズについて
#概要
ginで不確定なjosnをinterfaceに変換する際、一定サイズを超えると変換できない状態になった。###コード
“`
func SAmple(c *gin.Context) {
~~~
//bodyを取得
buf := make([]byte, 1028)
n, _ := c.Request.Body.Read(buf)
body := string(buf[0:n])
//bodyをmapに変換
var json_parse map[string]interface{}
err := json.Unmarshal([]byte(b), &json_parse)
~~~
}
“`c.Request.Body.Readでバイトスライスにボディを格納してstring形に変換していますが、
jsonのサイズが一定値を超えるとパースできなくなりました。私の環境ではnが2575で上限になりそれ以降のリクエストボディがbodyに格納されずjson.Unmarssamlでエラーになっていました。
##修正前に
Webサーバがbodyを制限なく受
自宅内の見守りカメラをアップデートした:④実装編:Go言語の基本を駆使してラズパイ制御&HTTPサーバー
## はじめに
本記事は[こちら](https://qiita.com/tenkoh/items/6aeed1bf767ed0c2594e)のパート④にあたります。
もし内容に興味を持たれましたら、他のパートもご覧頂けると幸いです。前回の記事までで、作成するシステムの構成まで固まりましたので、いよいよゴリゴリ実装していきます…!
## 成果物(クライアント側)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621288/b7bb29b0-0ac9-d5cf-dcee-c543988a8770.png)## コード
こちらに全て掲載しました。
https://github.com/tenkoh/go-home-camera## 補足説明など
### 自動調整の実行
UIにある自動調整実行ボタンに対して、jQueryのGETメソッドを送信する関数を設定しました。
リクエスト先は`api/calibration`としてあり、サーバ側ではそのURIにリクエストが送られると、一旦
自宅内の見守りカメラをアップデートした:③構成を変更しよう編:ラズパイカメラモジュールのマニュアル撮影を極める…!
## はじめに
本記事は[こちら](https://qiita.com/tenkoh/items/6aeed1bf767ed0c2594e)のパート③にあたります。
もし内容に興味を持たれましたら、他のパートもご覧頂けると幸いです。(順次執筆中…)## システム構成の変更
ハードウェアは据え置きで、ソフトウェアのみ構成を変更します。### パフォーマンス改善:画像取得方法の変更
カメラモジュールを使って単純に静止画を取得したいだけなので、標準コマンドを自作プログラムの中から呼び出して使うようにします。| Before | After |
| — | — |
| Opencv-python | ラズパイ標準コマンド`raspistill` |### 取得画像の明るさ適正化:画像取得設定の固定化とキャリブレーションモードの導入
画像取得設定を固定化するには、`raspistill`のオプションで各種自動調整を切りつつ、必要なパラメータを全て指定する必要があります。
ここで言うところの自動調整とは、オートホワイトバランス(awb)と自動ゲインコントロール(agc)です
[Go] データをファイルに書き込む方法をまとめる
色んな書き込み方があり、何かとごちゃまぜになったので、一旦まとめてみました。
パターンがあり、いつ何を使えば良いか見えてきたので、同じく混乱している方の参考になればと思います。## ざっくりと
こんな感じになる。
1. __書き込み先を決める__ (例: file, buffer)。ファイルの場合 `defer Close()` を忘れずに
2. __データを変換する__ (例: []byte, Marshal), または __書き込むやつを取得する__ (例: Writer, Encoder)
3. __書き込む__ (例: Write, Encode)データ格納先へのデータの渡し方が多少違うので、覚えてなければ、都度マニュアルを確認しましょ。
## 単純に文字列をファイルに書き込む
なんでもいいからファイルに書き込みたいときに使います。### 全体の流れ
1. 書き込み先のファイル作成 (`f := os.Create`)
2. バイト文字列に変換 (`d := []byte{“文字列”}`)
3. 書き込み (`f.Write(d)`)### コード①
`
golangでFargate運用を想定したDockerfile作成(Alpineベース)
# 概要
個人アプリにて、Fargateでのコンテナ運用を行うため、golang環境のDockerfileを作成しました。当環境の特徴として、
– DockerイメージをAlpine Linuxベースを使用し、軽量化。
– マルチステージビルド機能を使用し、ビルド環境でgolangアプリやその他バイナリを作成し、軽量化。
– Fargateで運用するコンテナの中に入ってシェル操作するため、ssm-agentを導入。です。
# 各種ファイル
### Dockerfile
~~~dockerfile
FROM golang:1.14.4-alpine3.12 as builderARG SSM_AGENT_VERSION=2.3.1205.0
RUN apk add –no-cache \
‘make~=4.3-r0’ \
‘git~=2.26.2-r0’ \
‘gcc~=9.3.0-r2’ \
‘libc-dev~=0.7.2-r3’ \
‘bash~=5.0.17-r0’
GCPのSpannerで allow_commit_timestamp = true のフィールドに現在時刻を入れてはいけない
## はじめに
Spannerはスキーマに他のデータベース同様TIMESTAMP型がありますがオプションとして `allow_commit_timestamp = true` を指定でき、Spanner側の時計を基準としたタイムスタンプを打つことができます。
これによりアプリケーション側でセットした時刻に依存しない厳格な履歴を作成できますが使い方を間違えると書き込みに失敗するケースがあったので紹介します。
## TL;DR
* `allow_commit_timestamp = true` にしたフィールドに未来時刻を入れることはできない
* このフィールドにOSから取得した現在時刻を入れると時刻ブレで未来時刻になり書き込みに失敗することがある
* 代わりにプレースホルダーを使おう## 検証
### 環境構築
以下のコマンドでSpannerを構築して下さい。gcloudの認証等は済んでいる前提でプロジェクト名は各々の環境に置き換えて下さい。
“`sql
— schema.sql として保存
CREATE TABLE users (
id STRING(MA
[追記]Go言語でチャンネル書込がブロックされるのを無理矢理解決した話
# 概要
Go言語のチャンネルは非常に便利なんですが、正直複雑すぎてあまり使いこなせていません。
この記事は、**チャンネルの受信側のgoroutineが先に死んだ場合に、送信側のチャンネル書き込みが永久にブロックされるのを無理矢理解決**した事例です。
正直こんな書き方がGo言語的に良いのかどうかわからないので、ご意見等いただけると嬉しいです。
**バッドノウハウかもしれないのでご注意を!!**
**[追記]もしかしてBind呼ぶたびに終わらないgoroutineが増えるかも?**## 参考
Go言語のチャンネル書き込みの時に…
| 条件 | 結果 |
|:—-:|:—-:|
| 受信ルーチンが生きていてチャンネルが満杯でない | ブロックしない |
| 受信ルーチンが生きていてチャンネルが満杯 | チャンネルが空くまでブロック |
| 受信ルーチンが死んでいる | 永久にブロック |
| チャンネルにnilが代入されている | 永久にブロック |
| チャンネルがcloseされている | panicする |# panicするコード
[Playg
sdk-goでdynamoDBの複雑なstructの値をupdateする
## やりたいこと
GoでのdynamoDBに対しての操作は割とめんどかったりします。単純なStringやIntのものであればまだ良いのですが、ListのMapのなかのListとか、値の構造が複雑になってくると気が滅入ります。“`go
// シンプルなパターン
&dynamodb.UpdateItemInput{
TableName: aws.String(“sampleTable”),
Key: // 省略,
ExpressionAttributeValues: map[string]*dynamodb.Attribute{
“:ssv”: {
S: aws.String(“sampleStringValue”)
},
“:siv”: {
N: aws.String(strconv.Itoa(0)) // ここもintをstringに型変換してそれをaws.String()してkeyにはNを指定って感じでわかりづらい。
},
},
UpdateExpression: aws.String(“set samp
Azure FunctionsとGoでZoom会議参加者を取得する
# はじめに
リモートワークによりZoom会議が増え、参加者を記録して残すことが増えてきました。
今までは会議にAcceptしたりした人をカウントしたり、会議参加者リストをスクリーンショットしたりして参加者を取得していましたが、書き漏らしたり、スクリーンショットを忘れていたりといったことが起きていました。Zoom自体に会議参加者をエクスポートする機能はあるのですが、せっかくなのでAPIを叩いて取得できるツールを作ってみようと思い、作り始めました。
# 構成
ツールを作るに当たり、必要な/やってみたい技術、どんな形にしたいかをまとめてみました。– 完成形のツールイメージ
→ Meeting UUIDをチャットツールから送信するだけで参加者一覧の名前が返ってくる– 使用する技術と理由
– Slack(チャットツールなら何でも良かったのですが、手元にSlackがあったので)
– Azure Functions(会社でAzureを使っているため個人でも使ってみたかった)
– Go(未体験の言語学習)
– Zoom(参加者取得)この技術を使ってイメージ図を作成しました。
RcppKagome – Rcpp経由でGoのライブラリを呼んで形態素解析するRパッケージ
[![paithiov909/RcppKagome – GitHub](https://gh-card.dev/repos/paithiov909/RcppKagome.svg)](https://github.com/paithiov909/RcppKagome)
## これは何?
Rで形態素解析するためのパッケージです。[Pure Goで辞書同梱な形態素解析器](https://qiita.com/ikawaha/items/ff27ac03e22b7f36811b)として知られる[ikawaha/kagome](https://github.com/ikawaha/kagome)をラップしています。
## 使い方
### インストール
ソースからビルドします。makeとGCCとGoが必要です。
“` r
remotes::install_github(“paithiov909/RcppKagome”)
“`### 形態素解析
character vectorを渡せます。戻り値はリストです。
“`r
res <- RcppKagome::kagome("
【自己学習用】はじめてのGo2
#基本的な文法の振り返り
####mainパッケージ
プログラムをコンパイルして実行すると,まずmainパッケージの中にあるmain()関数が実行される。“`
package mainfunc main() {
}
“`####インポート
インポートしたパッケージ内へは,パッケージ名にドットを付けてアクセスできる。“`
package mainimport (
“fmt”
“github.com/wdpress/gosample”
“strings”
)
func main() {
fmt.Println(“hello world”)
}
“`####オプションの指定
任意の名前(上記ではf)を指定した場合はfで使用可能。
_を付けた場合は使用しないの意。
.を付けた場合は,使用時にパッケージ名が省略可能。“`
package mainimport (
f “fmt”
_ “github.com/wdpress/gosample”
. “strings”
)func main() {
Goの複数バージョン管理をanyenv+goenvで行う
Go言語で開発している際にローカルで複数バージョン使い分けしたい時がしばしば発生するので、その対策としてgoenvおよびanyenvを使ってバージョンの切り替えを容易にする方法を紹介します。
# goenvとは
https://github.com/syndbg/goenv
pyenvやrbenvをモデルに作られたGoのバージョン管理ツールです。
これを使うことによってバージョンの切り替え、Goの開発プロジェクトごとにバージョンを変更、環境変数でGoのバージョンの切り替えなどを行うことができるようになります。# anyenvとは
https://github.com/anyenv/anyenv
〜env系のツールを管理するツールです。
上述のgoenvやpyenv,rbenvに加え、nodenvやtfenvなど様々な言語のバージョン管理ツールを制御することができます。
今回の記事ではGoだけを取り扱うのでanyenvはなくても大丈夫なのですが、今後他の言語のバージョン管理する可能性あることを考えて一緒に紹介しておきます。# インストール
## anyenvのインスト
Golangでのゼロ埋め
# Golangでのゼロ埋め
0~9の場合は数字の前に0を付け、
10以上の場合は0を付けない場合は以下の様に実現できる“`
s := 3
str := fmt.Sprintf(“%02d”, s)
fmt.Println(str)
// 03s2 := 13
str2 := fmt.Sprintf(“%02d”, s2)
fmt.Println(str2)
// 13
“`
知らずに以下の様な回りくどい方法で実現したので知ったときは衝撃だった…“`
if num < 10 { numStr = "0" + strconv.Itoa(num) } else { numStr = strconv.Itoa(num) } ```
Goでスライス内の最大値・最小値を抽出する関数
## はじめに
Goでコードを書いているとスライス内の最大値、もしくは最小値を算出する処理を
何度か利用したので忘れないためにもメモ### スライス内の最大値を取得
“`
func maxInt(a []int) int {
sort.Sort(sort.IntSlice(a))
return a[len(a)-1]
}
“`### スライス内の最小値を取得
“`
func minInt(a []int) int {
sort.Sort(sort.IntSlice(a))
return a[0]
}
“`### サンプルコード
以下コードを[The Go Playground](https://play.golang.org/)でコピペして実行
“`
package main
import “fmt”
import “sort”func main() {
test := []int{7, 8 ,1, 4, 3, 21}fmt.Println(“max:”, maxInt(test))
fmt.Println(