0% found this document useful (0 votes)
341 views28 pages

Vdocuments - MX - SGL Calling Watson From RPG Scott Klement Watson Docs Use Curl Docs Are

The document discusses calling IBM Watson services from RPG. It provides an overview of Watson, describes how to access Watson on IBM Cloud and set up services, and provides examples of calling Watson services like translation from RPG using HTTPAPI. It also discusses adapting Curl examples from Watson documentation to HTTPAPI calls in RPG.

Uploaded by

averanavar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
341 views28 pages

Vdocuments - MX - SGL Calling Watson From RPG Scott Klement Watson Docs Use Curl Docs Are

The document discusses calling IBM Watson services from RPG. It provides an overview of Watson, describes how to access Watson on IBM Cloud and set up services, and provides examples of calling Watson services like translation from RPG using HTTPAPI. It also discusses adapting Curl examples from Watson documentation to HTTPAPI calls in RPG.

Uploaded by

averanavar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Calling Watson from RPG

Presented by

Scott Klement
http://www.profoundlogic.com

© 2017-2018, Scott Klement

"Artificial intelligence is about replacing human decision


making with more sophisticated techniques"

The Agenda
Agenda for this session:

1. What Is Watson?

2. How Do I Use It?


• The gist of using it
• Where to find info
• Scott's examples

3. Watson Examples from RPG


• Translation
• Image Recognition

2
What is Watson?

• IBM's "cognitive" platform


• Aritificial Intelligence (AI)
• Understand things normally
understood only by humans
• Originally played "Jeopardy!"
• Set up and customize for your
needs.

Available Two Ways

Watson runs on POWER hardware.


• but, software requires IBM's own Watson (linux-based) platform
• Set up by IBM Watson experts

1. Some big companies have set up Watson on-site


• (working with IBM experts)

2. Anyone can utilitize it via IBM Cloud (formerly: Bluemix)


• this is the only way I've had the opportunity to try it.

IBM Cloud is a platform as a service (PaaS) that:


• Provides Software as a Service (SaaS)
• Provides a Web Service API (often just called "API")
• You can run it from any application that can do web service calls
• Available for free or very low cost.
• Pay more if your usage is higher.
4
Services/SaaS Available

https://www.ibm.com/watson/products-services/

• Conversation: build chat bots


• Discovery: Discover hidden value in data
• Vision: Search visual content with machine learning
• Speech: Convert audio to/from written text
• Language: Understand written human language
• Empathy: Understand tone and personality of language

Taking a Tour of the Web Site

Home Page for Watson:


https://www.ibm.com/watson/

The Products/Services Available (i.e. interesting part)


https://www.ibm.com/watson/products-services/

Signing Up for IBM Cloud (free)


https://www.ibm.com/cloud-computing/bluemix/watson

6
Inside Your IBM Cloud Account

https://console.bluemix.net/catalog
https://console.bluemix.net/dashboard/apps

• IBM Cloud has other (non-Watson) APIs as well


• You can set up a given service to run in your account
• You can read about the APIs, see docs and demos as well

• This is what your RPG programs will actually connect to


• This is what you can use directly.
• Dashboard/apps shows what you currently have set up

Watson Docs / Examples

To read about the different services:


• Go to the catalog link
• In the categories (on the left) click Watson

The next page shows what you can "create"


• "create" because you set up your own copy
• On your own (cloud-based) server

If you click one


• Option to create it
• Option to view docs
• Sometimes there's a demo available
• Pricing plan(s)

8
Create a Service on your IBM Cloud
These are the fields you'll need to provide. (You can usually just take the defaults.)

• Service Name = Unique name for your newly created service. IBM Cloud will
generate a name, but you can change it to whatever you like.

• Credential Name = Name of credentials (userid/password – or API key and


password) needed to use the service. You can create a new one or use an
existing one. You can create multiple if you'll have multiple people that should
not share.

• Region to deploy in = Which IBM Cloud server location. Pick the one closest to
you for best performance.

• Organization = Your organization.

• Choose a space = Space you set up when you signed up

• Connect to = Not sure, I always take the default!

How Does an API Work?

model_id = en-es
text = Hello

Hola

10
Lets Do it In RPG!

11

The Process in RPG

The process is basically the same!

• Show screen
• Get data from the screen and build strings
• Use HTTPAPI (or another HTTP tool) to send
and receive
• Put the response string on the screen

12
Watson Docs – Use Curl

