ねぎ嫌い

始業前に学んだことを小出しに。最近はHacker Newsの人気記事をまとめてみたり。

S3からShift JISファイルを取り込んで処理をする(Node.js)

ちょっとハマって悔しかったので。

node.jsがShift_JISの変換をうまいことやってくれない。
変換様のパッケージをインストールする。

npm i iconv-lite npm i -D @types/iconv-lite

UTF-8であれば、以下のように楽に取り込める
なお、Typescript

import { S3 } from 'aws-sdk';

export const loadContent = async(bucket: string, path: string): Promise<string> => {
    const s3: S3 = new S3();
    const params: S3.GetObjectRequest = {
      Bucket: bucket,
      Key: path
    };
    const ret: S3.Types.GetObjectOutput = await s3.getObject(params).promise();
    return ret.Body.toString('utf-8');
}

今回はStream APIを使って、バイナリ形式でファイルを取込み、Shift_JISに変換した。

//... 略

    const stream = s3.getObject(params).createReadStream().pipe(iconv.decodeStream('Shift_JIS'));
    let content = '';
    stream.on('data', d => content += d);


    await new Promise(function(resolve, reject) {
      stream.on('end', () => resolve(stream.read()));
      stream.on('error', reject);
    });

    return content;
}

古き良き時代に生きる私はNode v8.10でしかLambdaを動かせないのでAsync Iteratorが使えない。
多分Async Iteratorが使えると、

    for await (const chunk of stream) {
      content += chunk;
    }

で書けそう。

Requested factory com.ctc.wstx.stax.WstxOutputFactory cannot be locatedで怒られる

wsdlファイルからClientを書こうとして、Eclipseでインポートするときに掲題のエラーが発生した。

いろいろいじった結果、wstx-asl-4.0.0.jarをWEB-INF/lib以下に配置し、eclipseを再起動することで解消。

Exception occurred during code generation for WSDL  : javax.xml.stream.FactoryConfigurationError: Requested factory com.ctc.wstx.stax.WstxOutputFactory cannot be located.  Classloader =org.eclipse.osgi.internal.framework.ContextFinder@4d5361a8
    java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jst.ws.axis2.consumption.core.command.Axis2ClientCodegenCommand.execute(Axis2ClientCodegenCommand.java:222)
    at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.runCommand(CommandFragmentEngine.java:419)
    at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.visitTop(CommandFragmentEngine.java:359)
    at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.moveForwardToNextStop(CommandFragmentEngine.java:254)
    at org.eclipse.wst.command.internal.env.ui.widgets.SimpleCommandEngineManager$6.run(SimpleCommandEngineManager.java:294)
    at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:440)
    at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:356)
    at org.eclipse.jface.wizard.WizardDialog.run(WizardDialog.java:977)
    at org.eclipse.wst.command.internal.env.ui.widgets.SimpleCommandEngineManager.runForwardToNextStop(SimpleCommandEngineManager.java:264)
    at org.eclipse.wst.command.internal.env.ui.widgets.WizardPageManager.runForwardToNextStop(WizardPageManager.java:91)
    at org.eclipse.wst.command.internal.env.ui.widgets.WizardPageManager.performFinish(WizardPageManager.java:262)
    at org.eclipse.wst.command.internal.env.ui.widgets.DynamicWizard.performFinish(DynamicWizard.java:382)
    at org.eclipse.jface.wizard.WizardDialog.finishPressed(WizardDialog.java:775)
    at org.eclipse.jface.wizard.WizardDialog.buttonPressed(WizardDialog.java:414)
    at org.eclipse.jface.dialogs.Dialog.lambda$0(Dialog.java:622)
    at org.eclipse.jface.dialogs.Dialog$$Lambda$55/594043354.accept(Unknown Source)
    at org.eclipse.swt.events.SelectionListener$1.widgetSelected(SelectionListener.java:84)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4131)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1055)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3944)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3547)
    at org.eclipse.jface.window.Window.runEventLoop(Window.java:822)
    at org.eclipse.jface.window.Window.open(Window.java:798)
    at org.eclipse.wst.command.internal.env.ui.widgets.popup.DynamicPopupWizard.run(DynamicPopupWizard.java:130)
    at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:250)
    at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:568)
    at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:400)
    at org.eclipse.jface.action.ActionContributionItem$$Lambda$271/560752677.handleEvent(Unknown Source)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4131)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1055)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3944)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3547)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1173)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1062)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156)
    at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:636)
    at org.eclipse.ui.internal.Workbench$$Lambda$68/2118050088.run(Unknown Source)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:563)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:151)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:155)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:595)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1501)
    Caused by: javax.xml.stream.FactoryConfigurationError: Requested factory com.ctc.wstx.stax.WstxOutputFactory cannot be located.  Classloader =org.eclipse.osgi.internal.framework.ContextFinder@4d5361a8
    at javax.xml.stream.FactoryLocator.loadFactory(FactoryLocator.java:120)
    at javax.xml.stream.FactoryLocator.locate(FactoryLocator.java:109)
    at javax.xml.stream.FactoryLocator.locate(FactoryLocator.java:54)
    at javax.xml.stream.XMLOutputFactory.newInstance(XMLOutputFactory.java:29)
    at org.apache.axis2.util.PolicyUtil.policyComponentToString(PolicyUtil.java:186)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.getInputElement(AxisServiceBasedMultiLanguageEmitter.java:2824)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.generateMethodElement(AxisServiceBasedMultiLanguageEmitter.java:2358)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.loadOperations(AxisServiceBasedMultiLanguageEmitter.java:2242)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.createDOMDocumentForCallbackHandler(AxisServiceBasedMultiLanguageEmitter.java:1232)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.writeCallBackHandlers(AxisServiceBasedMultiLanguageEmitter.java:1198)
    at org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter.emitStub(AxisServiceBasedMultiLanguageEmitter.java:500)
    at org.apache.axis2.wsdl.codegen.CodeGenerationEngine.generate(CodeGenerationEngine.java:282)
    ... 61 more

