C++11 function static variable initialization weirdness - multithreading

I have plain simple function that maps some HTTP status codes to strings:
const std::string & status_name(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
One day, on our test servers, a crash has occurred. Analysing core dump is seems that std::out_of_range exception was thrown in status_table.at(0);. Another weird thing is that status code in question was 200. Program that crashed abuses multiple threads, so my stomach feel tells me that this issue is thread-related.
I'm really puzzled about how it's even possible. It's C++11 and this version of standard provides guarantees regarding thread-safety of static variable initialization. The compiler is clang-3.3, architecture is x64 and CPU is Intel(R) Xeon(R) CPU E5506.
The only two things come to mind:
there's some bug in the code I miss to see;
this weirdness is related to CPU cache incoherency: thread that caused crash saw guard variable as indicating 'initialized' state of
status_table but object itself was seen empty.
Update on the issue:
After making a small test case I was able to easily reproduce the problem:
#include <thread>
#include <atomic>
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#include <iostream>
#include <unistd.h>
const std::string & status_name1(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name2(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name3(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name4(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name5(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name6(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name7(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
const std::string & status_name8(int code)
{
static std::unordered_map<int, std::string> status_table {
{ 0, "UNKNOWN" },
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 200, "OK" },
{ 201, "Created" },
{ 202, "Accepted" },
{ 203, "Non-Authoritative Information" },
{ 204, "No Content" },
{ 205, "Reset Content" },
{ 206, "Partial Content" },
{ 300, "Multiple Choices" },
{ 301, "Moved Permanently" },
{ 302, "Found" },
{ 303, "See Other" },
{ 304, "Not Modified" },
{ 305, "Use Proxy" },
{ 307, "Temporary Redirect" },
{ 400, "Bad Request" },
{ 401, "Unauthorized" },
{ 402, "Payment Required" },
{ 403, "Forbidden" },
{ 404, "Not Found" },
{ 405, "Method Not Allowed" },
{ 406, "Not Acceptable" },
{ 407, "Proxy Authentication Required" },
{ 408, "Request Timeout" },
{ 409, "Conflict" },
{ 410, "Gone" },
{ 411, "Length Required" },
{ 412, "Precondition Failed" },
{ 413, "Request Entity Too Large" },
{ 414, "Request-URI Too Long" },
{ 415, "Unsupported Media Type" },
{ 416, "Requested Range Not Satisfiable" },
{ 417, "Expectation Failed" },
{ 499, "Rotten session" },
{ 500, "Internal Server Error" },
{ 501, "Not Implemented" },
{ 502, "Bad Gateway" },
{ 503, "Service Unavailable" },
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
};
auto it = status_table.find(code);
if (it != status_table.end())
return it->second;
return status_table.at(0);
}
int main(int argc, char ** argv)
{
std::vector<std::thread> thread_pool;
auto guard_variable = std::make_shared<std::atomic<int>>(0);
for (int i = 0; i < 8; ++i) {
thread_pool.push_back(std::thread([guard_variable] {
while (!guard_variable->load(std::memory_order_relaxed)) {
/// Noop.
}
int i = 0;
i += status_name1(200).length();
i += status_name2(200).length();
i += status_name3(200).length();
i += status_name4(200).length();
i += status_name5(200).length();
i += status_name6(200).length();
i += status_name7(200).length();
i += status_name8(200).length();
std::cout << i << std::endl;
}));
}
usleep(50000);
guard_variable->store(1, std::memory_order_relaxed);
for (auto && thread : thread_pool) {
thread.join();
}
return 0;
}
This code works as expected everywhere else other than on that test machine. No matter what version of clang I use (3.3, 3.6) this test program crashes due to exception immediately, at different times in different status_name* function.
What can possibly cause this behaviour? Is CPU cache inconsistency or is it bug in libc++?

Clang supports "magic statics" (N2660 Dynamic initialization and destruction with concurrency) since 2.9 per http://clang.llvm.org/cxx_status.html.
Rather than a bug in the compiler or your immediate code, it is more likely that a bug elsewhere in your code is corrupting program state, causing status_table to appear initialized but empty.

Related

How to Map the nested array using map function?

I/P:
[
{
"keyword": "outdoor cushion",
"bidInfo": [
{
"matchType": "EXACT",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 1,
"bid": 160,
"suggestedBid": {
"rangeStart": 90,
"rangeMedian": 160,
"rangeEnd": 188
}
},
{
"matchType": "PHRASE",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 1,
"bid": 104,
"suggestedBid": {
"rangeStart": 83,
"rangeMedian": 104,
"rangeEnd": 177
}
},
{
"matchType": "BROAD",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 1,
"bid": 106,
"suggestedBid": {
"rangeStart": 87,
"rangeMedian": 106,
"rangeEnd": 139
}
}
],
"translation": "アウトドアクッション",
"userSelectedKeyword": false,
"searchTermImpressionRank": 18,
"searchTermImpressionShare": 0.7346906874047442,
"recId": "e4918800-d0bf-4f20-8776-68574e4c8339"
},
{
"keyword": "cushion",
"bidInfo": [
{
"matchType": "EXACT",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 2,
"bid": 140,
"suggestedBid": {
"rangeStart": 140,
"rangeMedian": 140,
"rangeEnd": 140
}
},
{
"matchType": "BROAD",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 2,
"bid": 111,
"suggestedBid": {
"rangeStart": 79,
"rangeMedian": 111,
"rangeEnd": 155
}
},
{
"matchType": "PHRASE",
"theme": "CONVERSION_OPPORTUNITIES",
"rank": 2,
"bid": 107,
"suggestedBid": {
"rangeStart": 76,
"rangeMedian": 107,
"rangeEnd": 149
}
}
],
"translation": "クッション",
"userSelectedKeyword": false,
"searchTermImpressionRank": 60,
"searchTermImpressionShare": 0.04246088993932697,
"recId": "50a5705a-d79a-4f74-82bd-2836096b36fd"
}
]
trying:
const suggestionSp: { Rank: string; searchTerm: string; matchType: string; low: string; suggestedBid: string; high: string; translation: string; }[] = [];
if (suggestions.keywordTargetList.length > 0) {
await suggestions.keywordTargetList.map((item: { rank: string; keyword: string; matchType: string; suggestedBid: any; bid: any; bidInfo: any[]; translation: any; }) => {
suggestionSp.push({Rank: item.bidInfo.rank, searchTerm: item.keyword, matchType: item.bidInfo.matchType, low: item.bidInfo.suggestedBid.rangeStart, suggestedBid: item.bidInfo.suggestedBid.rangeMedian, high: item.bidInfo.suggestedBid.rangeEnd, translation: item.translation });
});
}
Expected O/P:
[{
"keyword": "outdoor cushion",
"matchType": "EXACT",
"rank": 1,
"rangeStart": 92,
"rangeMedian": 163,
"rangeEnd": 191,
"translation": "アウトドアクッション"
},
{
"keyword": "outdoor cushion",
"matchType": "PHRASE",
"rank": 1,
"rangeStart": 83,
"rangeMedian": 103,
"rangeEnd": 176,
"translation": "アウトドアクッション"
},
{
"matchType": "BROAD",
"rank": 1,
"rangeStart": 88,
"rangeMedian": 107,
"rangeEnd": 141,
"translation": "アウトドアクッション"
}
]
You can use the array's reduce method:
const output = input.reduce((result, current) => result.concat(
current.bidInfo.map(bidInfo => ({
"keyword": current.keyword,
"matchType": bidInfo.matchType,
"rank": bidInfo.rank,
"rangeStart": bidInfo.suggestedBid.rangeStart,
"rangeMedian": bidInfo.suggestedBid.rangeMedian,
"rangeEnd": bidInfo.suggestedBid.rangeEnd,
"translation": current.translation
})
)), []);
Used Reduce syntax:
reduce((accumulator, currentValue) => { /* … */ } , initialValue)

Updating dictionary in Python

I'm working on a project where I will retrieve data from various files and this data will then be written down in a file in geojson format.
Below you see a simplified example of some of the code and output:
Code:
def get_data(data):
features = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
data["lat"],
data["long"],
],
},
"properties": {
"obsid": data["file_name"],
"name": data["guid_id"],
"h_gs": data["z"],
},
}
],
}
for id, top, bot, code in zip(
data["id"],
data["top"],
data["bot"],
data["code"],
):
info = {
id: {
"top": top,
"bot": bot,
"code": code,
},
}
features["features"].append(info)
return features
def main(data):
data = get_data(data)
to_json = json.dumps(data, indent=4)
print(to_json)
if __name__ == "__main__":
# example data
data = {
"lat": 40.730610,
"long": -73.935242,
"z": 28.37,
"file_name": "tmrx.txt",
"guid_id": "d4d5b10a-c5fc-450a-9b3b-f309e7cb9613",
"id": ["id_0", "id_1", "id_2", "id_3", "id_4"],
"top": [100, 200, 300, 400, 500],
"bot": [90, 190, 290, 390, 490],
"code": ["a", "b", "c", "d", "e"],
}
main(data)
Output:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
40.73061,
-73.935242
]
},
"properties": {
"obsid": "tmrx.txt",
"name": "d4d5b10a-c5fc-450a-9b3b-f309e7cb9613",
"h_gs": 28.37
}
},
{
"id_0": {
"top": 100,
"bot": 90,
"code": "a"
}
},
{
"id_1": {
"top": 200,
"bot": 190,
"code": "b"
}
},
{
"id_2": {
"top": 300,
"bot": 290,
"code": "c"
}
},
{
"id_3": {
"top": 400,
"bot": 390,
"code": "d"
}
},
{
"id_4": {
"top": 500,
"bot": 490,
"code": "e"
}
}
]
}
This works fine but I wish I could get the output to look a little different.
Desired output:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
40.73061,
-73.935242
]
},
"properties": {
"obsid": "tmrx.txt",
"name": "d4d5b10a-c5fc-450a-9b3b-f309e7cb9613",
"h_gs": 28.37
}
"id_0": {
"top": 100,
"bot": 90,
"code": "a"
}
"id_1": {
"top": 200,
"bot": 190,
"code": "b"
}
"id_2": {
"top": 300,
"bot": 290,
"code": "c"
}
"id_3": {
"top": 400,
"bot": 390,
"code": "d"
}
"id_4": {
"top": 500,
"bot": 490,
"code": "e"
}
}
]
}
There, the 'unnecessary' brackets are removed.
Does anyone here on the forum know how i could achieve this result in the above code?
Best Regards,
Mikael
See the code sample above.
Change below Line in your code
features["features"].append(info)
To this
features["features"][0] |= info
Instead of features["features"].append(info) use:
features["features"][0].update(info)

