【OpenAI】API「That model is currently overloaded with other requests. You can retry your request, or contact us through our help center at help.openai.com if the error persists.」

最近、頻繁に出てます。レスポンスボディ。


{
  "error": {
    "message": "That model is currently overloaded with other requests. You can retry your request, or contact us through our help center at help.openai.com if the error persists. (Please include the request ID XXXXXXXXXXXXXXXXXXXXX in your message.)",
    "type": "server_error",
    "param": null,
    "code": null
  }
}

エラーコードが null なので、API クライアントの実装によっては影響あるか。

こんなの出ました。

Expected string literal but 'null' literal was found at path: $.error.code
Use 'coerceInputValues = true' in 'Json {}` builder to coerce nulls to default values.

👉 Kotlin Serialization ガイド 第5章 JSONの機能 - Qiita hatena-bookmark

Error codes - OpenAI API
👉 Error codes - OpenAI API hatena-bookmark

レスポンスボディでなく、レスポンスヘッダーから見るべきか。

👉 Status code 503: That model is currently overloaded with other requests - API - OpenAI Developer Forum hatena-bookmark

一応、サーバーステータスのページでも確認するといいですね。

OpenAI Status

👉 OpenAI Status hatena-bookmark


絵文字が意図しない白黒で表示される ➡️ - Unicode Variation Selector

一部の絵文字が白黒の記号と表示される場合があります。

カラーの絵文字と思いきや白黒。


Text("\u2B06\u27A1\u2B07\u2B05\u2195")

直接コードに絵文字埋め込むと意図通りに表示される。


// ブラウザ上でもうまく表示されないものがある。
Text("⬆️➡️⬇️⬅️↕️")

コードはわかりやすく Android Jetpack Compose にしています。

IDEのエディター上からコード内に直接絵文字を書くことができる感じもありますが、編集時にイラッとすること多いので直接書きたくありません。

これは、デバイスやOSやアプリが使用しているフォントだけに依るものなのでしょうか。

私の端末では、白黒とカラー両方の矢印を見たような気がする。

 

➡️ 調べてみる

この記事。

👉 Emoji displayed as monochrome symbol? 🤔 The Unicode variation selector hatena-bookmark

まとめると以下。

一部の記号は、意図しない白黒、またはカラー絵文字として表示される。

Unicode Variation Selector を使うとある程度制御できる。

Unicode Variation Selector を使用しない場合はシステム次第。

絵文字ピッカーには Unicode Variation Selector が含まれないものもある。

Mac の絵文字ピッカーや Emojipedia は Unicode Variation Selector が含まれています。

Unicode Variation Selector には  U+FE0E (VS15)と U+FE0F(VS16) が定義されている。

VS15 を追加すると白黒テキスト、VS16 はカラー絵文字が表示されます。

ここに挙げられている、Macの絵文字ピッカー (Control + Command + Space) でみると以下。右クリックで文字情報見れます。


⬆️
up arrow
Unicode: U+2B06 U+FE0F, UTF-8: E2 AC 86 EF B8 8F

⬇️
down arrow
Unicode: U+2B07 U+FE0F, UTF-8: E2 AC 87 EF B8 8F

➡️
right arrow
Unicode: U+27A1 U+FE0F, UTF-8: E2 9E A1 EF B8 8F

⬅️
left arrow
Unicode: U+2B05 U+FE0F, UTF-8: E2 AC 85 EF B8 8F

↕️
up-down arrow
Unicode: U+2195 U+FE0F, UTF-8: E2 86 95 EF B8 8F


⬆︎
UPWARDS BLACK ARROW
Unicode: U+2B06 U+FE0E, UTF-8: E2 AC 86 EF B8 8E

⬇︎
DOWNWARDS BLACK ARROW
Unicode: U+2B07 U+FE0E, UTF-8: E2 AC 87 EF B8 8E

➡︎
BLACK RIGHTWARDS ARROW
Unicode: U+27A1 U+FE0E, UTF-8: E2 9E A1 EF B8 8E