Docs are available for Curl, Node.js, Java and Python (but not RPG!)
Curl is the closest to plain HTTP, and easy to adapt to HTTPAPI

13

Watson Docs – Use Curl

Curl Is:
• command-line tool for HTTP and many other network protocols
• freely available (open source)
• most commonly found on Linux
• but, can run on IBM i in PASE (AIX version)
• or on Windows, Mac OS, Linux, FreeBSD, etc.
The Curl Home Page:
https://curl.haxx.se
The Curl Manual (to understand what the options do):
https://curl.haxx.se/docs/manpage.html
You will mainly use curl to test out and understand the Watson services, but
will adapt them to HTTPAPI (or another HTTP tool for RPG) for production
use. For that reason, I recommend running it on your PC.
Or, use the Watson API Explorer (next slide)

14
Watson API Explorer

The API Explorer (links are in API docs) provides a Web-based curl interface

15

About HTTPAPI

• HTTPAPI lets you make HTTP calls from RPG


• by Scott Klement, started in 2001 – but please use the latest!
• freely available (open source) at no charge
• very versatile
• very fast

Main routines that we want to use:


• http_req = routine for making an HTTP request (i.e. calling a URL)
• http_stmf = implified version of http_req when data sent/received is an IFS file
• http_string = simplified version of http_req when data send/received is in strings

Other routines that complement the main ones:


• http_setOption = sets various options to control how HTTPAPI works
• http_setAuth = sets userid/password used by the HTTP protocol
• http_debug = generates a file in the IFS with diagnostic information
• http_error = retrieves the last error that occurred in an HTTPAPI routine

16
Adapting Curl to HTTPAPI

CURL OPTION HTTPAPI Option

-X or --request with POST or GET “type” parameter = POST or GET

No -X or –request specified “type” parameter = GET

-u or --user with “user:pass” Use HTTP_setAuth(HTTP_AUTH_BASIC: ‘user’: ‘pass’)

-H or --header with “content-type” “contentType” parameter

-H or --header but not content-type Use HTTP_xproc(HTTP_POINT_ADDL_HEADER)


See Translation with JSON example.
-d or --data SendStr or SendStmf parameter

-F or –form SendStr or SendStmf encoded with “multipart/form-data” (MFD)


See Visual Recognition Example

Use of @ to get from file Use http_req or http_stmf with SendStmf parameter

URL parameter URL parameter

Output Use Response or Result Stmf/String parameters


Or return value from http_string() API.

17

Translate in RPG (Simple)

http_string() is an HTTP API routine to send/receive using character strings

full code sample can be downloaded from Scott's web site (link at end)

http_setAuth( HTTP_AUTH_BASIC
: 'api key from Watson API credentials'
: 'password from Watson API credentials' );

url = 'https://gateway.watsonplatform.net'
+ '/language-translator/api/v2/translate'
+ '?model_id=' + http_urlEncode(fromLang + '-' + toLang)
+ '&text=' + http_urlEncode(%trimr(fromText));

monitor;
resp = http_string('GET': url);
on-error;
httpcode = http_error();
endmon;
18
Even Better, Use JSON
Instead of the "simple" (plain text) format we've used so far, I recommend JSON
• Much more versatile
• Many of the APIs require it
• Works with POST methods, allowing much larger data to be passed

It is a little more work to process JSON in RPG vs plain text.


• the YAJL tool helps a lot
• YAJL is extremely fast

JSON looks like this:

{
"model_id": "en-es",
"text": "Hello"
}

19

Overview With JSON

{
"source": "en",
"target": "es",
"text": "Hello"
}

{
"translations": [{
"translation": "Hola"
}],
"word_count": 1,
"character_count": 5
}

20
Generating JSON with YAJL
yajl_genOpen(*off);
yajl_beginObj(); // {
yajl_addChar('source': fromLang); // "source": "en",
yajl_addChar('target': toLang); // "target": "es",
yajl_addChar('text': fromText ); // "text": "Hello"
yajl_endObj(); // }

request = yajl_copyBufStr();
yajl_genClose();

Very quick introduction to the YAJL tools for generating JSON documents:

• yajl_genOpen / yajl_genClose start/stop the JSON generator


• yajl_beginObj / yajl_endObj create a JSON object (the stuff in curly braces)
• yajl_addChar adds a character string to the open object
• yajl_addNum, yajl_addBool, yajl_beginArray, yajl_endArray also available
• yajl_copyBufStr copies the generated JSON buffer to an RPG string

