Slide 1

Slide 1 text

Julia クイズ ~API編~ 2024/06/29 JuliaTokai #19 antimon2(後藤 俊介)

Slide 2

Slide 2 text

お品書き ● お前誰よ? ● 簡単な Julia の紹介 ● Julia API クイズ(全10問)

Slide 3

Slide 3 text

お前誰よ?

Slide 4

Slide 4 text

自己紹介 ● 名前:後藤 俊介 ● 所属:有限会社 来栖川電算 ● コミュニティ:🌟JuliaTokai, 🌟機械学習名古屋, ⭐JuliaLangJa, Ruby東海, Python東海, … ● 言語:Julia, Python, Ruby, … ● SNS等:                  (@antimon2) ● SNS等(2):      (@antimon2.jl) ● 著書:実践Julia入門

Slide 5

Slide 5 text

https://www.kurusugawa.jp

Slide 6

Slide 6 text

プレスリリース → https://www.hatch-tech-nagoya.jp/pr-escalator-ai https://www.kurusugawa.jp/htn-2023-11-17

Slide 7

Slide 7 text

簡単な Juliaの紹介

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Julia とは?(1) ● The Julia Language ● 最新 v1.10.4(2024/06/04) ○ LTS:v1.6.7(2022/07/19) ○ 次期:v1.11.0-rc1(2024/06/25) ● 科学技術計算に強い! ● 動作が速い!(LLVM JIT コンパイル)

Slide 10

Slide 10 text

Julia とは?(2) ● Rのように中身がぐちゃぐちゃでなく、 ● Rubyのように遅くなく、 ● Lispのように原始的またはエレファントでなく、 ● Prologのように変態的なところはなく、 ● Javaのように硬すぎることはなく、 ● Haskellのように抽象的すぎない ほどよい言語である 引用元:http://www.slideshare.net/Nikoriks/julia-28059489/8

Slide 11

Slide 11 text

Julia とは?(3) ● C のように高速だけど、 Ruby のようなダイナミズムを併せ持っている ● Lisp のような真のマクロを持ちながら、 MATLAB のような直感的な数式表現もできる ● Python のように総合的なプログラミングができて、 R のように統計処理も得意で、 Perl のように文字列処理もできて、 MATLAB のように線形代数もできて、 shell のように複数のプログラムを組み合わせることもできる ● 超初心者にも習得は容易でありながら、 ハッカーの満足にも応えられる ● インタラクティブな動作環境もあって、コンパイルもできる (Why We Created Julia から抜粋・私訳)

Slide 12

Slide 12 text

要するに ● 動的言語なのに速い! ● 文法も覚えやすい! ● 数値計算に強い!

Slide 13

Slide 13 text

Julia の主な特徴 ● 多重ディスパッチ ● 動的型システム ● 並行・並列処理、コルーチン ● 組込パッケージマネージャ

Slide 14

Slide 14 text

それでは本題

Slide 15

Slide 15 text

Julia API クイズ

Slide 16

Slide 16 text

Julia API クイズ 概要 ● Julia の 標準API の知識を問う内容をクイズにしました。 ● このスライドで言う 標準API とは、以下のような関数・定数 等を指します: ○ 素の状態で hoge() のように使えるもの ○ 〃 «モジュール名».hoge() のように使えるもの(一部) ○ 組み込みパッケージで提供されているもの(using Hoge だけで利用できるもの)

Slide 17

Slide 17 text

Julia API クイズ 対象環境 ● Julia v1.10.4(現時点の最新安定版) ○ このバージョンで動作することが正解の 最低条件 ● すべて REPL で動作確認済

Slide 18

Slide 18 text

第 1 問

Slide 19

Slide 19 text

第1問: 実際にある関数 以下のうち、Julia 標準に存在する関数はどれ? 1. 数値が 平方数かどうか を判定する関数 2. 文字列が Julia の 予約語かどうか を判定する関数 3. イテレータの要素が すべて異なるかどうか を判定する関数 4. 型が Julia 組み込みの型かどうか を判定する関数

Slide 20

Slide 20 text

第1問: 実際にある関数《解答》 以下のうち、Julia 標準に存在する関数はどれ? 1. 数値が 平方数かどうか を判定する関数 2. 文字列が Julia の 予約語かどうか を判定する関数 3. イテレータの要素が すべて異なるかどうか を判定する関数 4. 型が Julia 組み込みの型かどうか を判定する関数

Slide 21

Slide 21 text