2017-10-23 Simple Ways to Be Better at Remembering

原文:www.nytimes.com

何かを思い出すための簡単な方法についてのお話。

平均的な1日では、人は47回もスマートフォンを確認している。
18歳から24歳に限って言えばその倍近くにも登る。
この状態は、何かを覚えておくのには難しい。
スマートフォンは歩行や会話、思考を変え、我々はほとんど追いついていない。

全てはGoogle検索によってほぼ瞬時に手に入れることが出来るのに、
何が役に立たない情報を保持しておく動機になるのだろうか。

このインスタントファクトはどの情報をフィルタリングして保持しておくかの判断を曇らせる。
もはや些細なデータを覚えておくことは重視されず、
大きい認知スペースを押し付けられている。
それではどのように覚えているものを選択しているのだろうか。

2種類の思い出があり、
1つは意識的な経験から作られる「明示的」なものと、
もう1つは過去に経験した恐ろしい体験や未知の出来事といった「暗黙的」なものである。

思い出は時の経過とともに変化する、あてにならないものである。
長期記憶を呼び出すことは、新しいコンテキストを加えた短期記憶として思い出す。
ゆえに、記憶は再構築であり、写真記録ではない。
合理的な目的のために、脳は永遠にその記憶を再録し、
多くのエラーを起こしやすくしてしまう。

多くの人は1つのタスクに継続的・持続的に取り組み、
より多くの成果を上げる可能性があることに気づいていない。
Facebook上で1つの会話から逃げ、別の会話に移ることは爽快かもしれないが、
人はこのプロセスで何を失ったのか気づいていない。
これは、頭の上で美味しいスープを注ぐようなものである。
タスク間の取り組みを最善の方法で共有できていると思っている人は、
実際には多くのものが欠落している。

脳は、処理や扱えることに制限がある。
とはいえ、それらを改善することは出来る。

Repeat After Me

思っているよりも簡単な方法の1つは、タスクを繰り返すこと。
何度も読んだり、単語を繰り返し言葉にしたり。
短期記憶を長期記憶に移動させるのに、最も適した方法である。
これをやるために、1度に1つのタスクに集中することを再教育しなければいけない。
悲しいことに、我々は既に生産的であると確信しているため、この方法を避けてしまう。

何かを学ぶとき、新しいコネクションが脳内で生成される。
学んだことを思い出すために、若いときはこういうことをやっていただろう。
単語を繰り返したり、正しい答えにたどり着くまで考えやアイディアを繰り返したり。

Take Your Time

詰め込み型の勉強のことは忘れる。
大学で上手く行かなかったように、現在も上手く行かない。
間隔反復が最も良い方法だろう。

脳に基本的な事実を詰め込むことは長期記憶において忘れさせてしまう。
知識や技能をなんども復習する時、それはとどまる。
なので、覚えようとしていることを日常生活に盛り込むことができれば、
記憶にとどめておくチャンスは劇的に向上する。

しかし、一度でも知識の復習を止めると、記憶力は大いに抜け落ちてしまう。
研究者はそれを忘却曲線と呼ぶ。

それを乗り越えるために、数日かけて繰り返すことと、効果を自身で確かめること。
ただし、多くのことを同時に繰り返すことはあまり効果が出ないので、
上手く効果の出せる健康的な方法を探すことに気をつける。
これは新しい言語に取り組み効果的な方法である。

Sit Down and Stay Put

記憶とフォーカスは密接に関連している。
フォーカスを改善するための一つの方法として、オフィスを組み替えることを提案している。
シリコンバレーでよくあるオープンオフィスは実際には生産性を大幅に低下させると考えられている。
同僚がドローンを操縦したり、スナックを食べたりしているそばで、
どのようにして一つのタスクに集中することが出来るだろうか。

オープンな職場の復活はこのようなシチュエーションを助けられない。
机もなく、物理的な遮蔽物もなく、プライバシーもなく、ただ遊具だけは多くある職場に言及している。
ヨガ用の部屋、ロッククライミングやガーデンは大きな特典になるが、
多数の挑発のなかで締め切りを守ることは難しくなる。