Getting error "There was a problem with the requested skill's response" while developing Alexa Skill through Alexa Developers Console?

When testing out my skill using the Test Simulator for Alexa I am getting the following error:
"There was a problem with the requested skill's response"
I tried looking at solutions, but I could not find anything.
Below is my JSON Input 1 and I am not getting anything in JSON output.
Please help me here?
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.8df6ac89-2811-43cf-8578-e9edc30fa091",
"application": {
"applicationId": "amzn1.ask.skill.b1f0f00c-d3a9-43b9-82fe-92f066c58880"
},
"user": {
"userId": "amzn1.ask.account.AHNEWQLTUHO42PDYBLNORMFZURAPP5WSA52C6HPP4GEUM3MPBRYTY6WKULN3BNXIKPEOLUDQMX7EOLCG3E7LCD3YPJ4QL5JZ2N2UTX4UUFIWFY5PVGNSWC4JVO2EVFV5TDJD6HIPHU5O4KTSQW7XWBTUCSZ4JFPMFBPKEQ5IFLBZMXJI2XSRSMXKJV3PVJRSR5OT32LGO74AP2A"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.ask.skill.b1f0f00c-d3a9-43b9-82fe-92f066c58880"
},
"user": {
"userId": "amzn1.ask.account.AHNEWQLTUHO42PDYBLNORMFZURAPP5WSA52C6HPP4GEUM3MPBRYTY6WKULN3BNXIKPEOLUDQMX7EOLCG3E7LCD3YPJ4QL5JZ2N2UTX4UUFIWFY5PVGNSWC4JVO2EVFV5TDJD6HIPHU5O4KTSQW7XWBTUCSZ4JFPMFBPKEQ5IFLBZMXJI2XSRSMXKJV3PVJRSR5OT32LGO74AP2A"
},
"device": {
"deviceId": "amzn1.ask.device.AHUW3YVJLFTNIZQ7UUMLHULHQWHKPMW2UICHN4DZRBGBSYZJ3LMSUZLC4LP7Q5F4M7IXQOCAJ4KFNFB7GVAIRLIOHK7YN62XTX6LKRODFUKR2LP4RSGJUQCJGHXP7KIEFULCF6GVQD77DVPOC6OILLKGPEKADVW253ZEOJX4FGLG2SVWZMFHW",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.eu.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLmIxZjBmMDBjLWQzYTktNDNiOS04MmZlLTkyZjA2NmM1ODg4MCIsImV4cCI6MTU4NTQ5NTU5NSwiaWF0IjoxNTg1NDk1Mjk1LCJuYmYiOjE1ODU0OTUyOTUsInByaXZhdGVDbGFpbXMiOnsiY29udGV4dCI6IkFBQUFBQUFBQVFDemhJWnNHUzR1L1cwK3VETTVuTkNjS2dFQUFBQUFBQUFZbjJTTllsbEhmUlVkbkFLU3E4Y0R3dXlNR2krUlUrWE90MVFuWXpkSERJUlpwUkhxdEoxcUZvMGRsM2YrRHFRSHJNeFFLaTlLR3FLa1RJQjlPOGJpUzcxZi9vMWJ6d1cvWlplcCtLTDlhem9yRUxYNjFXN2VBM3JnTy9PZkc0a1M4c1h5M2dmYTdEakxaUkRmUW9PWGZhZVJHa3p2Y1phUWQ4cmw4bDRWRlVsUnNLeEZadU9icmR3MTcvUkkxVHlWNERibFFhSHZjRXRtNUZJcnI4dmJ2bENyM3ZCWnJEVVFCSmxEN0ZrMG1lLzEwUHh2bnM1V05tcUl4ODN3WUFiUmdIUHEramhVZUpjM1lFcEpUYjcwZEllaHVoNUN4SDg3ZWZ5ckJPRDZFSnUwU1RCbmRQZGhnaXZnS3FNZUdVYkNWQmtzYmhVR1BIQy9HdjQxVmNlcDB2OXkrVk1iZFNROXFXbWV0aS9USm5hUFZWeVpyRFdLd0JDTGZ1RVoyWlloc2JzOGQxNTNPQlg2IiwiY29uc2VudFRva2VuIjpudWxsLCJkZXZpY2VJZCI6ImFtem4xLmFzay5kZXZpY2UuQUhVVzNZVkpMRlROSVpRN1VVTUxIVUxIUVdIS1BNVzJVSUNITjREWlJCR0JTWVpKM0xNU1VaTEM0TFA3UTVGNE03SVhRT0NBSjRLRk5GQjdHVkFJUkxJT0hLN1lONjJYVFg2TEtST0RGVUtSMkxQNFJTR0pVUUNKR0hYUDdLSUVGVUxDRjZHVlFENzdEVlBPQzZPSUxMS0dQRUtBRFZXMjUzWkVPSlg0RkdMRzJTVldaTUZIVyIsInVzZXJJZCI6ImFtem4xLmFzay5hY2NvdW50LkFITkVXUUxUVUhPNDJQRFlCTE5PUk1GWlVSQVBQNVdTQTUyQzZIUFA0R0VVTTNNUEJSWVRZNldLVUxOM0JOWElLUEVPTFVEUU1YN0VPTENHM0U3TENEM1lQSjRRTDVKWjJOMlVUWDRVVUZJV0ZZNVBWR05TV0M0SlZPMkVWRlY1VERKRDZISVBIVTVPNEtUU1FXN1hXQlRVQ1NaNEpGUE1GQlBLRVE1SUZMQlpNWEpJMlhTUlNNWEtKVjNQVkpSU1I1T1QzMkxHTzc0QVAyQSJ9fQ.L0hwnl1wAddgWkZBxbu9Q4nRHlzwWglcSiqzf4Z_Nzg8C4XzsP9-5x_wccMpDWRPQxE5s0YOf6UfkCooakR36lVkm6Z7PhVqJShNrF6YooC29vjJ50C1-_wg27AwcDWXBG4c_tjDTFcrAuwkNOo3pBUjA9xE00a3q6Ecs-UtD-stQXoLv4J0f8bpe7AEpfc1pzaqhBXkybYYA91IFLVX67Gvxqiag2CwjdT6BO0uayQqZpXZd5F4IRfYuLmsqK0aFIJv5g0h_kfwPusowLkGneegE2uTLE5SwZpZkWg9-aI-6HvdvRe1DvZbgnJKjw2SBRNGdKT-UOkJZTndI3mgag"
},
"Viewport": {
"experiences": [
{
"arcMinuteWidth": 246,
"arcMinuteHeight": 144,
"canRotate": false,
"canResize": false
}
],
"shape": "RECTANGLE",
"pixelWidth": 1024,
"pixelHeight": 600,
"dpi": 160,
"currentPixelWidth": 1024,
"currentPixelHeight": 600,
"touch": [
"SINGLE"
],
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
}
},
"Viewports": [
{
"type": "APL",
"id": "main",
"shape": "RECTANGLE",
"dpi": 160,
"presentationType": "STANDARD",
"canRotate": false,
"configuration": {
"current": {
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
},
"size": {
"type": "DISCRETE",
"pixelWidth": 1024,
"pixelHeight": 600
}
}
}
}
]
},
"request": {
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.b0de7b26-cfba-4942-92b4-d5589c7b8db3",
"timestamp": "2020-03-29T15:21:35Z",
"locale": "en-IN",
"shouldLinkResultBeReturned": false
}
}