第1問: 実際にある関数《解説》 allunique() ● allunique() は、引数 にイテレータ(配列じゃな くてもOK)を受け取り、そ の要素がすべて異なる場 合に true を返す関数。 ● 同一性の判定は isequal() で行われる。 ● 類似の関数として、 allequal() (すべての 要素が同じかどうかを判 定する関数)もある。 (Julia v1.8 以降) allunique([1, 2, 3]) #> true allunique("ABCDEFGHIA") #> false allequal(ones(100)) #> true

Slide 22

Slide 22 text

第1問: 実際にある関数《補足 1》 平方数の判定 ● 「数値が平方数かどう かを判定する関数」は 存在しない。 ● 比較的簡潔に定義で きる。 issq(n::Integer) = 0 ≤ n == isqrt(n)^2 # 整数版 issq(n::Number) = 0 ≤ n == trunc(√n)^2 # 整数以外版 issq(25) #> true issq(25.0) #> true

Slide 23

Slide 23 text

第1問: 実際にある関数《補足 2》 予約語? ● 「文字列が予約語かど うかを判定する関数」 は存在しない。 ● 「Julia の識別子とし て利用できるかどう かを判定する関数」な ら存在する (Base.isidentifi er()) Base.isidentifier("x") #> true # 一部の予約語は `false` が返る(この場合(狭義の)リテラル) Base.isidentifier("true") #> false # 多くの予約語は `true` が返る(実は識別子として利用できる) Base.isidentifier("if") #> true

Slide 24

Slide 24 text

第1問: 実際にある関数《補足 3》 プリミティブ型 ● 「Julia 組み込みの型 かどうかを判定する 関数」はない。 ● isprimitivetype( ) という関数はある が、プリミティブ型(原 始型)は 組み込み型 のことではない。 isprimitivetype(Int) # Julia の `Int` 型はプリミティブ型 #> true isprimitivetype(String) # `String` 型はプリミティブ型ではない #> false # 24ビットの整数型を定義してみた primitive type Int24 <: Signed 24 end isprimitivetype(Int24) #> true

Slide 25

Slide 25 text

第 2 問

Slide 26

Slide 26 text

第2問: 実際にはない関数・機能 以下のうち、Julia 標準には 存在しない 関数・機能はどれ? 1. 数値を 0から遠い方へ丸める RoundingMode 2. 数値の 4乗根を返す演算子 3. 対数スケールで等間隔の数列(=等比数列)を生成する関数 4. イテレータを連結する 関数

Slide 27

Slide 27 text

第2問: 実際にはない関数・機能《解答》 以下のうち、Julia 標準には 存在しない 関数・機能はどれ? 1. 数値を 0から遠い方へ丸める RoundingMode 2. 数値の 4乗根を返す演算子 3. 対数スケールで等間隔の数列(=等比数列)を生成する関数 4. イテレータを連結する 関数

Slide 28

Slide 28 text

第2問: 実際にはない関数・機能《解説》 logrange() ● 『対数スケールで等間 隔の数列(=等比数 列)を生成する関数』 は Julia v1.10 には まだない。 ● Julia v1.11 から そ のような関数 logrange(start, stop, length) が 追加される模様。 ○ v1.11-RC1 には少な くとも入っています。 @assert VERSION ≥ v"1.11.0-" # この時点でエラーが出たら以下は動作しない logrange(10, 4000, length=3) #> 3-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}: #> 10.0, 200.0, 4000.0 logrange(1, 1000, 4) ≈ 10 .^ (0:3) #> true

Slide 29

Slide 29 text

第2問: 実際にはない関数・機能《補足 1》 RoundFromZero ● RoundFromZero はそ の名の示すとおり「ゼロ から遠い方に丸める」丸 めモード。 ○ round(v, RoundFromZero) は v < 0 ? floor(v) : ceil(v) と等価 ● 実は Julia v0.x の時 代からあるにはあった。 ○ v1.8 までは BigFloat だけに対応 していた。 round(1.1, RoundFromZero) # == ceil(1.1) #> 2.0 round(-1.1, RoundFromZero) # == floor(-1.1) #> -2.0

Slide 30

Slide 30 text

第2問: 実際にはない関数・機能《補足 2》 ∜ 演算子 ● ∜ 演算子 (fourthroot() 関 数)は Julia v1.10 で追加。 ● √(sqrt())、∛ (cbrt())と同様に扱 える。 ∜2 # == fourthroot(2) #> 1.189207115002721 2∜2 # == 2 * fourthroot(2) #> 2.378414230005442

Slide 31

Slide 31 text

