Archive for 5月, 2017

2017/05/21 与えられた数が素数かどうかチェック v2

与えられた数が素数かどうか(素数テーブルを使わずに)チェックするAppleScriptの改良版です。

C言語などの他の言語での実装を確認していたら、「あれ、ループ範囲がチェック値の半分になってるぞ」と気づき、理由に思い当たって修正したものです。

よくよく考えてみたら、素数というのは「1とそれ以外で割ることのできない数」なわけですが、その範囲で最小の素数が2なので、素数チェックの範囲は「2から(その数-1)」ではなく、「2から(その数÷2)」の間でチェックすればよいことに。当初行っていたループ処理の半分の時間で素数チェックが行えます。

AppleScript名:与えられた数が素数かどうかチェック v2
– Created 2017-05-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
–http://piyocast.com/as/archives/4659

set pRes to checkPrimeNumber(9973) of me
–> true

set pRes to checkPrimeNumber(24) of me
–> false

set pRes to checkPrimeNumber(1021) of me
–> true

set pRes to checkPrimeNumber(311) of me
–> true

–素数チェック
on checkPrimeNumber(aNum as integer)
  if aNum < 1 then error “Number is smaller than 1.”
  
repeat with i from 2 to (aNum div 2)
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

★Click Here to Open This Script 

2017/05/20 与えられた数が素数かどうかチェック(PrimeNumberHelper)

オープンソースのprime-number-objc(By NazarYavornytskyy)中のPrimeNumberHelperをFramework化した「primeNumKit」を呼び出して指定の数が素数かどうかをチェックするAppleScriptです。

また、「primeNumKit」を利用した素因数分解のScriptも掲載しておきます。

OS X 10.10以降用にビルドしたフレームワークのバイナリを用意しておきました。興味のある方は自己責任で~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

素数のチェックで対象の数が大きく、かつ素数である場合には処理に時間がかかってしまいます。一方で、チェック対象の数がそれほど大きくない場合には、AppleScriptだけでループ処理した方がObjective-Cのプログラムを呼び出すよりも高速なケースが多々あります。

そこで、場合分けしてAppleScriptとObjective-Cのプログラムを選択的に呼び出すようにすると演算性能を維持できるようです。応用範囲が広いため、素数のチェックは割と重要です。

AppleScript名:与えられた数が素数かどうかチェック(PrimeNumberHelper)
– Created 2017-05-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “primeNumKit”
–https://github.com/NazarYavornytskyy/prime-number-objc
–http://piyocast.com/as/archives/4656

set aPrime to current application’s PrimeNumberHelper’s alloc()’s init()
set a to 75777773
set aRes to (aPrime’s isPrime:a) as boolean

★Click Here to Open This Script 

AppleScript名:簡単な素因数分解v4
– Created 2017-05-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “primeNumKit”
–https://github.com/NazarYavornytskyy/prime-number-objc
–http://piyocast.com/as/archives/4656

set aRes to getPrimeFactor(56) of me
–> {2, 3, 3}

set aRes to getPrimeFactor(4999999) of me
–> {2, 127}

set aRes to getPrimeFactor(9999991) of me
–> {1021} –素数

–与えられた数を素因数分解する
on getPrimeFactor(aTargNum)
  copy aTargNum to a
  
set pFactList to {}
  
  
repeat
    set pRes to checkPrimeNumber(a) of me
    
if pRes = true then
      set the end of pFactList to a
      
return pFactList
    end if
    
    
set aFactor to checkFactor(a) of me
    
set the end of pFactList to aFactor
    
set a to a div aFactor
  end repeat
end getPrimeFactor

–素数チェック
on checkPrimeNumber(aNum)
  if aNum < 10000 then –0.25秒以上かかりそうな処理はCocoaで処理(実測値ベース)
    return checkPrimeNumberSub1(aNum) of me
  else
    set aPrime to current application’s PrimeNumberHelper’s alloc()’s init()
    
return (aPrime’s isPrime:aNum) as boolean
  end if
end checkPrimeNumber