Azure OCR [printed text] is not reading the receipt lines in the right order

Application Goal: read the receipt image, extract the store/organization name along with the total amount paid. Feed it to web-form for auto-filling & submission.
Post Request - "https://*.cognitiveservices.azure.com/vision/v2.0/recognizeText?{params}
Get Request - https://*.cognitiveservices.azure.com/vision/v2.0/textOperations/{operationId}
however when I get the results back, sometimes it's confusing in line ordering (see below picture [similar results in JSON response])
This mixing is resulting in getting the total as $0.88
Similar situations are present for 2 out of 9 testing receipts.
Q: Why it's working for similar & different structured receipts but for some reason not consistent for all? Also, any ideas how to get around it?
I had a quick look to your case.
OCR Result
As you mentioned, the results are not ordered as you thought. I had a quick look to the bounding boxes values and I don't know how they are ordered. You could try to consolidate fields based on that, but there is a service that is already doing it for you.
Form Recognizer:
Using Form Recognizer and your image, I got the following results for your receipt.
As you can see below, the understandingResults contains the total with its value ("value": 9.11), the MerchantName ("Chick-fil-a") and other fields.
{
"status": "Succeeded",
"recognitionResults": [
{
"page": 1,
"clockwiseOrientation": 0.17,
"width": 404,
"height": 1226,
"unit": "pixel",
"lines": [
{
"boundingBox": [
108,
55,
297,
56,
296,
71,
107,
70
],
"text": "Welcome to Chick-fil-a",
"words": [
{
"boundingBox": [
108,
56,
169,
56,
169,
71,
108,
71
],
"text": "Welcome",
"confidence": "Low"
},
{
"boundingBox": [
177,
56,
194,
56,
194,
71,
177,
71
],
"text": "to"
},
{
"boundingBox": [
201,
56,
296,
57,
296,
71,
201,
71
],
"text": "Chick-fil-a"
}
]
},
...
OTHER LINES CUT FOR DISPLAY
...
]
}
],
"understandingResults": [
{
"pages": [
1
],
"fields": {
"Subtotal": null,
"Total": {
"valueType": "numberValue",
"value": 9.11,
"text": "$9.11",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/32/words/0"
},
{
"$ref": "#/recognitionResults/0/lines/32/words/1"
}
]
},
"Tax": {
"valueType": "numberValue",
"value": 0.88,
"text": "$0.88",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/31/words/0"
},
{
"$ref": "#/recognitionResults/0/lines/31/words/1"
},
{
"$ref": "#/recognitionResults/0/lines/31/words/2"
}
]
},
"MerchantAddress": null,
"MerchantName": {
"valueType": "stringValue",
"value": "Chick-fil-a",
"text": "Chick-fil-a",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/0/words/2"
}
]
},
"MerchantPhoneNumber": {
"valueType": "stringValue",
"value": "+13092689500",
"text": "309-268-9500",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/4/words/0"
}
]
},
"TransactionDate": {
"valueType": "stringValue",
"value": "2019-06-21",
"text": "6/21/2019",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/6/words/0"
}
]
},
"TransactionTime": {
"valueType": "stringValue",
"value": "13:00:57",
"text": "1:00:57 PM",
"elements": [
{
"$ref": "#/recognitionResults/0/lines/6/words/1"
},
{
"$ref": "#/recognitionResults/0/lines/6/words/2"
}
]
}
}
}
]
}
More details on Form Recognizer: https://azure.microsoft.com/en-us/services/cognitive-services/form-recognizer/

the difference between the following error

when i use nodejs http library(Request) to request target website, i get some error:
[{
"response": {
"code": "ECONNRESET",
"errno": "ECONNRESET",
"syscall": "read"
}
}, {
"response": {
"code": "ESOCKETTIMEDOUT",
"connect": false
}
}, {
"response": {
"code": "ETIMEDOUT",
"connect": true
}
}, {
"response": {
"code": "ETIMEDOUT",
"connect": false
}
}]
i want to know the difference between these error.

Resources