⬅︎
LEFTWARDS BLACK ARROW
Unicode: U+2B05 U+FE0E, UTF-8: E2 AC 85 EF B8 8E

⬍
UP DOWN BLACK ARROW
Unicode: U+2B0D, UTF-8: E2 AC 8D

同様に、以下からコピーした絵文字も Variation Selector きちんと入ってます。

👉 📙 Emojipedia — 😃 Home of Emoji Meanings 💁👌🎍😍 hatena-bookmark

入ってないツールや絵文字サイトもありますので注意です。

 

➡️ 試してみる

String がどうなってるか拡張関数を作っておきます。



これを使って詳細見てみます。


"⬆➡⬇⬅↕".printUnicodeEscapeSequences()

"⬆︎➡︎⬇︎⬅︎↕︎".printUnicodeEscapeSequences()

"⬆️➡️⬇️⬅️↕️".printUnicodeEscapeSequences()

"⬆️".printUnicodeEscapeSequences()

"➡️".printUnicodeEscapeSequences()

"⬇️".printUnicodeEscapeSequences()

"⬅️".printUnicodeEscapeSequences()

"↕️".printUnicodeEscapeSequences()

結果。


⬆➡⬇⬅↕
\u2B06\u27A1\u2B07\u2B05\u2195

⬆︎➡︎⬇︎⬅︎↕︎
\u2B06\uFE0E\u27A1\uFE0E\u2B07\uFE0E\u2B05\uFE0E\u2195\uFE0E

⬆️➡️⬇️⬅️↕️
\u2B06\uFE0F\u27A1\uFE0F\u2B07\uFE0F\u2B05\uFE0F\u2195\uFE0F

⬆️
\u2B06\uFE0F

➡️
\u27A1\uFE0F

⬇️
\u2B07\uFE0F

⬅️
\u2B05\uFE0F

↕️
\u2195\uFE0F

 

➡️ まとめ

異体字セレクタ (いたいじセレクタ、英: Variation Selectors) は、Unicode および ISO/IEC 10646 (UCS) における、文字の字体をより詳細に指定するためのセレクタ (選択子) である。

👉 異体字セレクタ - Wikipedia hatena-bookmark

矢印の場合カラー絵文字をある程度強制したい場合の Kotlin 文字列 Unicode 記述は、

Unicode Variation Selector\uFE0F (VS16) を文字シンボルの後につける。」


⬆️➡️⬇️⬅️↕️
\u2B06\uFE0F\u27A1\uFE0F\u2B07\uFE0F\u2B05\uFE0F\u2195\uFE0F

Jetpack Compose で書くと以下。


Text("\u2B06\uFE0F\u27A1\uFE0F\u2B07\uFE0F\u2B05\uFE0F\u2195\uFE0F")

逆に、白黒にしたい場合は、\uFE0E (VS15) をつければよい。

別に、layout.xml だろうが strings.xml だろうが同じ。

あと、ちなみに、いつも話題に上がる国旗とか。


🇯🇵
\uD83C\uDDEF\uD83C\uDDF5

👨‍👩‍👧‍👧
\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67

なげえ。

👉 【Kotlin】絵文字を含む Unicode 文字列の文字数をカウントする方法と文字ごとの構成要素 hatena-bookmark


テストの「Mock(モック)」についての著名ソフトウエアエンジニアはどう思っているか🤔

職場や開発環境や対象となるサービスによっては、テストが「だるすぎ」と思えることがあります。

世界的に著名な方々の意見が気になりますよね。

どのように心得て書くべきか、というようなことをまとめてくれています。

「Mock」についてです。

👉 Unit Testing Experts on Mocks | Perry Street Software Engineering hatena-bookmark

 

👨‍💻 Martin Fowler

In classic tests, many people like the fact that client tests may catch errors that the main tests for an object may have missed, particularly probing areas where classes interact. Mockist tests lose that quality. In addition you also run the risk that expectations on mockist tests can be incorrect, resulting in unit tests that run green but mask inherent errors

When you write a mockist test, you are testing the outbound calls of the SUT to ensure it talks properly to its suppliers. A classic test only cares about the final state — not how that state was derived. Mockist tests are thus more coupled to the implementation of a method. Coupling to the implementation also interferes with refactoring, since implementation changes are much more likely to break tests than with classic testing.