–小さい数の場合の素数検出
on checkPrimeNumberSub1(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumberSub1

–素因数チェック
on checkFactor(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return i
    end if
  end repeat
end checkFactor

★Click Here to Open This Script 

2017/05/20 最小公倍数を求める

2つの数の最小公倍数を求めるAppleScriptです。

最大公約数や素数チェックや素因数分解を作ったので、ついでにこの手の計算を行ってみました。

AppleScript名:最小公倍数を求める
– Created 2017-05-20 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4654

set a1Num to 75
set b1Num to 315
set cRes to getLCMbetweenTwoNums(a1Num, b1Num) of me
–> 1575

–2つの数の最小公倍数を求める
on getLCMbetweenTwoNums(a1Num, b1Num)
  set aGCD to getGCDbetweenTwoNums(a1Num, b1Num) of me
  
set a2Num to a1Num div aGCD
  
set b2Num to b1Num div aGCD
  
return (aGCD * a2Num * b2Num)
end getLCMbetweenTwoNums

–2つの数の最大公約数を求める
on getGCDbetweenTwoNums(aNum, bNum)
  set aRes to getPrimeFactor(aNum) of me
  
set bRes to getPrimeFactor(bNum) of me
  
  
–2つのリストを集合として扱い、積集合を求める
  
set aSet to current application’s NSMutableSet’s setWithArray:aRes
  
set bSet to current application’s NSMutableSet’s setWithArray:bRes
  
aSet’s intersectSet:bSet
  
set cRes to aSet’s allObjects() as list
  
  
set dRes to multipleListElements(cRes) of me
  
return dRes
end getGCDbetweenTwoNums

–与えられた数を素因数分解する
on getPrimeFactor(aTargNum)
  copy aTargNum to a
  
set pFactList to {}
  
  
repeat
    set pRes to checkPrimeNumber(a) of me
    
if pRes = true then
      set the end of pFactList to a
      
return pFactList
    end if
    
    
set aFactor to checkFactor(a) of me
    
set the end of pFactList to aFactor
    
set a to a div aFactor
  end repeat
end getPrimeFactor

–素数チェック
on checkPrimeNumber(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

–素因数チェック
on checkFactor(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return i
    end if
  end repeat
end checkFactor

–リスト内の要素をすべて乗算する
on multipleListElements(aList)
  set aNum to 1
  
set aRes to 1
  
repeat with i in aList
    set aRes to aRes * (aNum * i)
  end repeat
  
return aRes
end multipleListElements

★Click Here to Open This Script 

2017/05/20 最大公約数を求めるv2

2つの数の最大公約数を求めるAppleScriptです。

素数チェックや素因数分解を作ったので、この手の計算を行ってみました。

AppleScript名:最大公約数を求めるv2
– Created 2017-05-20 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4653

set aRes to getGCDbetweenTwoNums(12, 18) of me
–> 6

–2つの数の最大公約数を求める
on getGCDbetweenTwoNums(aNum, bNum)
  set aRes to getPrimeFactor(aNum) of me
  
set bRes to getPrimeFactor(bNum) of me
  
  
–2つのリストを集合として扱い、積集合を求める
  
set aSet to current application’s NSMutableSet’s setWithArray:aRes
  
set bSet to current application’s NSMutableSet’s setWithArray:bRes
  
aSet’s intersectSet:bSet
  
set cRes to aSet’s allObjects() as list
  
  
set dRes to multipleListElements(cRes) of me
  
return dRes
end getGCDbetweenTwoNums

–与えられた数を素因数分解する
on getPrimeFactor(aTargNum)
  copy aTargNum to a
  
set pFactList to {}
  
  
repeat
    set pRes to checkPrimeNumber(a) of me
    
if pRes = true then
      set the end of pFactList to a
      
return pFactList
    end if
    
    
set aFactor to checkFactor(a) of me
    
set the end of pFactList to aFactor
    
set a to a div aFactor
  end repeat
end getPrimeFactor

–素数チェック
on checkPrimeNumber(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

–素因数チェック
on checkFactor(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return i
    end if
  end repeat
end checkFactor

–リスト内の要素をすべて乗算する
on multipleListElements(aList)
  set aNum to 1
  
set aRes to 1
  
repeat with i in aList
    set aRes to aRes * (aNum * i)
  end repeat
  
return aRes
end multipleListElements

★Click Here to Open This Script 

2017/05/20 1箇所から別の箇所の方位を求める

1箇所から別の箇所の方位を求めるAppleScriptです。

主な三角関数を呼び出すためにBridgePlus AppleScript Librariesを、atan2関数を呼ぶためにSatimage OSAXを利用しています。

まだ正確かどうか検証しながら使っている状態なので、正しく方位が計算できているかわかりません。間違っている箇所がある可能性も否定できません。

テスト用の緯度経度情報は、住所情報からYaooの住所ジオコーダーAPIを使って求めました(日本測地系で)。

atan2はこういう用途で必要なので(こういう用途でもないと使わなさそうですが)、BridgePlusの機能に組み込んでもらえるようにShane Stanleyにお願いしているところです。

いっそ、Numbersで組み込み関数を一気に増やしたCephes Mathematical Libraryでも呼び出せるようにするといいのに、とは思っていますが・・・Cの関数ライブラリなのでObjective-Cでいったんラッピングする必要があるので大変そうです。

geo1_resized.png

geo2_resized.png

geo3_resized.png

geo4_resized.png

geo5_resized.png

AppleScript名:1箇所から別の箇所の方位を求める
– Created 2017-04-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use bPlus : script “BridgePlus”
–http://zurb.com/forrst/posts/Direction_between_2_CLLocations-uAo
–http://piyocast.com/as/archives/4647

set coord1 to {latitude:35.73677496, longitude:139.63754457} –中村橋駅

set coord2 to {latitude:35.78839012, longitude:139.61241447} –和光市駅
set dirRes to calcDirectionBetweenTwoPlaces(coord1, coord2) of me
–>  -25.925429877542

set coord2 to {latitude:35.7227821, longitude:139.63860897} –鷺宮駅
set dirRes to calcDirectionBetweenTwoPlaces(coord1, coord2) of me
–>  175.649833487804

set coord2 to {latitude:35.73590542, longitude:139.62986745} –富士見台駅
set dirRes to calcDirectionBetweenTwoPlaces(coord1, coord2) of me
–>  -96.385293928667

set coord2 to {latitude:35.73785024, longitude:139.65339321} –練馬駅
set dirRes to calcDirectionBetweenTwoPlaces(coord1, coord2) of me
–>  85.959474671834

set coord2 to {latitude:35.71026838, longitude:139.81215754} –東京スカイツリー
set dirRes to calcDirectionBetweenTwoPlaces(coord1, coord2) of me
–>  96.826542737106

–位置情報1から位置情報2の方角を計算。北が0度
on calcDirectionBetweenTwoPlaces(coord1, coord2)
  load framework
  
set deltaLong to (longitude of coord2) - (longitude of coord1)
  
set yComponent to bPlus’s sinValueOf:deltaLong
  
set xComponent to (bPlus’s cosValueOf:(latitude of coord1)) * (bPlus’s sinValueOf:(latitude of coord2)) - (bPlus’s sinValueOf:(latitude of coord1)) * (bPlus’s cosValueOf:(latitude of coord2)) * (bPlus’s cosValueOf:deltaLong)
  
  
set vList to {yComponent, xComponent}
  
set radians to atan2 vList —Requires SatImage OSAX
  
set degreeRes to (radToDeg(radians) of me)
  
  
return degreeRes
end calcDirectionBetweenTwoPlaces

on radToDeg(aRadian)
  return aRadian * (180 / pi)
end radToDeg

★Click Here to Open This Script 

2017/05/19 FileMaker Pro 16でセキュリティ機能が追加される

先日、FileMaker Proの最新バージョンv16が発表され、FileMakerからお試し版がダウンロードできるようになりました。

手元のデータベースを試してみたところ、メニューから(AppleScriptを呼び出している)FileMaker Scriptを実行したら実行権限エラーに。

display dialog程度のコマンドが書いてあるAppleScriptでは実行権限エラーにはなりません。正確に書けば、

「FileMaker Proを操作するAppleScriptがFileMakerスクリプトステップ中に書かれていた場合には実行権限エラーになる」

という状態です。ただし、これは仕様にもとづく動作であり、バグではありません。

FileMaker Pro 16では、アクセス権セットの「拡張アクセス権」で、詳細なシステムへのアクセス機能の許可/禁止が行えるようになったようです。

FileMaker Script中でAppleScriptを実行していると、「Apple EventおよびActive-XによるFileMaker操作の実行を許可」の項目にひっかかってAppleScriptの実行が遮断されるとのこと。

FileMaker Script中におけるAppleScriptの実行を許可するためには、この、

  「Apple EventおよびActive-XによるFileMaker操作の実行を許可」

にチェックを入れておく必要があります。

私が気づいていなかっただけで、より以前のFileMaker Proで追加されていた機能である可能性もあります。

2017/05/18 16進数文字列を10進数数値に変換するv2

16進数文字列をCocoaの機能を利用して10進数数値に変換するAppleScriptです。

以前、Pure AppleScriptで組んだものがありましたが、ためしにCocoaの機能を利用して実行速度を比較してみました。

 Pure AppleScript版:0.03秒ぐらい
 本AppleScript:0.02秒ぐらい

Cocoaの機能を呼び出すAppleScriptObjCのScriptは、Pure AppleScriptにくらべて1回目の実行がやや遅くなるものの、同じ処理を複数回呼び出すと2回目以降の速度が大幅に上がる傾向があります。繰り返し実行する場合にはAppleScriptObjC版のほうがおすすめです。

AppleScript名:16進数文字列を10進数数値に変換するv2
– Created 2017-05-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4645

set aHex to “0×9AC”
set hNum to retIntFromHexString(aHex) of me

on retIntFromHexString(aHex as string)
  set {aRes, hexRes} to (current application’s NSScanner’s scannerWithString:aHex)’s scanHexInt:(reference)
  
if aRes = false then
    return “” –エラーの場合
  else
    return hexRes
  end if
end retIntFromHexString

★Click Here to Open This Script 

2017/05/18 簡単な素因数分解v3

簡単な素因数分解を行うAppleScriptです。

これまで、素数のチェックを行う手間を省いて素数リストをデータに持って素因数分解を行ったりはしていましたが、素数のチェック自体はそれほど難しくないことに気づきまして(汗)

  「素数=1とそれ自体以外で割り切れない数」

ということで、普通に2から対象の数-1までループして、途中で割り切れたら素数ではない、というだけでチェックが可能でした。

素数のチェックさえ計算できてしまえば、応用で素因数分解も簡単なので、すぐに素因数分解までできました。

本格的に使うのであれば、素数計算の結果を「計算キャッシュ」としてファイルにキャッシュしておき、同じ数の素数判定演算を2回目以降は行わないようにするとよさそうです。ループで計算を行うコスト(時間)と、計算キャッシュの内容を取り出すコスト(時間)を実際に計測して釣り合いが取れるかどうか確認する必要はあるでしょう。

ループして割り切れないかどうかチェックしているだけなので、チェック対象の数値が大きくなると純粋に処理時間が伸びてしまいます。75777773の素数チェックを行ってみたら、本Scriptでは35秒。Objective-Cの素数チェックルーチンをFramework化して呼び出してみたら0.23秒でした。キャッシュするよりも、Objective-CのFrameworkを呼び出してみたほうが速度的にメリットが大きいかもしれません。

ただ、チェック対象の数が小さいと、Framework呼び出しの方が遅くなる傾向がありました。複数の手段をミックスして、チェック対象の数の大きさで場合分けするのがいいのかも。

AppleScript名:与えられた数が素数かどうかチェック
– Created 2017-05-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
–http://piyocast.com/as/archives/4644

set pRes to checkPrimeNumber(24) of me
–> false

set pRes to checkPrimeNumber(1021) of me
–> true

set pRes to checkPrimeNumber(311) of me
–> true

–素数チェック
on checkPrimeNumber(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

★Click Here to Open This Script 

AppleScript名:簡単な素因数分解v3
– Created 2017-05-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
–http://piyocast.com/as/archives/4644

set aRes to getPrimeFactor(18) of me
–> {2, 3, 3}

set aRes to getPrimeFactor(254) of me
–> {2, 127}

set aRes to getPrimeFactor(1021) of me
–> {1021} –素数

–与えられた数を素因数分解する
on getPrimeFactor(aTargNum)
  copy aTargNum to a
  
set pFactList to {}
  
  
repeat
    set pRes to checkPrimeNumber(a) of me
    
if pRes = true then
      set the end of pFactList to a
      
return pFactList
    end if
    
    
set aFactor to checkFactor(a) of me
    
set the end of pFactList to aFactor
    
set a to a div aFactor
  end repeat
end getPrimeFactor

–素数チェック
on checkPrimeNumber(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

–素因数チェック
on checkFactor(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return i
    end if
  end repeat
end checkFactor

★Click Here to Open This Script 

2017/05/16 MatRによる行列データの取り扱い

MatR(By David Cox)をFramework化した「DCMatrix.framework」を呼び出して行列データのハンドリングを行うAppleScriptです。

行列データの作成、入力、演算、出力などをひととおり試してみたものです(野球でいえば、素振りのレベル。でも、これをやっておかないと高度なScriptが組めない、、、)。

OS X 10.10以降用にビルドしたフレームワークのバイナリを用意しておきました。興味のある方は自己責任で~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

AppleScriptで行列を扱うのに、仏Satimage Softwareが提供しているOSAX「Numerics OSAX」を用いるのが一般的です。

ただ、数値変数の表現レンジ(指数表示を使わずに表現できる幅)が1E10ぐらいのAppleScriptの数値演算で、行列が扱えても実用上どうなんだろうと疑問に思っておりました。Numerics OSAX内で高精度の数値型のデータが使えるようではあるものの、外部とやりとりする場合には当然のごとく精度が落ちてしまいます。

# Satimage SoftwareのNumerics OSAXは、高速フーリエ変換とか画像処理とか、3次元配列の計算など、私には使い切れないほど高度な演算を提供してくれるOSAXなので、ぜひ知っておいていただきたいものです

ときに、そんなAppleScriptの数値ハンドリング機能でも、機械学習などの分野においては数値の表現レンジが大きくなくてよいので、割とよさそうです。

そうした利用分野では、CSVやタブ区切りテキストファイルから行列データを取得するケースが多いので、ファイルや配列から行列データを作成する手段を探していました。機械学習、とまで気合を入れなくても線形回帰分析(Linear Regression)を行うための準備として、このMatRを試してみたものです。

線形回帰分析の原理は、KeynoteやNumbersのグラフ「分散図」で実感することができます。「月ごとの平均気温とビール消費量の関係」「広告宣伝費と来店者数」など、グラフ化してみるととてもよく相関が見てとれます。

sample_graph.png

AppleScript名:MatRのじっけん v1
– Created 2017-05-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “DCMatrix”
–https://github.com/davidcox95/MatR
–http://piyocast.com/as/archives/4640

set aMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:5) andRows:3 byColumns:4
set aList to (aMatrix’s |print|())
(*
5 5 5 5
5 5 5 5
5 5 5 5
*)

set bMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:3) andRows:4 byColumns:3
set bScalar to current application’s NSNumber’s numberWithDouble:2
set bRes to bMatrix’s addScalar:bScalar
bRes’s |print|()
(*
5 5 5
5 5 5
5 5 5
5 5 5
*)

set cScalar to current application’s NSNumber’s numberWithDouble:2
set cRes to bMatrix’s subtractScalar:cScalar
cRes’s |print|()
(*
1 1 1
1 1 1
1 1 1
1 1 1
*)

set dScalar to current application’s NSNumber’s numberWithDouble:2
set eRes to bMatrix’s multiplyScalar:dScalar
eRes’s |print|()
(*
6 6 6
6 6 6
6 6 6
6 6 6
*)

set fScalar to current application’s NSNumber’s numberWithDouble:2
set fRes to bMatrix’s divideScalar:fScalar
fRes’s |print|()
(*
1.5 1.5 1.5
1.5 1.5 1.5
1.5 1.5 1.5
1.5 1.5 1.5
*)

set m4 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:4) andRows:3 byColumns:3
set m2 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:2) andRows:3 byColumns:3
set gRes to m4’s addMatrix:m2
gRes’s |print|()
(*
6 6 6
6 6 6
6 6 6
*)

set hRes to m4’s subtractMatrix:m2
hRes’s |print|()
(*
2 2 2
2 2 2
2 2 2
*)

set iRes to m4’s multiplyMatrix:m2
iRes’s |print|()
(*
24 24 24
24 24 24
24 24 24
*)

★Click Here to Open This Script 

AppleScript名:MatRのじっけん v2
– Created 2017-05-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “DCMatrix”
–https://github.com/davidcox95/MatR
–http://piyocast.com/as/archives/4640

set aMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:5) andRows:3 byColumns:4
set aList to doubleListFromMatrix(aMatrix) of me
–>  {{5.0, 5.0, 5.0, 5.0}, {5.0, 5.0, 5.0, 5.0}, {5.0, 5.0, 5.0, 5.0}}

set bList to intListFromMatrix(aMatrix) of me
–>  {{5, 5, 5, 5}, {5, 5, 5, 5}, {5, 5, 5, 5}}

set cList to strListFromMatrix(aMatrix) of me
–>  {{”5″, “5″, “5″, “5″}, {”5″, “5″, “5″, “5″}, {”5″, “5″, “5″, “5″}}

set bMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:3) andRows:4 byColumns:3
set bScalar to current application’s NSNumber’s numberWithDouble:2
set bRes to bMatrix’s addScalar:bScalar
set bbRes to intListFromMatrix(bRes) of me
–>  {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}, {5, 5, 5}}

set cScalar to current application’s NSNumber’s numberWithDouble:2
set cRes to bMatrix’s subtractScalar:cScalar
set ccRes to intListFromMatrix(cRes) of me
–>  {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}

set dScalar to current application’s NSNumber’s numberWithDouble:2
set eRes to bMatrix’s multiplyScalar:dScalar
set eeRes to intListFromMatrix(eRes) of me
–>  {{6, 6, 6}, {6, 6, 6}, {6, 6, 6}, {6, 6, 6}}

set fScalar to current application’s NSNumber’s numberWithDouble:2
set fRes to bMatrix’s divideScalar:fScalar
set ffRes to doubleListFromMatrix(fRes) of me
–>  {{1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}}

set m4 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:4) andRows:3 byColumns:3
set m2 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:2) andRows:3 byColumns:3
set gRes to m4’s addMatrix:m2
set ggRes to intListFromMatrix(gRes) of me
–>  {{6, 6, 6}, {6, 6, 6}, {6, 6, 6}}