21

Reading JSON with YAJL

docNode = yajl_string_load_tree(response: errMsg);


if errMsg = '';
node = yajl_object_find(docNode: 'translations');
node = yajl_array_elem(node: 1);
node = yajl_object_find(node: 'translation');
output = yajl_get_string(node);
yajl_tree_free(docNode);
endif;

Very quick introduction to the YAJL tools for reading JSON documents:

• yajl_string_load_tree loads the whole JSON document intro memory and returns
the "document node" (pointer to outermost JSON element)
• yajl_object_find given a pointer to an object, finds a subfield in that object
• yajl_array_elem given a pointer to an array, finds an element in that array
• yajl_get_string given a pointer to a string, returns the string value
• yajl_get_number, yajl_is_true, yajl_is_false can be used for other data types
• yajl_tree_free removes the JSON document from memory
22
Media Types (aka MIME types)
Various internet protocols use media types (also called "MIME" types) to identify the data
type of something.

• text/plain = a plain text document


• application/json = a JSON document
• image/jpeg = a .JPG image or picture
• etc.

These HTTP headers can be used with the Language Translator to tell Watson we want
to send/receive JSON documents instead of plain text.
• content-type header = the type of the document we're sending
• accept header = the type of the document we want to receive back

23

Media Types in Curl


This example (from the Watson docs) shows how to use JSON by specifying
the appropriate media types:

curl -u "{username}":"{password}"
-X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-d '{"text":"Hello","source":"en","target":"es"}'
"https://gateway.watsonplatform.net/language-translator/api/v2/translate"

Most of this is pretty easy to do in HTTPAPI as well.


• -u is simply passed to http_setAuth (like before)
• -X is the first parameter to http_req, http_string or http_stmf
• -d is the send data, and should be placed in the appropriate send parameter
• HTTPAPI also has a parameter for content-type, same as –H Content-Type
• Accept however is a bit trickier since HTTPAPI does not have a parameter
for the (infrequently used) Accept header.
• You can use http_xproc ("exit procedure") to customize HTTPAPI's behavior
• The HTTP_POINT_ADDL_HEADER option lets you call a subprocedure that
can (manually) add any additional HTTP header you wish.
24
Media Types in HTTPAPI
Here I wrote a subprocedure called AddAccept that manually adds the Accept
header, and registered it with http_xproc. When http_string() runs, it will call my
procedure, and add this new header.
http_xproc( HTTP_POINT_ADDL_HEADER: %paddr(AddAccept));

response = http_string('POST': url: request: 'application/json');


.
.
dcl-proc AddAccept;

dcl-pi *n;
header varchar(32767);
end-pi;
dcl-c CRLF x'0d25';

header = 'Accept: application/json' + CRLF;

end-proc;

25

Translate with JSON (1 of 6)


To put all of these concepts together, here's the full RPG code for the translate
example, using JSON rather than plain text.

**free
ctl-opt option(*srcstmt) dftactGrp(*no)
bnddir('HTTPAPI':'YAJL');
BNDDIR is used to bind
your program to the tools
/copy httpapi_h
/copy yajl_h
Copybooks contain the
dcl-f WATSONTR1D workstn indds(dspf); definitions we'll need to
call the HTTPAPI and
YAJL routines
dcl-Ds dspf qualified;
F3Exit ind pos(3);
end-Ds;

dcl-c UPPER 'ENESFRITPT';


dcl-c lower 'enesfritpt';

fromLang = 'en';
toLang = 'es';
26
Translate with JSON (2 of 6)
Main loop controls the flow of the program, repeating the screen until F3 key is
pressed.

dou dspf.F3Exit = *on;

exfmt screen1;
if dspf.F3exit = *on;
leave;
endif;

fromLang = %xlate(UPPER:lower:fromLang);
toLang = %xlate(UPPER:lower:toLang);
toText = translate( fromLang: toLang: %trim(fromText) );

enddo;

*inlr = *on;
return;

the translate procedure is what


actually calls Watson
27

Translate with JSON (3 of 6)


dcl-proc translate;

dcl-pi *n varchar(1000);
fromLang char(2) const;
tolang char(2) const;
fromText varchar(1000) const;
end-pi;

dcl-s url varchar(2000);


dcl-s request varchar(2000);
dcl-s response varchar(5000);
dcl-s output varchar(1000);
dcl-s errMsg varchar(500); Generate the JSON document to
dcl-s docNode like(yajl_val); send
dcl-s node like(yajl_val);

