<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Chashmeet Singh]]></title><description><![CDATA[This is a blog maintained to post my weekly accomplishments in GSOC.]]></description><link>https://chashmeetsingh.github.io</link><image><url>http://melissavandyke.com/wp-content/uploads/2015/09/code.jpg</url><title>Chashmeet Singh</title><link>https://chashmeetsingh.github.io</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 22 May 2017 18:04:41 GMT</lastBuildDate><atom:link href="https://chashmeetsingh.github.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Calculation of the frame size of the Chat Bubble(iOS Client)]]></title><description><![CDATA[<style>
  .post-title {
    margin-bottom: 80px;
  }
</style>
<div class="paragraph">
<p>Starting with the implementation, we will need a <code>UICollectionViewController</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>import UIKit

class ChatViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    let cellId = "cellId"

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, we setup the background of the view and configure the <code>collectionView</code> and call these methods inside inside <code>viewDidLoad</code> .</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>// Setup View
func setupView() {
   self.view.backgroundColor = UIColor.rgb(red: 236, green: 229, blue: 221)
}

// Setup Collection View
func setupCollectionView() {
    collectionView?.backgroundColor = .clear
    collectionView?.delegate = self

    collectionView?.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height - 50)

    // register cell
    collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>-50</code> is supposed to be occupied by the <code>Message Container</code>.
Continuing with this, we implement the <code>CollectionView</code> methods as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>    // Number of items to be displayed
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int {
        return 5
    }

    // Configure Cell
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
        cell.backgroundColor = .red
        return cell
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>When trying to run this, we get the following output.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="http://imgur.com/cfodV3e.png" alt="cfodV3e.png"></span></p>
</div>
<div class="paragraph">
<p>We need to increase the width of each cell as well give it a height for displaying a message.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>    // Calculate Bubble Height
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize {
        return CGSize(width: view.frame.width, height: 100)
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p><span class="image"><img src="http://imgur.com/FGgPXoB.png" alt="FGgPXoB.png"></span></p>
</div>
<div class="paragraph">
<p>To remove the cell spacing we override the edge insets as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>    // Calculate Bubble Height
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize {
        return CGSize(width: view.frame.width, height: 100)
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>We configure a custom Chat Cell to customize the cell according to the needs:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class BaseCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {}
}

class ChatLogMessageCell: BaseCell {

    let messageTextView: UITextView = {
        let textView = UITextView()
        textView.font = UIFont.systemFontOfSize(18)
        textView.text = "Sample message"
        textView.backgroundColor = UIColor.clearColor()
        return textView
    }()

    let textBubbleView: UIView = {
        let view = UIView()
        view.layer.cornerRadius = 15
        view.layer.masksToBounds = true
        return view
    }()

    static let grayBubbleImage = UIImage(named: "bubble_gray")!.resizableImageWithCapInsets(UIEdgeInsetsMake(22, 26, 22, 26)).imageWithRenderingMode(.AlwaysTemplate)
    static let blueBubbleImage = UIImage(named: "bubble_blue")!.resizableImageWithCapInsets(UIEdgeInsetsMake(22, 26, 22, 26)).imageWithRenderingMode(.AlwaysTemplate)

    let bubbleImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = ChatLogMessageCell.grayBubbleImage
        imageView.tintColor = UIColor(white: 0.90, alpha: 1)
        return imageView
    }()

    override func setupViews() {
        super.setupViews()

        addSubview(textBubbleView)
        addSubview(messageTextView)

        textBubbleView.addSubview(bubbleImageView)
        textBubbleView.addConstraintsWithFormat("H:|[v0]|", views: bubbleImageView)
        textBubbleView.addConstraintsWithFormat("V:|[v0]|", views: bubbleImageView)
    }
}

extension UIView {

    func addConstraintsWithFormat(format: String, views: UIView...) {

        var viewsDictionary = [String: UIView]()
        for (index, view) in views.enumerated() {
            let key = "v\(index)"
            viewsDictionary[key] = view
            view.translatesAutoresizingMaskIntoConstraints = false
        }

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Using this custom cell, we can now add text to the message cells and the only thing left is to configure the frame size of each chat bubble. To implement this, we will need an array string of <code>4</code> messages which can be used to test anc calculate dynamic frame for each message.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>let messages: [String] = ["Hello Susi", "I love FossAsia", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s", "The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from de Finibus Bonorum et Malorum"]</code></pre>
</div>
</div>
<div class="paragraph">
<p>We now modify the <code>sizeForItemAt</code> method to calculate the frame size.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>// Calculate Bubble Height
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize {
        let message = messages[indexPath.row]

        let size = CGSize(width: 250, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: message).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18)], context: nil)

