Attach external disks at particular position - ibm-cloud

By using this code i can attach disks sequentially.
device 2, device 3, device 4
But i want to attach disks for a particular position.
I want to directly attach 3rd disk or 4th disk.
Without upgrading the previous disks
code
for disk in external_disks:
obj = {}
obj['id'] = getDiskPriceId(client, disk)
#obj['id'] = 2277
#logger.info("disk %s size: %s --\n" ,(str(disk_num)), (str(disk)))
if obj['id'] == "":
print("Invalid external disk size")
exit(1)
categories = {}
categories['categoryCode'] = "guest_disk"+str(disk_num)
categories['complexType'] = "SoftLayer_Product_Item_Category"
obj['categories'] =[categories]
obj["complexType"] = "SoftLayer_Product_Item_Price"
prices.append(obj)
disk_num = disk_num + 1
response = client.call('SoftLayer_Product_Order','placeOrder', {
"virtualGuests": [{
"id": id
}],
"prices": prices,
"properties": [{
"name": "NOTE_GENERAL",
"value": "adding disks"
},{
"name": "MAINTENANCE_WINDOW",
"value": "now"
}],
"complexType": "SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade"
})

You can attach directly to an specific position through the attribute categoryCode, following is the order:
guest_disk1 for Second Disk
guest_disk2 for Third Disk
guest_disk3 for Fourth Disk
guest_disk4 for Fifth Disk
Make sure that item prices have the categoryCode you need, you can verify it by using the method SoftLayer_Virtual_Guest::getUpgradeItemPrices as following:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Virtual_Guest/[deviceId]/getUpgradeItemPrices
Following structure about prices allows to attach disks directly to the Third and Fourth position.
prices = [
{
'id': 2299,
'categories': [
{
'categoryCode': 'guest_disk2',
'complexType': 'SoftLayer_Product_Item_Category'
}
],
'complexType': 'SoftLayer_Product_Item_Price'
},
{
'id': 2288,
'categories': [
{
'categoryCode': 'guest_disk3',
'complexType': 'SoftLayer_Product_Item_Category'
}
],
'complexType': 'SoftLayer_Product_Item_Price'
}
]
In your code the disk_num value needs to be between 2 and 3 to attach disks directly to the third and fourth position.
Note:
If you want to change/replace disk by another one with more/less space, you only need to apply the same idea. Set the categoryCode of new disk with the same categoryCode value of current disk.
I hope this help you.

Related

Azure data factory pass activity output to a dataset

I am using a SQL Server query which would return the last 3 months since a customer last purchased a product. For instance, There's a customer 100 that last made a purchase in August 2022. The SQL query will return June, July, August. Which would be in the format 062022, 072022, 082022. Now I need to be able to pass these values to the Copy data activity REST api dataset Relative URL (/salemonyr/062022) in the ForEach activity.
So during the first iteration the Relative URL should be set to /salemonyr/062022 the second would be /salemonyr/072022 and third /salemonyr/082022.
Error: The expression 'length(activity('MonYear').output.value)' cannot be evaluated because property 'value' doesn't exist, available properties are 'resultSetCount, recordsAffected, resultSets, outputParameters, outputLogs, outputLogsLocation, outputTruncated, effectiveIntegrationRuntime, executionDuration, durationInQueue, billingReference
Script activity json:
{
"resultSetCount": 1,
"recordsAffected": 0,
"resultSets": [
{
"rowCount": 3,
"rows": [
{
"MonYear": 062022
},
{
"MonYear": 072022
},
{
"MonYear": 082022
}
]
}
],
"outputParameters": {},
"outputLogs": "",
"outputLogsLocation": "",
"outputTruncated": false,
"effectiveIntegrationRuntime": "",
"executionDuration": 0,
"durationInQueue": {
"integrationRuntimeQueue": 3
},
"billingReference": {
"activityType": "PipelineActivity",
"billableDuration": [
{
"meterType": "",
"duration": 0.016666666666666666,
"unit": "Hours"
}
]
}
}
How would I accomplish this to read the values dynamically from the SQL query.
You can use #split(item().colname,',')[0] , split(item().colname,',')[1] and split(item().colname,',')[2] in the relative URL path.
Check the below video for details:
You can use REST Dataset parameter and use it in the Relative URL.
Relative URL:
Give lookup output to ForEach. use your query in lookup.
Give this to ForEach and inside ForEach, in copy sink(REST DATASET) use the below expression for the dataset parameter.
/salemonyr/#{item().sample_date}
In source, you can give your source.
By this, you can copy the data to the respective Relative URL.