多数の研究で、先延ばしはストレスになり、完全にフォーカスを殺すことを発見されている。
ウェブサーフィンといった興味をそそるが無用なタスクをやめ、働くのに必要なことだけに取り組む。
そうするとフォーカスは高まり、記憶も改善する。
いわゆる「ライフハック」を追求し、お互いに不正行為を働いていない時、
フォーカスと記憶のパフォーマンスはより良くなる。

Incentivize Moments and Read Cues

精神は常にさまよっている。
学生に対して頻繁にテストを実施することで、
彼らは小テストが実施されることがわかるようになるため、 結果としてフォーカスを促すことになる。
ハーバードの調査ではこの手法は白昼夢を50%削減し、
結果を改善していると報告している。

このトリックはフォーカスにある。
ウェブサーフィンといった幾つかのタスクでは、分割された注意は無害に聞こえるが、
運転しているときはそのタスク以外何もない。
その忘却は人生全体の経過を変える可能性があり、最も深刻な脆弱性は記憶にある。

鍵のようなアイテムに視覚的あるいは言語的なきっかけを採用して、
場所やものを関連付ける方法を提案している。
我々の電子的なデバイスは想起することを助け、
例えば赤子を車のなかに置き去ったことを思い出させてくれる。
馬鹿げた話に聞こえるが、我々が失敗するときの悲劇でもある。

記憶は非常に”きっかけ”に依存している。
何かを参照することをぼんやりとした記憶障害(absent-minded memory failure)と呼ぶ。
多くの人は自分には決して起こらないことだと言うが、おおくのひとは既に起こしてしまっている。
このきっかけがなければ、ほとんどすべてのものを忘れる可能性がある。

ぼんやりとした記憶障害について本当にトリッキーなことは、
反応を起こす必要がある瞬間にきっかけが存在しなければ、
なににでも影響を与えられる可能性がある、ということである。

単純な方法は、リマインダーをセットすることである。
また、次のテクニックを組み合わせることも良い。

  • ポストイットにリマインダーを書いて、机の上に張っておくことで繰り返し目につくことを強制させる
  • 間隔反復の練習を実施する

これらのアプローチを組み合わせて、記憶を構築する。
近代の生活に保証はほとんどないが、これらのヒントを使うことできっと改善することができる。

多くの人々は注意散漫を扱うことが出来る、と自信過剰になっている。
1度に2つのことを行うことは常に影響している。
お金を払うときのように、注意を払うときは自身のおかれた状況を認識し、理解すること。 状況によっては問題にならないかもしれないが、その他の状況では全てを変えてしまうかもしれない。

2017-12-05 Introduction to logic programming with Prolog

原文:Introduction to logic programming with Prolog

Prologと言う論理型言語についてのお話。

筆者は大学時代に言語とパラダイムについて研究をしていて、
その中で多くの言語に触れ、良し悪しを把握してきた。
そのなかで、論理型言語であるPrologを計量言語学とAIに多く用いていた。

この記事ではPrologの軽い紹介と不可欠な機能について述べられている。

そもそも、なぜPrologやその他の言語を学ぶモチベーションがあるのかというと、
「達人プログラマー」でも以下に述べられているように、多くの言語を学ぶことで多くの解決策を仕入れることが出来るからである。

毎年少なくとも1つの言語を学ぶ。
異なる言語は同じ問題を異なる方法で解決している。
異なるアプローチを学ぶことは、考え方を広げ、同じ轍を踏まないように積み上げられる。
付け加えると、インターネット上で自由に使える豊富なソフトウェアのおかげで、現在では多くの言語を学ぶことははるかに簡単になっている。

例えば数独パズルをJavaやC、Prologで解くなど。

まず、論理型言語が何かについて述べる。

どのように完了するか、ではなく何がしたいかを述べる

論理型言語は数学の論理を基礎に持つプログラミングのパラダイムの1つである。
JavaやCと比べると、論理型言語で書かれたプログラムは連続した説明書のように構成されているわけではなく、公理の集合やオブジェクト間の関係の規則で成り立っている。
同様に命令型ではなく、宣言型のアプローチを採用している。

Prologはホーン節(第一階述語論理の部分集合)を基にしていて、多くの論理型言語と同様である。
Prologは1972年に初めて登場したが、現在では定理証明やエキスパートシステム自然言語処理あるいはAIにの領域で非常によく使われている。
また、Erlangの開発にも大きく影響を与えている。

他に、以下についても触れている

  • 言語構造
  • 基本的な「事実」とクエリ
  • ユニフィケーション
  • リスト表記
  • Prolog シェル
  • 回帰処理
  • 四色定理

2017-10-22 C++ Tips of the Week

原文:abseil.io

C++のtipsを週に一度書いていくウェブサイトのお話。

このウェブサイト自体はオープンソースC++の標準ライブラリ Abseilで、
このページはその中で議論されているC++のTipsを転記していく。

もともとはGoogleで行われてたTips of the Week(TotW)をAbseilのコミュニティでもやろうというもの。