text:
… I've written this!
Category Archives: Software
True Colors Shining Through
I can't help but believe the Microsoft CEO showed his true colors before the backtrack. I just don't think enough guys care to listen. The "trust the system" comment he made is the worst cause it's the system that's letting women down.
Something big is amiss and the Microsoft CEO's original statement betrays it. I mean, I've been doing this work for over 10 years and I'm crazy good at software engineering. Today, I want out of the field more than ever because of the treatment I've been taught to expect in the workplace. But! Student loans…
Sure, there are a some good advocates for women in a tech workplace. But there are way more than enough of those who prefer to tell us how to feel and prefer to tell us how to "fix" our lives rather than engage with us to see what we're talking about.
And it ain't just Nadella showing his true colors either:
ReSharper Hurts Me
I've never outrun a tool before and been forced to wait for my IDE to catch up to me.
Though what gets me more are claims of, "How do you work with out ReSharper?" Then I show them. Then there is a, "Woah."
In Browser, Computer Vision Based, Pong
To begin, I just couldn't resist using an a Atari harkening font in this one. 🙂
This particular project evolved my GLSL skills and started to teach my brain how to work on a GPU better which, naturally, means I have a very nicely decorated whiteboard to my right at the moment. And I'll be sharing it too, in a moment…
I've been thinking about doing a Computer Vision project for a little while now. I was inclined to do a desktop app and use OpenCV but on doing some research on what goes in to computer vision I realized, "Hey, I know the tools to make this work in browser." So, I did.
My first task to get Computer Vision working was take the RGB feed from my WebCam and convert it to HSV. I've done chroma keys before just using the raw RGB values but with the recommendation that HSV might work better, I figured why not give it a try? This is where the GLSL came in and what I had to write was an implementation of the following:
Let $$R = $$ the Red RGB component in the range 0.0 to 1.0
Let $$G = $$ the Green RGB component in the range 0.0 to 1.0
Let $$B = $$ the
Blue RGB component in the range 0.0 to 1.0
Let $$Epsilon =$$ a inconsequential float value to prevent division by 0.
The definition of $$max$$ is elided, but it just returns the maximum of the values it was passed in.
$$H =\begin{cases} G – B & max(R, G, B) = R \\ B – R & max(R, G, B) = G \\ R – G & max(R, G, B) = B\end{cases}$$
$$H$$ had to be accompanied with a related offset value:
$$H' =\begin{cases} 0 & max(R, G, B) = R \\ 1/3 & max(R, G, B) = G\\ 2/3 & max(R, G, B) = B\end{cases}$$
So my final result for Hue is actually $$H"=H+H'$$ This was because in the HSV colorspace, $$H$$ is represented as a circle going round from \(R \rightarrow G \rightarrow B \rightarrow R\) So, in order to get select the right hue, an offset will need to be applied to get the value round to the right place.
$$S=\frac{\Delta}{max(R, G, B) + Epsilon}$$
And finally
$$V=max(R, G, B)$$
I found some other documentation about this calculation online and found it messy. That might be normal when discussing math like, I don't really know, this but my engineering brain likes things broken down into their individual components. Hopefully, the above will help someone else out! 🙂 Now to calculate that on the GPU making it time to live up to my promise of bringing the whiteboard in…
I ended up being heavy on mix() and step() in order to reduce the branching I had to write. Branching, as I understand, is getting to be less of a concern in GPU programs but the article saying that branching implementation was improving was from 2011 and that's too recent to assume all GPU's will behave nicely. Below those function notes, there's a tracking of how my values were going to flow through in the vectors so I could end up with a the maximum in the first position, the two values I needed to subtract to get my $$H$$ and finally the offset $$H'$$ that went with the selected $$H$$ so I could calculate $$H"$$ properly. For the curious, the shuffling that's done with mix() and step() was effectively a vectorized ternary operator.
The conversation of RGB to HSV and writing the GLSL shader to do that was most of the effort. But the shader wasn't quite done yet. The final step was passing Min and Max values for each value: H, S, V. When all three where within the defined min and max, the shader needed to return white, when any of them were out of bounds, the shader had to return black. This way, the user can select an object in the real world by its color that will function as a paddle. Now I did look for and find shader implementations of RGB to HSV online, however, I opted to roll my own to make sure I understood what was going on as this was pretty much the beating heart of this project.
On the JavaScript side of things I did run into a problem. I wanted to use sliders so users could hone in on the color they wanted to select. However, HTML5 only allocates one thumb per slider. I know I could have used jQueryUI for to get two thumbs but I opted to stay away and handle the problem myself. It was also tempting to use three.js to handle the WebGL side of things but I decided to not bring it in either. The changes weren't too significant from my ANSI.WebGL project so I saw no need to take on another dependency.
The JavaScript I did write is pretty straight forward. There's a ball (a div that's been styled to look like aball) that flys around and when it hits a paddle it flies back the other way. Hitting here has been defined as the left or right side of the ball hits a white paddle pixel. When that happens, the column of pixels is counted for connected white pixels to figure out the length of the paddle. If it's above a threshold (provided to filter out artifacts) the calculation figures out where the ball was hit in relation to the paddle then the ball will bounce away at an angle. The only "gotcha" I ran into with this part was when I read the pixels from the buffer, I found them inverted which broke my hit detection! But it was a simple fix to right them thankfully.
For much larger computer vision problems I probably would turn to something like OpenCV. Still getting to understand something like sometimes, we convert to the HSV color space, is I think very important! Understanding how the tools you are using work I hold to be key to actually using them well. It also allows you to answer a question I've mentioned before as being part of my process. 😉
You will need either a recent version of Firefox or Chrome in order to run this project due to the needs of getUserMedia() and WebGL.
The problem I set out for myself of rendering ANSI art in a web browser turned out to have more ins and outs than I anticipated and quickly became a case where I needed to iterate and refine my idea in order to carry it out. In the beginning, I knew doing something like rendering a few thousand <span>s, one for each character so each character could be styled, was not going to be a viable solution because it would not scale to work well on all browsers. So I attempted to go with SVG as my solution and use a mask in order to get all the colors I needed, kinda like using an image brush, as this would afford me the possibility of limiting the number of elements I needed to create. After I got the right @font-face setup, the solution worked great in Opera (Blink), but not so hot in Firefox.
At that point I considered dropping the whole project as I found myself being pushed to a HTML5 canvas based renderer for speed and I didn't really want to reinvent the wheel as I found an implementation online that solved the problem that way already. Then, I lost my job. 🙁
But! Ok! 🙂 New reasons to putter: Keep my skills fresh, solve an interesting problem, learn something new and have a new project to show off to would be employers!
On project resumption, I opted to try and go the WebGL route. One thing I like about this solution is I only needed one sprite of all the characters to render any color combination I wanted as I'm able to draw each character with a fragment shader. When it reads black for the current texture pixel, put the background color, white put the foreground. Simple rule with a lot of flexibility.
I'm on Github!
And this is my first project I've put up XMPPBot
Exploiting HTML5 Geolocation is Too Easy
Titling this post was hard. I wanted something attention getting but yet not hyperbolic. Hopefully what I've selected works. I do think it's a pretty no nonsense way to sum up what I'm about to go into here because Computer Security boils down to answering the question of, "Secure against whom?" Well, I think I should have been driven to a point where I gave up and started to work on something else instead of being here now, able to write this post with the findings I have.
What got this started was when I took Introduction to Computer Security in Grad School my professor's stated goal was to make the students in the class think like an attacker. Today, I think the "attacker" mentality is a good one for all software engineers to have. It gets us thinking off the happy path, in the weeds and muck, perhaps finding a path to somewhere that you as the author didn't even know existed.
In this post, that path metaphor may be too literal.
After I was done with the class I remember thinking to myself, "Gee, I know how to do some Internet Explorer automation, I wonder if I can use IE to get my physical location on Earth?" So, I spent some time figuring out how to do just that and those results results are here. I was going to make this post a retelling of that find but I got to thinking, "You know Paige? Over the years a lot of people have picked on Internet Explorer. Don't cha think there's enough fodder out there for that?" Well, I happened to agree with me so I thought, what else could I go after? Well, what about the service that makes HTML5's Geolocation work itself?
navigator.geolocation.getCurrentPosition(function(p) { console.log(p.coords.latitude); console.log(p.coords.longitude); });
This is pretty much what my Internet Explorer solution relied on. Back then, I found that my IE instance was "hung" and that turned out to be because there was a, "Do you want to allow [X] website access to your location?" prompt up. I didn't want to look at a flashing IE window as automation ran so I added some registry keys to grant permanent permission to IE for it to be able to use Geolocaiton on a website I browsed to, automatically. When I was done I realized I'd in effect created something that could get my location on Earth without my permission.
Now, back to the task at hand.
What happens at the lower levels when you call getCurrentPosition in JavaScript? Well, in my case where the only wireless access I have is WiFi, all the wireless access points are scanned for their MAC addresses and signal strength because HTML5 Geolocation works by triangulating your device with the Access Points that it can see.
A lot of code is about to follow but all this C++/CLI code is doing is collecting the aforementioned information.
List<AccessPoint^>^ AccessPoint::QueryAll() { DWORD dwCurrentVersion = 0; HANDLE hClient = INVALID_HANDLE_VALUE; DWORD dwResult = WlanOpenHandle(2, nullptr, &dwCurrentVersion, &hClient); auto results = gcnew List<AccessPoint^>(); if(dwResult != ERROR_SUCCESS) return results; PWLAN_INTERFACE_INFO_LIST pIfList = nullptr; dwResult = WlanEnumInterfaces(hClient, nullptr, &pIfList); for(int i = 0; i < pIfList->dwNumberOfItems; i++) { PWLAN_BSS_LIST pBSSList = nullptr; dwResult = WlanGetNetworkBssList(hClient, &pIfList->InterfaceInfo[i].InterfaceGuid, nullptr, dot11_BSS_type_any, false, nullptr, &pBSSList); if(dwResult == ERROR_SUCCESS) { PWLAN_AVAILABLE_NETWORK_LIST pAvailableList = nullptr; dwResult = WlanGetAvailableNetworkList(hClient, &pIfList->InterfaceInfo[i].InterfaceGuid, WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES | WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES, nullptr, &pAvailableList); if(dwResult == ERROR_SUCCESS) { for (int availableIndex = 0; availableIndex < pAvailableList->dwNumberOfItems; availableIndex++) { for(int bssIndex = 0; bssIndex < pBSSList->dwNumberOfItems; bssIndex++) { if(!memcmp(&pAvailableList->Network[availableIndex].dot11Ssid, &pBSSList->wlanBssEntries[bssIndex].dot11Ssid, sizeof(DOT11_SSID))) { auto name = String::Empty; auto address = String::Empty; for(int c = 0; c < pBSSList->wlanBssEntries[bssIndex].dot11Ssid.uSSIDLength; c++) name += (Char)pBSSList->wlanBssEntries[bssIndex].dot11Ssid.ucSSID[c]; for(int c = 0; c < 6; c++) { if(c > 0) address += ":"; address += pBSSList->wlanBssEntries[bssIndex].dot11Bssid[c] .ToString("X02"); } int quality = -(pAvailableList->Network[availableIndex].wlanSignalQuality / 2); results->Add(gcnew AccessPoint(name, address, quality)); break; } } } if(pAvailableList != nullptr) WlanFreeMemory(pAvailableList); } if(pBSSList != nullptr) WlanFreeMemory(pBSSList); } } if(pIfList != nullptr) WlanFreeMemory(pIfList); if(hClient != INVALID_HANDLE_VALUE) WlanCloseHandle(hClient, nullptr); return results; }
Then I just had to send off the collected information to the right Web Service which I did in C#:
class Program { static void Main(string[] args) { var list = AccessPoint.QueryAll().Select(ap => new WiFiAccessPoint() { macAddress = ap.MACAddress, signalStrength = ap.SignalStrength }); var data = new Request() { cellTowers = new object[0], wifiAccessPoints = list.ToArray() }; var serializer = new JavaScriptSerializer(); var message = serializer.Serialize(data); byte[] bytes = System.Text.Encoding.ASCII.GetBytes(message); var request = WebRequest.Create([Elided but easy to get what is needed]) as HttpWebRequest; request.UserAgent = [Elided but also very easy to figure out, if even needed]; request.Method = "POST"; request.ContentType = "application/json"; request.ContentLength = bytes.Length; using (var stream = request.GetRequestStream()) stream.Write(bytes, 0, bytes.Length); string result = string.Empty; using (var response = request.GetResponse()) { if (response == null) throw new Exception("Yeah! I think this could be a good thing!"); using (var responseStream = response.GetResponseStream()) { using (var reader = new StreamReader(responseStream)) { result = reader.ReadToEnd().Trim(); Console.WriteLine(result); } } } using (var file = new StreamWriter("result.txt", false)) file.Write(result); } }
Regarding the elided bits, I'm not going to reveal what I did to fill them in cause that gets into information I'd rather you discover on your own. A little bit of critical thinking is all that's needed to find it just like only a little bit of critical thinking was needed to carry this out end to end. Anyway and as for WiFiAccessPoint and Request, they are simply:
public class WiFiAccessPoint { public string macAddress { get; set; } public int signalStrength { get; set; } } public class Request { public object cellTowers { get; set; } public WiFiAccessPoint[] wifiAccessPoints { get; set; } }
When I ran my project, my position was returned to me with an error of 33 feet. I was given no prompt and if I hid my console window I would have had no indicator that my process was running unless I was staring at process monitor.
The only thing that prevents an attacker from developing software that gets your device location is a requirement from the W3C (The group that dictates how HTML5 Geolocation shall work) that mandates apps ask for permission. If it would always have to ask instead of leaving it to merely trusting developers, or if it took someone with more knowledge than I to pull this off I wouldn't be bothered. As much. I like Geolocation for navigation, but I also like being asked my permission to opt apps in to using the Geolocation services on my devices. Google Maps, ok. Others, it depends.
Using IE to Save SVGs as Bitmaps to Wherever
You know, something that'll make you appreciate .NET really fast is programming COM by hand in C++. I suspect what follows can be converted into C# but I didn't go that route because while working to get to this point, I didn't want to worry about doing COM Interop in .NET on top of the problem I was trying to solve. Therefore, I ended up in C++ and COM.
On writing that last, now seems like a good time to remind folks, sanitize/be mindful of your inputs! 🙂
I knew I could get another library to handle the rendering but I didn't see why I needed to. I have a perfectly good SVG renderer on my computer after all. It's just embedded in Internet Explorer and much of IE is COM. That means I can get at its objects too, if one knows how.
I'm going to assume that most of the people who read this are more comfortable with C#. I'm also going to assume that because you've made it this far after I've talked about C++ and COM, odds are you're my kind of developer! 🙂
Finally, before the good stuff a note that as is my motif I'm not going to be giving ya'll a final working solution here but I will give you the knowledge to make it work for you. I'm a teach a developer to code kind of gal after all!
I like to start with the beginning so, here's your includes because it drives me batty when people leave those out of their code walk throughs!
#include <windows.h> #include <mshtml.h> #include <gdiplus.h> #include <functional> #include <iostream> #import <mshtml.tlb> #pragma comment( lib, "gdiplus" ) const int HIMETRIC_INCH = 2540; using namespace Gdiplus; using namespace std;
I'll assume knowledge of the basic #include, the #import directive is going to pull in type description information for the COM interfaces I'll be using. The #pragma comment() is a way to add a reference to a type library in code instead of adding the reference to the project. Great way to avoid, "Gagh! I setup my libraries for Debug/Release mode only!" Finally, HIMETRIC_INCH is a constant needed to get the output to render at the right size. We'll see that again later.
From here we're clear to look at main:
int main(int argc, char* argv[])
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
return 0;
First thing to note is the GdiplusStartup call. That's getting our application prepared to do the final rendering using GDI+. You wanna use GDI+ in your application, you gotta do this. As cleanup, when you're done you need to call GdiplusShutdown as shown above.
Next is the actual initialization of COM with CoInitalizeEx. This is responsible for setting up COM for use by the calling thread. I'm also calling it with COINIT_APARTMENTTHREADED so I don't have to worry about concurrency.
Ok, now on to ConvertToImage:
void ConvertToImage() { HRESULT hr = E_FAIL; int width = 120, height = 120; MSHTML::IHTMLDocument2Ptr pDoc = nullptr; hr = CoCreateInstance(CLSID_HTMLDocument, nullptr, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, (void**)&pDoc); if(SUCCEEDED(hr)) hr = SetDocumentViewPort(pDoc, width, height); if(SUCCEEDED(hr)) hr = LoadHTML(pDoc); if(SUCCEEDED(hr)) RenderImage(pDoc, width, height); }
I have some constants here (width, height) that just happen to match my SVG output. Bad, icky, terrible thing to do but I'm here to illustrate as simply as possible.
The most interesting thing happening here is the call to CoCreateInstance. Here I'm creating an HTML Document and note, I am bypassing IE entirely. Also note the CLSCTX_INPROC_SERVER parameter. That's telling COM To create the document in the space of the running process. This is one of the very extremely important things for our goal here.
The way that I'm checking if my HRESULTS succeed with SUCCEEDED(hr) is a result of my absolute abhorrence to using goto statements and desire to avoid arrow code. Also, I'm using smart COM pointers here. Usually I'd have to be aware of:
- IUnknown->AddRef()
- IUnknown->Release()
In order to avoid a memory leak. If you don't know what I'm talking about here, that's okay for the moment just if you find yourself working with raw COM you will need to know about it, else you're going to have a bad time. By that I mean you'll have a memory leak.
Next, we have to set the size of our document which SetDocumentViewPort handles.
HRESULT SetDocumentViewPort(MSHTML::IHTMLDocument2Ptr pDoc, int width, int height) { auto hdc = GetDC(NULL); auto x = MulDiv(width, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSX)); auto y = MulDiv(height, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSY)); ReleaseDC(NULL, hdc); IOleObjectPtr pOle = nullptr; HRESULT hr = pDoc->QueryInterface(IID_IOleObject, (void**)&pOle); if(SUCCEEDED(hr)) { SIZEL size = {x , y}; return pOle->SetExtent(DVASPECT_CONTENT, &size); } return hr; }
In completing the task at hand, this was one of the trickiest things to figure out starting with what interface to use and setting it to size in what units? The MulDiv lines are handing the unit conversion from pixels to "device units". Then, via a IOleObject, SetExtent is called which tells the object, in our case our HTMLDocument its size.
Next for you JavaScript developers we're actually going to get into a little familiar territory.
HRESULT LoadHTML(MSHTML::IHTMLDocument2Ptr pDoc) { SAFEARRAY* psa = SafeArrayCreateVector(VT_VARIANT, 0, 1); VARIANT *param; _bstr_t bsData("<!DOCTYPE html><html>...<meta http-equiv=\"X-UA-Compatible\" content=\"IE=11\" />...svg...</html>"); HRESULT hr = SafeArrayAccessData(psa, (LPVOID*)¶m); if(SUCCEEDED(hr)) { param->vt = VT_BSTR; param->bstrVal = bsData; hr = pDoc->write(psa); if(SUCCEEDED(hr)) hr = pDoc->close(); SafeArrayDestroy(psa); } if(SUCCEEDED(hr)) { MSHTML::IHTMLDocument6Ptr pDoc6 = nullptr; if(SUCCEEDED(hr)) hr = pDoc->QueryInterface(IID_IHTMLDocument6, (void**)&pDoc6); if(SUCCEEDED(hr)) { _variant_t mode = pDoc6->documentMode; cout << mode.fltVal << endl; MessagePump([&]() -> bool {return strcmp(pDoc->readyState, "complete") != 0;}); cout << pDoc->readyState << endl; } } return hr; }
Need to do a little manual memory management here around the SafeArrays. But another one of those very extremely important things to note is the X-UA-Compatible meta tag. This'll be familiar and I've got mine set to IE=11 for no good reason beyond it's not IE 7. It turns out, when you embed IE objects like this it will default to IE 7 for rendering. Therefore, to be able get the SVG rendering goodness we're after we need to tell IE to please be a current version of the browser.
The body tag of the HTML is elided but it'll also necessary to set your CSS margins and padding on your body element to be 0px.
Next see those calls to write() and close()? Those are in fact the same write() and close() you know of from JavaScript! They end up being a handy way to create the document we want to render.
From there I've got a check on the current documentMode to verify we're not using IE 7. The documentMode property however, is not implemented on the IHTMLDocument2Ptr I've got currently so I needed to get an IHTMLDocument6Ptr. From there I pump Windows messages to get the document into the complete state. Sleeping here will get you nowhere in the COM Context that we're using.
On to the home stretch.
void RenderImage(MSHTML::IHTMLDocument2Ptr pDoc, int width, int height) { IViewObjectPtr pView = nullptr; if(SUCCEEDED(pDoc->QueryInterface(IID_IViewObject, (void**)&pView))) { auto bmp = new Bitmap(width, height); auto g = Graphics::FromImage(bmp); auto graphicsHDC = g->GetHDC(); RECT rcClient = {0, 0, width, height}; HRESULT hr = pView->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, graphicsHDC, reinterpret_cast<LPRECTL>(&rcClient), NULL, NULL, 0); g->ReleaseHDC(graphicsHDC); if(SUCCEEDED(hr)) { CLSID pngClsid; GetEncoderClsid(L"image/png", &pngClsid); bmp->Save(L"circle.png", &pngClsid, nullptr); } delete g; delete bmp; } }
And we've got our image! What this does is gets an IViewObject which handles rendering to a Device Context Handle, in this case our GDI+ graphics object context. Note, here is why we told COM we wanted to create objects in the current processes' memory space too. Had we not done that, we wouldn't have an image coming. But we did and do so we'll render out with the Save() call.
We could actually render out a whole lot more than just SVG here, I'm talking full webpages with no changes to the code. This has also been only one demonstration of what you can do with IE automation. I'm thinking of revisiting another soon. But for now, a demo project for ya is available here. Enjoy!
Making C# Curry
A colleague of mine told me about currying sometime ago and I've been intrigued by the idea ever since. After playing around a little bit with F# and coming to understand the concept better, I thought I'd take a crack at making it work in C# because it seemed like a fun technical challenge to take on.
To begin, currying is taking a function with multiple arguments like:
string Foo(string str, object obj, int num)
And transforming it so the function call be called as a chain of function where the single parameter to that function correlates to a parameter in the original function call.
Currying is apparently a common thing in functional programming languages, like F# is.
So I got to thinking that this is interesting, but I wanted to be able to use the concept on an arbitrary function in C#. I didn't want to create a bunch of Func<> templates by hand either. I just wanted it to work with any method that takes multiple parameters.
Now, I've chosen to start with focus here and so I didn't bother with instance methods yet. Not going to be hard to add, I just wanted as clean a path to solving the problem at hand: the transformation itself.
First, I started to think about the individual method signatures. In the case of Foo, they would be:
str = Func<String, Func<Object, Func<Int32, String>>> obj = Func<Object, Func<Int32, String>> num = Func<Int32, String>
I think you can see why I didn't want to get bogged down in Func<>s 🙂
What I needed to do then, was generate these types, define a way to capture the arguments passed in by the caller, and generate a function. The class I've come up with thus far to do that is as follows:
public static class Curry { //Makes the return types for Func<,[THIS ONE!!!]> private static Type[] ReturnTypes(Type returnType, ParameterInfo[] parameterInfo) { var result = new Stack<Type>(); result.Push(returnType); foreach (var param in parameterInfo.Skip(1).Reverse()) result.Push(typeof(Func<,>).MakeGenericType(param.ParameterType, result.Peek())); return result.ToArray(); } private static LambdaExpression Make(MethodInfo methodInfo) { var parameters = methodInfo.GetParameters(); //Prepare the pieces for the Func<>s var returnTypes = ReturnTypes(methodInfo.ReturnType, parameters); var expressions = new ParameterExpression[parameters.Length]; //Create the expression parameters str, obj, num for (int i = 0; i < expressions.Length; i++) expressions[i] = Expression.Parameter(parameters[i].ParameterType, parameters[i].Name); //Create the call Program.Foo(str, obj, num) Expression lastOperation = Expression.Call(methodInfo, expressions); //Build Curried Method Call, note I'm building back from //the method invocation. //str => obj => num => Program.Foo(str, obj, num) for (int i = parameters.Length - 1; i >= 0; i--) { var genericType = typeof(Func<,>) .MakeGenericType(parameters[i].ParameterType, returnTypes[i]); lastOperation = Expression.Lambda(genericType, lastOperation, expressions[i]); } return (LambdaExpression)lastOperation; } }
It takes a MethodInfo object so the user can choose whatever (currently static) method they want to use. Will need to be static and public right now. So what's happening here is Make() gets all the parameters from the MethodInfo passed in then creates the Func<>s in the way discussed above. In addition, it creates the parameter name expressions that will allow the final Lambda to capture and use the parameter values the user passes in. Note, the parameter names equal the supplied MethodInfo's for clarity. Then finally, starting from the Method call, it builds out the curried method structure before returning a lambda.
The first way that I came up to use this with was via a dynamic method call as such.
public static dynamic Dynamic(MethodInfo methodInfo) { return Make(methodInfo).Compile(); }
Where the method is defined in my Curry static class and which I was then able to consume in my main program like so.
public class Program { public static string Foo(string str, object obj, int num) { return string.Concat(str, obj, num); } static void Main(string[] args) { var methodInfo = typeof(Program).GetMethod("Foo", BindingFlags.Static | BindingFlags.Public); dynamic fn = Curry.Dynamic(methodInfo); //Call made in pretty much the same way. //Prints string[System.Object]42 var result = fn("string")(new object())(42); Console.WriteLine(result); //Reuse parameters //prints Hello, Worldx1 //prints Hello, Worldx2 //... //prints Hello, Worldx10 var partial = fn("Hello, ")("World x"); for (int i = 1; i <= 10; i++) Console.WriteLine(partial(i)); Console.ReadKey(); } }
Which achieved my goals, but I'm not a fan of dynamic. I'm in a strongly typed language here so I'd like to take advantage of that. The best solution I've come up with to achieve that goal would be to build some kind of utility that integrates into Visual Studio to build the Curried Calls I want. Building the plugin is outside the scope of this document, but, I can render the C#:
public static string CSharp(MethodInfo methodInfo, string name) { var lambda = Make(methodInfo); var builder = new StringBuilder(); builder.AppendFormat("public static class {0}\r\n", name); builder.Append("{\r\n"); //PrettyPrint is an extension method to render the type in C# builder.AppendFormat("\tpublic static {0} Exec()\r\n", lambda.Type.PrettyPrint()); builder.Append("\t{\r\n"); //Actually, the lamda.ToString() needs to be fixed in order to deal with //namespaces properly but I left that out as it's not germane to the //theory I'm trying to work with. builder.AppendFormat("\t\treturn {0};\r\n", lambda.ToString()); builder.Append("\t}\r\n"); builder.Append("}\r\n"); return builder.ToString(); }
Which I put in my Curry static class and will generate a static class like this for me…
public static class FooTarget { public static Func<String, Func<Object, Func<Int32, String>>> Exec() { return str => obj => num => Program.Foo(str, obj, num); } }
…that I can use exactly the same way as the dynamic calls above only now with strongly typed goodness which means intellisense.
I've gotten the ball rolling here on what I think is a pretty good start to enable currying in C#.
You can get a demo project here.
Visibility of System Status
The following a is a pretend re-enactment of how the following webpage, I think, came to exist as is.
"Users are asking for the ability to have different addresses on their account. One to actually send credit cards to, one for statements and one for general correspondence. We have to enable that facility." says Boss Man.
"Ok, we'll put three address fields on the contact information section part of the webpage." says Software Engineer.
"No, not enough people are asking for it that I think we should show this to everyone. We'll only put one box up and give users a link to another page in order to manage the all three." says Boss Man. "The contact information page will continue to show just one address. Say, the one for statements."
"But what if there is a mistake? What if the addresses get incorrectly updated by a bug or human error?" Software Engineer protests, "How will the users find out?"
"They'll be able to tell when they click the link. Like I said, all three addresses will appear then." Boss Man says. "We'll also change the title of the surrounding box from 'Mailing Address' to 'Statement Mailing Address' to let them know that there is more than one address. They'll be fine!"
"But!" Software Engineer continues to protest.
"They'll be fine." Boss Man reassures.
And scene!
That, is what I thought of when I realized why my new credit card has been MIA for the last month. I didn't get mad at the company, I didn't get mad at the very, very nice and sweet customer service representative I ended up talking to. I didn't even get mad at Boss Man. I felt for the Software Engineer that had to implement the website that let me go unawares that I had incorrect addresses in the system. Had I not been told an earlier attempt to send me my card had been thwarted by an "address unknown" error on the part of the Post Office, I don't know that I would have noticed the link indicating that there were other address possibilities. I never entered multiple addresses before. I made just one update when I moved last. However, after I made said update, I had no visibility regarding the current system status and the newly mismatched addresses. Thus, no new card for me has arrived thus far.
Scenarios like these are why I care so very much about usability. Beyond Jakob Nielsen's usability heuristics, I'm mindful of the "Pit of Success" as Jeff Atwood Defines it:
The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find victory through many trials and surprises, we want our customers to simply fall into winning practices by using our platform and frameworks. To the extent that we make it easy to get into trouble we fail.
Only modified to apply to usability, instead of development.
I used to be the type of designer that thought my interfaces were "Da Bomb Yo!" and users would just get them. If they didn't that wasn't my problem, my UI was great! Then I watched someone very close to me, who I take to be computer savvy, struggle with a UI I designed. That was the moment my ego regarding design got put out to pasture and I'm better for it. Now I listen to user feedback as valuable input into the design process. 🙂


text:
At Marineland Dental Care (in Kennewick, WA), we are big believers in second chances, especially when it comes to your teeth that have been lost due to injury, tooth decay, or disease (usually advanced periodontal disease, also known as periodontitis). We offer advanced dental implants to our patients who would like a "second chance" to take better care of their smiles.
Dental implants are incredibly effective: they look just like your natural teeth, and there is no compromise in performance. However, there are certain limitations on what dental implants can do, and who can receive them. Dental implants are ideal for replacing one or a few teeth, but what if you have a relatively large number of teeth that have been lost? Certainly you would like to take advantage of dental implants, but because you're missing so many teeth, replacing them all with individual implants would be impractical.
Just because you're missing multiple teeth doesn't mean you have to live with it, nor should you have to take a lesser option if you're in good enough oral and general health to receive dental implants. That's why in addition to standard dental implants, we offer implant-supported dentures.
Aren't Dentures Less Effective Than Dental Implants?
It's true that conventional dentures (dentures which are not supported by dental implants) are less effective than dental implants in terms of performance (offering only 10% to 20% of your normal bite strength, which can change your life drastically), more noticeable and obvious to others, as well as requiring regular replacement when they become worn, or lose their fit. Loss of fit will happen to all dentures, and it can happen for a number of reasons having nothing to do with the dentures themselves. In fact, conventional dentures often lose their fit because the mouth of the person wearing them has undergone the changes in its shape. Poorly fitting conventional dentures are inconvenient and can lead to embarrassment when they slip out, or create an audible "clicking" sound when you move your mouth to speak. They can also be dangerous: all that moving and shifting of the dentures against your oral tissues and remaining teeth creates mouth sores that can easily be infected by bacteria, causing serious diseases.
So How Are Implant dentures Different?
Implant dentures, as the name implies, combines the best parts of dental implants with the best parts of dentures. Dentures are an ideal way to replace many teeth at the same time; instead of depending on your oral tissues and certain teeth to stay in place (through fit), four small mini dental implants support the entire denture.
Dental implants get their edge because they are embedded in your jawbone surgically, under the gums, and held fast by the bone; as part of the normal healing process, dental implants actually improve your jaw's bone density and actually become more effective due to a process called osseointegration. Literally meaning "coming together with bone", osseointegration causes your bone and your implant to actually fuse together, making them virtually indistinct from one another. For all intents and purposes, your implant is a part of you (as opposed to a dental bridge or conventional dentures, which are only on you).
Implant dentures avoid the embarrassing problems that conventional dentures cause, and the potential health risks they pose.
Can Anyone Get Dental Supported Implants?
Like standard dental implants, getting implant dentures is a surgical procedure. You must be able to tolerate general anesthesia, be an adult, and it is helpful if you are not a smoker (and if you are, you should quit; if it doesn't prevent you from getting your implants, smoking will impair the healing process that is critical to the success of any dental implant). You must also be in good general health, and your oral health must be in good condition. This means you must have enough bone in your jaw to support the implants (although they are much smaller than standard-sized implants, you still must have sufficient bone density to ensure that are not likely to fail).
Are There Limitations To Implant dentures?
Implant dentures are much more effective at replacing your missing natural teeth in terms of your appearance and your ability to chew and speak normally. However, dentures can still be damaged if you eat foods that are too hard or too sticky.
Implant dentures also require the same maintenance as conventional dentures; they must be cleaned daily to eliminate harmful bacteria.
However, implant dentures are far superior to conventional dentures.
Missing Lots of Teeth and Not Sure What to Do?
Give us a call! Your dentist will assess the condition of your teeth to determine if you are a suitable candidate for dental implants, or if necessary (or possible), help you to understand the reparative procedures you need to have before your implants are placed.
Dial 509-591-0515 now to reach Marineland Dental Care's front office to make an appointment, or book your visit now by clicking here to reach our online appointment form.

subset: commoncrawl


text:
« September 2006 | Main | November 2006 »
October 6, 2006
Review: Roberto Magris Europlane - Il Bello del Jazz
Roberto recently sent me his newest Europlane disc, Il Bello del Jazz. I've been listening to it lot lately. You'll be sure to hear it in heavy rotation soon on the Classic Jazz Corner. This CD is another great example of the kind of high quality jazz being recorded in, and birthed from, Italy. Roberto hails from Trieste (Google Maps), which is in northeastern Italy just at the border to Slovenia, at the northern end of the Adriatic Sea.
Magris's playing is superb on this recording. He's got a great ear for both melody and harmony. He proves his agility as a band leader with his ability to support the soloists so well. Herb Geller's tone is spot-on throughout the disc, and the production sounds fantastic. Not many new CDs sound so well. It's clean but not overproduced or sterile-sounding, that phenomenon oh so common to contemporary recordings. Perhaps it's the Italian wine influence that makes the production sound so great.
Roberto contributes three originals: "No Sadness", "Il Bello del Jazz", and "Parker's Pen." They're all up-tempo and give a lot of room for soloists to improvise. Jurkovich's guitar work on the opener is top-notch, and Engel's bass solo on "Il Bello del Jazz" is expressive and forceful. The band really smokes on "Here I'll Stay." The CD also contains moments of reflection on the slower, meandering tracks "Some Other Spring", "A New Town is a Blue Town", and "Pretty Woman", allowing Magris and Geller to showcase their attention to melody and grace.
Track listing:
1. No Sadness
2. Stray Form
3. Some Other Spring
4. Key Largo
5. A New town Is A Blue Town
6. Here I'll Stay
7. Ah Moore
8. Il Bello Del Jazz
9. Pretty Woman
10. Parker's Pen
11. Deception
Roberto Magris (p)
Herb Geller (as)
Darko Jurkovic (g)
Rudi Engel (b)
Gabriele Centis (d)
Album ratings (in blue notes):
Production: 4.5(5)
Composition: 4(5)
Improvisation: 4(5)
Groove Factor: 4.5(5)
Overall Rating: 4.25(5)
If you live near/in Los Angeles, be sure to check him out out live:
Catalina Bar and Gril (Hollywood) October 11 and 12
The Jazz Bakery (Culver City) October 16
:: Happy sounds ::
Posted by peder horner at 11:02 AM | Comments (0) | TrackBack
copyright :: peder e. horner, m.d. 2000-2007
October 4, 2006
Review: Wes Montgomery - Full House
I just purchased this CD a few weeks ago and have finally had some time to really give it a good listen. As always, Wes's guitar and method are clean and straight-forward, which is something I have come to expect from the master.
Overall, there are 9 tracks. Tracks as follows:
1. Full House
2. I've Grown Accustomed To Her Face
3. Blue 'N' Boogie
4. Cariba
5. Come Rain Or Come Shine (Take 1)
6. Come Rain Or Come Shine (Take 2)
7. S.O.S. (Take 3)
8. S.O.S. (Take 2)
9. Born To Be Blue
This 1962 lineup is incredible, as this live album pairs Montgomery with tenor Johnny Griffin and the Wynton Kelly Trio (Wynton on piano, Jimmy Cobb on drums, and Paul Chambers on the bass). The players are on fire on this one, and their improvisational chemistry really shines. This is one live Montgomery album every jazz enthusiast should own.
Happy sounds,
Posted by pederhorner at 10:11 AM | Comments (0) | TrackBack
copyright :: peder e. horner, m.d. 2000-2007
October 3, 2006
New Site Layout : Blog Format
After years of procrastinating, I've finally updated the website to allow me to post play list changes and CD reviews much easier. The overall format is about the same, although I had to make many modifications to the guts of the cascading style sheet and master index to allow for Movable Type to do its magic.
Now comes migrating some of the older CD reviews to this new format. This will be moderately painful, but it needs to be done.
Now, on to some more great music.
Happy sounds...
Posted by pederhorner at 8:31 PM | Comments (0) | TrackBack
copyright :: peder e. horner, m.d. 2000-2007


text:
The Post-War Origins of School Desegregation and Activism in Boston, 1936-1953
Zebulon Miletsky, Stony Brook University
"It Doth Not Appear What She Will Be": Ruth Batson and the Black Education Movement in Boston, 1960 - 1975
Lyda Peters, Cambridge College
Whose Community? Whose Schools? African Americans' Quest for Educational Self-Determination in Boston, Massachusetts, 1966-1972
Tess Bundy, University of Maryland College Park


text:
All the single ladies (and men), put your hands up…
Posted: February 12, 2015
Scala Playhouse is urging singletons everywhere to embrace their status with the release of two new gender-specific gift boxes from ToyJoy Just For You. The male and female Yeah I'm Single boxes (in blue and pink packaging, respectively) have been launched following Satisfied Staying Single Day (Feb 11th) and just in time for Singles Awareness Day (Feb 15th) and, in an apparent dig at UK chain B&Q, which has been in the news this week, Scala Playhouse said: "Doing it yourself has never been so much fun!"
The Yeah I'm Single box for her includes a vibrating egg, a stimulator, rose petals, a quality thong, a water-based lubricant and a powerful vibrator. The Yeah I'm Single box for him contains a masturbator, a vibrating cock ring, stretchy cock rings, an erotic DVD, condoms, a water-based lubricant and a prostate massager.
Purchasers do not, of course, have to be single to enjoy the boxes' contents. For more information visit www.scalaplayhouse.com


text:
One4Another - update
Mar 02, 2018
Glen Pascoe
One4Another - update
Glen Pascoe will give us an update on their continuing work with these children.
One4Another's primary focus is providing life-changing surgeries for children in Uganda who would never be able to afford it without outside help. One4Another provides them with a brighter, happier future!


text:
Planguru is a free UI Kit for Sketch and Photoshop that you can use to get started with an event or planning app.
Planguru includes 18 beautifully designed screens and a bunch of components covering many necessities for an app of that kind: a calendar for scheduling events, a group chat, notification system and more.
Nice typography, cool colour palette and a great use of white space… It's definitely worth a try!
Planguru: Free UI kit for event and planning apps Free PSD File Download Reviewed by Med Kada on 15:03 Rating:


text:
Carey 31st in Tunisia; back to sixth in Alps Tour money list
Teenager David Carey slipped to sixth in the Alps Tour money list after a closing 73 forced him to settle for a share of 31st in the Tunisian Golf Open.
The 19-year old picked up €812 at El Kantaoui Golf Club where England's Matt Wallace shot a 70 to win the €70,000 event by two strokes from Italy's Enrico Di Nitto (67) on 12 under par.
Wallace pocketed a cheque for €10,150 and now leads the Order of Merit with €19,766 from just four starts.
Carey is sixth with €5,076 from four events with his best performance a share of second place in the Dreamland Pyramids Open in February.
Brian Keogh


text:
Currency Displayed in
The Cruiser's Crutch is Slope compensating angle gauge calibrated 0 to 90 degrees slope. The Cruiser's Crutch gives correct basal area readings for English BAF factors of 10, 20, 30 and 40. The Cruiser's Crutch is available in a Metric model for Metric BAF 2, 3, 4, 5 and 6.
The Cruiser's Crutch is made of Lexan and includes a 26" nickel chain with 4 brass balls (one for each BAF). To use the Cruiser's Crutch, line up the tree to be measured with the appropriate slope percentage line on the gauge. The tree can be counted if it is wider at DBH (Diameter at Breast Height) than the line you are sighting across on the angle gauge.
This product hasn't received any reviews yet. Be the first to review this product!
All prices are in USD.


text:
Phone: (407).261.0400
Available Properties
Real Estate Strategies, Inc. uses the CoStar Showcase service to feature the properties we offer for sale. CoStar is a commercial real estate listing service and research firm that averages over 500,000 visitors each month on its site. Click the link below to access and download information about properties, including flyers, aerials, photos, maps and demographics.
Looking for Property Acquisitions?
Real Estate Strategies, Inc. will represent buyers, on a retained basis, to acquire properties anywhere in the United States. Whether you are an investor or user, we will work with you to analyze your needs and identify properties that fit your objectives. The advantage of retained buyer representation is that you have an expert representative looking after your interests every step of the way, from researching markets to financial analysis to handling contract negotiations and post-close concerns.


text:
With CORT gently used furniture and furniture rental, you're guaranteed to find high-quality furniture pieces for any home or office. Visit your nearest CORT location for savings today!
Find furniture that fits your needs from CORT. Whether you're shopping for furniture for your home or customizeable office furniture, CORT offers quality furniture solutions near 64089. With locations across the nation, you're sure to find a CORT location with furniture rental or gently used furniture nearby. Find your nearest location below.
When you rent or purchase gently used pieces, you're doing more than just furnishing your space. Whether you're interested in all new furniture, work stations for the office, or even home staging furnishings, CORT has a solution for your aesthetic. Plus, with the CORT Personal Service Guarantee, you know that you're getting the highest-quality furniture and customer service. It's what makes CORT so unique. Check out our furniture services near 64089 at a CORT location.


text:
Are you ready to see the List's of all Event management companies in Port Harcourt? Just keep calm as I show you the top 5 event planners in Garden City (Port Harcourt).
Let's help you plan your events, so you won't experience any challenges. You can call, SMS or WhatsApp 08060497906 for guidance on how to plan your events in Port Harcourt city.
See Also: Event centres in Port Harcourt, Rivers State – Here is all the best places to hold your events
So now, let's move a head and show you the top event management companies in Port Harcourt, Rivers State.
Please Note: You will have to contact any of the under listed companies to find out more about their event management services.
Event management is not as easy as you think, there are so many things involved. Managing an event in Port Harcourt isn't same as managing events in other parts of Nigeria. Port Harcourt is mainly for the middle and high class people, so you must have the requires funding if you are planing of hosting your proposed events in Port Harcourt.
Event management companies in Port Harcourt you can Trust
Dezua Events Limited
Virtues Events Consults Limited
Sarah Springs
Bouncy Blossoms
Ocean Vitec International Limited
Sophylet ushering team
Redkarpet Multi Link Limited
Excellent Event Makers
Elizabeth Alfred
Top Five Event Decorators In Port Harcourt City
Here are the top 5 event managers you can hire to work for you in Port Harcourt. We've listed them, according to popularity.
However, you have to have it at the back of your mind that these five most skillful event management companies in Port Harcourt charges so much.
Supreme Event managers (08060497906)
The Atrium Event Centre
Sarah Springs
Redkarpet Multi Link Limited
Ocean Vitec International Limited
5 reasons why you need the help of an event manager
You will be needing the help if an event manager if you are planing of hosting any of the following events:
Weddings (Traditional and White marriage)
Club meetings and many more.


text:
Imagine this. You are driving on the road. It's late at night, the only source of lights comes from dimmed street lights and ocassional vehicles that passes you. You have a destination in mind, you know that you want to get to that city before dawn. But. The thing is you have no idea how to get there. You don't have a map, your phone is out of battery so you can't access Google. You don't even have a GPS built-in system in your old car. With every trurn that you take, you feel even more lost than before.
You question yourself, is this the right way? Is this road going to lead me to my destination? Am I even heading towards the right direction? You may panic a little in your head, your heart may race as adrenaline rushes through your system.
The question is, how are you going to get to your destination before dawn, when you don't have the slightest idea on how to get there? Now, at this point of time, there is no return. The only way is to plunge forward into the unknown.
So what do you do? What can you do?
You evaluate your options. You calm your mind and weigh the available options in your head. Are these options feasible? Would you be able to achieve your target in time with these options?
I'm turning 25 tomorrow. Today, I'm sitting in a cafe evaluating my options. I've chosen not to follow societal norms because I've experienced first-hand how unmotivating and soul-sucking it can be when I worked for a 9-5 job that I do not feel passionate about. I have to admit that it is scary. In fact, it is absolutely terrifying to know that I'll not be receiving a paycheck next month.
My emotional mind is scared to bits. But I'll utilise this fear and manipulate it to drive me further into the unknown.
* * *
What have I achieved in the past year?
1. I made the decision to come back to Malaysia because I see no future in UK and because Malaysia is my home. The grass is greener where you water it.
2. I backpacked in Europe for a month. Priceless experience.
3. Embraced my nerdy side, I started learning a bunch of tech-related languages, like Ruby on Codecademy (still in progress), joined RailsGirlsKL, Java on FreeCodeCamp (still in progress).
4. Recently decided to leave my 9-5 job. Some may not consider this as an achievement, but hey, I decided that it is.
* * *
Before my 26th birthday, I want to have achieved these:
1. Acquire developer skills.
2. Commit my time to something that inspires and motivates me, something that pushes my learning curve as steep as possible.
3. Build or create something. Be it creative-related, tech-related or healthcare-related.
This is a promise to myself. No matter how dark it gets, or how much people around me tell me that it is a mistake to leave a secure job, I no longer want to work just for the sake of survival/paychecks. The biggest satisfation I can get is when I know that I have made a difference in someone else's lives. This will be the guiding light to my destination.


text: Pioneer Bank cares deeply about the people in the communities in which we are based. One of those communities is El Paso. Our employee, Alejandra Jaquez from the Trawood branch recently donated and volunteered at a school supply drive for under-privileged children at Cedar Grove Elementary. We are extremely proud of Alejandra and her love for her community!


text:
Can you recreate the story of your community and your business from archive images and films? Ask people to bring you images of local events, fetes, street parties, parades, Christmas lunches, open days etc., and scan them to create a simple slideshow of images about your community that will engage and fascinate.
Short film footage can be used to create mini-cinemas that can seat one to 50 people depending on your space and equipment. You can create a cinema in a box for up to 2 people featuring film footage of the community using nothing more than a laptop and a cardboard box!


text:
Contact Us
Telephone: 0117 980 0370
Email: email@example.com
Postal address: 35 Old Market Street, Old Market, Bristol, BS2 0EZ
Disabled access: unfortunately we are not wheelchair accessible
Our office admin staff are available 9.30 – 16.30 Monday – Thursday. Friday the admin office is closed but other projects are open for appointments only.
Services can be contacted directly by phone or email
There is an Advocacy Drop In at Bristol Mind on Tuesdays 11am to 2 pm, no appointment is necessary. All other community advocacy is done by appointments contact Claire Barnard on Tel: 0117 980 0376.


text:
Well, it's been a month. Or close to it since I started my experiment with Proferrin.
Due to some other issues that I was fairly certain were unrelated to my WLS, I decided to bite the bullet, go ahead and get my yearly lab draw out of the way. I mean, last year I had hit my deductible by the first week in February when I had an outpatient surgery so I wanted to see if I could at least come close to cleaning out the FSA with my lab work and some blood work the kids are bound to have next week. It's a morbid little game I play that is somewhat depressing, but reminds me that I have it so much better of than many others out there.
In any case, I needed to have a draw done to rule out some other issues. So I figured I'd update the status of the Proferrin experiment.
Unfortunately, not all of the values are identical, and the labs were not the same labs that did the testing — but I think we can get enough out of this to draw a few conclusions. If not, you're going to nod sagely, pretend that we could because it's 10:20pm, the youngest is refusing to go to bed, it's been a long day, and that's that. Kay? That's what I thought.
Ranges are for the lab that did the draw. Remember, different labs, thus different ranges. Hey, I wish there were standardized ranges, too.
HGB – 12.6 (12.0 – 18.0 g/dl)
Ferritin – 11.1 (11-137 ng/ml)
Iron – 41 (37 – 170 ug/dl)
TIBC – 310 (265 – 497 ug/dl)
Iron Saturation – 13% (20-55%)
HGB – 13.13 (12.0 – 15.0 g/dl)
Ferritin – 16.3 (6 – 81 ng/ml premenopausal *which seems odd cause post is 14-186….?*)
Iron – 45 (28 – 182 ug/ml)
UIBC – 326 (130 – 375 ug/dl)
TIBC – 371 (180 – 545 ug/dl)
Iron Sat – Not measured
So what happened?
Well, in a month, my ferritin shot up 5 points and my serum iron went up 4. Even the TIBC went up quite a bit, which would make me think that iron saturation would have if it had been measured by the second lab (which was asked for, by the way.. along with some other things that weren't reported.. I'm hoping they were just delayed)
Now, all of this is assuming that the labs are accurate across the board. For the sake of argument — THEY ARE. I mean, there's no way to say they are or aren't and we have to trust something in this world, so let's let this be one of those things that we trust. That the labs are somewhat on an even keel in the measurement of things.
So for now, I am going to continue the Proferrin as planned — 3x a day. It seems to be working.. and will retest. I see my GI doc, who is convinced he is the one following my iron in February and I plan to get a lab slip from him to test all of this at the end of the experiment. So we'll get a better idea as to what the true answer is.
But so far? Yeah, it's working for me. And I have to admit, the whole not having to wait 2 hours around calcium thing is pretty nice.
Bifera is the only over-the-counter (OTC) iron supplement to offer both heme iron (protein-based iron) and non-heme iron (plant-based iron). Unlike other iron supplements, Bifera provides two types of iron in one small, easy-to-swallow pill for maximum absorption with virtually no GI side effects.
For years, the popular prescription prenatal supplement PreferaOB has provided the nutritional community with an oral iron combination that offers both heme and non-heme iron in one small pill with virtually no side effects. Now, for the first time, this innovation in an iron supplement will be available over-the-counter in the same form, without the prenatal folic acid, in an iron supplement known as Bifera.
I've mentioned that I'm doing an experiment with Proferrin – a purely heme-iron based product to help boost my crappy iron scores. While in Walgreens, and now CVS (complete with iPhone at hand this time, and the presence of mind to use it), I found this — a Proferrin / Poly iron blend. And it's relatively cheap compared to the Proferrin. Admittedly it's not as strong , but it's readily available for those who aren't wanting to purchase online or aren't willing to take the plunge with something so completely "different" in terms of iron.
Bifera's website has more info, plenty of propaganda information, and ooh! A $2 coupon.
Some of the things discussed in our post-op health can be a bit confusing. Iron is one of those things, IMHO. So how about a session just on iron?
What is iron?
Iron is a mineral that can be found in plants, animals, soil, air, water, meteorites, and rocks, including on the surface of the moon. Here on earth, plants absorb iron through their root systems; animals eat these plants. Humans consume these plants and animals. Many think iron is a heavy metal, which it is not. Iron is an essential micronutrient. Essential used in this way means that the body does not produce the nutrient; micronutrient means that the body only requires tiny amounts to function.
Types of iron?
There are two forms of iron – heme and nonheme. Nonheme iron primarily comes from plants and heme iron comes primarily from meat.
Nonheme iron represents the majority of iron humans consume in their diets and is the type of iron in most supplements. Nonheme iron is inorganic and is found in grains such as rice, wheat and oats. It's also found in nuts, fruits, vegetables, most iron pills, fortificants, or contaminant iron such as from water, soil or cooking utensils.
Meat, especially red meat is the best source of heme iron. Heme iron is easily absorbed by the body and the best source of iron for people who are iron deficient.
Iron terminology
- Transferrin – a protein that is the major transporter of iron and ideally is saturated with 25-35% iron; when working properly, transferrin binds to iron and transports it to all tissues, vital organs, and bone marrow so that normal metabolism, DNA synthesis, and red blood cell production can take place
- Ferritin - a protein that acts like a large holding vessel; contains iron that we don't presently need
- Hemaglobin (hgb) – a protein that transports oxygen to the body
- Hematocrit (hct) – proportion of blood volume that is occupied by red blood cells
So someone who is anemic can still have normal hemaglobin and hematicrit numbers because their ferritin is being depleted in order to maintain those counts. But if the ferritin is in the toilet and no relief comes, the hgb and hct will eventually fall as well.
Types of non-heme supplemental iron:
- Ferric salts: These include ferrous sulfate, gluconate, and fumarate. Typically, the way these compounds are made is that pure iron is dissolved in sulfuric or hydrochloric acid. Once dissolved, a counter ion is added and the pH is adjusted to make neutral once again. When this happens, the iron binds to the counter-ion and drops out of the liquid solution. The slurry is then dehydrated and the dry stuff that is left is the iron salt. Ferric salts, especially ferrous sulfate, are not known to be easy on the digestive tract. Once ingested, it is imperative that the stomach contains acid to dissolve the iron salt. If a person is taking antacids or H2 blockers, their stomach will be "achlorhydric" – their stomach won't contain acid and the iron salt will not dissolve.
- Carbonyl iron is often used by physicians because it is less toxic to accidental overdose.
- Polysaccharide iron is a newer form that is coming up in popularity, absorbs better than the ferric salts, but is more expensive than the standard supplementation routes.
I discuss my current experiment with the heme iron, Proferrin, here. Information about it from the Iron Disorders Institute:
About Proferrin(tm): Performance studies indicate that iron absorption rates are between 15% and 20% withoute erythropoietin (EPO) therapy and as high as 30% with EPO therapy even in patients with high serum ferritin values (>600 ng/ml). In one study, the change in serum iron from Proferrin(tm) was nearly 23 times greater than from an identical dose of ferrous fumarate. Also, study participants were able to tolerate up to 60 mgs per dose on an empty stomach with fewer gastrointestinal side effects; a common complaint from patients taking traditional oral iron preparations. An additional benefit of heme iron supplementation is that patients can take it with their meals, unlike ionic iron preparations, which must be taken on an empty stomach between meals.
Info courtesy of the Iron Disorders Institute
I want it plainly made clear that I will do things for my peeps — those of you in the WLS family that I wouldn't do for many others. Got it? Good. Lavish praise, free samples, protein to sample, My Little Ponies for the pre-schooler to dress up, balls for the toddler to throw at my head while I blog are all welcome to show your happiness at my willingness to be your guinea pig. Just call me Winnie.
So last night, during a not-so-routine check with a doctor, I had a blood draw. This was after I dazzled him with my vitamin knowledge, and sharing my recent harrowing experience with blood draws of my children and not really wanting to drag them along. Realizing that I probably knew more than he did, he walked to the lab and said "draw whatever she wants" — and she did after consulting her book as some of it wasn't her norm.
So what does all of this mean for you? I'm GETTING THERE. It's been a LONG day at work. I'm slow.
I have issues with iron. My hematacrit (hct) and hemaglobin (hgb) are always fine (which are the two main things that are determining factors for "anemia") but my ferritin is in the single digits. I have been taking 600mgs of elemental chemical iron, in three forms — polysaccharide, carbonyl, and fumarate. And before someone does the smartass "But Andrea, are you taking it with C? Away from calcium? Away from tannins? Away from legumes and whole grains? With vitamin A? Is your B-12 good? What about copper and zinc — that chick on OH says you need those, too!" Remember to whom you are asking. OF COURSE I HAVE. DUH. For some reason, I just don't absorb the chemical iron. My ferritin has stayed at a 7 for over a year now.
So last night, I got a full iron panel pulled. I have the hct and hgb levels now, but am waiting for the rest in the mail in about a week. Hgb is 12.6 (12.0 – 18.0) and hct is 39.7 (37-51). Not horrible, high enough to donate blood.
I've heard of Proferrin, which is a heme iron — something completely different.
Increased Absorption*
Absorbing iron orally is difficult and Proferrin helps solve this problem. A study performed at the University of Colorado compared taking 20 mg. of elemental iron as heme iron polypeptide to taking 20 mg. of ionic iron (ferrous fumarate) with a standard meal. The study demonstrated that HIP increased serum iron levels 23 times greater than ionic iron on a milligram-per-milligram basis.1
Contains Only Iron from Natural Sources*
The HIP in Proferrin is extracted from hemoglobin, a naturally occurring iron source found in red meat and poultry.2 Proferrin does not contain common allergens, such as milk or wheat products, gluten, or significant amounts of oils or fats. If you have specific allergies, please contact your physician or Colorado Biolabs for more information.
Doesn't Compete with Other Nutrients*
The HIP found in Proferrin is absorbed differently than traditional irons. Unlike other irons, Proferrin does not compete with other nutrients.3,4
Fewer Dosing Restrictions*
HIP does not appear to be affected by calcium, coffee, or other foods, and can be taken with meals.1 It may even replace intravenous irons.5
Fewer Side Effects*
Traditional iron supplements are made with ionic irons, which can cause side effects such as constipation, cramping, gas and other forms of digestive system problems.6,7,8 Proferrin causes less gas9 and is unlikely to cause common iron-related digestive system side effects. This is due to Proferrin's heme iron polypeptide being absorbed differently than that of non-heme iron.
I thought — well, why not? So here's the experiment. I'm going to take 3 a day (which is per the bottle — 1-3 per day) for 90 days and have another draw and see if there is any change. I won't take any chemical iron between now and then just to see what this can do. I've heard it's wonderful, so I'm willing to give it a shot.
It's quite expensive — comes out around $50/ per month — so if chemical iron is working for you, then stay with it. But maybe this can eventually keep a needle out of my arm?
Taking bets — what does anyone think? Hype or not?


text:
A full-service advertising agency, Adcetera handles everything from strategy to concepting, billboards to websites. Our comprehensive capabilities mean that if something else comes up along the way, we can probably do that, too.
Strategy, Campaign Development, Branding, Presentation Development, Sell-in, Storytelling, Advertising, Print, Web, Motion, Video, Social
Logo, Tagline Development, Branding, Print, Sales Collateral, Advertising, Motion, Trade Show


text:
North Clear Creek Falls
This is North Clear Creek Falls.
It is the most photographed waterfall in Colorado - for two reasons. First of all, look at it. It's an extremely powerful waterfall. Secondly, it's right off of a major highway in south central Colorado. No hike, no remote location. Anyone can get out of their car and witness the roar of the falls.
The conditions this night seemed ripe for an extremely vibrant post-sunset blue hour but it never materialized. Still, soft blues and a hint of lavender aren't a bad consolation prize.
North Clear Creek FallsColoradoWaterfallSunsetMountainsLandscape Photography
From Mountains and Waterfalls
Log In:


text:
The project
The NADIR project, an integrating activity, organised around four types of activities: networking activities, trans-national access and service activities, joint research activities and one project management work package.
By browsing our site you accept the installation and use cookies on your computer. Know more
Home page
Subscribe to news
Direct accesses
Home page The project