I don’t see any compelling benefits for mockist TDD, and am concerned about the consequences of coupling tests to implementation. I really like the fact that while writing the test you focus on the result of the behavior, not how it’s done. A mockist is constantly thinking about how the SUT is going to be implemented in order to write the expectations. This feels really unnatural to me.

  • クライアントテストがオブジェクトのメインテストでは見逃す可能性があるエラーをキャッチできる。
  • クラス同士がやりとりする領域を調査することができる。
  • 期待値が誤っている場合、単体テストが通過し、本来のエラーが隠蔽される可能性がある。
  • メソッドの実装により結合しやすいため、クラシックテストよりもテストが破綻する可能性が高くなる。

👉 Mocks Aren't Stubs hatena-bookmark

 

👨‍💻 Robert C. Martin (Uncle Bob)

Mocking the interactions between all classes forces you to create mocks that return other mocks (that might return yet other mocks). You have to mock out all the data pathways in the interaction; and that can be a complex task. This creates two problems. 1. The setup code can get extremely complicated. 2. The mocking structure become tightly coupled to implementation details causing many tests to break when those details are modified.

The need to mock every class interaction forces an explosion of polymorphic interfaces. In statically typed languages like Java, that means the creation of lots of extra interface classes whose sole purpose is to allow mocking. This is over-abstraction and the dreaded ‘design damage’.

I recommend that you mock sparingly. Find a way to test — design a way to test — your code so that it doesn’t require a mock.

  • インタラクションをシミュレートするための便利なツール。
  • クラス同士のインタラクションをすべてモックする必要があるため、セットアップコードが複雑になる。
  • モックの構造は実装の詳細に密接に結合するため、実装の変更により多くのテストが破綻する可能性がある。
  • ポリモーフィックなインターフェースが必要となるため、設計上の過剰な抽象化が生じる可能性がある。

👉 Clean Coder Blog hatena-bookmark

 

👨‍💻 Kent Beck

I mock almost nothing. If I can’t figure out how to test efficiently with the real stuff, I find another way of creating a feedback loop for myself.

If I use TDD, I can refactor stuff. And then I heard these stories people say that they use TDD and now they can’t refactor anything. I couldn’t understand that and then I started looking at their tests: If you have mocks returning mocks, returning mocks, your test is completely coupled to the implementation, not the interface, but the exact implementation. Of course you can’t change anything without breaking the test. That for me is too high a price to pay, that’s not a trade-off I’m willing to make.

  • ほとんど使用しない。
  • 多重に入り組んでいると、テストが実装に結合しすぎるため、実装の変更が難しくなる。

👉 TW Hangouts | Is TDD dead? - YouTube hatena-bookmark

 

👨‍💻 Ian Cooper

When we refactored something all these tests with mocks broke and we had to rewrite all the mocks. It was kind of puzzling because the promise was that we should be able to refactor our code, because our tests would enable us to refactor and refactoring kept our code healthy. But the tests were an obstacle to that change, since they were breaking when we changed our implementation details.

Avoid heavy mocking. This allows you to meet the promise to refactoring. You will refactor your code and your tests won’t break.

Mocks are useful when a resource is expensive to create, but the problem with mock objects essentially is that people have used them to isolate classes. Don’t do that.

  • リソースを作成するのがコストが高い場合に便利である。
  • オブジェクトを使用すると、クラスを分離するために使用された場合、リファクタリングが非常に困難になる可能性がある。
  • ヘビーなモックは避けるべきである。

👉 🚀 TDD, Where Did It All Go Wrong (Ian Cooper) - YouTube hatena-bookmark

 

👨‍💻 まとめ

大まかにまとめると以下の3つ。

Mock はインタラクション(やり取り/相互作用)の確認が目的である。

リソース作成のコストが高い場合に便利。

実装と密になるので、実装は変更はしづらくなっていく。

ホンマもんのエンジニアの方々に口を揃えて言われるとスッキリします。