JSR223 Assertion : Passing a custom key to JsonOutput.toJson() - jmeter

I am doing a validation using the following code:
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
String sourceTargetPassJson = "{\"Apple\":[\"Apple\",\"Orange\",\"Kiwi\",\"Avocado\"],\"Orange\":[\"Orange\",\"Kiwi\",\"Avocado\"]}";
def sourceVar = vars.get("source_type");
def targetVar = vars.get("target_type");
log.info("Source :" + sourceVar + ", Target :" + targetVar + ".");
def jsonSlurper = new JsonSlurper();
def response = jsonSlurper.parseText(sourceTargetPassJson);
def json = JsonOutput.toJson(response.sourceVar);
log.info("Response: " + json);
vars.put("json", json);
Here, the def json = JsonOutput.toJson(response.sourceVar); is failing because there is no key called sourceVar, which is obtained based on the Jmeter variable source_type. Given that the above assertion is in a loop controller, I want to validate based on the source_type obtained on each iteration.
Example :
Iteration 1, sourceVar = "Apple", json should have ["Apple","Orange","Kiwi","Avocado"].
Iteration 2, sourceVar = "Orange", json should have ["Orange","Kiwi","Avocado"].
How do I obtain the value for the variable json here based on the custom value of sourceVar?

The issue was simply resolved by the following change :
String json = response[sourceVar];
So, if the sourceVar is "Apple", the value of json obtained is [Apple,Orange,Kiwi,Avocado]

Related

Storing dictionaries in json file

