Possible to "clear" a grade value using Desire2Learn Valence API? - desire2learn

Is there any possible way to completely clear a previously set grade value using the D2L Valence API? I can successfully set or update grade values, but it seems that there is no obvious way to totally delete the grade value like you can from the D2L user interface.
I've tried a few ways of doing this:
Setting the incoming grade value to null using the grade value update route:
PUT /d2l/api/le/(version)/(orgUnitId)/grades/(gradeObjectId)/values/(userId)
(Note that I am correctly substituting valid values for all of the IDs, versions, etc.) This returns a "400 Bad Request" status code.
Calling the same route with a DELETE verb. This returns a 404 Not Found error code (unsurprisingly, since it's not a documented route: I just tried it as a stab in the dark).
Calling the PUT route but omitting the incoming grade value body. This also returns a 404.
I can always just set the grade value to 0, but that is less than satisfactory because it's not the same thing. I don't actually want to assign a grade of zero; I want to assign no grade so that it is obvious that the grade needs to be assigned manually, etc. Is there some other sort of magic number/sentinel I could use, besides null, to achieve this, or is this just a gap in the Valence API?

I believe this is a gap in the Valence Learning Framework APIs. You can use the APIs to explicitly set a grade value, 0 or otherwise, but you can't currently use the APIs to unset the value for a grade object.

Related

Google Ads API: getMetrics doesn't get results for all passed keywords

I'm on migration from the old Google AdWords API to the new Google Ads API, using PHP-SDK by Google.
This is the use case, where I'm stuck:
I feed an amount of keywords (paginating them by keyword plans a 10k) to generateHistoricalMetrics($keywordPlanResource) and collect the results.
To do so I followed instructions at https://developers.google.com/google-ads/api/docs/keyword-planning/generate-historical-metrics and, especially, https://developers.google.com/google-ads/api/docs/keyword-planning/generate-historical-metrics#mapping_to_the_ui, with using of KeywordPlanAdGroupKeywords (with a single ad group) and avoiding to pass a specific date range for now, relying on the default value.
Further I had to apply some filters on my keywords because of KEYWORD_HAS_INVALID_CHARS and KEYWORD_TEXT_TOO_LONG, but all the errors which I'm aware of are gone now.
Now, I found out, that the KeywordPlanHistoricalMetrics object does not contain any keyword id (of the form customers//keywordPlanAdGroupKeywords/) So, I have to rely on the correct ordering. This is ok as it seems, that the original ordering of keywords is preserved within the results, as here https://developers.google.com/protocol-buffers/docs/encoding#optional
But still I have the problem, that
count($keywordPlanServiceClient->generateHistoricalMetrics($keywordPlanResource)->getMetrics()) is lower then count($passedKeywords), where each of $passedKeywords where passed to
new KeywordPlanAdGroupKeyword([
'text' => $passedKeyword,
'match_type' => KeywordMatchType::EXACT
'keyword_plan_ad_group' => $planAdGroupResource
]);
Q: So I have two questions here:
Why getMetrics() does not yield the same amount of results as the amount of passed keywords?
I'm struggling with debugging at this moment: Say, I want to know which keywords are let out. Either for providing more information at this place or just to skip them, and let my customer know, that these particular keywords were not queried. How to do this, when although I have a keyword id for every passed keyword I cannot match the returned metrics to them, because the KeywordPlanHistoricalMetrics object does not contain any keyword id.
Detail: While testing I found out, that the reducing of an amount of queried keywords reduces the amount of lost keyword data:
10k of queried keywords - 4,72% loss,
5k - 2,12%,
2,5k - 0,78%,
1,25k - 0,43%,
625 - 0,3%,
500 - 0,24%,
250 - 0,03%
200 - 0,03% of lost keywords.
But I can't imagine, that keywords should be queried one by one.

Advance Search : Airtable to Zapier

this is my first post!
We want to create an airtable integration: when an ID in a certain column is an ODD number, so we will automatically update the STATUS for another column. Have googled and searched but perhaps couldn't find the right answer, especially for the Search Formula field. Appreciate any help for this!
Huge Thanks!
Within your Airtable table, you can create a new formula field called "Is Odd." The formula within that field would then be IF(MOD({ID}, 2) = 1, "True", "False"). If the ID field mod 2 is equal to 1, then the field is odd, otherwise, it is not.
You could just use this Airtable formula logic to assign a status. Change "True" and "False" to whatever your status values are. You can then group, filter and sort your records based on the values in that field. For more info on Airtable formulas: https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference
If you really need to continue with Zapier, you have a couple of different options for how to proceed. One way would be to use the "Path" helper step to split your workflow. Zapier should follow Path A if the Is Odd field of the record is equal to the string True and Path B if the field is equal to the string False. Down each path, you can then use the Update Record Airtable action to update the record with the correct status. The "Path" step requires a "Professional" account with Zapier.
The other option requires a "Pro" account (which is cheaper than a Professional account). You can create two different Zaps, one for Odd IDs and one for Even IDs. Use the Filter helper step in Zapier to then only execute the Odd Zap if Is Odd is equal to the string True and the Even Zap if Is Odd is equal to the string False. Each Zap can then use the Update Record Airtable action to update the record with the correct status.
I definitely recommend using functions within Airtable to manage this. No reason to include a third party if you don't have to!

How to get grade calculation option values using Valence APIs?

Is there some way to get the grade calculation option values for course sections using the Valence APIs? I looked through the Grades documentation, but couldn't find anything. What I'm trying to get are the following.
Grading System: Weighted, Points, or Formula
Final Grade Released: Calculated Final Grade or Adjusted Final Grade
Ungraded Items: Drop ungraded items or Treat ungraded items as 0
Auto Update: Automatically keep final grades updated
I've also tried looking at Configuration Variables, but that doesn't seem relevant.
Perhaps you can meet some of these goals with GradeCategories via the API, but I believe that some of them are not currently accessible through the API.
It does look like you can determine the grading system from the Grade Categories section. I see attributes for weight, which would likely be null if the item is not weighted.
Regarding ungraded items, there's this note in the GradeValue section:
Nullable grade values in the computable grade value structures indicate (when null) a default grade value state before a grade value has actually been assessed.
So your code could get computable GradeValues and ignore any with null or assign 0 to them.
I only see an option to PUT a final adjusted grade value.

Orbeon - empty value as 0

I have many input fields in Orbeon in Form builder as war1, war2 , war3, and not all fields have to be filled. I want to make a sum of this fields (I can't make them repeatable because I want to reset it via web service), but when some of the fields are empty, the sum doesn't display. Using an initial value doesn't resolve the problem because I want to set values via a web service, and sometimes the values returned by the service are empty string.
Assuming your fields are named war1, war2, war3, use:
sum(($war1, $war2, $war3)[string() castable as xs:decimal], 0.0)
And for some background on this, see the blog post Formulas for summing values, done right, which is exactly about this topic. (The very fact that there is a blog entry about this tells you that this is rather subtle, which makes your question all the more justifiable.)

Accessing an item beyond start_index=1000 in a YouTube user upload feed

I am currently trying to pull data about videos from a YouTube user upload feed. This feed contains all of the videos uploaded by a certain user, and is accessed from the API by a request to:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads
Where USERNAME is the name of the YouTube user who owns the feed.
However, I have encountered problems when trying to access feeds which are longer than 1000 videos. Since each request to the API can return 50 items, I am iterating through the feed using max_length and start_index as follows:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=1&max-results=50&orderby=published
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=51&max-results=50&orderby=published
And so on, incrementing start_index by 50 on each call. This works perfectly up until:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=1001&max-results=50&orderby=published
At which point I receive a 400 error informing me that 'You cannot request beyond item 1000.' This confused me as I assumed that the query would have only returned 50 videos: 1001-1051 in the order of most recently published. Having looked through the documentation, I discovered this:
Limits on result counts and accessible results
...
For any given query, you will not be able to retrieve more than 1,000
results even if there are more than that. The API will return an error
if you try to retrieve greater than 1,000 results. Thus, the API will
return an error if you set the start-index query parameter to a value
of 1001 or greater. It will also return an error if the sum of the
start-index and max-results parameters is greater than 1,001.
For example, if you set the start-index parameter value to 1000, then
you must set the max-results parameter value to 1, and if you set the
start-index parameter value to 980, then you must set the max-results
parameter value to 21 or less.
I am at a loss about how to access a generic user's 1001st last uploaded video and beyond in a consistent fashion, since they cannot be indexed using only max-results and start-index. Does anyone have any useful suggestions for how to avoid this problem? I hope that I've outlined the difficulty clearly!
Getting all the videos for a given account is supported, but you need to make sure that your request for the uploads feed is going against the backend database and not the search index. Because you're including orderby=published in your request URL, you're going against the search index. Search index feeds are limited to 1000 entries.
Get rid of the orderby=published and you'll get the data you're looking for. The default ordering of the uploads feed is reverse-chronological anyway.
This is a particularly easy mistake to make, and we have a blog post up explaining it in more detail:
http://apiblog.youtube.com/2012/03/keeping-things-fresh.html
The nice thing is that this is something that will no longer be a problem in version 3 of the API.

Resources