So I managed to split the following data to k/v pairs
"tags": [
"category--Cola",
"sugar--3.000000",
"barcode--cola001",
"barcode--cola001_1",
"language--en",
"sku--cola_classic",
"sku--cola_cherry",
],
like so...
t = product['tags']
t_filtered = [k for k in t if '--' in k]
product['tags'] = dict(s.split('--') for s in t_filtered)
I want the output to be something like this
{
"category": [Cola],
"sugar":[3.0],
"barcode":[cola001,cola001_1],
"language":[en],
"sku": [cola_classic, cola_cherry],
}
so I tried this... (ref: https://docs.python.org/3/library/collections.html#collections.defaultdict)
product['tags'] = dict(s.split('--') for s in t_filtered)
s = product['tags']
d = {}
for k, v in s:
d.setdefault(k, []).append(v)
print(d)
but getting this error:
ValueError: too many values to unpack (expected 2)
Also, just to verify s is a <classic 'dict'> so I can't figure out the issue.
My Python script is working and appends to my JSON file; however, I have tried to add a numbered entry identification with no success. Additionally, I am trying to get a specific output each time the calculations are iterated. Looking for detailed examples and guidance.
Current Python Script
import json
# Dictionary All-Calculations
def dict_calc(num1, num2):
add = str(float(num1)+float(num2))
sub = str(float(num1)-float(num2))
mul = str(float(num1)*float(num2))
div = str(float(num1)/float(num2))
calc_d = {"Add" : add, "Subtract" : sub, "Multiply" : mul, "Divide" : div}
return calc_d
# Yes or No
def y_n(answer):
if answer[:1] == 'y':
return True
if answer[:1] == 'n':
return False
# Main Dictionary
data_table = {}
while True:
num1 = input("\n Enter first number: ")
num2 = input("\n Enter second number: ")
data_table = dict_calc(num1, num2)
with open('dict_calc.json', 'a', encoding='utf-8') as f:
json.dump(data_table, f, ensure_ascii=True, indent=4)
answer = input("\n Run Again? (Y/N) ").lower().strip()
if y_n(answer) == True:
continue
else:
print("\n Thank You and Goodbye")
break
Current Output Example
{
"Add": "579.0",
"Subtract": "-333.0",
"Multiply": "56088.0",
"Divide": "0.26973684210526316"
}{
"Add": "1245.0",
"Subtract": "-333.0",
"Multiply": "359784.0",
"Divide": "0.5779467680608364"
}{
"Add": "1396.0",
"Subtract": "554.0",
"Multiply": "410475.0",
"Divide": "2.315914489311164"
}
Desired Output Example - I am trying to add the Entry plus number, which increases after each iteration. In addition, I am also trying emulate this same output.
[
{
"Entry": "1",
"Add": "579.0",
"Subtract": "-333.0",
"Multiply": "56088.0",
"Divide": "0.26973684210526316"
},
{
"Entry": "2",
"Add": "1245.0",
"Subtract": "-333.0",
"Multiply": "359784.0",
"Divide": "0.5779467680608364"
},
{
"Entry": "3",
"Add": "1396.0",
"Subtract": "554.0",
"Multiply": "410475.0",
"Divide": "2.315914489311164"
}
]
JSON is a nested structure. You can't simply append more data to it. See JSON Lines format for that.
If using regular JSON format, you must read the whole JSON structure in, update it, then write it out fully again, or simply write it once the structure is complete.
Example:
import json
# Dictionary All-Calculations
def dict_calc(num1, num2, entry):
add = str(float(num1)+float(num2))
sub = str(float(num1)-float(num2))
mul = str(float(num1)*float(num2))
div = str(float(num1)/float(num2))
calc_d = {"Entry": str(entry), "Add" : add, "Subtract" : sub, "Multiply" : mul, "Divide" : div}
return calc_d
# Yes or No
def y_n(answer):
if answer[:1] == 'y':
return True
if answer[:1] == 'n':
return False
# Empty List that will hold dictionaries.
data_table = []
entry = 0 # for tracking entry numbers
while True:
num1 = input("\n Enter first number: ")
num2 = input("\n Enter second number: ")
# Count entry and add it to dictionary list.
entry += 1
data_table.append(dict_calc(num1, num2, entry))
answer = input("\n Run Again? (Y/N) ").lower().strip()
if y_n(answer) == True:
continue
else:
print("\n Thank You and Goodbye")
# Write the complete list of dictionaries in one operation.
with open('dict_calc.json', 'w', encoding='utf-8') as f:
json.dump(data_table, f, ensure_ascii=True, indent=4)
break
Output:
[
{
"Entry": "1",
"Add": "3.0",
"Subtract": "-1.0",
"Multiply": "2.0",
"Divide": "0.5"
},
{
"Entry": "2",
"Add": "8.0",
"Subtract": "-1.0",
"Multiply": "15.75",
"Divide": "0.7777777777777778"
},
{
"Entry": "3",
"Add": "13.399999999999999",
"Subtract": "-2.2",
"Multiply": "43.68",
"Divide": "0.717948717948718"
}
]
A few things you might need to change:
you need to change data_table type to list.
you need to append dict_calc function result to it.
Add a counter
Here is your code:
import json
# Dictionary All-Calculations
def dict_calc(counter, num1, num2):
add = str(float(num1)+float(num2))
sub = str(float(num1)-float(num2))
mul = str(float(num1)*float(num2))
div = str(float(num1)/float(num2))
calc_d = {"Entry": str(counter), "Add" : add, "Subtract" : sub, "Multiply" : mul, "Divide" : div}
return calc_d
# Yes or No
def y_n(answer):
if answer[:1] == 'y':
return True
if answer[:1] == 'n':
return False
# Main Dictionary
data_table = []
counter = 1
while True:
num1 = input("\n Enter first number: ")
num2 = input("\n Enter second number: ")
data_table.append( dict_calc(counter, num1, num2))
counter += 1
with open('dict_calc.json', 'a', encoding='utf-8') as f:
json.dump(data_table, f, ensure_ascii=True, indent=4)
answer = input("\n Run Again? (Y/N) ").lower().strip()
if y_n(answer) == True:
continue
else:
print("\n Thank You and Goodbye")
break
I have a question in regards to formatting a file so that it displays a Json output to the correct format.
At the moment the code I have below imports a json into a file but when I open the file, it displays the json in a single line (word wrap unticked) like so:
{"products":[{"type":null,"information":{"description":"Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights","items":{"provider Company":"Juniper","provider Hotel ID":"245","provider Hotel Room ID":"200"}},"costGroups":[{"name":null,"costLines":[{"name":"Hotel Cost","search":null,"quote":234.43,"quotePerAdult":null,"quotePerChild":null}
I want to format the json in the file so that it looks like actual json formatting like so:
{
"products": [
{
"type": null,
"information": {
"description": "Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights",
"items": {
"provider Company": "Juniper",
"provider Hotel ID": "245",
"provider Hotel Room ID": "200"
}
},
"costGroups": [
{
"name": null,
"costLines": [
{
"name": "Hotel Cost",
"search": null,
"quote": 234.43,
"quotePerAdult": null,
"quotePerChild": null
}
Virtually each header has its own line to contain its values.
What is the best way to implement this to get the correct json formatting within the file?
Below is the code:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath +"//Log Data//"
def response = testRunner.testCase.getTestStepByName("GET_Pricing{id}").getProperty("Response").getValue();
def jsonFormat = (response).toString()
def fileName = "Logged At - D" +date+ " T" +time+ ".txt"
def logFile = new File(dataFolder + fileName)
// checks if a current log file exists if not then prints to logfile
if(logFile.exists())
{
log.info("Error a file named " + fileName + "already exisits")
}
else
{
logFile.write "Date Stamp: " +date+ " " + time + "\n" + jsonFormat //response
If you have a modern version of groovy, you can do:
JsonOutput.prettyPrint(jsonFormat)
How convert JSON to CoffeeScript and write on a file ".coffee" with NodeJS?
JSON:
{
"name": "jack",
"type": 1
}
to CoffeeScript:
"name": "jack"
"type": 1
Should be easy enough by traversing the object (for … of). Just use recursion and take the indent level as an argument:
esc_string = (s) ->
return '"' + s.replace(/[\\"]/g, '\\$1') + '"'
csonify = (obj, indent) ->
indent = if indent then indent + 1 else 1
prefix = Array(indent).join "\t"
return prefix + esc_string obj if typeof obj is 'string'
return prefix + obj if typeof obj isnt 'object'
return prefix + '[\n' + (csonify(value, indent) for value in obj).join('\n') + '\n' + prefix + ']' if Array.isArray obj
return (prefix + esc_string(key) + ':\n' + csonify(value, indent) for key, value of obj).join '\n'
Test case:
alert csonify
brother:
name: "Max"
age: 11
toys: [
"Lego"
"PSP"
]
sister:
name: "Ida"
age: 9
Result:
"brother":
"name":
"Max"
"age":
11
"toys":
[
"Lego"
"PSP"
]
"sister":
"name":
"Ida"
"age":
9
No live demo, since I don't know a JSFiddle for CoffeScript.
Live demo: http://jsfiddle.net/vtX3p/
I hope you know how to read and write files in nodejs, so i will not address that here.
To convert javascript to coffeescript you can use this npm:
https://github.com/rstacruz/js2coffee
I am writing some helper functions to convert my R variables to JSON. I've come across this problem: I would like my values to be represented as JSON arrays, this can be done using the AsIs class according to the RJSONIO documentation.
x = "HELLO"
toJSON(list(x = I(x)), collapse="")
"{ \"x\": [ \"HELLO\" ] }"
But say we have a list
y = list(a = "HELLO", b = "WORLD")
toJSON(list(y = I(y)), collapse="")
"{ \"y\": {\n \"a\": \"HELLO\",\n\"b\": \"WORLD\" \n} }"
The value found in y -> a is NOT represented as an array. Ideally I would have
"{ \"y\": [{\n \"a\": \"HELLO\",\n\"b\": \"WORLD\" \n}] }"
Note the square brackets. Also I would like to get rid of all "\n"s, but collapse does not eliminate the line breaks in nested JSON. Any ideas?
try writing as
y = list(list(a = "HELLO", b = "WORLD"))
test<-toJSON(list(y = I(y)), collapse="")
when you write to file it appears as:
{ "y": [
{
"a": "HELLO",
"b": "WORLD"
}
] }
I guess you could remove the \n as
test<-gsub("\n","",test)
or use RJSON package
> rjson::toJSON(list(y = I(y)))
[1] "{\"y\":[{\"a\":\"HELLO\",\"b\":\"WORLD\"}]}"
The reason
> names(list(a = "HELLO", b = "WORLD"))
[1] "a" "b"
> names(list(list(a = "HELLO", b = "WORLD")))
NULL
examining the rjson::toJSON you will find this snippet of code
if (!is.null(names(x)))
return(toJSON(as.list(x)))
str = "["
so it would appear to need an unnamed list to treat it as a JSON array. Maybe RJSONIO is similar.