Build a currency rates application using the ESP8266 and I2C LCD Display in the upcoming IOT104 - Programming IoT using Arduino course.
Learn2Develop is a technology company specializing in hands-on training on the latest Web and Mobile technologies.
Email: weimenglee@learn2develop.net
Sunday, November 27, 2016
Internet of Things (IoT) Course Roadmap
Here is the series of courses that participants may find useful if they want to embark on the journey of Internet of Things (IoT) development.
Wednesday, November 23, 2016
Swift Tip: Understanding and using Closures
In Swift, closures are self-contained blocks of code that can be passed around and used in your code. Think of closures as anonymous functions in JavaScript, lambda expressions in C#, and blocks in C and Objective-C. Here is an example of closure in action in Swift:
In the above code snippet, when the OK button in the alert is tapped, you handle the action using a closure:
This closure takes in a single parameter - action, and does not return any value (Void). The body of the closure is a single statement that prints a string to the Output window. You can of course have more than one statement in the body of the closure. This works just like a usual function without the func keyword and the function name.
Besides this example, what are the real advantages of closures? Let's consider the classic example of the bubble sort:
The above code snippet contains a function that takes in an array and then performs a bubble sort on it:
var numbers = [5,2,8,7,9,4,3,1]
There are two potential disadvantages with this implementation:
A better approach would be to rewrite the bubbleSort() function using a closure so that the caller of this method can provide its own implementation for the sort order. The rewritten function would look like this:
Observe that:
Note the closure highlighted in bold. In essence, you are passing in a function with two parameters. This function will return a true if the first number is greater than the second number. Essentially, you are sorting the numbers in ascending order. If you want to sort the numbers in descending order, simply change the comparison operator to <:
The real advantage of using closure if when you need to sort strings in your own custom order. For example, you have an array of strings like this:
var names = ["xxx","yy","z"]
To sort the strings based on string length, you can specify your closure like this:
For purist, the above code snippet can be rewritten like this:
How cool is that. Hopefully, this posting can help you better understand and appreciate closures!
let alertController = UIAlertController(
title: "Hello!",
message: "Hello, World!",
preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.default) {
(action) -> Void in
print("Tapped on OK")
}
alertController.addAction(okAction)
self.present(alertController,
animated: true, completion: nil)
In the above code snippet, when the OK button in the alert is tapped, you handle the action using a closure:
{
(action) -> Void in
print("Tapped on OK")
}
Besides this example, what are the real advantages of closures? Let's consider the classic example of the bubble sort:
func bubbleSort(items:inout [Int]) {
for j in 0 ..< items.count-1 {
var swapped = false
for i in 0 ..< items.count-1-j {
if (items[i] > items[i+1]) {
let temp=items[i+1]
items[i+1]=items[i]
items[i]=temp
swapped=true
}
}
if !swapped {
break
}
}
}
The above code snippet contains a function that takes in an array and then performs a bubble sort on it:
var numbers = [5,2,8,7,9,4,3,1]
bubbleSort(items: &numbers)
print (numbers) // [1, 2, 3, 4, 5, 7, 8, 9]
There are two potential disadvantages with this implementation:
- What happens if you want to sort non-integer values, such as string, doubles, etc? You need to rewrite the code to sort different data types. To solve this, you can use generics.
- What happens if you want to sort the values in descending order? You need to rewrite the code to perform the appropriate logic for swapping. And what happens if you have different criteria to determine the sort order for different data types?
A better approach would be to rewrite the bubbleSort() function using a closure so that the caller of this method can provide its own implementation for the sort order. The rewritten function would look like this:
func bubbleSort(items: inout [T],
compareFunction:(T, T) -> Bool) {
for j in 0 ..< items.count-1 {
var swapped = false
for i in 0 ..< items.count-1-j {
//---if the two numbers need to be swapped---
if compareFunction(items[i],items[i+1]) {
let temp=items[i+1]
items[i+1]=items[i]
items[i]=temp
swapped=true
}
}
if !swapped {
break
}
}
}
Observe that:
- The function now has a second parameter (compareFunction:) of function type (T,T) -> Bool where T is a generic type. Caller of this function are expected to pass in a closure with two input parameters and return a Bool result.
- Within the bubbleSort() function, it will call the closure passed into it and use its result to determine if a variable swap is needed.
To use the rewritten bubbleSort()function, you can call it like this:
var numbers = [5,2,8,7,9,4,3,1]
bubbleSort(items: &numbers,
compareFunction: {
(num1:Int, num2:Int) -> Bool in
//--if num1 > num2, need to swap--
return num1 > num2
})
print (numbers) // [1, 2, 3, 4, 5, 7, 8, 9]
Note the closure highlighted in bold. In essence, you are passing in a function with two parameters. This function will return a true if the first number is greater than the second number. Essentially, you are sorting the numbers in ascending order. If you want to sort the numbers in descending order, simply change the comparison operator to <:
var numbers = [5,2,8,7,9,4,3,1]
bubbleSort(items: &numbers,
compareFunction: {
(num1:Int, num2:Int) -> Bool in
//--if num1 > num2, need to swap--
return num1 < num2
})
print (numbers) // [9, 8, 7, 5, 4, 3, 2, 1]
The real advantage of using closure if when you need to sort strings in your own custom order. For example, you have an array of strings like this:
var names = ["xxx","yy","z"]
To sort the strings based on string length, you can specify your closure like this:
bubbleSort(items: &names,
compareFunction: {
(name1:String, name2:String) -> Bool in
//--if length of name1 > length of name2, need to swap--
return name1.characters.count > name2.characters.count
})
print (names) // ["z", "yy", "xxx"]
For purist, the above code snippet can be rewritten like this:
bubbleSort(items: &names) {
(name1, name2) -> Bool in
name1.characters.count > name2.characters.count
}
print (names)
How cool is that. Hopefully, this posting can help you better understand and appreciate closures!
Tuesday, November 22, 2016
C# Tip - Using the async and await keywords for asynchronous programming
In C#, you can use the async and await keywords for asynchronous programming (such as fetching data from a network, or saving/loading data from files). To understand how to use these 2 keywords, consider the following example:
async Task DownloadFromWebAsync()
{
HttpClient client = new HttpClient();
Task getStringAsyncTask =
client.GetStringAsync("http://www.google.com");
string content = await getStringAsyncTask;
// control is returned to the caller
// of the DownloadFromWebAsync() method
// and resumed after getStringAsyncTask
// is completed
return content;
}
In the above DownloadFromWebAsync() method , it is first of all prefixed with the async keyword, which indicates that this method contains an asynchronous operation. This method returns a Task result. This represents an asynchronous operation that returns a result of type string:
async Task DownloadFromWebAsync()
Within this method, we use the HttpClient class to help us connect to the Web:
HttpClient client = new HttpClient();
In particular, the GetStringAsync() method connects to the specified URL and returns the content of the URL. It returns an object of type Task :
Task getStringAsyncTask =
client.GetStringAsync("http://www.google.com");
Because the GetStringAsync() method could potentially take a long time, and so you need to run it asynchronously. This is achieved by using the await keyword:
string content = await getStringAsyncTask;
At this point, the GetStringAsync() method will proceed to download the specified URL and control will return to the caller of the DownloadFromWebAsync() method. All statements after this line will only be executed after the GetStringAsync() method returns.
When the GetStringAsync() method returns, the result is passed to content, and the DownloadFromWebAsync() method will now return a string.
To call the DownloadFromWebAsync() method, you would need to use the await keyword. Also, the method from which you are calling the DownloadFromWebAsync() method must also be prefixed with the async keyword, like this:
private async void button1_Click(object sender, EventArgs e)
{
string content = await DownloadFromWebAsync();
}
Note that the 2 statements:
Task getStringAsyncTask =
client.GetStringAsync("http://www.google.com");
string content = await getStringAsyncTask;
Can also be rewritten as:
string content = await
client.GetStringAsync("http://www.google.com");
I hope this simple example makes it easier for you to understand how to use the async and await keywords.
async Task
{
HttpClient client = new HttpClient();
Task
client.GetStringAsync("http://www.google.com");
string content = await getStringAsyncTask;
// control is returned to the caller
// of the DownloadFromWebAsync() method
// and resumed after getStringAsyncTask
// is completed
return content;
}
In the above DownloadFromWebAsync() method , it is first of all prefixed with the async keyword, which indicates that this method contains an asynchronous operation. This method returns a Task
async Task
Within this method, we use the HttpClient class to help us connect to the Web:
HttpClient client = new HttpClient();
In particular, the GetStringAsync() method connects to the specified URL and returns the content of the URL. It returns an object of type Task
Task
client.GetStringAsync("http://www.google.com");
Because the GetStringAsync() method could potentially take a long time, and so you need to run it asynchronously. This is achieved by using the await keyword:
string content = await getStringAsyncTask;
At this point, the GetStringAsync() method will proceed to download the specified URL and control will return to the caller of the DownloadFromWebAsync() method. All statements after this line will only be executed after the GetStringAsync() method returns.
When the GetStringAsync() method returns, the result is passed to content, and the DownloadFromWebAsync() method will now return a string.
To call the DownloadFromWebAsync() method, you would need to use the await keyword. Also, the method from which you are calling the DownloadFromWebAsync() method must also be prefixed with the async keyword, like this:
private async void button1_Click(object sender, EventArgs e)
{
string content = await DownloadFromWebAsync();
}
Task
client.GetStringAsync("http://www.google.com");
string content = await getStringAsyncTask;
string content = await
client.GetStringAsync("http://www.google.com");
I hope this simple example makes it easier for you to understand how to use the async and await keywords.
Monday, November 21, 2016
Course Updates
Courses Confirmed for December 2016
Here is the list of courses that are confirmed for December 2016:
MOB104 - Writing Cross Platform iOS and Android Apps using Xamarin.Forms and C#
MOB104 is now a 2-day course. Due to the focus of Microsoft on the cross-platform developers' tools, Xamarin.Forms is now more important than ever. In this course, you will learn how to develop cross-platform mobile apps for Android and iOS, as well as learn some advanced techniques like:
IOS302 - Advanced iOS - Apple Watch Programming
With the latest watchOS from Apple, the Apple Watch is now a much more compelling wearable device. Apps now launch quicker, and battery life is much improved on the new Apple Watch series 2. We have since revised this course to 2 days, so that we have time to cover all the cool new features in watchOS 3. (Course comes with an Apple Watch Series 2 watch)
IOT201 - Python Programming
IOT201 is now titled "Python Programming". Instead of focusing just on the syntax of Python, we now cover doing interesting things with Python, such as:
As such, the IOT201 is now a 2-day course.
Here is the list of courses that are confirmed for December 2016:
- IOT202 - Introduction to Data Science using Python
- AND101 - Fundamentals of Android Programming using Android Studio
- IOS101 - Fundamentals of iPhone Programming using Swift
- IOT101 - Programming Internet of Things (IoT) using Raspberry Pi
- IOT104 - Programming Internet of Things (IoT) using Arduino
- WEB202 - Implementing iOS and Android Push Notifications
MOB104 - Writing Cross Platform iOS and Android Apps using Xamarin.Forms and C#
- Cross-platform User Interface
- Dependency Injection
- MVVM Architecture
IOS302 - Advanced iOS - Apple Watch Programming
With the latest watchOS from Apple, the Apple Watch is now a much more compelling wearable device. Apps now launch quicker, and battery life is much improved on the new Apple Watch series 2. We have since revised this course to 2 days, so that we have time to cover all the cool new features in watchOS 3. (Course comes with an Apple Watch Series 2 watch)
IOT201 - Python Programming
IOT201 is now titled "Python Programming". Instead of focusing just on the syntax of Python, we now cover doing interesting things with Python, such as:
- Developing RESTful service using Flask
- Securing your RESTful service using a SSL and Basic Authentication
- Sockets programming using Python
- Push notifications using Python
- Writing your own modules
As such, the IOT201 is now a 2-day course.
Saturday, November 19, 2016
Swift Tip - Using the guard statement
Very often, in your app you need to check if multiple variables are non-nil before you can perform some processing. For example, the following example shows that you can use the if statement to verify that both the credit card no. and expiry date is non-nil before you validate the credit card:
However, the nesting of multiple if statements makes your code really unwieldy. A better way is to use the guard statement, like this:
The guard statement ensures that both statements (let cc = creditCardNo and let exp = expiry) are true; else it will execute the else block.
The following shows the output of the function with the following combinations of arguments:
func validatePayment(creditCardNo:String?, expiry:String?){
if let cc = creditCardNo {
if let exp = expiry {
print("Validating credit card...")
//...
return
}
}
print("Missing Credit Card No. or Expiry Date")
}
However, the nesting of multiple if statements makes your code really unwieldy. A better way is to use the guard statement, like this:
func validatePayment(creditCardNo:String?, expiry:String?){
guard let cc = creditCardNo, let exp = expiry
else {
print("Missing Credit Card No. or Expiry Date")
return
}
//---validate credit card---
print("Validating credit card...")
}
The following shows the output of the function with the following combinations of arguments:
//---Missing Credit Card No. or Expiry Date---
validatePayment(creditCardNo: nil, expiry: "11/21")
validatePayment(creditCardNo: "1234567890123456", expiry: nil)
validatePayment(creditCardNo: nil, expiry: nil)
//---Validating credit card...---
validatePayment(creditCardNo: "1234567890123456", expiry: "11/21")
Swift Tip - Extensions
Extensions allow you to extend the functionality of an existing class, structure, enumeration, or protocol. Here is an useful example:
extension Int {
var isPerfectSquare:Bool {
let sr = sqrt(Double(self))
return ((Int(sr) * Int(sr)) == self)
}
}
The above isPerfectSquare() function extends the Int class. You can call it to check if a number is a perfect square, like this:
print(25.isPerfectSquare) //---true---
print(26.isPerfectSquare) //---false---
print(27.isPerfectSquare) //---false---
print(36.isPerfectSquare) //---true---
Thursday, November 17, 2016
IOT101 - Integrating Alexa Voice Service with Raspberry Pi
Create your own Amazon Echo by integrating the Alexa Voice Service with your Raspberry Pi. Join us in the upcoming IOT101 to learn how to do that.
IOT101 - Programming Internet of Things (IoT) using Raspberry Pi
Course Fee
S$1897 (nett; no GST)
If your company is sponsoring you for the training, your company can enjoy 400% tax deductions/ allowances and/or 40% cash payout for investment in innovation and productivity improvements under the Productivity and Innovation Credit (PIC) scheme. For more details, check out the Productivity and Innovation Credit page.
Schedules
Start Date | End Date | Course Outline and Application Form | Category |
---|---|---|---|
Tue Dec 13 2016 CONFIRMED | Wed Dec 14 2016 | ||
Tue Mar 14 2017 | Wed Mar 15 2017 |
Venue
IBIS HOTEL
170 Bencoolen Street
Singapore 189657
170 Bencoolen Street
Singapore 189657
If your company requires in-house training, you can contact us to customize the topics to meet your training requirements. We train worldwide! We have conducted customized classes in the United States, Canada, Norway, Denmark, Japan, China, Hong Kong, Taiwan, and Thailand.
Thursday, November 10, 2016
IOT104 - Displaying ticker text using a LED matrix display
Want to display ticker text on a LED Matrix display? In the upcoming IOT104 - Programming Internet of Things using Arduino course, you will learn how to interface your Arduino with a 4 8x8 LED Matrix display.
Wednesday, November 09, 2016
Integrating the Alexa Voice Service into your Raspberry Pi
IOT101 - Programming Internet of Things (IoT) using Raspberry Pi
Course Fee
S$1897 (nett; no GST)
If your company is sponsoring you for the training, your company can enjoy 400% tax deductions/ allowances and/or 40% cash payout for investment in innovation and productivity improvements under the Productivity and Innovation Credit (PIC) scheme. For more details, check out the Productivity and Innovation Credit page.
Schedules
Start Date | End Date | Course Outline and Application Form | Category |
---|---|---|---|
Tue Dec 13 2016 CONFIRMED | Wed Dec 14 2016 | ||
Tue Mar 14 2017 | Wed Mar 15 2017 |
Venue
IBIS HOTEL
170 Bencoolen Street
Singapore 189657
170 Bencoolen Street
Singapore 189657
If your company requires in-house training, you can contact us to customize the topics to meet your training requirements. We train worldwide! We have conducted customized classes in the United States, Canada, Norway, Denmark, Japan, China, Hong Kong, Taiwan, and Thailand.
Subscribe to:
Posts (Atom)