Learning Swfit: Calculator App, part 2. Case, Auto Layout, Variable types

This is part 2 of my Learning Swift Calculator App.

Progress:

  • +, -, x operations are now functional
  • decimals also work

Lessons learned:

  • It’s easy to get caught up on a new programming language and forget to use universal concepts of programming that would have made my life a lot easier
    • In my haste (and learning/programming style), I jumped in with both feet, and soon I had one too many else if statements.  I cleaned up the initial logic to use case statements instead.  Not different than any other programming language out there – just common sense and cleaner programming all around.
  • Layout issues – for the first few versions, I will stick with programming for a target device (iPhone5) instead of universal design.  This can be enabled on the view controller file inspector > disable “Use Auto Layout” (thanks Dr. Hooper for pointing me to this setting!)
  • Calculators are very complicated!
    • My initial versions will ignore order of operations
    • Will not check user input for errors (for example, if the user presses + +, it will give unexpected results)
  • I have some issues with decimals (1+1.1=2.0999….) – need to check into how my values are being saved.  Again variable types seem to be haunting me.
  • Break points are super easy to use!  (Apple+”\” to add/delete)  The debug interface is intuitive and clearly shows all the variables.  The debug navigator (6th icon on the 2nd row of icons on the top left… looks like a line, 3 columns, and a line) is also a great snapshot into what’s going on – shows cpu/memory/disk/network usage.

Code as of this writing for ViewController.swift:

//
//  ViewController.swift
//  Calculator
//
//  Created by Jin S. An on 10/1/14.
//  Copyright (c) 2014 jinsungpsu.com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    
    var displayString = ""
    
    @IBOutlet var calcDisplay: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func updateCalculatorDisplay(buttonPressed: String) {

        switch (buttonPressed) {
        case ".","1","2","3","4","5","6","7","8","9","0":
            displayString += buttonPressed
        case "-","+","x":
            displayString += " " + buttonPressed + " "
        default:
            displayString += buttonPressed
        }
        calcDisplay.text = displayString
    }

    @IBAction func calc01(sender: AnyObject) {
        updateCalculatorDisplay("1")
    }
    @IBAction func calc02(sender: AnyObject) {
        updateCalculatorDisplay("2")
    }
    @IBAction func calc03(sender: AnyObject) {
        updateCalculatorDisplay("3")
    }
    @IBAction func calc04(sender: AnyObject) {
        updateCalculatorDisplay("4")
    }
    @IBAction func calc05(sender: AnyObject) {
        updateCalculatorDisplay("5")
    }
    @IBAction func calc06(sender: AnyObject) {
        updateCalculatorDisplay("6")
    }
    @IBAction func calc07(sender: AnyObject) {
        updateCalculatorDisplay("7")
    }
    @IBAction func calc08(sender: AnyObject) {
        updateCalculatorDisplay("8")
    }
    @IBAction func calc09(sender: AnyObject) {
        updateCalculatorDisplay("9")
    }
    @IBAction func calcDecimal(sender: AnyObject) {
        updateCalculatorDisplay(".")
    }
    @IBAction func calc00(sender: AnyObject) {
        updateCalculatorDisplay("0")
    }
    @IBAction func calcPlus(sender: AnyObject) {
        updateCalculatorDisplay("+")
    }
    @IBAction func calcMinus(sender: AnyObject) {
        updateCalculatorDisplay("-")
    }
    @IBAction func calcMultiply(sender: AnyObject) {
        updateCalculatorDisplay("x")
   }
    @IBAction func calcEqual(sender: AnyObject) {
        var tempArray = displayString.componentsSeparatedByString(" ")
        var currentOperation = "initial"
        var calculatedValue:Float = 0.0;
        for tempValue in tempArray {
            switch (tempValue) {
                case "+":
                    currentOperation = "+"
                case "-":
                    currentOperation = "-"
                case "x":
                    currentOperation = "x"
                case "%":
                    currentOperation = "%"
                default:
                    switch (currentOperation) {
                        case "+":
                            calculatedValue += (tempValue as NSString).floatValue
                        case "-":
                            calculatedValue -= (tempValue as NSString).floatValue
                        case "x":
                            calculatedValue *= (tempValue as NSString).floatValue
                       case "initial":
                            calculatedValue = (tempValue as NSString).floatValue
                        default:
                            calculatedValue += 0.0
                    }
            }
        }
        displayString = "=" + calculatedValue.description
        calcDisplay.text = displayString
    }
    @IBAction func calcClear(sender: AnyObject) {
        displayString = ""
        calcDisplay.text = ""
    }
}