        return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>And accordingly modify the <code>cellForItemAt</code> method as well.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>// Configure Cell
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {

        let message = messages[indexPath.row]

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatLogMessageCell

        cell.messageTextView.textColor = .black

        let size = CGSize(width: 250, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: message).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18)], context: nil)

        if indexPath.row % 2 == 0 {

            cell.bubbleImageView.image = ChatLogMessageCell.grayBubbleImage
            cell.bubbleImageView.tintColor = .white
            cell.messageTextView.textColor = UIColor.black
            cell.messageTextView.frame = CGRect(x: 16, y: 0, width: estimatedFrame.width + 16, height: estimatedFrame.height + 30)
            cell.textBubbleView.frame = CGRect(x: 4, y: -4, width: estimatedFrame.width + 16 + 8 + 16, height: estimatedFrame.height + 20 + 6)

        } else {
            cell.messageTextView.frame = CGRect(x: view.frame.width - estimatedFrame.width - 16 - 16, y: 0, width: estimatedFrame.width + 16, height: estimatedFrame.height + 20)
            cell.textBubbleView.frame = CGRect(x:view.frame.width - estimatedFrame.width - 16 - 8 - 16, y: -4, width: estimatedFrame.width + 16 + 8 + 10, height: estimatedFrame.height + 20 + 6)
            cell.bubbleImageView.image = ChatLogMessageCell.blueBubbleImage
            cell.bubbleImageView.tintColor = UIColor.rgb(red: 220, green: 248, blue: 198)
        }

        cell.messageTextView.text = message

        return cell
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Below is the final output:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="http://imgur.com/4MQcd0I.png" alt="4MQcd0I.png"></span></p>
</div>]]></description><link>https://chashmeetsingh.github.io/2017/05/22/Calculation-of-the-frame-size-of-the-Chat-BubbleiOS-Client.html</link><guid isPermaLink="true">https://chashmeetsingh.github.io/2017/05/22/Calculation-of-the-frame-size-of-the-Chat-BubbleiOS-Client.html</guid><dc:creator><![CDATA[Chashmeet Singh]]></dc:creator><pubDate>Mon, 22 May 2017 00:00:00 GMT</pubDate></item><item><title><![CDATA[Susi AI Skill Development]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<style>
  .post-title {
    margin-bottom: 30px;
  }
