func fontForDisplay(atIndexPath indexPath: NSIndexPath) -> UIFont? {
if indexPath.section == 0 {
let familyName = familyNames[indexPath.row]
let fontName = UIFont.fontNamesForFamilyName(familyName).first as String
return UIFont(name: fontName, size: cellPointSize)
} else {
return nil
}
}
The above snippet of code is from
Beginning iPhone Development with Swift Exploring the iOS SDK
I'm trying this on el capitan and xcode 7.01, which now uses swift 2.0
The first issue is that xcode will warn you that 'String?' is not convertible to 'String'
Adding a ! to force cast and will allow the code to run. (append it to either first! or String!)
The next issue is that this is thrown: EXC_BAD_EXCEPTION
Looking at the trace, we can see
familyName = (String) "Bangla Sangam MN"
fontName = (String!) nil
So it appears that we're trying to get the first element of an empty array. I ended up with this solution:
let fontArray: String? = UIFont.fontNamesForFamilyName(familyName).first
let fontName = (fontArray != nil) ? fontArray! : ""
Let me know if there is a more idiomatic way of doing this with Swift 2.0
Monday, October 12, 2015
Thursday, January 8, 2015
golang: Do you need a singleton? Where are my private/public class modifiers?
Intro: Singletons can be useful, but as mentioned in other people's posts they are an anti pattern and can make testing and debugging difficult. A post on stack overflow had this short nonspecific message "Just put your variables and functions at the package level." http://stackoverflow.com/questions/1823286/singleton-in-go I took this as a hint that with a little more knowledge of how go packages work, I could get a single instance of an object and have it abstracted so that modification would be difficult, if not impossible.
Let's start with three files.
src/logger/logger.go
src/chat_server/main.go
src/chat_server/sub/sub.go
logger.go
There is a logger object named log with a single timestamp field. The other thing to note is that the functions, variables and structs (golang's version of a class) can have an upper or lower case first letter.
"if something starts with a capital letter that means other packages (and programs) are able to see it" - http://www.golang-book.com/11/index.htm
For those us who are used to having public and private keywords in our OO language, this capital letter convention is how go restricts access. This means that Togger, Tog, and Debug() can be referred to once logger is imported in another file. While log, loger and write*() can not. This takes a little closer to our goal because we should be able to instantiate an instance of logger, and only allow specific functions to act on it.
main.go
Here are some examples of how this works. Debug is a function that can be accessed after the import. It can refer to var log as it's within the same package. Trying to access logger.log directly is not allowed, while the analagous struct value logger.Tog can be called. Any attempt to init a new 'logger' object also fails.
There is one more quick check that I wanted to verify and that is to confirm the log object continues to be the only instance no matter where it is imported.
sub.go
Way back in logger.go I print out the memory address of the Timestamp field.
fmt.Println(&log.Timestamp)
After running main, the output is:
one
0x547068
two
0x547068
In SUB
0x547068
555
12345
We get the same address so it's good.
Conclusion: I was able to create a single instance of my logger struct without resorting to a singleton and learned how go packages limit access to vars and and functions.
Let's start with three files.
src/logger/logger.go
src/chat_server/main.go
src/chat_server/sub/sub.go
logger.go
package logger import ( "fmt" ) type logger struct { Timestamp int } type Togger struct { Timestamp int } var log = logger{Timestamp: 12345} var Tog = Togger{Timestamp: 12345} func (l *logger)writeInfoFile(s string) { fmt.Println(s) } func (l *logger)writeErrorFile(s string) { fmt.Println(s) } func Debug(s string) { log.writeInfoFile(s) fmt.Println(&log.Timestamp) }
There is a logger object named log with a single timestamp field. The other thing to note is that the functions, variables and structs (golang's version of a class) can have an upper or lower case first letter.
"if something starts with a capital letter that means other packages (and programs) are able to see it" - http://www.golang-book.com/11/index.htm
For those us who are used to having public and private keywords in our OO language, this capital letter convention is how go restricts access. This means that Togger, Tog, and Debug() can be referred to once logger is imported in another file. While log, loger and write*() can not. This takes a little closer to our goal because we should be able to instantiate an instance of logger, and only allow specific functions to act on it.
main.go
package main import ( "logger" "chat_server/sub" "fmt" ) func main() { logger.Debug("one") logger.Debug("two") sub.CheckingAddress() isPublic := logger.Togger{Timestamp: 555} fmt.Println(isPublic.Timestamp) fmt.Println(logger.Tog.Timestamp) // These will cause an error // fmt.Println(logger.log.Timestamp) // isPublic := logger.logger{Timestamp: 333} }
Here are some examples of how this works. Debug is a function that can be accessed after the import. It can refer to var log as it's within the same package. Trying to access logger.log directly is not allowed, while the analagous struct value logger.Tog can be called. Any attempt to init a new 'logger' object also fails.
There is one more quick check that I wanted to verify and that is to confirm the log object continues to be the only instance no matter where it is imported.
sub.go
package sub import ( "logger" ) func CheckingAddress() { logger.Debug("In SUB") }
Way back in logger.go I print out the memory address of the Timestamp field.
fmt.Println(&log.Timestamp)
After running main, the output is:
one
0x547068
two
0x547068
In SUB
0x547068
555
12345
We get the same address so it's good.
Conclusion: I was able to create a single instance of my logger struct without resorting to a singleton and learned how go packages limit access to vars and and functions.
Wednesday, December 17, 2014
VMware Player Free and changing boot devices.
VMWare player free doesn't include all the settings that the commercial editions offer. In order to boot an iso, you must hand edit the *.vmx file and add the following settings.
bios.bootOrder = "cdrom,hdd,floppy"
bios.hddOrder = "scsi0:0,ide1:0"
Adding the above information allowed me to install fedora 21 over my existing fedora 20.
Tip: After installation, I powered the vm off. Removed the above lines and removed the fedora iso from the vmware cd drive.
bios.bootOrder = "cdrom,hdd,floppy"
bios.hddOrder = "scsi0:0,ide1:0"
Adding the above information allowed me to install fedora 21 over my existing fedora 20.
Tip: After installation, I powered the vm off. Removed the above lines and removed the fedora iso from the vmware cd drive.
Monday, September 1, 2014
Using Chef to auto create an instance on Amazon ec2
Chef is one of the major server automation tools out there along with Puppet and Ansible. I decided to give chef a try by auto creating an ec2 instance. They're all trying to get you to buy saas packages for nodes greater than around 5. I will be using the free account offered by opscode to store my recipes.
For testing I cloned a new chef-repo
git clone git://github.com/opscode/chef-repo.git ec2chefrepo
I get a password old/new page. Instead go to the left side and click on Users.
Then click on your email and then the security credential tab
Click on Manage Access Keys
Create a new key and you will get two strings.
Note: The secret key is show and available this one time. You will need to create new access keys if the secret key is lost.
Access Key Id
AKAJG6Z4AFQ5YPQ
Secret Access Key
Mw5sHvDgJRtAVP2vkA8gL8XJkvoZijhNMf
Note: the ssh_key_id is your key name without the pem
gem install bundle
rbenv rehash
cd ~/ec2chefrepo/
vim Gemfile
Note: I had to run this before running bundle installs
sudo yum install gcc-c++
bundle install
Had to run:
gem install rb-readline unf
http://aws.amazon.com/amazon-linux-ami/
To get a list of AMI Image Ids
1) Create a new chef-repo or use your current chef-repo
For testing I cloned a new chef-repo
git clone git://github.com/opscode/chef-repo.git ec2chefrepo
2) From the previous tutorial ./chef-repo copy over ./chef-repo/.chef into our new chef-repo
3) In Amazon Ec2 click on your name in the top right
I get a password old/new page. Instead go to the left side and click on Users.
Then click on your email and then the security credential tab
4) Get the Access Keys and Secret Keys
Click on Manage Access Keys
Create a new key and you will get two strings.
Note: The secret key is show and available this one time. You will need to create new access keys if the secret key is lost.
Access Key Id
AKAJG6Z4AFQ5YPQ
Secret Access Key
Mw5sHvDgJRtAVP2vkA8gL8XJkvoZijhNMf
5) With the above access keys and your ec2 .pem add these lines to ec2chefrepo/.chef/knife.rb
knife[:aws_access_key_id] = 'AKAJG6Z4AFQ5YPQ' knife[:aws_ssh_key_id] = 'bunwichchef' knife[:aws_secret_access_key] = 'Mw5sHvDgJRtAVP2vkA8gL8XJkvoZijhNMf'
Note: the ssh_key_id is your key name without the pem
6) Create a gemfile to install some gems
gem install bundle
rbenv rehash
cd ~/ec2chefrepo/
vim Gemfile
source 'https://rubygems.org' gem 'chef' gem 'knife-ec2'
Note: I had to run this before running bundle installs
sudo yum install gcc-c++
bundle install
7) Create and Deploy An Instance
Had to run:
gem install rb-readline unf
http://aws.amazon.com/amazon-linux-ami/
To get a list of AMI Image Ids
knife ec2 server create \ --availability-zone us-east-1b \ --node-name bunwichchefinstance.demo \ --flavor t1.micro \ --image ami-ba18d2 \ --run-list "role[memcached]" \ --identity-file ~/.ssh/bunwichchef.pem \ --ssh-user ec2-user
Sunday, June 15, 2014
vlc no decoder module fedora 20
Sometime after updating Fedora 19 to 20 (using fedup), VLC stopped playing some h264 videos.
An error message such as this appeared:
no suitable decoder module for fourcc `h264'. VLC probably does not support this sound or video format.
It was missing lame-libs. A sudo yum install lame-libs solved my issue.
What is more important is how I solved this:
a) vlc -vvv mediafile.mp4
b) Look for yellow or red warning/error messages. A lot of information gets outputted.
eg:
0x1666118] main libvlc warning: cannot load module `/usr/lib64/vlc/plugins/demux/libavformat_plugin.so' (libmp3lame.so.0: cannot open shared object file: No such file or directory)
c) This message states that libmp3lame.so.0 does not exist.
d) sudo repoquery --whatprovides '*/libmp3lame.so.0'
returned:
lame-libs-0:3.99.5-2.fc19.i686
An error message such as this appeared:
no suitable decoder module for fourcc `h264'. VLC probably does not support this sound or video format.
No suitable decoder module:
VLC does not support the audio or video format "h264". Unfortunately there is no way for you to fix this. It was missing lame-libs. A sudo yum install lame-libs solved my issue.
What is more important is how I solved this:
a) vlc -vvv mediafile.mp4
b) Look for yellow or red warning/error messages. A lot of information gets outputted.
eg:
0x1666118] main libvlc warning: cannot load module `/usr/lib64/vlc/plugins/demux/libavformat_plugin.so' (libmp3lame.so.0: cannot open shared object file: No such file or directory)
c) This message states that libmp3lame.so.0 does not exist.
d) sudo repoquery --whatprovides '*/libmp3lame.so.0'
returned:
lame-libs-0:3.99.5-2.fc19.i686
Friday, May 30, 2014
Failed to load libGL.so on Fedora 20 and Android emulator
I got this warning when trying to get the android emulator working on Fedora 20.
You need to install 2 packages to get this working:
sudo yum install mesa-libGL-devel mesa-libGL-devel.i686
The libGL.so message disappeared after this. Command to search for this lib on future installs.
sudo yum whatprovides */libGL.so
You need to install 2 packages to get this working:
sudo yum install mesa-libGL-devel mesa-libGL-devel.i686
The libGL.so message disappeared after this. Command to search for this lib on future installs.
sudo yum whatprovides */libGL.so
Thursday, May 1, 2014
How humor and software development are related.
I've been putting out a few resumes and getting back to an HR person with my status. Part of my response describes how having a funny bone has affected me as a developer.
A large part of software development is analyzing a situation and choosing an option and testing the results. Comedy is analyzing a situation, finding the absurdity and testing among your peers. Nothing is funnier than seeing your TDD tests pasts, am I right? Is it no wonder that some great comedians had STEM backgrounds?
Jimmy Fallon - CPSC (yes he dropped out for SNL)
Mike Judge - Physics
Rowan Atkinson - EEng
Ray Romano - Accounting
Hi XXX,
Hope your talent search is going well for XXX. We had a short but good talk last week and went over my qualifications and past work experience. I enjoyed listening to what you and XXX were looking for in prospective employees. I did my best to be as cool as possible, but having our call dropped and me running around the all corners of my building trying to find a good connection, might have made me sound a little nervous :)
My three main takeaways from our call was that culture, personality and technology skills were equally valued by XXX.
Coming from a small town, I feel that I was able to grow up in an environment where being good to your neighbours and having great friends were an important part of life. People still left their doors unlocked and when you drive by in a car you wave your hand. I think I certainly have brought this attitude with me as a Vancouverite, and will wave to my neighbours when I bike or walk around my part of town. I stopped doing this downtown as people looked at me strange (except in downtown east side where they tried to hug me...ewww)
Having not a lot to do in a small town also made you grow your personality and one aspect is that I think I have a great sense of humour and wit. All you have are your friends and when there wasn't much to do we would sit around and make jokes. It was a game of one upmanship, when someone said something funny, you tried your best to build on it or say something even funnier. It's important to note that humour can sometimes hurt people, and being careful not to cross that line is part of the fun. I tend to respect Stephen Colbert's type of humour, and know I'll never be as good. People have told me that I'm funny, but I always tell them, "Really? I'm the least funny person among my funny group of friends".
This trait has helped me make friends and interact with people, but I think it also has helped my career. Rule of comedy - funny comes in threes. You tend to look at a situation or a phrase and think of three things that you can add to it. It really helps with improving your lateral thinking and I find that I apply this to all aspects of my every day work. During a conversation or a question, I come up a set of options, and try to mentally travel down each path and drop the ones that don't work. Then express the good ones. Keep repeating until the best solution is found. This is what developers do all day I feel that it is one of my strongest attributes that one would expect from someone who was more artsy.
...
A large part of software development is analyzing a situation and choosing an option and testing the results. Comedy is analyzing a situation, finding the absurdity and testing among your peers. Nothing is funnier than seeing your TDD tests pasts, am I right? Is it no wonder that some great comedians had STEM backgrounds?
Jimmy Fallon - CPSC (yes he dropped out for SNL)
Mike Judge - Physics
Rowan Atkinson - EEng
Ray Romano - Accounting
Subscribe to:
Posts (Atom)