yajl_genOpen(*off);
yajl_beginObj(); // {
yajl_addChar('source': fromLang); // "source": "en",
yajl_addChar('target': toLang); // "target": "fr",
yajl_addChar('text': fromText ); // "text": "String here"
yajl_endObj(); // }
Put the JSON data into a variable
request = yajl_copyBufStr();
named "request"
yajl_genClose(); 28
Translate with JSON (4 of 6)
http_debug(*on: '/tmp/watson-diagnostic-log.txt');
Translate our job's
http_setOption('local-ccsid': '0');
EBCDIC to UTF-8
http_setOption('network-ccsid': '1208');
(standard for web)
http_xproc( HTTP_POINT_ADDL_HEADER: %paddr(AddAccept));

http_setAuth( HTTP_AUTH_BASIC: 'the-credential': 'the-password' );

url = 'https://gateway.watsonplatform.net'
+ '/language-translator/api/v2/translate';

monitor;
response = http_string('POST': url: request: 'application/json');
on-error;
httpcode = http_error();
endmon;
http_string will send the "request"
variable we made, and receive
Watson's output into "response"

If an error occurs, we'll put the error


information into the "httpcode" variable
that will be shown on the screen 29

Translate with JSON (5 of 6)

docNode = yajl_string_load_tree(response: errMsg);


if errMsg = '';
node = yajl_object_find(docNode: 'translations');
node = yajl_array_elem(node: 1);
node = yajl_object_find(node: 'translation');
output = yajl_get_string(node);
yajl_tree_free(docNode); {
"translations": [{
endif;
"translation": "Hola"
}],
return output; "word_count": 1,
"character_count": 5
end-Proc; }

We first get the "translations" subfield of the document, which is itself an array
of objects. We'll take the first array element, and get it's "translation" subfield,
and then get a string from that.

30
Translate with JSON (6 of 6)
All that's left is the AddAccept subprocedure (that I showed you several slides
back)

dcl-proc AddAccept;

dcl-pi *n;
header varchar(32767);
end-pi;
dcl-c CRLF x'0d25';

header = 'Accept: application/json' + CRLF;

end-proc;

31

Got the Idea?


You now know the basics of how to call the Watson services from RPG.
• Find the service you want
• Create it
• Read the documentation for that service
• Use "curl" examples
• Adapt the "curl" examples to HTTPAPI

Following the same techniques will allow you to call any of Watson's services!

32
Example of Finding Approved Vendors

This Example uses Watson's Natural Language Understanding API


• Loop through a table (PF) with approved vendor's web sites
• Ask Watson to analyze them and find keywords on their site
• Put the keywords in a file
• Allow the user to query the file by keyword

33

The AVLIST Table

This is what the "AVLIST" (approved vendor list) table (PF) looks like (excerpt)

34
Natural Language Understanding (1 of 5)
This is the main loop that controls the program to analyze the vendor's sites:
exec SQL declare C1 cursor for
select * from AVLIST;

exec SQL open C1;

exec SQL fetch next from C1 into :AVLIST;


dow sqlstt='00000';

request = createJsonRequest(AVLIST);

monitor;
response = http_string('POST': url: request: 'application/json');
on-error;
response = '';
endmon;

extractKeywords(AVLIST.VNUM: response);

exec SQL fetch next from C1 into :AVLIST;


enddo;

exec SQL close C1;


35

Natural Language Understanding (2 of 5)


Create the JSON document that is sent to Watson to tell it what to do.
dcl-proc createJsonRequest;

dcl-pi *N varchar(1000);
VEND likeds(AVLIST) const;
end-pi;

dcl-s json varchar(1000);

yajl_genOpen(*off);
yajl_beginObj(); // {
yajl_addChar('url': %trim(VEND.VURL)); // "url": "http://example.com",
yajl_beginObj('features'); // "features" : {
yajl_beginObj('keywords'); // "keywords": {
yajl_endObj(); // }
yajl_endObj(); // }
yajl_endObj(); //

json = yajl_copyBufStr();
yajl_genClose();

return json;
end-proc;
36
Natural Language Understanding (3 of 5)
The "extractKeywords" subprocedure interprets the JSON document that
Watson sent back, gets the keywords that it found, and writes those keywords to a
second table named AVKEYWORDS.
This AVKEYWORDS table (PF) can then be searched by the user.

dcl-proc extractKeywords;

dcl-pi *N;
vnum packed(7: 0) value;
json varchar(100000) const;
end-pi;