第2問: 実際にはない関数・機能《補足 3》 Iterators.flatten() ● Iterators.flatte n() は、引数に イテ レータを列挙するイテ レータ を受け取り 各 イテレータの列挙する 要素を列挙するイテ レータ を返す関数。 ● つまり引数に「連結し たいイテレータを並べ たタプル」を渡せば、 それを連結したイテ レータが返ってくる。 Iterators.flatten(( 1:3, (:a, :b, :c), "あいうえお" )) |> collect #> [1, 2, 3, :a, :b, :c, 'あ', 'い', 'う', 'え', 'お']

Slide 32

Slide 32 text

第 3 問

Slide 33

Slide 33 text

第3問: 文字列以外の replace() (1) 次のうち、動作するものを すべて選べ(複数回答) 1. replace([1, 2, 3], 1=>100) 2. replace((1, 2, 3), 1=>100) 3. replace(Set([1, 2, 3]), 1=>100) 4. replace(Dict(:a=>1, :b=>2, :c=>3), 1=>100)

Slide 34

Slide 34 text

第3問: 文字列以外の replace() (1)《解答》 次のうち、動作するものを すべて選べ(複数回答) 1. replace([1, 2, 3], 1=>100) 2. replace((1, 2, 3), 1=>100) 3. replace(Set([1, 2, 3]), 1=>100) 4. replace(Dict(:a=>1, :b=>2, :c=>3), 1=>100)

Slide 35

Slide 35 text

第3問: 文字列以外の replace() (1)《解説 1》 ● replace() は、一般 的なコレクション型の 多くで動作するよう多 重定義されている。 ● 配列(Array)・タプル (Tuple)・集合(Set) などは右の通り。 replace([1, 2, 3], 1=>100) #> [100, 2, 3] replace((1, 2, 3), 1=>100) #> (100, 2, 3) replace(Set([1, 2, 3]), 1=>100) #> Set([2, 3, 100])

Slide 36

Slide 36 text

第3問: 文字列以外の replace() (1)《解説 2》 ● replace() は辞書 (Dict)でも右のよう にすれば動作する ● 名前付きタプル (NamedTuple)には 非対応。 # ↓これだと `«old»=>«new»` が型が合わないためエラー replace(Dict(:a=>1, :b=>2, :c=>3), 1=>100) #! MethodError # ↓これならエラーにならない replace(Dict(:a=>1, :b=>2, :c=>3), (:a=>1)=>(:a=>100)) #> Dict(:a=>100, :b=>2, :c=>3) # NamedTuple には非対応 replace((a=1, b=2, c=3), (:a=>1)=>(:a=>100)) #! MethodError

Slide 37

Slide 37 text

第 4 問

Slide 38

Slide 38 text

第4問: 文字列以外の replace() (2) replace([1, 2, 3, 2], >(1)=>100) の実行結果は? 1. [1, 100, 100, 100] 2. [1, 100, 3, 2] 3. [1, 2, 3, 2] 4. MethodError が発生

Slide 39

Slide 39 text

第4問: 文字列以外の replace() (2)《解答》 replace([1, 2, 3, 2], >(1)=>100) の実行結果は? 1. [1, 100, 100, 100] 2. [1, 100, 3, 2] 3. [1, 2, 3, 2] 4. MethodError が発生

Slide 40

Slide 40 text

第4問: 文字列以外の replace() (2)《解説》 ● replace(collectio n, «old»=>«new») は、collection 中に 存在する «old» とい う要素を «new» に置 き換えるだけの機能。 ● replace(«文字列», «関数»=>~) は、「その 関数に渡して true が 返ってくる文字を~に 置換する」という動きを する。 replace([1, 2, 3, 2], >(1)=>100) #> [1, 2, 3, 2] replace([1, isodd, 2, iseven], isodd=>100) #> [1, 100, 2, iseven] replace("1232", >('1')=>'X') #> "1XXX"

Slide 41

Slide 41 text

第 5 問

Slide 42

Slide 42 text

第5問: replace() の do ブロック構文 次のうち、動作するものを すべて選べ(複数回答) # 1. replace("ABC") do v v > 'A' ? 'X' : v end # 2. replace([1, 2, 3]) do v v > 1 ? 100 : v end # 3. replace(Set([1, 2, 3])) do v v > 1 ? 100 : v end # 4. replace(Dict(:a=>1, :b=>2, :c=>3)) do (k, v) k=>(v > 1 ? 100 : v) end

Slide 43

Slide 43 text