Create Entities and training phrases for values in functions for google action

I have created a trivia game using the SDK, it takes user input and then compares it to a value in my DB to see if its correct.
At the moment, I am just passing a raw input variable through my conversation, this means that it regularly fails when it mishears the user since the exact string which was picked up is rarely == to the value in the DB.
Specifically I would like it to only pick up numbers, and for example realise that it must extract '10' , from a speech input of 'my answer is 10'.
{
"actions": [
{
"description": "Default Welcome Intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "welcome"
},
"intent": {
"name": "actions.intent.MAIN"
}
},
{
"description": "response",
"name": "Raw input",
"fulfillment": {
"conversationName": "rawInput"
},
"intent": {
"name": "raw.input",
"parameters": [{
"name": "number",
"type": "org.schema.type.Number"
}],
"trigger": {
"queryPatterns":[
"$org.schema.type.Number:number is the answer",
"$org.schema.type.Number:number",
"My answer is $org.schema.type.Number:number"
]
}
}
}
],
"conversations": {
"welcome": {
"name": "welcome",
"url": "https://us-central1-triviagame",
"fulfillmentApiVersion": 2
},
"rawInput": {
"name": "rawInput",
"url": "https://us-central1-triviagame",
"fulfillmentApiVersion": 2
}
}
}
app.intent('actions.intent.MAIN', (conv) => {
conv.data.answers = answersArr;
conv.data.questions = questionsArr;
conv.data.counter = answersArr.length;
var thisQuestion = conv.data.questions;
conv.ask((conv.data.answers)[0]));
});
app.intent('raw.input', (conv, input) => {
if(input == ((conv.data.answers)[0])){
conv.ask(nextQuestion());
}
app.intent('actions.intent.TEXT', (conv,input) => {
//verifying if input and db value are equal
// at the moment input is equal to 'my number is 10' (for example) instead of '10'
//therefore the string verification never works
conv.ask(nextQuestion());
});
In a previous project i used the dialogflow UI and I used this #system.entities number parameter along with creating some training phrases so it understands different speech patterns.
This input parameter I am passing through my conv , is only a raw string where I'd like it to be filtered using some sort of entity schema.
How do I create the same effect of training phrases/entities using the JSON file?
You can't do this using just the Action SDK. You need a Natural Language Processing system (such as Dialogflow) to handle this as well. The Action SDK, by itself, will do speech-to-text, and will use the actions.json configuration to help shape how to interpret the text. But it will only return the entire text from the user - it will not try to determine how it might match an Intent, nor what parameters may exist in it.
To do that, you need an NLP/NLU system. You don't need to use Dialogflow, but you will need something that does the parsing. Trying to do it with simple pattern matching or regular expressions will lead to nightmares - find a good system to do it.
If you want to stick to things you can edit yourself, Dialogflow does allow you to download its configuration files (they're just JSON), edit them, and update or replace the configuration through the UI or an API.

In terms of application running time, is putting array elements on the root of UserDefaults preferred than putting them in container key?

I have an array of chat threads, which each also has array of chat messages.
Thread 1: "Hello world."
Participant: Alex, Billy, Cherry
Alex = "Hello"
Billy = "World"
Cherry = "Hahaha"
Thread 2: personal chat
Participants: Alex, Daniel
Alex = "Gday mate!"
Daniel = "Hey, how is it going?"
Alex = "Cool, lots of fun!"
I want to save this in UserDefaults. All of these will be saved in form of dictionaries and arrays.
Now imagine structure like this with thousands of threads and millions of messages. Then imagine I have to save it on the UserDefaults. Which way is better for me in saving these information?
Method 1: Save everything under one key "threads". In this method, I have to load everything and save everything each time I add/change/delete even one message or thread.
{
"threads": [
{
"id":90, "title":"Hello World", "participants":[7,12,54],
"messages": [
{ "id":827, "sender":7, "text":"Hello" },
{ "id":828, "sender":12, "text":"World" },
{ "id":836, "sender":7, "text":"Hahaha" }
...
]
},
{
"id":92, "title":"", "participants":[7,9],
"messages": [
{ "id":850, "sender":7, "text":"Gday mate!" },
{ "id":855, "sender":12, "text":"Hey, how is it going?" },
{ "id":861, "sender":7, "text":"Cool, lot's of fun!" }
...
]
}
...
]
}
Method 2: Break down the threads into elements, and save them one by one on the root. This way I'll only operating with one key at a time. Still have the original "threads" key though, to know what thread entries do I have. But that means the key on the the root level is going to be massive (the phone needs to load all the root key each time I tried to access UserDefaults?), and I'm not only going to have just chats to save.
{
"threads": [ 90, 92, ... ],
"thread-90": {
"id":90, "title":"Hello World", "participants":[7,12,54],
"messages": [
{ "id":827, "sender":7, "text":"Hello" },
{ "id":828, "sender":12, "text":"World" },
{ "id":836, "sender":7, "text":"Hahaha" }
...
]
},
"thread-92": {
"id":92, "title":"", "participants":[7,9],
"messages": [
{ "id":850, "sender":7, "text":"Gday mate!" },
{ "id":855, "sender":12, "text":"Hey, how is it going?" },
{ "id":861, "sender":7, "text":"Cool, lot's of fun!" }
...
]
}
...
}
Which one is better in the long run in terms of access speed, application performance, and CPU load, if all of these will be accessed quite frequent? I don't know how significant the loading time is if it's from UserDefaults.

Rally SDK 2.0: How to display multiple data columns with a TimeSeriesCalculator

I would like to display 2 time series of data with columns in the same "Rally.ui.chart.Chart". The config below for "Rally.data.lookback.calculator.TimeSeriesCalculator" stacks the columns on the same X column. Is there an easy way to group the data to be shown side-by-side instead for the same date (like the "accepted" and "time remaining" in the iteration burn-down chart) ?
Perhaps something like this?
getMetrics: function () {
return [
{
"field": "TaskRemainingTotal",
"as": "Hours Remaining",
"f": "sum",
"display": "column"
},
{
"field": "PlanEstimate",
"as": "Story Points Accepted",
"f": "filteredSum",
"filterField": "ScheduleState",
"filterValues": ["Accepted", "Verified"],
"display": "column",
"group": "1" //????? is there a specifier to separate this data?
},
];
},
Here is the code for the calculator used for the burn chart:
https://github.com/RallyApps/app-catalog/blob/master/src/apps/charts/burndown/BurnDownCalculator.js
Writing calculators for generating charts from lookback api is probably the most difficult thing to do in the app platform, so kudos for tackling it!
I'm not an expert either, but hopefully that above code is enough to point you in the right direction. Please post back if you either solve it or run into a new issue.
I was able to get it to work by adding the following to the chartConfig:
plotOptions: {
column: {
stacking: null
}
}
I've found some more on this subject that I believe may be helpful:
The "stack" member of the series config in highcharts allows a series to be stacked by name. We can create a much more flexible system that allow us to specify how to stack the data by using this and overriding some methods in the Rally.data.lookback.calculator.TimeSeriesCalculator to allow the series data to be modified.
prepareChartData returns series data, so we can override the output of that to add series data:
prepareChartData: function(store) {
var snapshots = [];
store.each(function(record) {
snapshots.push(record.raw);
});
var a = this.runCalculation(snapshots);
for (var k in a.series) {
if (a.series[k].name.startsWith("Story")) a.series[k].stack = "Story";
}
return a;
}
we can override the _buildSeriesConfig function to push any properties listed in the seriesConfig array in the metric config to the series config. This allows us to specify the series formatting in a nicer way and also gives us much more power in modifying other attributes of the chart config :
_buildSeriesConfig: function(calculatorConfig) {
var aggregationConfig = [],
metrics = calculatorConfig.metrics,
derivedFieldsAfterSummary = calculatorConfig.deriveFieldsAfterSummary;
for (var i = 0, ilength = metrics.length; i < ilength; i += 1) {
var metric = metrics[i];
var seriesConfig = {
name: metric.as || metric.field,
type: metric.display,
dashStyle: metric.dashStyle || "Solid"
};
for (var k in metric.seriesConfig) {
seriesConfig[k] = metric.seriesConfig[k];
}
aggregationConfig.push(seriesConfig);
}
for (var j = 0, jlength = derivedFieldsAfterSummary.length; j < jlength; j += 1) {
var derivedField = derivedFieldsAfterSummary[j];
var seriesConfig = {
name: derivedField.as,
type: derivedField.display,
dashStyle: derivedField.dashStyle || "Solid"
};
for (var k in derivedField.seriesConfig) {
seriesConfig[k] = derivedField.seriesConfig[k];
}
aggregationConfig.push(seriesConfig);
}
return aggregationConfig;
},
this method allows us to supply a seriesConfig property in getMetrics like so:
getMetrics: function() {
return [{
"field": "TaskRemainingTotal", // the field in the data to operate on
"as": "Hours Remaining", // the label to appear on the chart
"f": "sum", // summing function to use.
"display": "column", // how to display the point on the chart.
seriesConfig: {
"stack": "Hours",
"color": "#005eb8"
}
}, {
"field": "PlanEstimate", // the field in the data to operate on
"as": "Story Points Accepted", // the label to appear on the chart
"f": "filteredSum",
"filterField": "ScheduleState", // Only use points in seduled sate accepted or Verified
"filterValues": ["Accepted", "Verified"],
"display": "column",
seriesConfig: {
"stack": "Points",
"color": "#8dc63f"
}
}, {
"field": "PlanEstimate", // the field in the data to operate on
"as": "Story Points Remaining", // the label to appear on the chart
"f": "filteredSum",
"filterField": "ScheduleState", // Only use points in seduled sate accepted or Verified
"filterValues": ["Idea", "Defined", "In Progress", "Completed"],
"display": "column",
seriesConfig: {
"stack": "Points",
"color": "#c0c0c0"
}
},
];
},
With option #2, we can control and add any series config data in the same context that we are configuring the metrics, without worrying about configuration orders. Option #2 is a little dangerous though as the underscore implies that the method is private and therefore has no contractual guarantee to remain compatible in future revisions. (Maybe the rally guys will see this and extend the functionality for us)

Select an item from Dojo Grid's store and display one of its attributes (array of objects) on grid

I have a Dojo EnhancedGrid which uses a data store filled with the following data structure:
[
{ id: 1, desc: "Obj Desc", options: [ { txt: "text", value: 0 }, { obj2 }, { objn } ] },
{ id: 2, ... },
{ id: 3, ... },
{ id: n, ... }
]
Currently I'm doing all this with an auxiliary store...but I believe this is far from a good approach to the problem, it's too ugly and doesn't work really well with edition (because I have to send changes from one store to another).
Instead of displaying all this objects at the same time, I wanted to select just one object (using its id) and display its options objects on grid. At the same time, the changes on grid should make effect on store, to be able to save them later.
Is it possible to query the grid's store, in order to display just one object? How?
And is it possible to fill the grid with objects list present on "options" attribute?