</style>
</div>
</div>
<div class="sect1">
<h2 id="_what_is_susi">What is Susi?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Susi is an open source intelligent personal assistant which has the capability to learn and respond better to queries. It is also capable of making to-do lists, setting alarms, providing weather and traffic info all in real time. Susi responds based on skills.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_what_is_a_skill_how_do_we_teach_a_skill">What is a skill? How do we teach a skill?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A skill is a piece of code which performs a set of actions in order to respond to the user’s query. These skills are based on pattern matching which help them mapping the user’s query to a specific skill and responding accordingly. Teaching a skill to Susi is surprisingly very easy to implement. One can take a look at the Susi Skill Development Tutorial and a video workshop by Michael Christen.</p>
</div>
<div class="paragraph">
<p>I will try to give a basic idea on how to create a skill, it’s basic structure and some of the skills I developed in the first week.</p>
</div>
<div class="sect2">
<h3 id="_prepare_to_create_a_skill">Prepare to create a skill:</h3>
<div class="paragraph">
<p>Head over to <a href="http://dream.susi.ai" class="bare">http://dream.susi.ai</a>
Create a etherpad with some relevant name
Delete all text currently present in there
Start writing your skill
Adding to this, for testing a skill one can head over to Susi Web Chat Interface.</p>
</div>
<div class="paragraph">
<p>Basic Structure for calling an API:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>&lt;Regular expression to be matched here&gt;
!console:&lt;response given to the user&gt;
{
  "url":"&lt;API endpoint&gt;",
  "path":"&lt;Json path here&gt;"
}
eol</pre>
</div>
</div>
<div class="paragraph">
<p>So, let me explain this line by line.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The regular expression is the one to which the user’s query is matched first.</p>
</li>
<li>
<p>The console is meant to output the actual response the user sees as response.</p>
</li>
<li>
<p>In place of the <em>url</em>, the API endpoint is passed in.
“path” here specifies how we traverse through the response Json or Jsonp to get the object, starts with <em>$.</em>.</p>
</li>
<li>
<p>At last, <em>eol</em> which is the end-of-line marks the end of a skill.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Let’s take an example for better understanding of this:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>random gif
!console: $url$
{
    "url" : "http://api.giphy.com/v1/gifs/trending?api_key=dc6zaTOxFJmzC",
    "path" : "$.data[0].images.fixed_height"
}
eol</pre>
</div>
</div>
<div class="paragraph">
<p><strong>This skill responds with a link to a random gif.</strong></p>
</div>
<div class="paragraph">
<p>Steps involved:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Match the string <em>random gif</em> with the user’s query.</p>
</li>
<li>
<p>On successful match, make an API call to the API endpoint specified in <em>url</em></p>
</li>
<li>
<p>On response, extract the object at the specified path in the json under <em>path</em></p>
</li>
<li>
<p>Respond to the user with the <em>url</em> key’s value which would here be an URL of a GIF.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Let’s try it out on <a href="http://susi.ai/chat">Susi Web Chat</a>. For this, you will first have to load your skill using the dream command followed by etherpad name:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>dream &lt;etherpad name&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>And then you can start testing your skill.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://github.com/chashmeetsingh/chashmeetsingh.github.io/blob/master/images/random-gif.png?raw=true" alt="Random GIF">
</div>
</div>
<div class="paragraph">
<p>So, we queried <em>random gif</em> and we got a response <em>Click Here!</em>. The complete URL didn’t show up because all the URLs are currently parsed and a hyperlink for each is created. So try clicking on it to find a GIF.</p>
</div>
<div class="paragraph">
<p>Now, let’s look at one more skill I developed during this period.</p>
</div>
<div class="literalblock">
<div class="content">
<pre>#Returns the name of the president of a country
president of *|who is the president of *| president *
!console:$plaintext$
{      "url":"https://api.wolframalpha.com/v2/query?input=president+$1$&amp;output=JSON&amp;appid=9WA6XR-26EWTGEVTE&amp;includepodid=Result",
  "path" : "$.queryresult.pods[0].subpods[0]"
}
eol</pre>
</div>
</div>
<div class="paragraph">
<p>Let’s understand this step by step:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>We have here president of \*|who is the president of *| president *, which means the user’s query matches with anyone of the following because of the use of pipe symbol <em>|</em>. The <em>*</em> here replaces a word or a list of words, which can be accessed like: <em>${index}$</em>  where index is replaced by the position of the <em>*</em> in the expression starting from 1.</p>
</li>
<li>
<p>Now we have something new in the URL. See that  <em>$1$</em>  inside the URL? On runtime, that is replaced with the content of the <em>*</em> variable. So if a user puts in query like: <em>president of usa</em>, <em>usa</em> is mapped to <em>$1$</em> and is replaced in the URL and appropriate API request is made.</p>
</li>
<li>
<p>Then the path is traversed in the json response and the value of the <em>plaintext</em> key is used to respond to the user.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It’s now time to try it out on <a href="http://susi.ai/chat">Susi Web Chat</a>.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://github.com/chashmeetsingh/chashmeetsingh.github.io/blob/master/images/president.png?raw=true" alt="President">
</div>
</div>
<div class="paragraph">
<p>So, we got our desired response here, i.e., the name of the president of usa.</p>
</div>
</div>
</div>
</div>]]></description><link>https://chashmeetsingh.github.io/2017/05/13/Susi-AI-Skill-Development.html</link><guid isPermaLink="true">https://chashmeetsingh.github.io/2017/05/13/Susi-AI-Skill-Development.html</guid><dc:creator><![CDATA[Chashmeet Singh]]></dc:creator><pubDate>Sat, 13 May 2017 00:00:00 GMT</pubDate></item></channel></rss>