I am trying to store dictionaries in a JSON file which user input. The code is:
#client.command()
async def shibaku0(ctx, coin1, coin2, coin3, coin4, coin5, coin6, shibakunumber, oslink):
await ctx.message.delete()
with open('Shibaku0.json', 'r') as f:
coins_data = json.load(f)
coins_data[str(ctx.author.id)]["coins"] = (coin1, coin2, coin3, coin4, coin5, coin6)
shibakunumber[str(ctx.author.id)]["shibakunumber"] = (shibakunumber)
oslink[str(ctx.author.id)]["oslink"] = (oslink)
with open('Shibaku0.json', 'w') as f:
json.dump(coins_data, f)
embed=discord.Embed(title="Shibaku0", url=f'{oslink}', description=f'No. {shibakunumber}')
embed.add_field(name="Coins: ", value=f'{coin1} {coin2} {coin3} {coin4} {coin5} {coin6}', inline=True)
embed.set_footer(text=f"{ctx.author.name}'s Shibaku")
await ctx.send(embed=embed)
I want to store the "coins", "shibakunumber, "oslink", but I am getting this error message when I try and run the code:
TypeError: list indices must be integers or slices, not str
To make a json that is an associative array (JSON object / dict). You need to have { or a single object within the file. Each object associates userid with the data for that user, i.e, a nested object.
Here's a sample :
import json
# sample_data/Obj.json
# {
# "user1": {"coins": "coinstringvalue", "shibakunumber": 1, "oslink": "linkstringvalue"},
# "user2": {"coins": "coinstringvalue2", "shibakunumber": 2, "oslink": "linkstringvalue2"}
# }
mydata = json.load(open('sample_data/Obj.json', 'r'))
print(mydata['user1'])
print(mydata['user2'])
print(mydata['user2']['shibakunumber'])
This gives the output:
{'coins': 'coinstringvalue', 'shibakunumber': 1, 'oslink': 'linkstringvalue'}
{'coins': 'coinstringvalue2', 'shibakunumber': 2, 'oslink': 'linkstringvalue2'}
2
Note that the mydata is a dict type in python.
Here's an example of starting with an empty json file.
import json
# sample_data/empty.json
# {}
mydata = json.load(open('sample_data/empty.json', 'r'))
print(mydata)
# author_id = str(ctx.author.id)
author_id = str(1161214)
if author_id not in mydata:
mydata[author_id] = dict()
mydata[author_id]['coins'] = ("coin1", "coin2")
mydata[author_id]['shibakunumber'] = 2
mydata[author_id]['oslink'] = "somelink"
json.dump(mydata, open('sample_data/new_file.json', 'w'))
loaded_data = json.load(open('sample_data/new_file.json', 'r'))
print(loaded_data)
Produces:
mydata {}
loaded_data {'1161214': {'coins': ['coin1', 'coin2'], 'shibakunumber': 2, 'oslink': 'somelink'}}

Get value from xml and calculate

I am getting the amounts from an xml file but I need to sum them to check.
I am using Ruby on rails with the Nokogiri gem
Example from xml file:
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="15101514" NoIdentificacion="PL/762/EXP/ES/2015-16665610" Cantidad="52.967" ClaveUnidad="LTR" Descripcion="MAGNA (LT)" ValorUnitario="16.34" Importe="865.74">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="842.59" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="134.81"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
<cfdi:Concepto ClaveProdServ="15101514" NoIdentificacion="PL/767/EXP/ES/2015-8515840" Cantidad="35.045" ClaveUnidad="LTR" Descripcion="MAGNA (LT)" ValorUnitario="16.34" Importe="572.80">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="557.49" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="89.20"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
<cfdi:Concepto ClaveProdServ="15101514" NoIdentificacion="PL/762/EXP/ES/2015-16665910" Cantidad="21.992" ClaveUnidad="LTR" Descripcion="MAGNA (LT)" ValorUnitario="16.34" Importe="359.45">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="349.84" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="55.97"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
<cfdi:Concepto ClaveProdServ="15101514" NoIdentificacion="PL/762/EXP/ES/2015-16665560" Cantidad="25.002" ClaveUnidad="LTR" Descripcion="MAGNA (LT)" ValorUnitario="16.34" Importe="408.62">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="397.69" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="63.63"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
I managed to obtain all the amounts and taxes with these line of code:
array = []
array_i = []
file = Nokogiri::XML(File.open(params[:consumption][:factura]))
doc_pass = file.xpath("//cfdi:Comprobante/cfdi:Conceptos/cfdi:Concepto")
doc_pass.each do |pass|
hash_importe = {}
hash_importe[:total] = pass['Importe']
array << hash_importe
end
doc_pass2 = file.xpath("//cfdi:Comprobante/cfdi:Conceptos/cfdi:Concepto/cfdi:Impuestos/cfdi:Traslados/cfdi:Traslado")
doc_pass2.each do |pass2|
hash_impuesto = {}
hash_impuesto[:tax] = pass2['Importe']
array_i << hash_impuesto
end
these are the results I get from the xml file:
(byebug) array
[{:importe=>"865.74"}, {:importe=>"572.80"}, {:importe=>"359.45"}, {:importe=>"408.62"}, {:importe=>"324.48"}, {:importe=>"649.64"}, {:importe=>"823.45"}, {:importe=>"545.15"}, {:importe=>"428.02"}, {:importe=>"527.21"}, {:importe=>"487.67"}, {:importe=>"331.72"}, {:importe=>"511.64"}, {:importe=>"406.67"}, {:importe=>"820.81"}, {:importe=>"1635.54"}, {:importe=>"484.14"}, {:importe=>"564.83"}, {:importe=>"1463.30"}]
(byebug) array_i
[{:importe=>"134.81"}, {:importe=>"89.20"}, {:importe=>"55.97"}, {:importe=>"63.63"}, {:importe=>"50.52"}, {:importe=>"101.18"}, {:importe=>"128.21"}, {:importe=>"84.88"}, {:importe=>"66.73"}, {:importe=>"82.10"}, {:importe=>"75.90"}, {:importe=>"51.58"}, {:importe=>"79.67"}, {:importe=>"63.33"}, {:importe=>"127.80"}, {:importe=>"254.69"}, {:importe=>"75.36"}, {:importe=>"87.92"}, {:importe=>"227.84"}]
now what I want is to sum both values(importe + impuesto) ​​for example:
865.74 + 134.81
572.80 + 89.20
359.45 + 55.97
I am new with rails, I would appreciate your help
You can return an array with results if both arrays have the same size(I think yes), like this:
(0..array.size - 1).each_with_object([]) { |i, obj| obj << array[i][:importe].to_f + array_i[i][:importe].to_f }
result:
[1000.55, 662.0, 415.41999999999996, 472.25, 375.0, 750.8199999999999, 951.6600000000001, 630.03, 494.75, 609.3100000000001, 563.57, 383.3, 591.31, 470.0, 948.6099999999999, 1890.23, 559.5, 652.75, 1691.1399999999999]
Use zip method to combine values at corresponding index of two arrays
result = array.zip(array_i)
.map { |importe, impuesto| importe[:importe].to_f + impuesto[:importe].to_f }
Or can be simplified more for your concrete data structure
result = array.zip(array_i).map { |hashes| hashes.sum {|h| h[:importe].to_f }}
Better approach would be if you extract Concepto object with Impuesto and Importe values directly from xml, then you don't need to combine different arrays, but use nicely structured object.

Get position of token in berts output layer

We are interested in the bert vectors for each token. With bert vector we mean the word vector for a specific token in berts output layer. So we would like to find out which token produces which bert vector. We wrote some code but we are not sure if it is correct or how to test it.
So in the code we process a sentence with bert. We construct a list of position ids and hand them to the model. Afterwards we use the same position ids to map the tokens to the output layer. Then there is some code that produces calculates the character offsets of each vector in the input sentence.
Is this the correct way how to use position_ids to generate
from transformers import BertModel, BertConfig, BertTokenizer
import torch
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
def sentence_to_vector(input_sentence):
tokens_encoded = tokenizer.encode(input_sentence, add_special_tokens=True)
input_ids = torch.tensor(tokens_encoded).unsqueeze(0) # Batch size 1
seq_length = input_ids.size(1)
# code to construct position_ids from here:
# https://github.com/huggingface/transformers/blob/8da280ebbeca5ebd7561fd05af78c65df9161f92/pytorch_pretrained_bert/modeling.py#L188:L189
position_ids = torch.arange(seq_length, dtype=torch.long, device=input_ids.device)
position_ids = position_ids.unsqueeze(0).expand_as(input_ids)
outputs = model(input_ids, position_ids=position_ids)
tokens = tokenizer.convert_ids_to_tokens(input_ids[0])
# from the BertModel documentation (example at the bottom):
# The last hidden-state is the first element of the output tuple
# https://huggingface.co/transformers/model_doc/bert.html#transformers.BertModel
#ttv = {} # token to vector
#for i in position_ids[0]:
# ttv[tokens[i]] = outputs[0][0][position_ids[0][i]]
data = []
last_offset = 0
for i in range(0, len(position_ids[0])):
token = tokens[position_ids[0][i]]
vector = outputs[0][0][position_ids[0][i]]
pos_begin = None
pos_end = None
if not token == "[CLS]" and not token == "[SEP]":
pos_begin = input_sentence.find(token, last_offset)
pos_end = pos_begin + len(token)
last_offset = pos_end
data.append({
"token": token,
"pos_begin": pos_begin,
"pos_end": pos_end,
"vector": vector
})
return data
input_sentence = "do the chicken dance!"
data = sentence_to_vector(input_sentence)
for token in data:
print(token["token"] + "\t" + str(token["pos_begin"]) + "\t" + str(token["pos_end"]) + "\t" + str(token["vector"][0:3]) + "..." )

How to generate signature using SHA-1 HMAC for google map in ruby

I am trying to generate signature using SHA-1 HMAC in ruby for google maps calls. I have got a python's code from the internet which I am trying to copy into ruby. Following is phython's code
import urllib.parse
import base64
import hashlib
import hmac
GOOGLEAPIS_URL = 'http://maps.googleapis.com'
STREETVIEW_ENDPOINT = '/maps/api/streetview'
encodedParams = urllib.parse.urlencode({'size':'50x50','location':'42.35878993272469,-71.05793081223965','sensor':'false','client':'gme-securealert'});
privateKey = 'Encoded_Key' # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
decodedKey = base64.urlsafe_b64decode(privateKey)
urlToSign = STREETVIEW_ENDPOINT + '?' + encodedParams
print(urlToSign)
signature = hmac.new(decodedKey, urlToSign.encode('utf-8') , hashlib.sha1)
encodedSignature = base64.urlsafe_b64encode(signature.digest())
print(encodedSignature
)
that generates OI2DXDLq7Qd790Lokaxgqtis_pE= signature.
Following is the Ruby code that I am trying to achieve same signature with.
GOOGLE_APIS_URL= "http://maps.googleapis.com"
key = Encoded_Key # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
data ='/maps/api/streetview?size=50x50&sensor=false&client=gme-securealert&location=42.35878993272469,-71.05793081223965'
data_array = data.split("?")
STREET_VIEW_ENDPOINT = data_array[0]
query_string = data_array[1]
encoded_query_string = URI.escape(query_string) # to encode parameters only
decoded_key = Base64.decode64(key) # to decode the key
data = STREET_VIEW_ENDPOINT << '?' << encoded_query_string
#p "DATA #{data}"
#data = Base64.decode64(data)
#puts "data #{data}"
digest = OpenSSL::Digest.new('sha1')
p OpenSSL::HMAC.digest(digest, decoded_key, data)
hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, decoded_key, data))
p hmac
but this seems to be not working for me.
Please guide.
You can create the hash for request parameters and use URI.encode_www_form for encoding parameters. Use Base64.urlsafe_decode64 and Base64.urlsafe_encode64 instead of Base64.decode64 and Base64.encode64. In my case, I have used reverse geocoding api. You will need to ammend the parameters and REVERSE_GEOCODING_ENDPOINT_JSON. Hope this will help you. Please let me know if you have any queries.
GOOGLE_MAPS_API_CLIENT_ID = 'gme-xyz'
GOOGLE_MAPS_API_CRYPTO_KEY = 'private_key'
GOOGLEAPIS_HTTP_URL = 'http://maps.googleapis.com'
REVERSE_GEOCODING_ENDPOINT_JSON = '/maps/api/geocode/json'
str_latlng = lat.to_s + ',' + lon.to_s
encoded_params = URI.encode_www_form({'latlng' => str_latlng,
'client' => GOOGLE_MAPS_API_CLIENT_ID})
decoded_key = Base64.urlsafe_decode64(GOOGLE_MAPS_API_CRYPTO_KEY)
url_to_sign = REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params
digest = OpenSSL::Digest.new('sha1')
signature = OpenSSL::HMAC.digest(digest, decoded_key, url_to_sign)
encoded_signature = Base64.urlsafe_encode64(signature)
signed_url = GOOGLEAPIS_HTTP_URL + REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params + '&signature='+encoded_signature