第5問: replace() の do ブロック構文《解答》 次のうち、動作するものを すべて選べ(複数回答) # 1. replace("ABC") do v v > 'A' ? 'X' : v end #! MethodError # 2. replace([1, 2, 3]) do v v > 1 ? 100 : v end #> [1, 100, 100] # 3. replace(Set([1, 2, 3])) do v v > 1 ? 100 : v end #> Set([1, 100]) # 4. replace(Dict(:a=>1, :b=>2, :c=>3)) do (k, v) k=>(v > 1 ? 100 : v) end #> Dict(:a=>1, :b=>100, :c=>100)

Slide 44

Slide 44 text

第5問: replace() の do ブロック構文《解説》 ● replace(collecti on) do «old»; ~; end は、do ブ ロックの戻り値に従っ て要素を置換 する。 ● replace(«文字列») do ~ はサポートさ れていない。 replace([1, 2, 3]) do v v > 1 ? 100 : v end #> [1, 100, 100] replace("ABC") do v v > 'A' ? 'X' : v end #! MethodError

Slide 45

Slide 45 text

第5問: replace() の do ブロック構文《補足》 ● 配列に対する replace(arr) do v ~ は実質 map(arr) do v ~ と同等。 ● 配列以外のコレクションに対 する replace(collection) do ~ は map() の代わり に「要素を加工して新しい (同じ型の)コレクションを生 成」する目的にも使える。 ● 破壊的関数 replace!(~) を使えばコレクションの更新 も可能。 dic = Dict(v=>v for v=0:3); replace!(dic) do (k, v) (k - k % 2)=>v end; dic #> Dict(0=>1, 2=>3) # ↑どうしてこうなるか考えてみよう!

Slide 46

Slide 46 text

第 6 問

Slide 47

Slide 47 text

第6問: pairs() 以下の説明について 誤っているもの はどれか? 1. Julia では enumerate(arr) より pairs(arr) が推奨される。 2. pairs(arr)(arr isa AbstractVector)は、配列(ベクトル)のインデックス と値の タプルを列挙するイテレータを返す。 3. pairs(IndexLinear(), arr)(arr は2次元以上の配列)という書き方もで きる。 4. pairs(dict)(dict isa Dict)は、引数に渡した辞書 dict そのものを返 す。

Slide 48

Slide 48 text

第6問: pairs() 《解答》 以下の説明について 誤っているもの はどれか? 1. Julia では enumerate(arr) より pairs(arr) が推奨される。 2. pairs(arr)(arr isa AbstractVector)は、配列(ベクトル)のインデックス と値の タプルを列挙するイテレータを返す。 3. pairs(IndexLinear(), arr)(arr は2次元以上の配列)という書き方もで きる。 4. pairs(dict)(dict isa Dict)は、引数に渡した辞書 dict そのものを返 す。

Slide 49

Slide 49 text

第6問: pairs() 《解説 1》 ● pairs(coll) は、 coll の「キー」と「値」 の ペア(Pair)を列挙 するイテレータを返す 関数。 ● coll は配列だけで なく、keys(coll) が動作するもの なら 何でもOK(文字列も OK) eltype(pairs([1, 2, 3])) #> Pair{Int64, Int64} str = "あいう"; for (idx, chr) in pairs(str) @assert str[idx] == chr end # ↑ `enumerate(str)` だとこうはいかない

Slide 50

Slide 50 text

第6問: pairs() 《解説 2》 ● pairs(«IndexStyl e», arr) のように 第1引数に インデック ススタイルを指定する ことも可能。 ● Dict はそれ自体が キーと値のペアを列 挙するイテレータとし て動作するので、 pairs(dict::Dict ) は dict そのもの を返す。 pairs([1 2; 3 4]) |> collect #> [CartesianIndex(1, 1)=>1 CartesianIndex(1, 2)=>2 #> CartesianIndex(2, 1)=>3 CartesianIndex(2, 2)=>4] pairs(IndexLinear(), [1 2; 3 4]) |> collect #> [1=>1 3=>2 #> 2=>3 4=>4] pairs(Dict(:a=>1, :b=>2)) == Dict(:a=>1, :b=>2) #> true

Slide 51

Slide 51 text

第 7, 8 問

Slide 52

Slide 52 text

第7問: => (1) print(=>) の実行結果は? 1. 「=>」が出力される 2. 「Pair」が出力される 3. 「Tuple」が出力される 4. 文法エラー(ParseError) 第8問: => (2) a=>b=>c の実行結果は? 1. (a=>b)=>c (左結合) 2. a=>(b=>c) (右結合) 3. (a, b, c) (3値タプル) 4. 文法エラー(ParseError)