dcl-s docNode like(yajl_val);


dcl-s keywords like(yajl_val);
dcl-s keyword like(yajl_val);
dcl-s errMsg varchar(500);
dcl-s text char(40);
dcl-s relv packed(5: 3);
dcl-s i int(10);

37

Natural Language Understanding (4 of 5)

docNode = yajl_string_load_tree(response: errMsg);


if errMsg = '';
keywords = yajl_object_find(docNode: 'keywords');
i = 0;
dow YAJL_ARRAY_LOOP(keywords: i: keyword);

text = yajl_get_string(yajl_object_find(keyword: 'text'));


Only if Watson is
relv = yajl_get_number(yajl_object_find(keyword: 'relevance'));
35% sure of this
if relv > 0.35; keyword
exec SQL insert into AVKEYWORDS values(:vnum, UPPER(:text));
endif;
{
enddo;
"keywords": [
yajl_tree_free(docNode); {
endif; "text": "first keyword",
"relevance": 0.99321
end-proc; },
{
"text": "second keyword",
"relevance": 0.32123
}
]
} 38
Natural Language Understanding (5 of 5)
A second program uses traditional RPG techniques (code not shown – it's just normal
RPG) to search the AVKEYWORDS table that we just populated.

39

Visual Recognition API

Watson's Visual Recognition can "understand" the contents of photographs or


video frames. It seeks to answer two questions:
• What is in this image?
• Are there other, similar, images?

There is setup involved. You must "train" Watson in how to recognize a given
subject.

Once trained, however, it can recognize the same subject in any picture, even
from different angles.

40
Training the Visual Recognition Tool

Training involves:
• Upload .ZIP files with matching
images.
• Upload .ZIP file(s) with "negative"
matches (to teach Watson what not
to consider a match)

There is a tool on IBM Cloud that you


can use to train the API. (No need to
write code to do that if you don't want
to!)

41

Insurance Claim Example (Background Info)

This example started with an old, green-screen, RPG program for entering
insurance claims (such as car accidents)

42
Insurance Claim Example (Background Info)

Years later (but still awhile back) this application was converted to a web-based
GUI using Profound Logic's tools. RPG Open Access was used so the RPG
code didn't have to change, though a small amount of code was added to allow
picture uploads.

43

Insurance Claim Example (Background Info)

We decided to use Watson to help set the "Classication" of each claim.


• Trained Watson with images to recognize each classification category
• Now, when a user adds a new picture (or changes existing one)
• Watson figures out the right "classification" of the claim.

44
What Watson Determines

We wrote a routine named watson_classify for our RPG program. It accepts the
pathname to the photograph (in the IFS) and returns the following data structure:

D classify_t ds qualified
D template
D code 10i 0 inz(1)
D errMsg 500a varying inz('')
D class 256a varying inz('')
D score 9p 7 inz(0)

D obj ds likeds(classify_t)

• "code" and "errMsg" are used to report an error (if any)


• "class" is the classification determined by Watson
• "score" is how confident (from 0=unlikely to 1=completely positive) Watson was

45

Incorporating Into Existing Code


The existing fixed format code was modified to call the Watson Visual
Recognition "classify" API when the image was changed, and based on Watson's
"first" choice (most likely classification) it sets the classification field to Y or N

C If UploadInfo = '001'
C Eval done = *Off

// --------------------------------------------------------
// New Code for recognizing image:
C eval obj = watson_classify(imagefile)
C if obj.score > 0.75
C
C select
C when obj.class = 'motorcycleaccident'
C eval cmmotor = 'Y'
C when obj.class = 'brokenwinshield'
C eval cmbrokenw = 'Y'
...etc...

If Watson wasn't 75% sure, we ignored it's classification (leaving it to the user)
46
Visual Recognition RPG (1 of 6)

dcl-proc watson_classify;

dcl-pi *n likeds(classify_t);
imageName varchar(256) const;
end-pi;

dcl-c WATSON_API_KEY 'the api key from IBM Cloud is put here';

dcl-s imagePath varchar(256);


dcl-s params varchar(256);
dcl-s form pointer;
dcl-s contentType char(64);
dcl-s tempFile varchar(256);
dcl-s rc int(10);
dcl-s docNode like(yajl_val);
dcl-s topClass like(yajl_val);
dcl-s node like(yajl_val);
dcl-s response varchar(100000);
dcl-s errMsg varchar(500);
dcl-s url varchar(500);