set hRes to m4’s subtractMatrix:m2
set hhRes to intListFromMatrix(hRes) of me
–>  {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}

set iRes to m4’s multiplyMatrix:m2
set iiRes to intListFromMatrix(iRes) of me
–>  {{24, 24, 24}, {24, 24, 24}, {24, 24, 24

on doubleListFromMatrix(aMatrix)
  set aList to {}
  
set aRows to aMatrix’s rows()
  
set aColumns to aMatrix’s columns()
  
  
repeat with rowC from 0 to (aRows - 1)
    set colList to {}
    
repeat with colC from 0 to (aColumns - 1)
      set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as real
    end repeat
    
set the end of aList to colList
  end repeat
  
return aList
end doubleListFromMatrix

on intListFromMatrix(aMatrix)
  set aList to {}
  
set aRows to aMatrix’s rows()
  
set aColumns to aMatrix’s columns()
  
  
repeat with rowC from 0 to (aRows - 1)
    set colList to {}
    
repeat with colC from 0 to (aColumns - 1)
      set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as integer
    end repeat
    
set the end of aList to colList
  end repeat
  
return aList
end intListFromMatrix

on strListFromMatrix(aMatrix)
  set aList to {}
  
set aRows to aMatrix’s rows()
  
set aColumns to aMatrix’s columns()
  
  
repeat with rowC from 0 to (aRows - 1)
    set colList to {}
    
repeat with colC from 0 to (aColumns - 1)
      set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as string
    end repeat
    
set the end of aList to colList
  end repeat
  
return aList
end strListFromMatrix

★Click Here to Open This Script 

AppleScript名:MatRのじっけん v3
– Created 2017-05-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “DCMatrix”
–https://github.com/davidcox95/MatR
–http://piyocast.com/as/archives/4640

–listからMatrixを作る
set mList to {{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}}
set aMatrix to current application’s |Matrix|’s alloc()’s initWithArray:mList andRows:3 byColumns:4
aMatrix’s |print|()
(*
1 2 3 4
11 12 13 14
21 22 23 24
*)

set a1Res to aMatrix’s |transpose|() –左回転
(
a1Res’s |print|())
(*
1 11 21
2 12 22
3 13 23
4 14 24
*)

★Click Here to Open This Script 

tab_sep_text.png

AppleScript名:MatRのじっけん v4
– Created 2017-05-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “DCMatrix”
–https://github.com/davidcox95/MatR
–http://piyocast.com/as/archives/4640

–タブ区切りテキストファイルからMatrixを作る
set aPosixFile to POSIX path of (choose file)
set aMatrix to current application’s |Matrix|’s alloc()’s initWithContentsFromFile:aPosixFile
aMatrix’s |print|()
(*
5 6 7 8
3 4 5 6
1 2 3 4
*)

★Click Here to Open This Script 

2017/05/15 感情推定(極性判定) v2

apitoreのREST API「感情推定(極性判定) v2」を呼び出すAppleScriptです。

400文字以下のテキストを解析して、極性(感情)を判定します。ただし、文章が短すぎると判定しづらくなる傾向があるようです。これまでの感情推定APIではpositive/negativeとして判定する傾向があったため、このv2 APIではneutralとして判定する幅を広めにとってもらいました。

本Scriptをテストするためには、apitoreにサインアップしてAccess Tokenを取得し、Script末尾の伏字部分にコピー&ペーストしてください(掲載リストをそのまま実行してもエラーになります)。

AppleScript名:感情推定(極性判定) v2
– Created 2017-05-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4639

set aString to "このePubの考え方にそぐわない文章要素がいろいろある。代表的なものは「表」だ。データを掲載しておくのに、「表」は便利な存在だ。書く方からしても、いちいち長々とした文章で説明しなくていいし、読む方からしても整理された情報を読めるわけで、とくにお年寄りに好まれる。ところが、この「表」がePubの出版物にそぐわない。表の幅は変わってほしくないし、文字サイズが大きくなって数ページにわたって表示されるといったことは好ましくない。"
set a1Res to getSentimentFromString(aString) of me
–>  "positive"(なのか?)

on getSentimentFromString(aString)
  set reqURLStr to "https://api.apitore.com/api/39/sentiment-v2/predict"
  
set accessToken to retAccessToken() of me
  
set aRec to {access_token:accessToken, |text|:aString}
  
set aURL to retURLwithParams(reqURLStr, aRec) of me
  
  
set aRes to callRestGETAPIAndParseResults(aURL) of me
  
  
set aRESCode to (responseCode of aRes) as integer
  
if aRESCode is not equal to 200 then return false
  
  
set aRESTres to ((json of aRes)’s valueForKeyPath:"predict.sentiment") as string
  
return aRESTres
end getSentimentFromString

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:"GET"
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
aRequest’s setValue:"application/json" forHTTPHeaderField:"Accept"
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code & Header
  
set dRes to contents of second item of resList
  
if dRes is not equal to missing value then
    set resCode to (dRes’s statusCode()) as number
    
set resHeaders to (dRes’s allHeaderFields()) as record
  else
    set resCode to 0
    
set resHeaders to {}
  end if
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
end callRestGETAPIAndParseResults

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

on retAccessToken()
  return "xxXXXxxX-XxXx-XXXX-xXXX-XXxXXxxXxxXx" –API Tore Access Token
end retAccessToken

★Click Here to Open This Script 

2017/05/14 Twitter ScripterでAppleScriptからTwitter投稿、検索

AppleScriptから利用する専用のGUIなしTwitterクライアント「Twitter Scripter」(By Mousedown)を呼び出してTwitter投稿や検索を行うAppleScriptです。

Twitter Scripterはフリーでダウンロードして利用できます。Twitter Scripterは本当にAppleScriptから呼び出すためだけに作られているので、ユーザーインタフェースは一切ありません。

tw1.png

システム環境設定から確認できる(macOS 10.12, Sierra)、Twitterアカウントの一覧を取得します。Twitterアカウントは複数登録されている可能性があるため、リスト(配列)で返ってきます。

AppleScript名:Twitterアカウントを取得
–http://piyocast.com/as/archives/4636
tell application “Twitter Scripter”
  set availableAccounts to available accounts
  
–> {”piyomaru”}
end tell

★Click Here to Open This Script 

さらに、得られたアカウント一覧から適当なものを選んでTwitter投稿してみましょう。

AppleScript名:Twitterにアカウントを指定して投稿(テキストのみ)
–http://piyocast.com/as/archives/4636
tell application “Twitter Scripter”
  set availableAccounts to available accounts
  
–> {”piyomaru”}
  
  
if length of availableAccounts = 0 then return
  
  
set twitterAccount to first item of availableAccounts
  
–> “piyomaru”
  
  
tweet “てすと” using account twitterAccount
end tell

★Click Here to Open This Script 

twitter2.png

システムからTwitterアカウントを取得しなくても、直接文字列で指定することも(当然)できます。ただし、自分で所有してOSに登録していないTwitterアカウントを指定するとエラー応答が返ってきます。

–> {response:{{}}, action:false}

AppleScript名:Twitterにアカウントを指定して投稿(テキストのみ2)
–http://piyocast.com/as/archives/4636
tell application “Twitter Scripter”
  tweet “てすと” using account “piyomaru”
end tell

★Click Here to Open This Script 

Twitter Scripterからはコマンド実行時に大量のデータが返ってくるため、Cocoaの機能を利用してデータの絞り込みを行うのにぴったりです。むしろ、Cocoaの機能を使わないと大量のデータからのしぼりこみを行うのは大変です。

画像を指定してテキストと一緒に画像を投稿することもできるのですが、画像添付についてはうまく動くときと画像が投稿されないときがあるようです(なんで? どうして???)。

検索も可能で、出力対象にrecent(最近の投稿から)、popular(話題の投稿から)、mixed(デフォルト)の3タイプから選択可能です。出力件数には数値で自由に指定できるようになっていますが、実際にためしてみたところ最大件数は100件のようです。

AppleScript名:Twitterを検索する
tell application “Twitter Scripter”
  set availableAccounts to available accounts
  
if length of availableAccounts = 0 then return
  
  
set anAccount to first item of availableAccounts
  
search for “戦場の絆” using account anAccount returning entries 10 result type “mixed”
end tell

★Click Here to Open This Script 

AppleScript名:Twitterを検索する(最近の投稿から)
tell application “Twitter Scripter”
  set availableAccounts to available accounts
  
if length of availableAccounts = 0 then return
  
  
set anAccount to first item of availableAccounts
  
search for “戦場の絆” using account anAccount returning entries 10 result type “recent” –最近の投稿
end tell

★Click Here to Open This Script 

AppleScript名:Twitterを検索する(話題の投稿から)
tell application “Twitter Scripter”
  set availableAccounts to available accounts
  
if length of availableAccounts = 0 then return
  
  
set anAccount to first item of availableAccounts
  
search for “戦場の絆” using account anAccount returning entries 10 result type “popular” –話題の投稿
end tell

★Click Here to Open This Script 

その他のサンプルScriptもMousedownのWebサイトに掲載されています。

2017/05/12 システムスペルチェック辞書への学習と削除

システムのスペルチェック辞書への学習と削除を行うAppleScriptです。

Shane StanleyがMLに投稿したScriptと、それを元に辞書の言語指定をしてみたものです。

AppleScript名:システムスペルチェック辞書への学習と削除
– Created 2017-01-22 by Shane Stanley
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
–http://piyocast.com/as/archives/4635

–スペルチェック辞書への学習
set theWord to "piyomaru"
set theChecker to current application’s NSSpellChecker’s sharedSpellChecker()
theChecker’s learnWord:theWord
set knewIt to theChecker’s hasLearnedWord:theWord
–>  true

–スペルチェック辞書からの削除
theChecker’s unlearnWord:theWord
set knowsItNow to theChecker’s hasLearnedWord:theWord
return {knewIt, knowsItNow}
–>  {true, false}

★Click Here to Open This Script 

システムスペルチェック辞書で、辞書の言語を指定して学習させてみました。

AppleScript名:ロシア語(ru)のシステムスペルチェック辞書を指定して学習
– Created 2017-05-12 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
–http://piyocast.com/as/archives/4635

set theChecker to current application’s NSSpellChecker’s sharedSpellChecker()

set langList to (theChecker’s availableLanguages()) as list
–>  {"en", "en_GB", "en_CA", "en_IN", "en_SG", "en_AU", "en_JP", "fr", "da", "de", "es", "it", "nl", "nb", "pl", "pt_BR", "pt_PT", "fi", "sv", "tr", "ru", "ko"}

set curCheckerLang to (theChecker’s |language|()) as string
–> "en_GB"

set aWord to "Su-35"
theChecker’s setLanguage:"ru"
theChecker’s learnWord:aWord
set knewIt to theChecker’s hasLearnedWord:aWord
–>  true

set curCheckerLang to (theChecker’s |language|()) as string
–>  "ru"

★Click Here to Open This Script 

2017/05/06 Bing Web Search APIでWebキーワード検索

MicrosoftのBing Web Search APIを呼び出してWebのキーワード検索を行うAppleScriptです。

Microsoft Cognitive Servicesのサイトで、開発者アカウント登録を行えば、本APIについては1か月に1,000回まで無料で使用できます(1秒間に7回までという制限もあります)。

アカウント登録を行い、Bing Web SearchをEnableに設定して、本AppleScriptの末尾のretAPIKey()ハンドラ内にAPI Key 1を入力してください(API Keyを記入したScriptを決してそのまま第三者に配布しないでください。あくまでテストと確認用です)。

個人的にBingは検索エンジンとして常用していません。Google検索にくらべて見つかる情報量が少ないと実感していることがその理由です。そのため、Bingの検索エンジンを呼び出せてもあまりメリットを見出せないところ。あくまで実験の一環です。

AppleScript名:Bing Web Search APIでWebキーワード検索
– Created 2017-05-03 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4634

set aStr to “戦場の絆”

set reqURLStr to “https://api.cognitive.microsoft.com/bing/v5.0/search” –Microsoft Project Oxford
set myAPIkey to retAPIkey() of me –API Primary Key

set aRec to {q:aStr, |count|:“5″, |offset|:“0″, mkt:“ja-JP”}
set bURL to retURLwithParams(reqURLStr, aRec) of me
set aRes to callRestGETAPI(bURL, myAPIkey) of me
set aRESTres to json of aRes
set aRESCode to responseCode of aRes
set aRESHeader to responseHeader of aRes

return (webPages of aRESTres)

–POST methodのREST APIを画像をアップロードしつつ呼ぶ
on callRestGETAPI(aURL, anAPIkey)
  –Request
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“GET”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
aRequest’s setValue:anAPIkey forHTTPHeaderField:“Ocp-Apim-Subscription-Key”
  
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
  
–Parse Results
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
if dRes = missing value then
    set resCode to -1
    
set resHeaders to {}
  else
    set resCode to (dRes’s statusCode()) as integer
    
–Get Response Header
    
set resHeaders to (dRes’s allHeaderFields()) as record
  end if
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestGETAPI

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

on retAPIkey()
  return “XxXxXXxXxXxXXxXXxXXXxXXXxxxxXxxX” –API Key 1
end retAPIkey

★Click Here to Open This Script 

2017/05/04 Analyze Imageで画像認識

MicrosoftのCognitive ServicesのREST APIのひとつ、Computer Vision APIの「Analyze Image」を呼び出して画像認識するAppleScriptです。

Microsoft Cognitive Servicesのサイトで、開発者アカウント登録を行えば、本APIについては1か月に5,000回まで無料で使用できます(1分間に20回までという制限もあります)。

アカウント登録を行い、Analyze ImageをEnableに設定して、本AppleScriptの末尾のretAPIKey()ハンドラ内にAPI Key 1を入力してください(API Keyを記入したScriptを決してそのまま第三者に配布しないでください。あくまでテストと確認用です)。

指定した画像のカテゴリ(Categories)、タグ情報(Tags)、詳細内容(Description)の情報を取得しています。

精度については、実際にテスト画像と得られた認識データを見比べていただくしかありません。カタツムリとか誕生日ケーキとか夕日や花火、ワインボトルなど(!)、驚くほど正確に認識されています。夕日の手前にあるのは飛行機ではないのですが、そのぐらいの誤差はあります(イルカを「犬」と判定されたりもしました)。

ためしに、この結果(Description)をそのままGoogle Tlanstlate APIに渡して日本語訳させ画像のFinderコメント欄に入れる実験などもやってみたところ、面白い結果が得られました(実用性はまだまだですが、言いたいことはわかる、というレベル。個人的には英語のままのほうがわかりやすいかも)。

こうしたサービスを利用して、写真.app(Photos.app)内の写真にすべてタグ付けして、タグをもとに風景の写真だけを新規アルバムに入れて分類するといった使い方はできそうです(すでにやってるし)。そして、AppleのアプリケーションとMicrosoftやGoogleのWebサービスを連携させるといった使い方はAppleが提供するわけがないので、こういう用途こそAppleScriptで勝手に連携させるべきだと思います。

r0010704_resized.png
{{metadata:{width:2592, |format|:”Jpeg”, height:1944}, tags:{{|name|:”fireworks”, confidence:0.998994648457}, {|name|:”outdoor object”, confidence:0.998748064041}}, categories:{{|name|:”dark_fireworks”, score:0.99609375}}, |description|:{tags:{”fireworks”, “object”}, captions:{{|text|:“a close up of fireworks”, confidence:0.233880494749}}}, requestId:”ce5e5c15-f68f-4647-9694-5fb8ede9cd31″}}

r0015213_resized.png
{{metadata:{width:2592, |format|:”Jpeg”, height:1944}, tags:{{|name|:”ground”, confidence:0.999917149544}, {|name|:”animal”, confidence:0.993541717529}, {|name|:”invertebrate”, hint:”animal”, confidence:0.952201843262}, {|name|:”outdoor”, confidence:0.887740492821}, {|name|:”mollusk”, hint:”animal”, confidence:0.814713895321}, {|name|:”snail”, hint:”animal”, confidence:0.649717211723}}, categories:{{|name|:”abstract_texture”, score:0.6015625}}, |description|:{tags:{”animal”, “outdoor”, “shellfish”, “snail”, “piece”, “laying”, “food”, “sitting”, “top”, “surface”, “lying”, “banana”, “close”, “fruit”, “bird”, “beach”, “plate”, “board”, “street”}, captions:{{|text|:“a snail on the ground”, confidence:0.480042590526}}}, requestId:”b290dc83-0e33-41b0-8a39-76c067bcffb8″}}

r0015918_resized.png
{{metadata:{width:2048, |format|:”Jpeg”, height:1536}, tags:{{|name|:”grass”, confidence:0.99923813343}, {|name|:”outdoor”, confidence:0.997150361538}, {|name|:”ground”, confidence:0.972813665867}, {|name|:”standing”, confidence:0.93672734499}, {|name|:”animal”, confidence:0.917161226273}, {|name|:”bird”, confidence:0.824012756348}}, categories:{{|name|:”animal_horse”, score:0.98046875}}, |description|:{tags:{”grass”, “outdoor”, “standing”, “bird”, “animal”, “water”, “field”, “white”, “small”, “walking”, “front”, “sitting”, “parrot”, “brown”, “large”, “grassy”, “green”, “body”, “dirt”, “red”, “river”}, captions:{{|text|:“a bird that is standing in the grass”, confidence:0.859258793309}}}, requestId:”bc5b8778-cf96-4d3c-8ba9-be22b38c36dd”}}

img_2502_resized.png
{{metadata:{width:3264, |format|:”Jpeg”, height:2448}, tags:{{|name|:”sky”, confidence:0.999066531658}, {|name|:”outdoor”, confidence:0.99786490202}, {|name|:”sunset”, confidence:0.880310297012}, {|name|:”distance”, confidence:0.229086950421}}, categories:{{|name|:”outdoor_”, score:0.0078125}, {|name|:”outdoor_waterside”, score:0.5234375}}, |description|:{tags:{”outdoor”, “sunset”, “airplane”, “plane”, “sitting”, “building”, “runway”, “large”, “front”, “water”, “pier”, “top”, “sun”, “track”, “orange”, “light”, “road”, “bridge”, “standing”, “train”, “man”, “jet”, “white”, “city”, “riding”, “red”, “flying”, “bird”, “blue”, “night”, “river”, “tower”, “tarmac”}, captions:{{|text|:“a plane that is in front of a sunset”, confidence:0.493561860724}}}, requestId:”49705b7d-99cb-4234-9af6-b30a32f02ad5″}}

img_0313_resized.png
{{metadata:{width:4032, |format|:”Jpeg”, height:3024}, tags:{{|name|:”indoor”, confidence:0.929384291172}, {|name|:”candle”, confidence:0.877458691597}, {|name|:”birthday”, confidence:0.817751348019}, {|name|:”lit”, confidence:0.53784763813}}, categories:{{|name|:”others_”, score:0.01171875}}, |description|:{tags:{”table”, “indoor”, “cake”, “birthday”, “food”, “sitting”, “lit”, “plate”, “front”, “small”, “top”, “bowl”, “fruit”, “filled”, “chocolate”, “holding”, “man”, “woman”}, captions:{{|text|:“a birthday cake with lit candles”, confidence:0.8700279282}}}, requestId:”62b58a19-2d3a-4f9a-bd54-5aa4460d8385″}}

img_2187_resized.png
{{metadata:{width:3264, format:”Jpeg”, height:2448}, tags:{{name:”bottle”, confidence:0.999316096306}, {name:”table”, confidence:0.987863183022}, {name:”indoor”, confidence:0.968602716923}, {name:”wine”, confidence:0.928377449512}, {name:”alcohol”, confidence:0.846504926682}, {name:”food”, confidence:0.785823404789}, {name:”glass”, confidence:0.782037138939}, {name:”beverage”, confidence:0.776733756065}}, categories:{{name:”drink_”, score:0.90234375}}, description:{tags:{”bottle”, “table”, “indoor”, “wine”, “sitting”, “alcohol”, “food”, “glass”, “beverage”, “cup”, “banana”, “empty”, “top”, “sandwich”, “counter”, “beer”, “phone”, “orange”, “wooden”, “computer”, “laying”}, captions:{{text:“a bottle of wine”, confidence:0.858091829408}}}, requestId:”d2db3a05-fcb0-43bb-8191-89707904918a”}}

r0020016_resized.png
{{metadata:{width:1280, format:”Jpeg”, height:960}, tags:{{name:”sky”, confidence:0.999883055687}, {name:”outdoor”, confidence:0.997511506081}, {name:”person”, confidence:0.910886585712}, {name:”toy”, confidence:0.878364562988}}, categories:{{name:”others_”, score:0.00390625}, {name:”outdoor_”, score:0.01171875}}, description:{tags:{”outdoor”, “person”, “toy”, “thing”, “man”, “white”, “grass”, “standing”, “people”, “field”, “riding”, “jumping”, “doing”, “air”, “holding”, “group”, “trick”, “board”, “statue”, “dog”, “player”, “ramp”}, captions:{{text:“a statue of a man jumping in the air”, confidence:0.153422169506}}}, requestId:”ec5dc466-76c5-47df-b858-2e418ce891a8″}}

r0016164_resized.png
{{metadata:{width:2048, format:”Jpeg”, height:1536}, tags:{{name:”water”, confidence:0.999519586563}, {name:”animal”, confidence:0.993490874767}, {name:”outdoor”, confidence:0.992024421692}, {name:”aquatic mammal”, hint:”animal”, confidence:0.978799343109}, {name:”mammal”, hint:”animal”, confidence:0.914148926735}, {name:”ocean”, confidence:0.804374277592}, {name:”whale”, hint:”animal”, confidence:0.533892810345}, {name:”wave”, confidence:0.527211129665}, {name:”dolphin”, hint:”animal”, confidence:0.340564578772}}, categories:{{name:”outdoor_”, score:0.00390625}}, description:{tags:{”water”, “animal”, “outdoor”, “mammal”, “ocean”, “wave”, “laying”, “brown”, “riding”, “surfing”, “top”, “body”, “lying”, “board”, “large”, “beach”, “floating”, “swimming”, “standing”, “dog”, “young”, “white”, “man”}, captions:{{text:“a dog swimming in the ocean”, confidence:0.604725984086}}}, requestId:”161b6c0f-f3fd-4e06-b4be-d5baa9516e53″}}

AppleScript名:Analyze Image APIで画像認識
– Created 2017-05-03 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4625

set imgFilePath to POSIX path of (choose file of type {“public.jpeg”} with prompt “Select an Image to Analyze”)
set aRes to recogImage(imgFilePath) of me

on recogImage(imgFilePath)
  set reqURLStr to “https://api.projectoxford.ai/vision/v1.0/analyze”
  
set myAPIkey to retAPIkey() of me –API Key 1
  
  
set aRec to {visualFeatures:“Categories,Tags,Description”, details:“Celebrities”, language:“en”}
  
set bURL to retURLwithParams(reqURLStr, aRec) of me
  
  
set aRes to callRestPOSTAPIAndParseResultsWithImage(bURL, imgFilePath, myAPIkey) of me
  
set aRESTres to json of aRes
  
set aRESCode to responseCode of aRes
  
set aRESHeader to responseHeader of aRes
  
  
return (aRESTres as list)
end recogImage

–POST methodのREST APIを画像をアップロードしつつ呼ぶ
on callRestPOSTAPIAndParseResultsWithImage(aURL, imgFilePath, myAPIkey)
  –Get Image Contents from file
  
set imgPathStr to current application’s NSString’s stringWithString:imgFilePath
  
set imgData to current application’s NSData’s dataWithContentsOfFile:imgPathStr
  
set postBody to current application’s NSMutableData’s |data|()
  
postBody’s appendData:imgData
  
  
–Request
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“POST”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
aRequest’s setHTTPBody:postBody
  
aRequest’s setValue:“application/octet-stream” forHTTPHeaderField:“Content-Type”
  
aRequest’s setValue:myAPIkey forHTTPHeaderField:“Ocp-Apim-Subscription-Key”
  
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
  
–Parse Results
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
if dRes = missing value then
    set resCode to -1
    
set resHeaders to {}
  else
    set resCode to (dRes’s statusCode()) as integer
    
–Get Response Header
    
set resHeaders to (dRes’s allHeaderFields()) as record
  end if
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestPOSTAPIAndParseResultsWithImage

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString())
  
  
return aURL
end retURLwithParams

on retAPIkey()
  return “xXXxXXXXxXXxXXXxXXXXXXXXxXXXXXXx” –API Key 1
end retAPIkey

★Click Here to Open This Script