Slide 53

Slide 53 text

第7問: => (1) 《解答》 print(=>) の実行結果は? 1. 「=>」が出力される 2. 「Pair」が出力される 3. 「Tuple」が出力される 4. 文法エラー(ParseError) 第8問: => (2) 《解答》 a=>b=>c の実行結果は? 1. (a=>b)=>c (左結合) 2. a=>(b=>c) (右結合) 3. (a, b, c) (3値タプル) 4. 文法エラー(ParseError)

Slide 54

Slide 54 text

第7, 8問: => 《解説》 ● =>(ペア演算子)は、実は Pair 型のエイリアス! a => b は Pair(a, b) と同じ意味 になる。タプ ルではない。 ● Julia の => は文法要素 ではなく純粋に演算子。 なので print(=>) など というコードも別にエラー にならない。 ● 右結合 となっており a=>b=>c は a=>(b=>c) と同等となる。 print(=>) ## Pair (:a => 1) === Pair(:a, 1) #> true (:a => (:b => :c)) == (:a => :b => :c) != ((:a => :b) => :c) #> true (:a => :b => :c) != (:a, :b, :c) #> true

Slide 55

Slide 55 text

第 9 問

Slide 56

Slide 56 text

第9問: 標準ライブラリ(標準パッケージ) (1) Julia 標準パッケージについて正しい説明はどれ? 1. ArgTools は コマンドライン引数を扱う パッケージ 2. Dates パッケージで扱える日付の最大値は 146138512年12月31日 である 3. Tar パッケージは .tar.gz ファイルは扱えない 4. UUIDs パッケージは最新の uuidv7 にも対応済 である

Slide 57

Slide 57 text

第9問: 標準ライブラリ(標準パッケージ) (1)《解答》 Julia 標準パッケージについて正しい説明はどれ? 1. ArgTools は コマンドライン引数を扱う パッケージ 2. Dates パッケージで扱える日付の最大値は 146138512年12月31日 である 3. Tar パッケージは .tar.gz ファイルは扱えない 4. UUIDs パッケージは最新の uuidv7 にも対応済 である

Slide 58

Slide 58 text

第9問: 標準ライブラリ(標準パッケージ) (1)《解説》 ● ArgTools は ファイル入出力やデータ処理のためのユーティリ ティパッケージ。 ● typemax(Dates.Date) == Date(252522163911149, 12, 31)  ● Tar パッケージは tarball を扱えるが、各種圧縮形式には対応 していない。 ● UUIDs で最新の uuidv7 がサポートされるのは Julia v1.12 以降の予定(nightly build では利用できる)。

Slide 59

Slide 59 text

第 10 問

Slide 60

Slide 60 text

第10問: 標準ライブラリ(標準パッケージ) (2) Julia 標準パッケージについて 誤っている 説明はどれ? 1. using Downloads しなくても download() 関数は利用でき る(ただし機能制限がある) 2. Printf の @printf マクロでは 動的精度(桁数等)は扱えない 3. Profiling は CPU と メモリ のプロファイリング に対応している 4. Random パッケージは ランダム文字列の生成にも対応 している

Slide 61

Slide 61 text

第10問: 標準ライブラリ(標準パッケージ) (2)《解答》 Julia 標準パッケージについて 誤っている 説明はどれ? 1. using Downloads しなくても download() 関数は利用でき る(ただし機能制限がある) 2. Printf の @printf マクロでは 動的精度(桁数等)は扱えない 3. Profiling は CPU と メモリ のプロファイリング に対応している 4. Random パッケージは ランダム文字列の生成にも対応 している

Slide 62

Slide 62 text

● Printf の書式文字列 が Julia v1.10 から 拡張され、%*s や %*.*f などの書式で 動的幅/動的精度 が サポートされた。 第10問: 標準ライブラリ(標準パッケージ) (2)《解説》 using Printf let ss=["あ","いう","えおか"] maxw = maximum(textwidth.(ss)) for s=ss @printf("%*s\n", maxw, s) end end ## あ ## いう ## えおか

Slide 63

Slide 63 text

まとめ

Slide 64

Slide 64 text

まとめ ● Julia 標準API も日々進化! ● みんな 標準API 極めよう! ● Julia 楽しいよ!

Slide 65

Slide 65 text

参考

Slide 66

Slide 66 text

参考文献・リンク等 ● julialang.org(Julia 本家サイト) ○ Julia Documentation (v1.10)

Slide 67

Slide 67 text

ご清聴ありがとうございます。