Hey, remember how last time we did that one problem where we calculated the mass of a protein? Wasn’t that fun? Probably because we came up with a pretty concise solution, which is always awesome and directly correlates to the fun we have finding a solution. To that end, I figured we could rewrite the solution and maybe have even more fun! So let’s do that.
Another day, another Project Rosalind problem to dive into. And again we move into the wonderful world of proteins. However, we only need to calculate the mass of some proteins, so that should be easy, right? Let’s find out!
In this problem we need to calculate the
weight of a
weighted string using a
weighted alphabet. And that string is going to be made of amino acids (thus representing a protein). All that ends up meaning is we will be given a table that represents the weight of each amino acid. That can then be used to look up each individual amino acid weight and we can combine all those weights to get the final value.
Convert all the Datas!
In the problem there is a link to the monoisotopic mass table on Wikipedia. Here we can pull the mass for each amino acid. With the always handy copy-paste and some fun multiline text editn we can quickly convert the original table into a useable form and include that in our
monoisotopicMasses = M.fromList [(A, 71.03711), (C, 103.00919),(D, 115.02694), (E, 129.04259), (F, 147.06841), (G, 57.02146), (H, 137.05891), (I, 113.08406), (K, 128.09496), (L, 113.08406), (M, 131.04049), (N, 114.04293), (P, 97.05276), (Q, 128.05858), (R, 156.10111), (S, 87.03203), (T, 101.04768), (V, 99.06841), (W, 186.07931), (Y, 163.06333 )]
Get all the Datas!
Well, that was the hard part. The rest is just a normal look up into our masses table to get a specific mass and then adding all the values up.
calculateProteinMass :: P.Protein -> Double calculateProteinMass ps = let masses = map getValue ps getValue aa = maybe 0.0 id (M.lookup aa P.monoisotopicMasses) in sum masses
At least, that is conceptually how it works. Turns out that we get kind of bit in the butt by having to lookup the value in the map because it returns a
Maybe Double value instead of just a
Double value. This is not the first time we have seen this, so it isn’t completely unexpected, but it does throw a wrench in the machine.
To handle that we will write a small helper function that uses the
maybe function to go from a
Maybe Double to a plain old
Double. As we have mentioned before, the
maybe function takes three parameters. We will look at them in reverse order. The last parameter is a value of type
Maybe a where the
a could be any other type. Therefore, that third parameter could either be some value wrapped in a
Just or be a
Nothing. The second parameter is a function to convert from a value inside the
Just to some other value, in this case we want the value so we pass in the
id function which just returns us our wrapped
Double. And finally, the first parameter is the default value if the last parameter was
Nothing. Since we know we will be adding everything up, we make our default parameter
0.0 as that will not impact the sum in any way.
Also, notice how we are not using a
lambda function in the
map functions first parameter. In the past we have generally done that to make it clear and explicit what we are expecting. However, Haskell lets us write it more concisely. If we have a function that takes in one parameter that is of the type of the list we are
mapping over, we can use that function as the first parameter to
map and Haskell will handle passing the parameter in for us. Pretty handy!
main function is pretty much exactly what we would expect — it gets input from the command line, processes the input, and then prints the out put.
I may not mention this very much (or at all), but all of these solutions I’m posting are pretty much my second rewrites of each one. As in, when I originally solved the problem I was doing it very quickly and down and dirty. I didn’t take time to think of idiomatic ways to solve the problem. However, on these write ups I am trying to look at my solution and see what I could do to make it more Haskell-y and utilize the power of the language. This is one solution where I think I could even do better, and so I think I will redo this problem for the next post too, but it is going to require some discussion of relatively deep topics. As such, I’m going to try and take a similar approach as my first blogs — write the solution and then go back and explain stuff in follow up posts. Except, this time I won’t be so scatter brained and won’t try and explain everything right away, just give the high level concepts and then break it down later. Look forward to that!
As you may have noticed, I’ve been really on this Haskell kick recently. What with doing a book club at work based on Learn You a Haskell. Then there was doing all of the Project Rosalind problems that have (but not all of them yet!). And now, I’ve gone and bought another book on Haskell. This one is Real World Haskell, and it is so far pretty awesome.
What does Real World have that makes me like it so much? At this point, I am enjoying how business like it is. The book has a solid voice, but it is not overly trying to be something or other. While I enjoyed LYaH‘s sense of humor at the time. And as an intro, it was a great way to keep the material interesting. However, after you have read it once and have "learned" the content, it isn’t really as engaging.
RWH does not do that. It has a few witty comments within the first three chapters. However, that isn’t the way it conveys the material or progresses the concepts. Instead, it takes a more "educational" approach to presenting the material. As these first couple chapters are essentially review of the content of LYaH, that may be helping. I enjoy that the concepts make sense.
Finally, the book has exercises to work on! The exercises actually emphasize the material in the chapter, and make you think. I have been working on the CIS 194 which ends up being even more reinforcement of the concepts. Which hammers home the various best practices of Haskell.
At the end of the day, learning Haskell has lead to changes in the way I write code in general. I have taken more to recursive solutions and immutable data.
After reading all this, I realize it wasn’t too well written, so I’ll try again another time. Probably sometime where I am surrounded by less distraction.
Here’s a fun little fact about
UIKit — it loves fonts but wants to make it hard to use them.
UIKit makes it really easy to display different fonts in an app. You don’t have to think about how they are going to lay out, or the differences between the various fonts. All you have to do is tell
UIKit what to use, and off you go.
Except, that getting to the point where
UIKit is down to play that game takes a bit of work. You first have to copy the font into the project (or link to it at least). Pretty normal, but annoying that if the font is installed on the system it can’t just find it. Then you have to add the specific font of interest to the
Info.plist for each target that will use it. These entries must be under the
UIAppFonts key, which is an
Array. Then each entry must be the name of the font file. Finally, you have to use the
PostScript name to reference the font. You can get that name from the
Font Book app on OSX.
With all that done you are set to go!
Until you merge your project file and some how the reference to the font gets lost. Then when you run your app and a view that is referencing that font can’t find it, it will take a few seconds to load. The best part? There is no warning/indication that it cannot find a font file.
Moral of the story — use custom fonts but be very careful that you don’t lose references to them.
This is the 13th entry in the Project Rosalind series of blog posts. Dang, really getting up there! This problem ends up being much more statistics based and not necessarily so much bioinformatics. As in others, the problem space will be described and then the solution method will be explained.
On the 12th problem of Project Rosalind, they gave to us — the opportunity to take a string of Protein amino acids and convert it into the number of different mRNA strings that could produce that Protein. Which seems like a better deal than having a bunch of drummers whacking out some dirty beats all over the place. Ew.
I’m not sure if anyone has ever wondered what I use to write my various missives, but in case you have, here goes!
- Notepad: I use this sparingly. Pretty much it is just for quick edits that are easier to do by double clicking on a file in the
Finder. Anything more than that, and I skip right over it.
- Sublime Text: This is my go to when I have a lot of repetitive editing to accomplish. The find and replace are stellar and pretty much they only place I feel comfortable doing regex.
- DayOne: This is where I write all of my Haskell/Project Rosalind posts. I like the sparse interface and the default styles it has. It is where I learned to use Markdown when writing, which really does speed up the overall process. It is nice that when I hit the
Donebutton, it renders the content as it will be shown on my blog. In fact, I have modified some of the CSS on the blog to match that of the DayOne editor’s renderer because I like it so much. Also, the fact it syncs to my iPhone and iPad is a huge win.
- Typed: I just recently picked up this editor. It is purely for writing and is most likely to be similar to iA Writer. It has some nice typography by default and a "Zen Mode" that removes all distractions. I find myself enjoying it most for this kind of post – more free form and less technical. The interface just seems to go with that better.
And that’s it! That’s where and why I write. If you have any suggestions on tools to use for writing I’d be more than happy to listen and give them a try! Or, if you have a writing tool you’d like me to give feedback on, please feel free to reach out to me and we can work out the details.
Welcome back for the next Project Rosalind problem — Mortal Fibonacci Rabbits, or, How Many Rabbits are There if Some Die? Yeah, a little more morbid with that name, probably why it wasn’t chosen. This problem will take a bit more work to get through, so grab your favorite beverage of choice and settle in.