Posted in Class, Professional Development, Research | Tagged , , | Comments Off on Learning Swfit: Calculator App, part 2. Case, Auto Layout, Variable types

Learning Swift – Calculator App, part 1

As part of my course work for Design Studio (LDT550) at Penn State, I am learning how to program in Swift (Apple’s iOS programming language) using xCode 6 beta.  In particular, I am working with Dr. Simon Hooper to get some of the basics down by programming a simple calculator.

Here is my progress…

First of all, connecting UI elements from storyboard (Main.storyboard) to the code that controls (ViewController.swift) isn’t too difficult.  It’s a bit abstract and there are multiple ways to connect them (ctrl+drag from storyboard or using the connections inspector), but once you figure it out, it seems straightforward.

The actual programming was more challenging than I expected.  I never thought about the intricacies of calculators.  Modern devices have changed our expectations on how calculators work.  Our current expectations are closer to how graphing calculators operate.

For example, in an basic calculator, you can enter a number and as soon as you press an operator, it clears the screen and expects the next number:

Press 1 (display shows “1”)

Press + (display shows “+” and clears old value waiting for new value)

Press 1 (display shows “1”)

Press = (display shows “2”)

However, in a graphing calculator, you can enter an entire expression before calculating

Press 1 (display shows “1”)

Press + (display shows “1 +”)

Press 1 (display shows “1+1”)

Press = (display shows “2” or “1+1=2”)

There are many design decisions to make before programming even a simple calculator – and the design decisions are not simply visual – not by a long shot.

Some technical lessons learned:

  • Type inference and type safety came into play right away (https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html).
  • Converting to and from Strings is a bit tricky (for display onto a Text Field) – I may not be doing it correctly right now – need to learn some more about this.
  • Syntax is very familiar, but it’s unnatural not to end lines with a semi colon.
  • xCode hints and autocomplete feature is very helpful and educational.
  • I am not quite sure how the layout works (with the square View Controller – which I assume it’s for designing apps that will work well for landscape/portrait/different size devices), so I have placed everything close to the top/left to start.

Here’s the app so far (only + works, not thoroughly tested):

Story board and Connections for calculator app
Story board and Connections for calculator app

And here’s the code:

//
//  ViewController.swift
//  Calculator
//
//  Created by Jin S. An on 10/1/14.
//  Copyright (c) 2014 jinsungpsu.com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    
    var displayString = ""
    
    @IBOutlet var calcDisplay: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func updateCalculatorDisplay(buttonPressed: String) {
        displayString += buttonPressed + " "
        calcDisplay.text = displayString
    }

    @IBAction func calc01(sender: AnyObject) {
        updateCalculatorDisplay("1")
    }
    @IBAction func calc02(sender: AnyObject) {
        updateCalculatorDisplay("2")
    }
    @IBAction func calc03(sender: AnyObject) {
        updateCalculatorDisplay("3")
    }
    @IBAction func calc04(sender: AnyObject) {
        updateCalculatorDisplay("4")
    }
    @IBAction func calc05(sender: AnyObject) {
        updateCalculatorDisplay("5")
    }
    @IBAction func calc06(sender: AnyObject) {
        updateCalculatorDisplay("6")
    }
    @IBAction func calc07(sender: AnyObject) {
        updateCalculatorDisplay("7")
    }
    @IBAction func calc08(sender: AnyObject) {
        updateCalculatorDisplay("8")
    }
    @IBAction func calc09(sender: AnyObject) {
        updateCalculatorDisplay("9")
    }
    @IBAction func calcDecimal(sender: AnyObject) {
        updateCalculatorDisplay(".")
    }
    @IBAction func calc00(sender: AnyObject) {
        updateCalculatorDisplay("0")
    }
    @IBAction func calcPlus(sender: AnyObject) {
        updateCalculatorDisplay("+")
    }
    @IBAction func calcMinus(sender: AnyObject) {
    }
    @IBAction func calcMultiply(sender: AnyObject) {
    }
    @IBAction func calcEqual(sender: AnyObject) {
        var tempArray = displayString.componentsSeparatedByString(" ")
        var currentOperation = ""
        var calculatedValue:Float = 0.0;
        for tempValue in tempArray {
            displayString += tempValue
            if tempValue == "+" {
                currentOperation = "+"
            } else if currentOperation == "" {
                calculatedValue = (tempValue as NSString).floatValue
            } else {
                if currentOperation == "+" {
                    calculatedValue += (tempValue as NSString).floatValue
                }
            }
        }
        displayString = "=" + calculatedValue.description
        calcDisplay.text = displayString
    }
    @IBAction func calcClear(sender: AnyObject) {
        displayString = ""
        calcDisplay.text = ""
    }
}


 

Posted in Class | Tagged , , | Comments Off on Learning Swift – Calculator App, part 1

ICON Lab move, VOIP phone logistics, Getting the new building connected

What’s keeping me busy this week?

  • Finalizing the Immersive Construction Lab (ICON Lab) move details
  • Transitioning phone service to VOIP in preparation to the move
  • Getting equipment ready for Comcast to connect the new building (Building 661)

Finalizing the Immersive Construction Lab (ICON Lab) move details

We had our second meeting yesterday with Christie Digital (http://www.christiedigital.com/en-us/pages/default.aspx) regarding the install.  The first meeting was a kick off meeting gathering details.  One of their techs also has come to visit the old and new site to take measurements and figure out egress from the old site (building 101) and ingress into the new site (building 661).  Main takeaways from this experience has been that all parties need to be flexible.  While Christie Digital has been finalizing placement of microphones, speakers, screens, rack, etc. in the new space, a few changes have come up that will require new conduit to be run, ducts to be moved, etc.  Our architect (http://www.kierantimberlake.com/) has been extremely responsive and easy to work with to make sure that all our needs can be met (within reason).  The main changes as we move will driven by the fact that the new space has very high ceilings, so we will not be ceiling mounting speakers, microphones, and videoconferencing cameras.

Transitioning phone service to VOIP in preparation to the move

This has definitely been an interesting project pulling together many things I already knew, but in an unexpected manner.  This project is primarily organized by central IT at the College of Engineering.

As we move into the new building, we will be transitioning from Verizon to VOIP (centrally managed and provided by Penn State Telecommunication and Networking Services – TNS).  There are two particular challenges we needed to overcome – porting the telephone numbers and minimizing interruptions.

The plan is:

  1. Provide new VOIP service in the old building
  2. Port the numbers before we move and disconnect the old analog phones
  3. Take the new phones when we move and they should “automagically” work.

Step 1 was the first big obstacles as our current space was not designed to provide enough data ports.  We are now running a secondary switch sitting under a desk in the cubicle area to be able to provide enough data connections for computers and phones.  Secondly, we had to prioritize what phones we would connect.  Instead of purchasing and running long wires all over the place, we decided that only the phones that are used by staff (instead of visiting researchers) would be connected.

Step 2 is a step of faith.  Since the porting process is completely out of our hands, our staff will have two phones on their desk during this time.  One day, the phones should start ringing in the VOIP phones and the old phones should be disconnected.  The timing of porting numbers is a mystery and we are taking this two phone approach to minimize any interruption of service.

Step 3 is only possible because our network infrastructure is inside Penn State’s network.  Building 101 and Building 661 will both be on fiber optic point-to-point connection back to University Park.  Basically, it’s like we’re all in one physical space and we’re just unplugging the phone from one room and plugging it into another port in the same network.

Voila!  We should have new phone service with the old numbers without any down time.

Getting equipment ready for Comcast to connect the new building

This is just another exercise in communication and patience.  Working with external contractors and vendors can be a challenge.  My only responsibility is that Comcast has everything they need to provide a connection in the new building.  For now, this includes a rack for them to install a modem and switch after the building is connected.

Comcast is responsible for running the conduit from the street into the building.  Then there are a number of different crews pulling cable, splicing, and installing equipment.  Again, I don’t have a big hand in the project other than trying to stay informed, so that we do not get into a situation where our move is delayed due to lack of connectivity.

Posted in Projects | Comments Off on ICON Lab move, VOIP phone logistics, Getting the new building connected

CBEI and long overdue update

My last post was January 2013 when I started working at my, then, new job at the EEB Hub. A lot has happened since. I have been here for 1.5 years and I can honestly say I could not have predicted that this job would shape into what it has become.

First of all, we went through a re-branding/re-naming. It is a bit frustrating, to say the least, since this organization was already re-named once (from GPIC, Greater Philadelphia Innovation Cluster, to EEB Hub, Energy Efficient Buildings Hub). It is now CBEI, the Consortium for Building Energy Innovation). One of the big things I needed to help with was our new website: www.cbei.psu.edu