dcl-ds result likeds(classify_t) inz;

47

Visual Recognition RPG (2 of 6)

http_debug(*on: '/tmp/watson-claim15r.txt');

imagePath = '/www/profoundui/htdocs/profoundui/userdata/'
+ 'images/claims/' + %trim(imageName);

// Create a JSON document containing the


// parameters to the "classify" API:

yajl_genOpen(*off);
yajl_beginObj(); // {
yajl_beginArray('classifier_ids'); // "classifier_ids": [
yajl_addChar('insuranceclaims_1650517727'); // "id-goes-here"
yajl_endArray(); // ]
yajl_endObj(); // }
params = yajl_copyBufStr();
yajl_genClose();

The input JSON document is very simple – it just tells Watson which "classifier"
to use (i.e. which set of data that we trained Watson with)
48
Visual Recognition RPG (3 of 6)
// Create a multipart/form-data form (like curl -F switch)
// to contain both the image and the parameters
// (this is created in a temporary IFS file)

tempFile = http_tempfile();
form = http_mfd_encoder_open( tempFile: contentType );
http_mfd_encoder_addstmf( form
: 'images_file'
: imagePath
: 'image/jpeg' );
http_mfd_encoder_addvar_s( form: 'parameters': params );
http_mfd_encoder_close(form);

The image is uploaded using a "multi part form", like a web browser would use.
• One part contains the input JSON document (from last slide)
• The other part contains the image.
HTTPAPI's multi-part form data (MFD) tool creates this form in a temporary IFS
file. Although the images in the insurance claims are small, HTTPAPI has the
capacity to handle multiple gigabytes of data, so keeping the form in memory
isn't practical.
49

Visual Recognition RPG (4 of 6)


url = 'https://gateway-a.watsonplatform.net'
+ '/visual-recognition/api/v3/classify'
+ '?api_key=' + WATSON_API_KEY
+ '&version=2016-05-19';

rc = http_req( 'POST'
: url
: *omit: response
: tempFile: *omit
: %trim(contentType) );

// delete temporary file -- no longer needed.


unlink(tempFile);

Since the input is an IFS file, but I wanted the output to be returned as a string, I
used the http_req() routine.

There are two parameters for "response data", for string and file, respectively.
Also two for "send data", a string and a file.
One send option and one response option must be set to *omit.
50
Response JSON Document
{ We only upload one
"custom_classes":5, image at a time, so there
"images":[ will never be more than
{ one entry in the images
"classifiers":[ array.
{
"classes":[ Only asked for one
{ classifier (trained
"class":"brokenwinshield", databased) so
"classifiers" will only have
"score":0.976408 one array entry.
}
],
"classifier_id":"insuranceclaims_1650517727", Watson might see more
"name":"insurance-claims" than one class. But the
} "top pick" will be first.
],
"image":"image path name here"
} Conclusion: We want the first
], array entry inside the first array
"images_processed":1 entry of the first array entry!
}
51

Visual Recognition RPG (5 of 6)


docNode = yajl_string_load_tree( response: errMsg);
if errMsg <> '';
result.errMsg = errMsg;
result.code = -999;
return result;
endif;

// Get first "images" array entry:


node = yajl_object_find(docNode: 'images');
node = yajl_array_elem(node: 1);

// Get first "classifers" array entry:


node = yajl_object_find(node: 'classifiers');
if yajl_array_size(node) >= 1;

node = yajl_array_elem(node: 1);

// Get first "classes" array entry:


node = yajl_object_find(node: 'classes');
topClass = yajl_array_elem(node: 1);

52
Visual Recognition RPG (6 of 6)

// get the class name and score of the


// top class for our return value

node = yajl_object_find(topClass: 'class');


result.class = yajl_get_string(node);
node = yajl_object_find(topClass: 'score');
result.score = yajl_get_number(node);

endif;

yajl_tree_free(docNode);

return result;
end-proc;

53

Conclusion

This presentation barely scratches the surface of what Watson can do!
• Cognitive Computing
• A computer that can "think"!
• Understand human language better than ever before
• Understand human photographs better than ever before
• Can search and understand massive volumes of (unstructured)
documents and pictures and discover trends, patterns, etc.
• Best of all, anyone can use it – from RPG on IBM i!
• It's just a web service (API) call!

54
This Presentation

You can download a PDF copy of this presentation and the


sample code that I used from
http://www.scottklement.com/presentations/

Thank you!

55

You might also like