On August, Wednesday 3 we hosted our d-shop’s very first Hololens Hackaton. People who had never used Unity3D before and of course who had never code for the Hololens before gathered together to have a fun and exciting learning experience.
Thanks to the hard work and organization efforts from my team partners Aaron Williams and Julia Satsuta we had three awesome guys from Microsoft Vlad Kolesnikov, Petri Wihelmsen and Jaime Rodriguez.
The first day was spend with explanations of what Hololens is…a quick introduction to Unity3D and a design thinking / brainstorming part where the teams could develop their ideas.
The second day started with Hololens coding and coaching from our side. People were totally excited and pumped up…trying things out on the Unity3D editor…on the Hololens emulator and on the device itself.
As a way to include more people and leave the teams working without too many distractions, we had a session on Hololens on Building 7…open for anyone to join in…
After that, we went back to keep coaching and helping the teams. They needed to be fully ready by 3:30pm as we had the demo presentation at 4:00pm.
The demo presentation happened at the cafeteria on Building 8.
We had 5 teams presenting their awesome work…
Holoterior
Design your dream room
Mechannotate
Order part on the go...don't waste your time filling sheets
Next Talent
Engage your newly hired talents by immersing them in your culture and history
TripIp
Planning your next trip? Get the seat that it's more comfortable for you
The Wesley Crushers
Is your pipe broken? Check it...measure it and request a replacement
As you can see…all the teams put a lot of effort and created some really awesome demos…but…there’s always need to be only one winner…so the last team to present was the team who won…so…congratulations “The Wesley Crushers” team!
After this really nice experience…I’m sure we’re going to come back for more…Hololens is still a brand new technology, so there’s still a lot to learn, a lot to hack and a lot of possibilities.
If you’re in Palo Alto…come and visit us! Remember that the d-shop is located on the first floor of Building 9 on Deer Creek Road -;)
This is my first blog of the year…so I want it to be something really nice and huge -:) You know how much I love the R Programming Language…but I also love other technologies as well…so taking a bunch of them and hooking them up together is what really brings me joy.
Now…you may be wondering about the blog title…”There’s a party at Alexa’s place”…well…I wanted it to describe the blog in a funny way…so let’s see what we’re going to build -;)
Got any idea? Basically…we’re going to use Amazon Alexa as our UI…when we ask a command…we’re going to call a NodeJS Server on Heroku (Which BTW has a PhantomJS client installed)…this NodeJS will call an R Server on Heroku (Using the Rook Server)…and this R Server is going to call HANA Cloud Platform to get some Flights information and generate nice graphics that are going to be returned to the NodeJS Server which is going to call our web browser to display the graphic generated by the R Server…of course…by using PhantomJS were going to read the generated web page on the browser and this will be sent back to Amazon Alexa so she can read out the response…interesting enough for you? I hope -:) I took me more than two weeks to get all this up and running…so you better like it -:P
So…let’s go in some simple steps…
GET A HANA CLOUD PLATFORM ACCOUNT
You should have one already…if not…just go here to create one…
Then…we need to download the HANA Cloud Platform SDK extract it and modify the file tools/neo.sh on line 57…
Instead of this…
javaExe="$JAVA_HOME/bin/$javaCommand"
Use this…
javaExe="$JAVA_HOME"
Why? Well…it will make sense later on…or maybe it will make sense now If you have the SAP HANA Client installed…otherwise download it from here take a note that will need to copy the ngdbc.jar file…
GETTING THE DATA THAT WE'RE GOING TO USE
As always…in almost all my blogs…we’re going to use tables from the Flight model…which of course…doesn’t exist on HANA Cloud Platform…
The easiest way (at least for me) was to access an R/3 server…and simply download the tables as XLS files…convert them into CSV files and upload them into HCP…
And BTW…for some weird reason my R/3 didn’t have American Airlines listen on the SCARR table…so I just added it -;)
Now…if you don’t have access to an R/3 system…then you can download the tables in CSV format from here
CREATE THE R SERVER ON HEROKU
If you don’t have the Heroku Tool Belt installed…then go and grab it…
Steps to install R on Heroku with Graphic Capabilities
mkdkir myproject && cd myproject
mkdir bin
echo “puts ‘OK’ > config.ru
echo “source ‘http://rubygems.org’\n gem ‘rack’” > Gemfile
#Open your project folder and modify the Gemfile to replace the “\n” with an actual break line…
bundle install
git init . && git add . && git commit –m “Init”
heroku apps:create myproject –stack=cedar
git push heroku master
#Copy and paste the content of my installR.sh into the /bin folder of your project
git add . && git commit –am “message” && git push heroku master
heroku ps:scale web=0
installR.sh
#!/bin/bash
function download() {
if [ ! -f "$2" ]; then
echo Downloading $2...
curl $1 -o $2
else
echo Got $2...
fi
}
set -e
r_version="${1:-3.2.3}"
r_version_major=${r_version:0:1}
if [ -z "$r_version" ]; then
echo "USAGE: $0 VERSION"
exit 1
fi
basedir="$( cd -P "$( dirname "$0" )" && pwd )"
# create output directory
vendordir=/app/vendor
mkdir -p $vendordir
# R
download http://cran.r-project.org/src/base/R-$r_version_major/R-$r_version.tar.gz R-$r_version.tar.gz
tar xzf R-$r_version.tar.gz
# build R
echo ============================================================
echo Building R
echo ============================================================
cd $basedir/R-$r_version/
./configure --prefix=$vendordir/R --with-blas --with-lapack --enable-R-shlib --with-readline=no --with-x=yes
make
cd /app/bin
ln -s R-$r_version/bin/R
rm R-3.2.3.tar.gz
rm -rf erb gem irb rake rdoc ri ruby testrb
rm ruby.exe
cd /app/bin/R-$r_version
rm -rf src
rm Make*
rm -rf doc
rm -rf tests
rm README ChangeLog COPYING INSTALL SVN-REVISION VERSION
Now…we need to do a very important step -:) We need to install the totally awesome heroku-buildpack-multi from ddollar.
With this done…we will have all the missing libraries needed to compile R on the new Cedar Stack on Heroku and also…we will have a nicely installed R instance with Graphic capabilities…but of course…we’re not done yet…
Installing the R Libraries
#This will open R on Heroku…
R
#This will install the libraries with their corresponding dependencies
install.packages("Rook",dependencies=TRUE)
install.packages("Cairo",dependencies=TRUE)
install.packages("maps",dependencies=TRUE)
install.packages("forecast",dependencies=TRUE)
install.packages("plotrix",dependencies=TRUE)
install.packages("ggplot2",dependencies=TRUE)
install.packages("ggmap",dependencies=TRUE)
install.packages("rJava",dependencies=TRUE)
install.packages("RJDBC",dependencies=TRUE)
q()
All right…we’re almost there -;) The problem with Heroku is that is not writable…meaning that once you get disconnected…you will lost all your work -:(
So…we need to back it up and sent it somewhere else…I used my R Server on Amazon WebServices for this…
First…we need to compress the bin folder like this…
tar -cvzf bin.tar.gz bin
and then we need to save this file in our external server…
and of course after that we need it on our project folder…so we need to send it from our external server to our project folder, where will simply would need to uncompressed it…
So…let’s take some time to understand what’s going on with this code…we’re going to create a Rook server…which will allow us to host webpages from R…then, we’re going to use our hcp.sh script to get the password for our HANA Cloud Platform bridge…so we can get an JDBC connection to the database…from there we want to get a list of all the airports and also read the airports from a file detailed later (this airports file contains the geolocation of the airports). With this…we want to filter out the airports from HANA with the airports from the flight…so we don’t have any extra data…now…we have three choices…airports, US airports or carriers…the first one will generate a map of the world with all the airports as little red dots…the second one will generate a map of the US with the airports as little red dots but also showing the name of the cities…the last one will generate a geometric histogram with the details of the flights distance according to their carriers…later on…we’re going to read the information of the generated graphic to create a hexadecimal string of the graphic along with some information that Alexa should spell out…easy as cake, huh?
Procfile
web: bundle exec rackup config.ru
We want this R Server to be able to access HANA Cloud Platform…so let’s do that before we keep going…
With the location of Java…apply this command…
heroku config:set JAVA_HOME='/usr/bin/java'
Now…Copy the following files into your project folder…
“tools” folder from the HANA Cloud Platform SDK ngdbc.jar from SAP HANA Client
Also…create this little script which is going to allow us to connect to HCP…
var WebSocketServer = require("ws").Server
, http = require("http")
, express = require("express")
, request = require('request')
, fs = require('fs')
, app = express()
, arr = []
, msg = ""
, port = process.env.PORT || 5000
, childProcess = require('child_process')
, phantomjs = require('phantomjs-prebuilt')
, path = require('path')
, binPath = phantomjs.path;
app.use(express.static(__dirname + "/"))
var server = http.createServer(app)
server.listen(port)
var wss = new WebSocketServer({server: server})
var childArgs = [path.join(__dirname, 'phantom.js')]
var childStats = [path.join(__dirname, 'readphantom.js')]
app.get('/path', function (req, res) {
if(req.query.command == 'map'){
URL = "http://blagrookheroku.herokuapp.com/custom/summarize?airports=xyz&us_airports=&carriers=";
request(URL, function (error, response, body) {
if (!error) {
arr = body.split("/");
msg = "There are " + arr[1] + " airports around the world";
var bitmap = new Buffer(arr[0], 'hex');
var jpeg = new Buffer(bitmap,'base64');
fs.writeFileSync('Graph.jpg', jpeg);
res.redirect('/');
};
});
}else if(req.query.command == 'usmap'){
URL = "http://blagrookheroku.herokuapp.com/custom/summarize?airports=&us_airports=xyz&carriers=";
request(URL, function (error, response, body) {
if (!error) {
arr = body.split("/");
msg = "There are " + arr[1] + " airports in the US";
var bitmap = new Buffer(arr[0], 'hex');
var jpeg = new Buffer(bitmap,'base64');
fs.writeFileSync('Graph.jpg', jpeg);
res.redirect('/');
};
});
}else if(req.query.command == 'carriers'){
URL = "http://blagrookheroku.herokuapp.com/custom/summarize?airports=&us_airports=&carriers=xyz";
request(URL, function (error, response, body) {
if (!error) {
arr = body.split("/");
msg = "" + arr[1];
var bitmap = new Buffer(arr[0], 'hex');
var jpeg = new Buffer(bitmap,'base64');
fs.writeFileSync('Graph.jpg', jpeg);
res.redirect('/');
};
});
}else if(req.query.command == 'stat') {
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr){
if(!err){
res.redirect('/');
};
});
}else if(req.query.command == 'readstat') {
childProcess.execFile(binPath, childStats, function(err, stdout, stderr){
if(!err){
res.write(stdout);
res.end();
};
});
}else if(req.query.command == 'bye'){
if(fs.existsSync('Graph.jpg')){
fs.unlink('Graph.jpg');
}
res.redirect('/');
}
});
wss.on("connection", function(ws) {
var id = setInterval(function() {
fs.readFile('Graph.jpg', function(err, data) {
if(!err){
ws.send(JSON.stringify("Graph.jpg/" + msg), function() { })
}else{
ws.send(JSON.stringify("Gandalf.jpg/No problem...I'm crunching your data..."), function() { })
}
});
}, 3000)
ws.on("close", function() {
clearInterval(id)
})
})
Let’s explain the code for a little bit and believe me…I’m far from being a NodeJS expert…this is really the first time I develop something this complex…and it took me a really long time and tons of research…so please try not to criticize me too much -:(
We’re going to create a express application that uses Web Sockets in order to refresh the browser in order to show the graphics generated by our R Server…it will also call PhantomJS to both create and read the generated web page so we can send it back to Alexa…
Here…we have six choices…map, usmap and carriers…the first three are going to call our R Server passing all parameters but leaving the ones that we don’t need empty…and just passing “xyz” as parameter…
When we got the response from R it’s going to be a long string separated by an “/”…which is going to be the hexadecimal string for the graphic along with the text intended for Alexa…Node will read the graphic…generated it and then refresh the browser in order to show it on the screen…
The stats option will call our PhantomJS script to simply read the page and create a new file with the Javascript part already executed…the readstat will read this information and extract the text that we need for Alexa…finally…bye will delete the graphic and the web socket will call the main graphic to be displayed on the screen.
Finally…the web socket is going to constantly check…every 3 seconds to see if there’s a graphic or not…and the display the related image…
index.html
<html>
<head>
<title>I'm a NodeJS Page!</title>
<div id="container" align="center"/>
<script>
var host = location.origin.replace(/^http/, 'ws')
var ws = new WebSocket(host);
ws.onmessage = function (event) {
var container = document.getElementById('container');
var data = JSON.parse(event.data);
data = data.split("/");
var url = data[0];
var msg = data[1];
container.innerHTML = '<img src="' + url + '"></br><p><b>' + msg + '</b></p>';
};
</script>
</head>
<body>
</body>
</html>
This one is going to be called by our express application and it will simply call the web socket to determine what it needs to display…it has some Javascript…that’s why we need PhantomJS to interact with it…
phantom.js
var page = require('webpage').create();
var fs = require('fs');
page.open('http://blagnodeheroku.herokuapp.com/', function () {
window.setTimeout(function () {
page.evaluate(function(){
});
fs.write('stats.html', page.content, 'w');
phantom.exit();
},4000);
});
Not the best and most describing name…but who cares -:P Anyway…this script will load the page…that is the express application…wait for 4 seconds for the Javascript to get generated and then create a web page called stats.html
readphantom.js
var page = require('webpage').create(),
address = "stats.html";
page.open(address, function (status) {
if (status == 'success') {
var results = page.evaluate(function() {
return document.querySelector('p').innerText.trim();
});
console.log(results);
phantom.exit();
}
});
This script will simply read the stats.html page and return the text that it’s located inside the “p” tag…dead simple…
SETTING UP ALEXA Creating the Lambda function
Now…we need to setup Alexa…so we can control everything via voice commands -:)
First…we need to go to Amazon Lambda and log in if you have an account…otherwise…please create one…and make sure you’re on the West Virginia region…
In the list of functions…look for color…
Choose the NodeJS one…Python has been included as well…but wasn’t when I started to work on this blog -:)
Here, just click next....
I already create the function…but you shouldn’t have a problem...
Basic execution role is more than enough…
This will provide a pop up window…simply press the “Allow” button and then “Create function”…we will include the source code later on…but notice the ARN generated number…because we’re going to need it on the next step…
Creating the Skill
Go to http://developer.amazon.com and log in…then choose Apps & Services --> Alexa --> Alexa Skills Set
Choose Alexa Skills Kit and fill the blanks...
As soon as we hit next an application number will be generated on a new field called Application ID. Grab this number as we’re going to need it for our application code.
The Interaction Model section is very important as here we’re going to define the “Intent Schema” and “Sample Utterances”…the first will define the parameters that we’re going to send to Alexa and the second is how we are going to call our application.
Our variable is going to be called “command” and it’s going to be a LITERAL…other types are NUMBER, DATE, TIME and DURATION. The intent is the method that we’re going to call in our code…
Sample Utterances
GetFlightsIntent airports from {around the world|command}
GetFlightsIntent airports from {united states|command}
GetFlightsIntent flight distance from {carriers|command}
GetFlightsIntent {thank you|command}
The test section help us to say commands and see how Alexa responds…but we’re not going to do that here…we’re going to test it using a real Alexa device -;)
Forget about the Publishing Information section unless you really want to publish your application…
Create a folder call Flights…Alexa_Party…or whatever you fancy…then create a folder call src and copy this file in there…calling it AlexaSkills.js
We’re going to need to install only one library….”request”…
sudo npm install --prefix=~/Flights/src request
This will create a folder called “node_modules” with the package in our project folder…then create a file called “index.js” and copy and paste the following code…
index.js
var request = require("request")
, AlexaSkill = require('./AlexaSkill')
, APP_ID = 'amzn1.echo-sdk-ams.app.8c0bd993-723f-4ab2-80b5-84402a7a59ce';
var error = function (err, response, body) {
console.log('ERROR [%s]', err);
};
var getJsonFromFlights = function(command, callback){
var msg = "";
if(command == "thank you"){
request("http://blagnodeheroku.herokuapp.com/path/?command=bye", function (error, response, body) {
if (!error) {
console.log("Done");
};
});
setTimeout(function() {
callback("thank you");
},2000);
}else if (command == "around the world"){
request("http://blagnodeheroku.herokuapp.com/path/?command=bye", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=map", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=stat", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=readstat", function (error, response, body) {
if (!error) {
msg = body;
};
});
};
});
};
});
}
});
setTimeout(function() {
callback(msg.trim());
},15000);
}else if (command == "united states"){
request("http://blagnodeheroku.herokuapp.com/path/?command=bye", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=usmap", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=stat", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=readstat", function (error, response, body) {
if (!error) {
msg = body;
};
});
};
});
};
});
}
});
setTimeout(function() {
callback(msg.trim());
},15000);
}else if (command == "carriers"){
request("http://blagnodeheroku.herokuapp.com/path/?command=bye", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=carriers", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=stat", function (error, response, body) {
if (!error) {
request("http://blagnodeheroku.herokuapp.com/path/?command=readstat", function (error, response, body) {
if (!error) {
msg = body;
};
});
};
});
};
});
}
});
setTimeout(function() {
callback(msg.trim());
},15000);
}
};
var handleFlightsRequest = function(intent, session, response){
getJsonFromFlights(intent.slots.command.value, function(data){
if(data != "thank you"){
var text = data;
var reprompt = 'Please say a command?';
response.ask(text, reprompt);
}else{
response.tell("You're welcome");
}
});
};
var Flights = function(){
AlexaSkill.call(this, APP_ID);
};
Flights.prototype = Object.create(AlexaSkill.prototype);
Flights.prototype.constructor = Flights;
Flights.prototype.eventHandlers.onSessionStarted = function(sessionStartedRequest, session){
console.log("onSessionStarted requestId: " + sessionStartedRequest.requestId
+ ", sessionId: " + session.sessionId);
};
Flights.prototype.eventHandlers.onLaunch = function(launchRequest, session, response){
// This is when they launch the skill but don't specify what they want.
var output = 'Welcome to Flights. ' +
'Please, say a command.';
var reprompt = 'Please, say a command?';
response.ask(output, reprompt);
console.log("onLaunch requestId: " + launchRequest.requestId
+ ", sessionId: " + session.sessionId);
};
Flights.prototype.intentHandlers = {
GetFlightsIntent: function(intent, session, response){
handleFlightsRequest(intent, session, response);
},
HelpIntent: function(intent, session, response){
var speechOutput = 'Get the information for airports and flights. ' +
'Please say a command?';
response.ask(speechOutput);
}
};
exports.handler = function(event, context) {
var skill = new Flights();
skill.execute(event, context);
};
Time to explain what I was trying to do here -:P
The handleFlightsRequest method will manage the response that Alexa will spell out for us…and inside this method we can find getJsonFromFlights which will take the command defined in the our Intent Schema. This function will call our NodeJS server for the following commands…”thank you” will simply call the bye command….”around the world” will call the bye, map, stat and readstat commands…”united states” will call the bye, usmap, stat and readstat commands…finally carriers will call the bye, carriers, stat and readstat commands…
After 15 seconds (Yep…I know it’s too much but there are a lot of processes going on) Alexa will get the response message and simply speak it to us -;)
That’s pretty much it…now…I can show some images before we jump into the video…
So...as promised...here's my LED Numbers app written in Elm -:)
Now...this took me more time than expected, due to a couple of things...
a) Elm likes to handle Just and Maybe values...Haskell does the same...but Haskell provide alternative functions that deal with Just and Maybe...Elm does not...so I need to come up with some functions for it...
b) Elm doesn't provide a function to get elements from a list...so I need to build the function...
c) I'm still an Elm newbie
That put aside...Elm is still awesome and I love it -;)
Anyway...let's get to work...
Create an folder called LED_Numbers and type this into the terminal...
elm package install evancz/elm-html elm package install evancz/start-app
Then, open your favorite editor and copy and paste the code...
LED_Numbers.elm
module LED_Numbers where
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import StartApp.Simple as StartApp
import String exposing (toInt,toList)
import Dict
--MODEL
type alias Model =
{
number: String,
leds: Dict.Dict Char (List String),
line: String
}
initialModel: Model
initialModel =
{
number = "",
leds = Dict.fromList[('0',[" _ ","| | ","|_| "]),('1',[" ","| ","| "]),
('2',[" _ "," _| ","|_ "]),('3',["_ ","_| ","_| "]),
('4',[" ","|_| "," | "]),('5',[" _ ","|_ "," _| "]),
('6',[" _ ","|_ ","|_| "]),('7',["_ "," | "," | "]),
('8',[" _ ","|_| ","|_| "]),('9',[" _ ","|_| "," _| "])],
line = ""
}
--UPDATE
fromJust : Maybe a -> a
fromJust x = case x of
Just y -> y
Nothing -> Debug.crash ""
fromMaybe : Maybe (List String) -> List String
fromMaybe x = case x of
Just y -> y
Nothing -> Debug.crash ""
fromMaybeChar : Maybe Char -> Char
fromMaybeChar x = case x of
Just y -> y
Nothing -> Debug.crash ""
get_elem : List a -> Int -> Maybe a
get_elem lst n =
List.head (List.drop n lst)
fromMaybeListChar : Maybe (List Char) -> List Char
fromMaybeListChar x = case x of
Just y -> y
Nothing -> Debug.crash ""
get_list: String -> List Char
get_list str =
String.toList str
type Action = NoOp | Submit | UpdateNumber String
update: Action -> Model -> Model
update action model =
case action of
NoOp ->
model
UpdateNumber contents ->
{ model | number = contents }
Submit ->
{ model |
line = get_led (get_list model.number) 0 model,
number = ""
}
get_led: List Char -> Int -> Model -> String
get_led lst n model =
if List.length lst > 0
then let h = fromMaybeChar(List.head lst)
t = fromMaybeListChar(List.tail lst)
leds = model.leds
line = Dict.get h leds
in fromJust(get_elem (fromMaybe line) n) ++ get_led t n model
else if n < 2
then "" ++ "\n" ++ get_led (get_list model.number) (n+1) model
else if n == 2
then "" ++ "\n"
else ""
--VIEW
buttonStyle: Attribute
buttonStyle =
style
[ ("outline", "none"),
("border", "none"),
("border-radius","4px"),
("margin-right","5px"),
("padding","4px 10px"),
("background","#61a1bc"),
("color","#fff")
]
divStyle: Attribute
divStyle =
style
[ ("margin", "50px auto"),
("padding", "0px 50px"),
("text-align", "center")
]
pStyle: Attribute
pStyle =
style
[ ("font-size", "30px") ]
pageHeader : Html
pageHeader =
h1 [ ] [text "LED Numbers"]
view: Signal.Address Action -> Model -> Html
view address model =
div [ divStyle ]
[ pageHeader,
input
[
type' "text",
name "number",
placeholder "Enter a number",
value model.number,
on "input" targetValue (\v -> Signal.message address (UpdateNumber v))
]
[ ],
button [ buttonStyle, onClick address Submit ] [ text "Submit" ],
pre [ pStyle ]
[ text (model.line) ]
]
main: Signal Html
main =
StartApp.start { model = initialModel, view = view, update = update }
Go into the terminal again and type this...
elm make LED_Numbers.elm --output LED_Numbers.html
Open the file in your browser and run it...
Looking through my list of new languages to learn...I came upon Elm...functional reactive programming in the browser...
Isn't that cool? Of course it is -:)
Now...Elm came to life around 2012...so it's fairly new...which means not some many tutorials and no books that I know of...but...don't let that scare you away...there's actually a couple of awesome courses handled by The Pragmatic Studio that will help you to get up and running -;)
Now...to install Elm...if you have NodeJS already installed then you can simply use npm which is I guess the preferred and easier way...
sudo npm install elm
Otherwise just go the download section for the installers or for the source code to build it...but keep in mind that to build it you will need to have Haskell installed as well...
Anyway...we're going to see how to create a Fibonacci List app in Elm... -:)
Create a folder a call it "Fibonacci_App" and the go into it from the terminal...
elm package install evancz/elm-html
elm package install evancz/start-app
The first package is going allow us to generate HTML code and the second one is going to make our lives easier...
Now...open your favorite editor and type this away...
Fibonacci.elm
module Fibonacci where
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import StartApp.Simple as StartApp
import String exposing (toInt)
--MODEL
type alias Model =
{
number: String,
fibonacci: String
}
initialModel: Model
initialModel =
{
number = "",
fibonacci = ""
}
--UPDATE
parseInt : String -> Int
parseInt string =
case String.toInt string of
Ok value ->
value
Err error ->
0
type Action = NoOp | Submit | UpdateNumber String
update: Action -> Model -> Model
update action model =
case action of
NoOp ->
model
UpdateNumber contents ->
{ model | number = contents }
Submit ->
{ model |
fibonacci = fib (parseInt model.number) 0 1,
number = ""
}
fib: Int -> Int -> Int -> String
fib num a b =
if a > 0 && num > 1 then toString(a+b) ++ " " ++ fib (num-1) (a+b) a
else if a == 0 then toString a ++ " " ++ toString b ++ " "
++ toString(a+b) ++ " " ++ fib(num-1) (a+b) b
else ""
--VIEW
buttonStyle: Attribute
buttonStyle =
style
[ ("outline", "none"),
("border", "none"),
("border-radius","4px"),
("margin-right","5px"),
("padding","4px 10px"),
("background","#61a1bc"),
("color","#fff")
]
divStyle: Attribute
divStyle =
style
[ ("margin", "50px auto"),
("padding", "0px 50px"),
("text-align", "center")
]
pStyle: Attribute
pStyle =
style
[ ("font-size", "30px") ]
pageHeader : Html
pageHeader =
h1 [ ] [text "Fibonacci List"]
view: Signal.Address Action -> Model -> Html
view address model =
div [ divStyle ]
[ pageHeader,
input
[
type' "text",
name "number",
placeholder "Enter a number",
value model.number,
on "input" targetValue (\v -> Signal.message address (UpdateNumber v))
]
[ ],
button [ buttonStyle, onClick address Submit ] [ text "Submit" ],
p [ pStyle ]
[ text (model.fibonacci) ]
]
main: Signal Html
main =
StartApp.start { model = initialModel, view = view, update = update }
Now, we just need to compile our application -;)
elm make Fibonacci.elm --output Fibonaccci.html
Now, we can just open that Fibonacci.html file and test our app -:D
Hope you like it -:) I will try to get my LED_Numbers app ready soon -;)
Lua is a lightweight multi-paradigm programming language designed as a scripting language with extensible semantics as a primary goal. Lua is cross-platform since it is written in ANSI C, and has a relatively simple C API.
If you wonder about the title…well…Lua means Moon in Portuguese -;)
Lua is very powerful but easy to learn and use. If you already know Python or Ruby, you will be just fine…
Before we move on…I want to share a little joke…which is not specific to Lua only…but still funny -;)
So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)
First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.
First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.
Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.
Then create a Projection object and select only PRICE and CARRNAME.
On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.
Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.
Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.
Create an empty “.xsapp” file.
Create a file called “.xsaccess” with the following code.
To code for Lua, you can use any editor that you like…Copy and paste the following code…
Lua_HANA.lua
http = require("socket.http")
mime = require("mime")
ltn12 = require("ltn12")
json = require("json")
h = {Authorization = "Basic " .. (mime.b64("SYSTEM:YourPassword")),
["Content-Type"] = "application/json", ["content-length"] = jsonsize }
local resp ={}
ok, code, headers = http.request{url = "http://YourServer:8000/Flights/flights.xsodata/FLIGHTS?$format=json",
redirect = true, method = "GET", headers = h, source = source,
sink = ltn12.sink.table(resp)}
local dec = json.decode(resp[1])
local d = dec["d"]["results"]
for i = 1, #d do
io.write(d[i]["CARRNAME"]," : ",d[i]["PRICE"], "\n")
end
print("")
Doing this integration with Lua was quick and easy…Lua is a really nice language with some really nice features that can’t be found on other languages…
Falcon is an Open Source, multi-paradigm programming language. It supports procedural, object-oriented, prototype-based, functional, tabular and message passing. It first appeared 12 years ago…so not a new and fresh language. It was the default scripting language for the now disappeared Auroraux operating system.
Falcon is pretty awesome and has some features that other programming languages would kill to have -:)
So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)
First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.
First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.
Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.
Then create a Projection object and select only PRICE and CARRNAME.
On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.
Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.
Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.
Create an empty “.xsapp” file.
Create a file called “.xsaccess” with the following code.
Now…as I’m still a Falcon newbie…I’m not sure if we really need this…but just in case…install it…
apt-get install falconpl-curl
It’s the curl binding for Falcon…
Grab your favorite editor and copy and paste the following code…
falcon_hana.fal
import from curl
import from json
h = curl.Handle("http://YourServer:8000/Flights/flights.xsodata/FLIGHTS?$format=json")
auth = "Authorization:Basic " + Base64.encode("SYSTEM:YourPassword")
headers = [auth]
h.setOption(curl.OPT.HTTPHEADER,headers)
h.setOption(curl.OPT.SSL_VERIFYPEER,false)
data = h.setOutString().exec().getData()
try
raw = json.JSONdecode( data )
catch
printl( "Can't decode the string" )
end
d = raw["d"]
results = d["results"]
for Index in [0:results.len()]
print(results[Index]["CARRNAME"])
print(" : ")
printl(results[Index]["PRICE"])
end
To execute it…simply open a terminal session and go to source code folder and type
Falcon falcon_hana.fal
I have to admit that this wasn’t easy at first…the Falcon documentation doesn’t talk about curl…so I need to check the source code on GitHub…make a lot of testing…until I finally could get it to work…the json part on the other hand was extremely easy -:D
Yep...I'm aware that there must be a lot of more efficient and short ways to do this...but then again...my purpose with this is to have the same base code for all the programming languages that I learn...
Usually I write this code after a couple of days of learning the language...so in no way I can be aware of all the crazy and optimized features...
This code is just for fun and for me...a really good way to introduce the syntax of a language in a very friendly way...
So what's Kotlin all about? Well...Kotlin is a Statically typed programming language for the JVM, Android and the browser. It's also 100% interoperable with Java.
While this is not a mind bending language...meaning that you can get used to it pretty fast...it has some nice and cool feature that are worthy to explore...
As always...being this my first post...here's the Fibonacci list example...
fibonacci.kt
package Fibonacci
fun fib(num: Int, a: Int, b: Int): String {
var result: String = ""
if(a > 0 && num > 1) {
result = result + (a+b) + " " + fib(num-1,a+b,a)
}else if (a == 0) {
result = a.toString() + " " + b + " " + (a+b) + " " + fib(num-1,a+b,b)
}
return result
}
fun main(args: Array<String>) {
if (args.size == 0) {
println("Please provide a number...")
return
}
val num: Int = args[0].toInt()
println(fib(num,0,1))
}
And the screenshot for sure -:)
Will post the LED_Numbers app really soon...so stay tuned -;)
Erlang is a general-purpose concurrent, garbage-collected programming language and runtime system. And it’s also Functional, with eager evaluation, single assignment and dynamic typing. Did I forget to mention that it’s also distributed, concurrent and fault-tolerant.
Big description, huh? Well…Erlang has been around for the almost past 30 years…
So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)
First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.
First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.
Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.
Then create a Projection object and select only PRICE and CARRNAME.
On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.
Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.
Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.
Create an empty “.xsapp” file.
Create a file called “.xsaccess” with the following code.
Finally create a file called “flights.xsodata” with the following code
flights.xodata
service {
"Blag/FLIGHTS_BY_CARRIER.calculationview" as "FLIGHTS" keys
generate local "Id";
}
Activate your project and launch it on your browser, you should see something like this…
The SAP HANA part is done…so we can move into the Erlang part…
Erlang, as opposed to many other languages, doesn’t have a Package Manager, so we need to only download the package that we want and compile it -;)
To code for Erlang I use one of the most awesome editors I have ever found…Geany. It comes almost pre-configured to handle a lot of programming languages, so you will be ready to code for Erlang.
We need to download mochijson2.erl and save it on our project folder, then we can simply compile it by calling
erlc mochijson2.erl
From the terminal or press the “Compile the current file” button. First one on the image.
With that, we should be more than ready to start coding -:) Copy and paste the following code…