How does Xpath in groovy to return Tags and Values

I have the following XML, and in SOAPUI Groovy I am attempting go capture a set of XML with its tags and values, for example:
<telephoneNumbers>
<telephone>
<id>125042741</id>
<areaCode>0161</areaCode>
<phoneNumber>4804420</phoneNumber>
<extension>1234</extension>
<usage>Work</usage>
</telephone>
</telephoneNumbers>
im trying to return to following outcome (tags and values):
<telephone>
<id>125042741</id>
<areaCode>0161</areaCode>
<phoneNumber>4804420</phoneNumber>
<extension>1234</extension>
<usage>Work</usage>
</telephone>
Here is the groovy:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def Recall = groovyUtils.getXmlHolder( "Recall#Response" )
def telephone = Recall[ "//telephone//*" ] as String
String returnXml = ""
if ( Recall["//restrict"] != null ) {
returnXml= telephone
}
else
return returnXml
Similar to this answer How do I print a groovy Node with namespace preserved? you could parse the Xml using XmlSlurper and afterwards print the xml nodes you wish to with StreamingMarkupBuilder.
String xml = Recall.getXml()
def telephoneNumbers = new XmlSlurper().parseText(xml)​​​​​​​​
def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
String telephoneXml = outputBuilder.bind { mkp.yield telephoneNumbers.telephone }
I posted a runnable example here: http://groovyconsole.appspot.com/script/1245001 not using SOAPUI but a simple string for demonstration. Hope this helps!

Resources