The new site means we are no longer using an outside contractor to maintain our website. It is now hosted within the College of Engineering at Penn State. There are many challenges now that the site is in-house, but, one thing is for sure, it is much, much, much, much cheaper. This website probably deserves its own post at a later date.

Our new headquarters is still under construction (http://kierantimberlake.com/posts/view/259/) and planning for the move has been a great learning experience. Just today, we received a few of our new VOIP phones. We will be transition to VOIP from analog before the move, so we can port the numbers ahead of time and just “plug and play” once we get to our new offices.

CBEI VOIP phones
CBEI VOIP phones

There’s a lot more I could write about, but one of the biggest news is that our budget from the Department of Energy has been cut by more than 50%, so our staff has been shrinking. This directly impacts my workload, since I am in a support role. This also opens up some time to catch up and think of places to improve or catch up. For example, I have been working on getting Dell KACE set up on our machines for patching and software deployment.

Also, with the extra time, I plan on incorporate blogging into my regular routine, so there should be more consistent updates.

Posted in Projects | Comments Off on CBEI and long overdue update

First day at EEB Hub

Wow.  Where has the time gone?  World Campus was all someone could ask for from an employer – great people, support, experience, and more.  However, I could not pass up the opportunity that was given to me by the Energy Efficent Buildings HUB (www.eebhub.org).  I am still technically working for Penn State – as the Hub is a group of researchers, institutions, and companies brought together by the Department of Energy.  The grant is managed by Penn State, so my employer stays the same.

What will I be doing here?  We’ll have to see how it shapes up.  I know for sure I will be doing some IT support – Cisco TelePresence, desktop troubleshooting, web development, and whatever else comes up.  Stay tuned to see what I actually end up doing!

My family will be relocating to the Philadelphia area in a couple of weeks – the EEB Hub is located at the Naval Yard in Philadelphia.

New year… new job… new city… new adventures!

Posted in Uncategorized | Comments Off on First day at EEB Hub

Omnidisksweeper – finding and delete big files from my Mac

Today is my second to last day as  Multimedia Specialist at World Campus Learning Design.  I am in the process of cleaning up my computers.  I am doing a secure erase on my main computers, but I am choosing to keep one of the computers intact since it has some legacy software that will be useful to the group when I am gone (such as Macromedia Flashpaper, various versions of Camtasia and Captivate, Adobe Presenter, etc.).

There was a whole lot of hard drive space that was unaccounted for and I couldn’t easily figure out what was using it up – a quick google search came up with omnidisksweeper.  http://www.omnigroup.com/products/omnidisksweeper/

Quickly and easily found what was hogging up the hard drive space and “destroyed” the guilty files (in my case, a lot of Premiere Pro cache files).

 

Posted in Technology | Comments Off on Omnidisksweeper – finding and delete big files from my Mac

JW Player, Play playlist item by filename, rather than index

Problem:

I have a playlist of 45 items that will be played via javascript throughout one page (it’s a glossary page with audio files).  I found myself repeatedly making mistakes on which index belongs to what word.  As it stands, you would have to remember that the 40th item belongs to a specific word and play it by using jwplayer(‘playerID’).playlistItem(39).  What happens if I insert an item on the playlist?  I either have to put it at the end, putting things out of alphabetical order, or have to go back and change all the index references in the page.

Solution:

When the page is loaded, I go through the entire playlist once and create a key/value object with the filename and index.  Now I can play the items by name.  Instead of jwplayer(‘playerID’).playlistItem(39), it will be a much more readable playItemByName(‘the40thitem.mp3’).  This will be MUCH more easier to debug and maintain.

This could easily be modified to play using the title or description instead.

The code:

// Go through the playlist and create a key/value pair array so that we can assign playlist index numbers (since jw player can only reference playlist items by index, not name)
var playlistIndices = new Array();
$(document).ready(function() {
var i = 0;
for (i=0; i<glossaryPlaylistItems.length; i++) {
var path = glossaryPlaylistItems[i].file.split(‘/’); // split up the path by ‘/’ for next step
path = path[path.length-1]; // get the filename, lose the folder reference part
playlistIndices[path]=i;
}
});

function playItemByName(itemName) {
jwplayer(‘glossaryPlaylist’).playlistItem(playlistIndices[itemName]);
}

Posted in Technology | Comments Off on JW Player, Play playlist item by filename, rather than index

Multicam editing in Premiere Pro CS6 and its many quirks

So we (World Campus Learning Design Multimedia Specialists: Brian Strauss, Pete Warren, and myself) went on a very interesting video shoot recently. This was for a psychology class modeling some simulated psychotherapy sessions; we were able to get students from the Penn State theater department to do an excellent job as patients and therapists. This was a 3 camera shoot with primary audio from wireless lavalieres and a secondary room microphone as a backup.

I made many, MANY discoveries during the editing process that others may find helpful.

Here’s an overview of what our process ended up being.

  • Import all the clips into Premiere and organize them into whatever folder/bin structure works for you. This is important, because we will be creating a couple of intermediary sequences in order to get the job done.
  • Go through each clip and mark the in points (we used a clapper – not timecode).
  • Create a sequence from each scene/clip (some scenes may have more than one clip since our camera chunks them into 2GB files, so one scene may have two or more clips). This will also give us the ability later to set effects on the entire clip without going through the hassle of selecting multiple segments in the sequence when they have been edited/cut.
  • Create a multicam source from the sequences (not the clips!).
  • (optional)You can right click the multicam source and click on edit sequence in audition, which will bring up all the audio tracks in Audition in multitrack mode – AWESOME! You can then create a mixed down audio file that can be put into the audio track of the CamChanges sequence.
  • Create a sequence from the multicam source. We will call this sequence “CamChanges.”  This is where you will do the camera changes – Record multi-camera edits.
  • Finally, create a sequence from the “CamChanges” sequence. We will call this sequence “TimeEdits.”  This is where you can make the “time” edits/cuts.

Why did we have to do all that? Well, it turns out that if we just drop the multicam source into a sequence and start making time edits and camera changes, Premiere gets very confused. The audio/video kept going off sync. If you do things in a very specific order (make the camera edits first, then make the cuts), then it seems to work fine. However, as soon as you need to make any further changes to the camera chosen, it seems to go off sync again.

One big downside to this workflow is that you don’t see the camera changes and time edits on the same sequence. It’s abstracted.

An alternative way to do this would be to set up the sequences in a more logical manner – no intermediary CamChanges sequence, and use the razor blade and choose which camera each segment uses manually (instead of using the live multicam record tool). This is more intuitive, so you’re not dealing with two sequences to make separate camera change and time edits.

Posted in Projects, Research, Technology | Comments Off on Multicam editing in Premiere Pro CS6 and its many quirks

WordPress theme updated, new Lightbox plugin

Decided it was time to update the theme. Now moved over to Brunelleschi 1.5.3 by Kit MacAllister. I’m all about letting the content speak for itself. I don’t like bright colors. I don’t like light fonts on dark backgrounds. The layout should be exactly the same, so hopefully no one will get lost.

As I was updating my theme and plugins, I realized that the lightbox wasn’t working on some of my posts. I also decided that I wanted to have the ability to use a modal lightbox for iFrame content. Now I have moved to Pirobox (http://wordpress.org/extend/plugins/pirobox-extended-for-wp-v10/) from the jQuery lightbox plugin. I liked the flexibility and simplicity of Pirobox. It automatically detects images in posts and adds class=”pirobox_gall”. Additionally, I can add manually add it, in addition to attributes like rel=”iframe-650-450″ to a <a> tag for iFrames. Overall, I am please with how easy it was to add and how the finished product looks.

You can see how the iFrame lightbox looks on this post – CRIMJ 450W, Racial Percentages, Version 2
You can see how the img gallery lightbox looks on this post – Snap by Lectora Quick Review

Posted in Technology | Comments Off on WordPress theme updated, new Lightbox plugin

Drag and Drop Weights Exercise

A toned butt is an amazing thing. Strong glutes are your body’s powerhouse—they can help you burn more calories, keep you stable, and make you better at hiking, cycling, yoga, or any activity, says Courtney Paul, the founder of CPXperience training and a master trainer at Ripped Fitness in New York City. Building a foundation of muscle on your backside can also boost your metabolism around the clock. “The muscles that make up your butt are the largest in your body, so strengthening them can have the biggest positive effect on your calorie-burning potential,” he says. And let’s not forget: Muscle back there can also help your rear appear smoother and perkier, leptitox can be really useful for burning fat and muscle gain. (Surprise: there are even more reasons it’s important to have a strong butt.)

“Train heavy, hard, and consistently,” says Paul, who created this targeted mix of lower-body moves to ensure no fiber is left un-firmed. Do the routine twice a week for three weeks, and you’ll start to see definition in your butt, quads, and hamstrings. You’ll also notice a boost in your overall strength and stamina. Buns of steel, indeed.

How it works: Do each move as indicated. Limit rest between exercises to only what’s needed. Do 3 total rounds of this routine 2 days a week on non-consecutive days.

Total Time: up to 45 minutes

You will need: Free weights

1. Football Squat

A
B

View larger

A. Stand with feet hip-width apart and palms pressed together at chest, elbows bent downward to start. Squat as low as you can, resting elbows lightly atop knees.

B. Maintain elbow-knee contact as you straighten legs, sending hips up and back and folding forward from waist. Return to start. That’s 1 rep. Repeat for 60 seconds.

Sets: 3

Reps: 60 seconds

Mistakes and Tips: Scale down: Instead of taking elbows to knees, cross your arms with hands on top of shoulders.​
Scale up: As you return to start, pulse the squat twice.

2. Back Kick Combo

A
B
C

View larger

A. Start on floor on forearms and knees. Keeping hips square throughout, lift bent left leg, driving flexed foot toward ceiling. Return to start.

B. Next, lift bent left leg out to left side in line with hips. Squeeze your glutes twice. Extend left leg straight back, touching toes to floor with foot flexed.

C. Lastly, lift left leg as high as you can, then pause and pulse leg up and down 3 times. Return to start. That’s 1 rep. Repeat for 60 seconds. Switch sides; repeat.

Posted in Projects, Research, Technology | Comments Off on Drag and Drop Weights Exercise