Please take a look at this post for more info I am trying to find something like this
screen_shots = full_data['tabs'][0]['views'][1]['screenshots']
but for a new JSON file but I keep getting
KeyError: 'screenshots'
I tried a few things to fix it but nothing works so any help will be welcomed
JSON
{
"minVersion":"0.1",
"class":"DepictionTabView",
"tintColor":"#2cb1be",
"headerImage":"",
"tabs":[ {
"tabname":"Details",
"class":"DepictionStackView",
"tintColor":"#2cb1be",
"views":[ {
"class": "DepictionSubheaderView", "useBoldText": true, "useBottomMargin": false, "title": "Description"
}
,
{
"class": "DepictionMarkdownView", "markdown": "<p>This is a description...<\/p>", "useRawFormat": true
}
,
{
"class": "DepictionSeparatorView"
}
,
{
"class": "DepictionSubheaderView", "useBoldText": true, "useBottomMargin": false, "title": "Screenshots"
}
,
{
"class":"DepictionScreenshotsView",
"itemCornerRadius":6,
"itemSize":"{160, 284.44444444444}",
"screenshots":[ {
"accessibilityText": "Screenshot", "url": "Screenshot URL 1"
}
]
}
,
{
"class": "DepictionSeparatorView"
}
,
{
"class": "DepictionSubheaderView", "useBoldText": true, "useBottomMargin": false, "title": "Information"
}
,
{
"class": "DepictionTableTextView", "title": "Author", "text": "User"
}
,
{
"class": "DepictionTableTextView", "title": "Version", "text": "1.0"
}
,
{
"class": "DepictionTableTextView", "title": "Price", "text": "free"
}
,
{
"class": "DepictionSpacerView", "spacing": 16
}
,
{
"class":"DepictionStackView",
"views":[
{
"class": "DepictionTableButtonView", "title": "Support", "action": "", "openExternal": true
}
]
}
,
{
"class": "DepictionSpacerView", "spacing": 16
}
]
}
,
{
"tabname":"Changelog",
"class":"DepictionStackView",
"tintColor":"#2cb1be",
"views":[
{
"class": "DepictionSubheaderView", "useBoldText": true, "useBottomMargin": false, "title": "1.0"
}
,
{
"class": "DepictionMarkdownView", "markdown": "<ul>\n<li>Initial release.<\/li>\n<\/ul>", "useRawFormat": true
}
]
}
]
}
In your JSON, many of the views do not have a screenshots key. The 2nd view (views[1]) definitely does not while the 5th view (views[4]) does.
If you're trying to collect all the screenshots from the views you'll need to use a loop and some conditional logic to find them.
screenshots = [] # an accumulator to collect our screenshots
for view in full_data['tabs'][0]['views']: # loop over each view
if 'screenshots' in view: # only process views with a screenshots key
# there can be multiple screenshots per view, so concatenate them to our accumulator
screenshots += view['screenshots']
You can further simplify this to a list comprehension
screenshots = [*screenshot for screenshot in full_data['tabs'][0]['views'] if 'screenshots' in view]
The *screenshot tells Python to "unroll" the list of screenshots. Adding each item to the list, rather then inserting a list into our list.
In the example you posted:
screen_shots = full_data['tabs'][0]['views'][1]['screenshots']
Goes to:
{
"class": "DepictionMarkdownView", "markdown": "<p>This is a description...<\/p>", "useRawFormat": true
}
Which doesn't have any key called screenshots. Your JSON keys at that level are not guaranteed to have that key. I'm guessing that screenshots will only be there if class is DepictionScreenshotsView.
So you can try:
tab = full_data['tabs'][0]
screen_shots = [tab['views'][i]['screenshots'] for i in range(len(tab)) if tab['view'][i]['class'] == 'DepictionScreenshotsView')
Related
I have 10k+ records in elastic search. one of the fields(dept) holds data in form of array
eg records are
{
"username": "tom",
"dept": [
"cust_service",
"sales_rpr",
"store_in",
],
"location": "NY"
}
{
"username": "adam",
"dept": [
"cust_opr",
"floor_in",
"mg_cust_opr",
],
"location": "MA"
}
.
.
.
I want to do autocomplete on dept field, if user search for cus it should return
["cust_service", "cust_opr", "mg_cust_opr"]
With best match at the top
I have made the query
query = {
"_source": [],
"size": 0,
"min_score": 0.5,
"query": {
"bool": {
"must": [
{
"wildcard": {
"dept": {
"value": "*cus*"
}
}
}
],
"filter": [],
"should": [],
"must_not": []
}
},
"aggs": {
"auto_complete": {
"terms": {
"field": f"dept.raw",
"size": 20,
"order": {"max_score": 'desc'}
},
"aggs": {
"max_score": {
"avg": {"script": "_score"}
}
}
}
}
}
It is not giving ["cust_service", "cust_opr", "mg_cust_opr"] instead gives other answers which are irrelevant to search key(cus). but when field is just string instead of array it is giving the result as expected.
How do i solve this problem?
Thanks in advance!
I want to retrieve a field as well as it's normalized version from Elasticsearch.
Here's my index definition and data
PUT normalizersample
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"refresh_interval": "60s",
"analysis": {
"normalizer": {
"my_normalizer": {
"filter": [
"lowercase",
"german_normalization",
"asciifolding"
],
"type": "custom"
}
}
}
},
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"myField": {
"type": "text",
"store": true,
"fields": {
"keyword": {
"type": "keyword",
"store": true
},
"normalized": {
"type": "keyword",
"store": true,
"normalizer": "my_normalizer"
}
}
}
}
}
}
POST normalizersample/_doc/1
{
"myField": ["Andreas", "Ämdreas", "Anders"]
}
My first approach was to use scripted fields like
GET /myIndex/_search
{
"size": 100,
"query": {
"match_all": {}
},
"script_fields": {
"keyword": {
"script": "doc['myField.keyword']"
},
"normalized": {
"script": "doc['myField.normalized']"
}
}
}
However, since myField is an array, this returns two lists of strings per ES document and each of them are sorted alphabetically. Hence, the corresponding entries might not match to each other due to the normalization.
"hits" : [
{
"_index" : "normalizersample",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"fields" : {
"de" : [
"amdreas",
"anders",
"andreas"
],
"keyword" : [
"Anders",
"Andreas",
"Ämdreas"
]
}
}
]
While I would like to retrieve [(Andreas, andreas), (Ämdreas, amdreas) (Anders, anders)] or a similar format where I can match every entry to its normalization.
The only way I found was to call Term Vectors on both fields since they contain a position field, but this seems like a huge overhead to me. (https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-termvectors.html)
Is there a simpler way to retrieve tuples with the keyword and the normalized field?
Thanks a lot!
This script updates the code in the json file with the users input but doesn't replace the placeholder text Screenshot URL X x is a number (1, 5). I want to remove the placeholder text that hasn't been updated by the script with the user input. It was working before but now it isn't and I can find out why. Any help will be welcomed! Thanks!
Code:
# Load the data
file_name = path/to/json/file
with open(file_name) as fh:
full_data = json.load(fh)
# Dig into the data to find the screenshots
screen_shots = full_data['tabs'][0]['views'][1]['screenshots']
# Loop over each screen shot, updating each one
print("Press return/enter to enter another url or press it again with nothing entered to stop asking and continue the script.")
for number, screen_shot in enumerate(screen_shots):
new_url = input("Screnshot URL: ").strip()
if new_url:
# Updating the data here will also update the 'full_data' object
# as we are just referencing a part of it, not making copies
screen_shot.update({"url": new_url, "fullSizeURL": new_url})
else:
break
# Remove all entries which we did not update
screen_shots = screen_shots[:number]
# Save the data
with open(file_name, 'w') as fh:
json.dump(full_data, fh, indent=4)
JSON File:
{
"minVersion": "0.1",
"headerImage": "Header Image URL",
"tintColor": "",
"tabs": [
{
"tabname": "Details",
"views": [
{
"title": "Package Name",
"useBoldText": true,
"useBottomMargin": false,
"class": "DepictionSubheaderView"
},
{
"itemCornerRadius": 6,
"itemSize": "{160, 275.41333333333336}",
"screenshots": [
{
"accessibilityText": "Screenshot",
"url": "Screenshot URL 1",
"fullSizeURL": "Screenshot URL 1"
},
{
"accessibilityText": "Screenshot",
"url": "Screenshot URL 2",
"fullSizeURL": "Screenshot URL 2"
},
{
"accessibilityText": "Screenshot",
"url": "Screenshot URL 3",
"fullSizeURL": "Screenshot URL 3"
},
{
"accessibilityText": "Screenshot",
"url": "Screenshot URL 4",
"fullSizeURL": "Screenshot URL 4"
},
{
"accessibilityText": "Screenshot",
"url": "Screenshot URL 5",
"fullSizeURL": "Screenshot URL 5"
}
],
"class": "DepictionScreenshotsView"
},
{
"markdown": "This is a description.",
"useSpacing": true,
"class": "DepictionMarkdownView"
},
{
"class": "DepictionSeparatorView"
},
{
"title": "Known Issues",
"class": "DepictionHeaderView"
},
{
"markdown": "None",
"useSpacing": true,
"class": "DepictionMarkdownView"
},
{
"class": "DepictionSeparatorView"
},
{
"title": "Latest Version",
"class": "DepictionHeaderView"
},
{
"title": "Version",
"text": "1.2",
"class": "DepictionTableTextView"
},
{
"title": "Released",
"text": "1/1/11",
"class": "DepictionTableTextView"
},
{
"title": "Price",
"text": "Free",
"class": "DepictionTableTextView"
},
{
"title": "Developer",
"text": "Dev",
"class": "DepictionTableTextView"
},
{
"title": "Contact Support",
"action": "",
"class": "DepictionTableButtonView"
},
{
"spacing": 16,
"class": "DepictionSpacerView"
},
{
"spacing": 20,
"class": "DepictionSpacerView"
}
],
"class": "DepictionStackView"
},
{
"tabname": "Changelog",
"views": [
{
"title": "1.2",
"useBoldText": true,
"useBottomMargin": true,
"class": "DepictionSubheaderView"
},
{
"markdown": "\t\n\u2022 Initial Release",
"useSpacing": false,
"class": "DepictionMarkdownView"
},
{
"markdown": "<small style=\"color: #999; margin-top: -8px;\">Released 1/1/11</small>",
"useRawFormat": true,
"class": "DepictionMarkdownView"
}
],
"class": "DepictionStackView"
}
],
"class": "DepictionTabView"
}
Does this work?
import json
file_name = "test.json"
with open(file_name) as fh:
full_data = json.load(fh)
# Dig into the data to find the screenshots
screen_shots = full_data['tabs'][0]['views'][1]['screenshots']
# Loop over each screen shot, updating each one
print("Press return/enter to enter another url or press it again with nothing entered to stop asking and continue the script.")
for number, screen_shot in enumerate(screen_shots):
new_url = input("Screnshot URL: ").strip()
if new_url:
# Updating the data here will also update the 'full_data' object
# as we are just referencing a part of it, not making copies
screen_shot.update({"url": new_url, "fullSizeURL": new_url})
else:
break
# Remove all entries which we did not update
screen_shots = screen_shots[:number]
full_data['tabs'][0]['views'][1]['screenshots'] = screen_shots #-> this lines removes the placeholder text that is not updated by the user
# Save the data
with open(file_name, 'w') as fh:
json.dump(full_data, fh, indent=4)
How do I change a value in a json file with python? I want to search and find "class": "DepictionScreenshotsView" and replace it with "class": ""
JSON File:
{
"minVersion": "0.1",
"class": "DepictionTabView",
"tintColor": "#2cb1be",
"headerImage": "",
"tabs": [
{
"tabname": "Details",
"class": "DepictionStackView",
"tintColor": "#2cb1be",
"views": [
{
"class": "DepictionSubheaderView",
"useBoldText": true,
"useBottomMargin": false,
"title": "Description"
},
{
"class": "DepictionMarkdownView",
"markdown": "Some dummy text...",
"useRawFormat": true
},
{
"class": "DepictionSeparatorView"
},
{
"class": "DepictionSubheaderView",
"useBoldText": true,
"useBottomMargin": false,
"title": "Screenshots"
},
{
"class": "DepictionScreenshotsView",
"itemCornerRadius": 6,
"itemSize": "{160, 284.44444444444}",
"screenshots": [
{
"accessibilityText": "Screenshot",
"url": "http://example.com/image.png"
}
]
},
{
"class": "DepictionSeparatorView"
},
{
"class": "DepictionSubheaderView",
"useBoldText": true,
"useBottomMargin": false,
"title": "Information"
},
{
"class": "DepictionTableTextView",
"title": "Author",
"text": "User"
},
{
"class": "DepictionSpacerView",
"spacing": 16
},
{
"class": "DepictionStackView",
"views": [
{
"class": "DepictionTableButtonView",
"title": "Contact",
"action": "http://example.com/",
"openExternal": true
}
]
},
{
"class": "DepictionSpacerView",
"spacing": 16
}
]
},
{
"tabname": "History",
"class": "DepictionStackView",
"views": [
{
"class": "DepictionSubheaderView",
"useBoldText": true,
"useBottomMargin": false,
"title": ""
},
{
"class": "DepictionMarkdownView",
"markdown": "<ul>\n<li>Initial release.<\/li>\n<\/ul>",
"useRawFormat": true
}
]
}
]
}
You can read a json file in python as follow:
import json
with open('your_file.json') as f:
data = json.load(f)
Then you access and change the value (for your case):
data['tabs'][0]['views'][4]['class'] = ""
After having changed the data, you can save it :
with open('your_file.json', 'w') as outfile:
json.dump(data, outfile)
My Alexa skill keeps getting rejected for the reason:
'Please note "help" fails not reaching the endpoint of the skill.'
I'm using the Skill builder to build the skill, which by default implements the help intent.
My python code that I'm running on lambda has a handler for the help intent (full code can be seen at https://github.com/kkoppenhaver/last-episode/blob/master/skill.py )
## Handle the help intent
if intent_name == "AMAZON.HelpIntent" or intent_name == "TroubleshootIntent":
return build_response("Last Episode", "Welcome to Last Episode. Ask me about a T.V. series. For example, when was the last episode of How I Met Your Mother?", False)
And when I test using their testing interface, the help intent returns this string of text as intended.
Nevertheless, it continues to get rejected. Is there something simple I'm missing? I've filed a support request with Amazon as well, but would really like to get this approved as it's a relatively simple skill.
Any thoughts would be appreciated.
EDIT: Full schema
{
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "GetLastEpisodeIntent",
"samples": [
"last episode summary for {series_name}",
"what was the last episode of {series_name}",
"the last episode of {series_name}",
"about {series_name}",
"when was the last episode of {series_name}"
],
"slots": [
{
"name": "series_name",
"type": "AMAZON.TVSeries",
"samples": [
"{series_name}"
]
}
]
}
],
"prompts": [
{
"id": "Elicit.Intent-GetLastEpisodeIntent.IntentSlot-series_name",
"promptVersion": "1.0",
"definitionVersion": "1.0",
"variations": [
{
"type": "PlainText",
"value": "What series are you looking for?"
}
]
}
],
"dialog": {
"version": "1.0",
"intents": [
{
"name": "GetLastEpisodeIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "series_name",
"type": "AMAZON.TVSeries",
"elicitationRequired": true,
"confirmationRequired": false,
"prompts": {
"elicit": "Elicit.Intent-GetLastEpisodeIntent.IntentSlot-series_name"
}
}
]
}
]
}
}