Tag: Programming

  • Extracting Dominant Color: RGB Averaging Doesn’t Work

    Extracting Dominant Color: RGB Averaging Doesn’t Work

    This makes sense – two colors can have the same R values, but wildly different G and B values. The result of averaging them will bear no relation to the originals.

    However just to prove it, it was very easy to tweak my code to average the RGB values instead of counting the hues. The result for the same four photos is as follows. If the color is really prevalent, the result isn’t so different, but in the case where it isn’t, this way doesn’t really work at all.

    Source Code

    package ui;
    
    import processing.core.PApplet;
    import processing.core.PImage;
    
    @SuppressWarnings("serial")
    public class RGBImageViewApplet extends PApplet {
    
    	PImage img;
    	float r;
    	float g;
    	float b;
    
    	public void setup() {
    		size(640,600);
    		background(0);
    		img = loadImage("" /* Your image here */);
    		colorMode(RGB);
    		extractColorFromImage();
    	}
    
    	public void draw() {
    		image(img, 0, 0, 640, 480);
    		fill(r, g, b);
    		rect(0, 480, 640, 120);
    	}
    
    	private void extractColorFromImage() {
    		img.loadPixels();
    		int numberOfPixels = img.pixels.length;
    		float totalRed = 0f;
    		float totalGreen = 0f;
    		float totalBlue = 0f;
    
    		for (int i = 0; i < numberOfPixels; i++) {
    			int pixel = img.pixels[i];
    			totalRed += red(pixel);
    			totalGreen += green(pixel);
    			totalBlue += blue(pixel);
    		}
    
    		// Set the vars for displaying the color.
    		r = totalRed / numberOfPixels;
    		g = totalGreen / numberOfPixels;
    		b = totalBlue / numberOfPixels;	
    	}
    }
  • Extracting the Dominant Color from an Image in Processing

    Extracting the Dominant Color from an Image in Processing

    I’ve had an idea in mind for a while now, that requires extracting the dominant color from an image. I had no idea how to do this, and worried it would be really hard.

    The first thing was extracting the pixels from the image for processing, this was super easy thanks to this handy image processing tutorial.

    Some Googling took me to Stack Overflow (always a great starting point) and I discovered the concept of color “bins” – this makes sense, I’d imagine it’s quite possible that all pixels in an image are subtly different, and actually you want to group them in some way. This led me to find out about calculating distances between colors, which is a solved problem, but somewhat complicated.

    Finally I ended up looking at HSB colors – hue, saturation, brightness, and this really simple tutorial. Colors are represented on a cone, and the values are as follows (from the tutorial).

    Hue is the actual color. It is measured in angular degrees counter-clockwise around the cone starting and ending at red = 0 or 360 (so yellow = 60, green = 120, etc.).

    Saturation is the purity of the color, measured in percent from the centre of the cone (0) to the surface (100). At 0% saturation, hue is meaningless.

    Brightness is measured in percent from black (0) to white (100). At 0% brightness, both hue and saturation are meaningless.

    At this point, it was clear to me that what I really wanted to do was to extract the dominant hue, and then I planned to average the brightness and the saturation. In the end, I decided to average the brightness and saturation for that hue, rather than for the entire image.

    After this, it should have been easy, but I had some confusion in terms of the range of hues, and converting from HSB to RGB. This I eventually fixed by just setting the ColorMode and working purely in HSB. The ColorMode allows me to set the maximum range, and as I just round the float to an int I can make my buckets bigger or smaller according to that. It turned out that 360 ended up being pretty close to what I want, although I think 320 is slightly better! It’s interesting to see the change of the extracted “dominant” color as the buckets change in size.

     

    If you liked this, you might also be interested in: Colors of the Internet (which I found as I was waiting for pictures to upload to this post – beautiful timing!)

    Source Code

    import processing.core.PApplet;
    import processing.core.PImage;
    
    @SuppressWarnings("serial")
    public class ImageViewApplet extends PApplet {
    
    	PImage img;
    	float hue;
    	static final int hueRange = 360; 
    	float saturation;
    	float brightness;
    
    	public void setup() {
    		size(640,600);
    		background(0);
    		img = loadImage("" /* Your image here */);
    		colorMode(HSB, (hueRange - 1));
    		extractColorFromImage();
    	}
    
    	public void draw() {
    		image(img, 0, 0, 640, 480);
    		fill(hue, saturation, brightness);
    		rect(0, 480, 640, 120);
    	}
    
    	private void extractColorFromImage() {
    		img.loadPixels();
    		int numberOfPixels = img.pixels.length;
    		int[] hues = new int[hueRange];
    		float[] saturations = new float[hueRange];
    		float[] brightnesses = new float[hueRange];
    
    		for (int i = 0; i < numberOfPixels; i++) {
    			int pixel = img.pixels[i];
    			int hue = Math.round(hue(pixel));
    			float saturation = saturation(pixel);
    			float brightness = brightness(pixel);
    			hues[hue]++;
    			saturations[hue] += saturation;
    			brightnesses[hue] += brightness;
    		}
    
    		// Find the most common hue.
    		int hueCount = hues[0];
    		int hue = 0;
    		for (int i = 1; i < hues.length; i++) {
     			if (hues[i] > hueCount) {
    				hueCount = hues[i];
    				hue = i;
    			}
    		}
    
    		// Set the vars for displaying the color.
    		this.hue = hue;
    		saturation = saturations[hue] / hueCount;
    		brightness = brightnesses[hue] / hueCount;
    	}
    }
  • Medium Term: Tradeoffs and Refactoring

    Medium Term: Tradeoffs and Refactoring

    The Start and Finish Line of the "Inishowen 100" Scenic Drive
    Credit: flickr / Andrew Hurley

    Ages ago, I wrote this post on meeting deadlines – things I’d learned, what had worked. One thing I wrote is about thinking “medium term”:

    Think Medium Term

    I don’t hack. I worry, actually, that I literally can’t hack. I can’t fight with something, and be happy with a one line fix labelled “DO NOT TOUCH THIS”. I always need to understand why, and to rationalize why things interact, or work the way they do.

    Hacking is short term thinking. I’m in a hurry, do this quickly, come back later. It borrows time from future-you, to save time today. But you don’t know when future-you is going to pay the bill. You might find it’s tomorrow (before you ship) – that’s the worst case. And hacks multiply, the more you have, the more expensive each one will be to fix, so here’s the next worst case, you ship something full of hacks, and now you can’t do anything interesting until you unravel them all.

    The thing about long term thinking, is that the world is going to be different a year, hell, a month from now than it is today. Long term is an investment in the future, but you have no idea what the future is going to look like. Isn’t that one of the awesome things about working in tech? Everything changes, all the time.

    Medium term is the balance, and I find when I think medium term I know what issues will result from that decision, and I know roughly when they will occur. Choosing X over Y will mean that we have to adjust some things, in a relatively minor way, if we do Z, but I’m confident Z won’t be on any of the next few iterations I’m OK with that, but document it somewhere.

    Medium term is doing things that will get harder over time sooner rather than later. In this case, Y is a pain, but needs to happen for Z. If we do it now, it’s very easy, and has and intermittent slightly higher overhead for a while. If we wait, it becomes a huge problem that takes someone a long and miserable time to unravel.

    Engineers cause so many problems from being smart-and-knowing-it, also known as “just enough knowledge to be dangerous”.  It’s really hard to build for the general use case, and (from observation) surprisingly easy to think you know what that is, when you don’t.

    Sometimes I feel like I must be the crazy person who believes in deadlines in an industry that often – very publicly – doesn’t meet them, or does at the expense of burning out and going mad. I think they are a negotiation, and an art.

    It’s hard to estimate software development. I think one reason is that confidence is crucial to being an engineer, the ability to say “I don’t know how but I believe in myself and I can figure it out”. It seems like it’s easy for that to tip into over-confidence – “I don’t know how but I believe in myself and I can figure it out in an hour“.

    Thinking and working for the medium-term, means understanding the tradeoffs and making a judgement about what will be important, when. Refactoring is my current best idea on how to measure this; I think that you can measure how you’re doing working for the medium term using refactoring.

    If you never refactor – too much short-term, or hacking.

    If you always refactor – too much long-term, or over-engineering.

    Project level, how do you estimate something built on hacks? Hacks are inconsistent, unpredictable, work for corner cases, not in general.

    And how do you estimate building something that works for every use-case? Including many that you haven’t imagined yet.

    The answer is – you can’t.

    Thanks Alex who read a draft of this and helped clarify some of my thinking around refactoring as a measurement.

  • Pycon AU: Making Python More Fun for Everyone

    Pycon AU: Making Python More Fun for Everyone

    Screen shot from Spy Who Coded game
    Screen shot from Spy Who Coded game

    Interesting talk from the creators of SingPath – games to help people learn to code. Left me wanting to try the game! Some insights about women and what they find off-putting – nothing unexpected. Notes below:

    Intrinsic vs. extrinsic motivation: autonomy, mastery, purpose (Dan Pink’s book – Amazon).

    Want to extrinsically motivate people without killing intrinsic motivation. This is really hard. Decided to focus on extrinsic.

    Quests: “The Spy Who Coded Javascript” – it’s a first person coder.

    Games are hard fun. They:

    • Have clear goals.
    • Require concentration.
    • Give immediate feedback.
    • Deep, effortless involvement.
    • Uncertain outcome.

     

    Hard to find balance – some people find it too easy, others too hard. Answer: adaptive difficulty (difficulty changes, depending on how you’re doing).

    A setting easier than easy – drag and drop. This is not intimidating. Also allows for tablet based – an iPad app.

    Individual learner – try to maximise classroom efficiency.

    Tournaments – everyone in the room is solving the same thing, at the same time.

    Idea: “Tournament based teaching”. First 5 minutes are close-book, after that open book. Peer based learning – first 10 finish, then go and help people who haven’t finished. There will always be some students who are very fast – these students then get to explain/mentor.

    First pro tournament at Pycon APAC.

    Collaborative learning – fun round, then prize round. No qualitative judging, the most efficient coding wins.

    Team-based tournaments.

    Pair-programming tournaments.

    Contemplating: mixed doubles (one female, one male on the team) – encourage peer-based learning, diversity.

    How do you balance carrot/stick with things that people are intrinsically motivated for?

    Women less likely to participate in the competitive rounds – the fun round, yes, prize round no.

  • On Building The Things You Want

    On Building The Things You Want

    lego titanic
    Credit: flickr / ericconstantineau

    I think my best reason of why we need more women working in technology can be explained with two websites.

    OKCupid is a dating site, it’s very successful, and they have a great blog. Part of the premise is that users answer all these questions – it’s very data-driven.

    The other one is a Spanish dating website I read about some time ago (cannot find the article), aimed at women. I say dating website, but really the main purpose was to meet other women, but women could recommend guys who could then join.

    So here we have two solutions to the same problem – meeting people, that take very different approaches, almost to the point where the whole idea can be presented differently. The first one posits that more data will mean more sex, the other addresses the side effects of being single (not having someone to go see that movie with, for example) by providing a way to increase the number of people in your life, and turns a potential relationship into the side effect.

    That is the benefit of diversity – not just solving problems differently, but seeing different problems.

    There was this NYT article, which started horrifyingly, “Men invented the internet”. This is manifestly untrue – the first programmer was a woman, the field used to be dominated by women (see – ENIAC Programmer project) the internet was created by many, many people. Not all of them were straight white males.

    But in terms of our experience on the internet, the World Wide Web, the things we used, the creators of those websites, mobile apps, software, the creators are dominated by what I will term nerdy boys.

    Here’s the thing about nerdy boys – they build the things they want. So we have 4chan, and more porn than anyone could want. Shopping for electronics, comparing, recommending is really good. There are many, many virtual ways to kill people.

    But there are other things that we are only just beginning to explore, that are nowhere near solved – online shopping and recommendations for clothes and accessories, for example. Or health care – there’s an interesting startup from the former CEO of Sun, for example. We know that women, statistically, are the primary caregivers for sick family members.

    My point here, is not that women don’t like electronics (I do!) or may not want virtual violence, but that we live in a digital world, created by a group of people who are not representative of the population, and I think, if this digital world was built by 50% women it would look very different.

    Creating ways to appeal to women makes sense – women are the predominant users of social networking, and the drivers of consumer spending. But Pinterest is derided as being “girly” – (fascinating article – it’s not actually that dominated by women, Wikipedia is far more dominated by men, but domination by men is normal, and around equal representation is “feminine”) – but if you look at the way traffic from Pinterest is monetized, being “girly” starts to look like an incredible business strategy.

    We live in a digital world, but the secret that hasn’t been widely enough shared, in my opinion, is that we don’t have to just live in it – we can shape it. Edit a Wikipedia article. Create a webpage, a web app, a mobile app, a tech company. We – women – have to go out and build it, because there are a lot of terrible products out there – pink, underpowered laptops, as one example – which can be broadly described as “what men think women want”. Learning how to develop things gives you the power to make the things that you want to exist – whatever that might be.

  • Book: Unlocking the Clubhouse

    Book: Unlocking the Clubhouse

    unlocking the cloubhouseI’d heard about this book (Amazon) for a long time, but especially since I arrived here – the other women in the office are huge fans, and talked about it a lot. And I kept thinking I would get around to reading it, but no hurry, I’ve read a lot of the research, I think I get what the issues are.

    But we were running these events in New Zealand – discussion groups about the book. So it became pressing and there was a deadline! So I finally got around to reading it.

    I was right. I didn’t get much new information out of it – but wow, how I wish I had read it when I was 18. It’s full of information and data about things that I learned the hard way. How you don’t need to be one-dimensional to be a good engineer, how women are less likely to only code – “dream in code” – in their spare time, and that is OK. The kind of things – poor teaching, for example – that disproportionately affect women.

    That was just the book. The discussion groups were amazing, the best events I have done for university students. We just had these amazing and open conversations about what we find hard, and ways that we find to cope. Especially afterwards, when we could go around and chat to the girls in smaller groups, and they would really open up. I’ve been getting amazing, lovely emails in response to the events, and hopefully more events will follow.

    Seriously, if you have any interest in female engineers, read this bookIf you can, get a or some copies for female university students near you. I wonder how much would change if every first year girl in (or near) CS got a copy! And if you want to run a discussion group, hit me up, I’d be happy to help.

  • Fighting Monsters

    Fighting Monsters

    cate with captive
    I was looking for a picture of me kickboxing, but I couldn’t find one. I did find this picture my friend Sarah drew, which I love. I’ve linked it to her blog with more of her art – zealousceles.blogspot.com

    A long time ago, when I was training in China, I was struggling to learn a form correctly and my master threatened me with no food until I got it right.

    This seemed like a terrible idea, I mean, it was hard enough to focus and be physical on the small amount of food (mostly chicken) that we did get, let alone without.

    But today this came back to me as I continued a long battle with some code. That maybe he had a point and the answer was that I should lock myself away in my apartment, where there is no food, until I get it right.

    (Knowing I was going to be working from home today, I did try to buy some, but it turns out after 3 months in Sydney I didn’t know where the fresh food in Woolworth’s was, not having had occasion to buy any yet.)

    I’ve been trying to change something for nearly a week now, and I feel like I’m making very little progress. There’s a monster in our codebase, something we’ve written and rewritten because it deals with this poorly documented API and it’s been a case of look at the documentation, do something, try it, discover it fails on data quality or battery life, think, try again.

    So there are a number of things that at the time seemed like good decisions, mostly were good decisions in the context of what we thought we knew, are there, and every time I go to change something, it’s a cascading thing of, oh, then I should change that, and that, and that. And so I cut change after change, making concrete improvements, trying to turn the monster into something that I can operate on.

    And I just berate myself – how did I, who am so fanatical about design, who wrote or reviewed every line in this monster, let it get that way? Approaching it with fresh eyes after a break, having figured out this new way to do it (basically, all of the ways we’ve tried so far, in combination. Way more complicated that it should be with a decent API, but que sera sera).

    Maybe this is the process, of figuring out how to do something that there’s no API well suited for, no blog posts explaining well, no expert down the hall to ask and review. Maybe this is just the part of what we’re doing that is learning, because everything else is pretty easy and I look at the design, or the feature spec, and know. This is the challenge.

    And so I’ll go back to the office and keep poking this thing into shape. I’ll keep making improvements until it’s more of a Stegosaurus than a T-Rex. The compiler won’t hit me with a stick, but it might make me cry. And the determination that got me to master that form (long since forgotten), the thing that pushes me out of bed in time for early morning spin class is the same thing I need here to keep on fighting with it, until it’s tamed and improved.

    Becoming a better engineer, becoming a better programmer, I think it’s really about being able to embracing this process of sucking. Of breaking things. Screwing up. Being mistaken. Thinking you’ve discovered all the goddamn ways you can be wrong, and then finding out you were wrong about that, too. And then making it better, whether you rip something out and replace it in a caffeine-fueled epiphany or snip away at it like you’re sculpting a tree.

    This time 5 years ago, I was 22 and had just started on my year of being an “international hobo” (aka, fuckwit). And it seems like I did some really random stuff, but for all I joke about how grad school was a terrible life choice, I never feel that year was a waste. I learned so much about humans, about how to have an adventure, but I also learned how to suck.

    I say learn how to suck, because it’s something we make such efforts to avoid, especially women. It’s not safe for us to fail, we view failure as a judgement on our innate abilities, not our learned ability to pick ourselves up and keep moving. And you know, that year, I got really, really good at sucking. I lost count of how many times I hit myself, hard, spinning my 5 foot staff. I came in last from climbing the steps, but I went up and down all four times instead of giving up part way through. I concussed myself and ended up in hospital. I concussed myself again (and again, and again, and again), but learned my lesson about the hospital. I wiped out in less dramatic ways. Flew out of my skiis leaving them upright in a ditch. Swam downhill in the sugary power that just kept knocking me over. Broke a ski pole, another, so many I used to buy them 2×2 at a time.

    And now, you know, I suck less. I suck less at skiing. Less at kickboxing. And I suck less at sucking at programming.

    So I went and lifted weights, and reminded myself that a year ago I couldn’t have lifted those, because my shoulder was such a mess.

    And I came home and reminded myself of all the other things that I’m less terrible at now, than I used to be.

    And tomorrow, I’ll go to work, and by the end of the day, this bit of code might not be amazing, but it’s going to be less monsterous than it is today.

  • From Hard Focus, to Flow, to Stop

    From Hard Focus, to Flow, to Stop

    Crocodile Rock - Millport
    © Copyright Raymond Okonski and licensed for reuse under the Creative Commons Licence.

    Interesting project the past few weeks. Basically I was swapping out a large and central component to what my team is building. It was really tough, to do that and keep everything functional. Normally I ask – what is the least amount I can do to make an improvement? This time, I had to ask, what’s the most I can eliminate and still remain functional?

    A genuine challenge, and it was good for me.  The first couple of days were hard focus, and tough lessons. A day writing code that I couldn’t even compile until it was done, because it wouldn’t without everything. By 4pm I felt like my brain had bled out through my eyes, and went back to the hotel (I was in NYC) to collapse. At the end of it, I realized I had to do something else first, before I could test and check in.

    So I came back and did that. Again, by the end of the 2nd large thing I felt physically exhausted.

    Day 3 I put them together and checked in. After that I could do smaller things, figure out what wasn’t working, delete things, make small improvements. Change the way we were doing things – because we didn’t have to follow the way the replaced thing was working anymore.

    Once functional, but not beautiful, I picked a new (smaller) UI component, and replaced it with an improved version. Again – hard focus. Desperate to be distracted. It’s like a fight. With the problem – because I’m still figuring out the best way to approach things – and with myself because it’s frustrating, and difficult.

    The following week I have to do the same (UI component) thing again. By this time I’m flying – it’s flow. I’ve learned how to do things to build on each other he hard way, and this time I’m cutting CL after CL and I’m zooming. This little project is coming to an end, soon.

    But… plans change, and this little project is now obsolete. I’m completely “in the zone” and racing towards the finish, and it’s like a rug being pulled from under me. All of a sudden I’m back to asking – what next, what order. Feeling discouraged. Someone reminds me that it’s the right decision, and what I always thought was right, but somehow when I was “in flow” I forgot.

    Some observations about hard focus and flow.

    • Hard focus is hard. It’s like a fight, and I would love anyone to distract me at any time.
    • It’s also completely exhausting. 4 hours of hard focus will leave me physically and mentally exhausted.
    • Flow comes after, it’s the sweet spot before something gets boring but you know what you’re doing.
    • Still figuring out new things in flow, but it’s more like building on understanding, “oh I don’t actually need this”, or “this is neater”.
    • Things stuck on in hard focus take much longer to move forward on than in flow. In flow a tea-break will do. In hard focus it’s more like lunch or a new day.
    • Flow can last for days, effectively. I’ll get tired and stop, but I’ll come back the following day and pick right up again.
    • Hard focus is a fight every morning, even more so than the rest of the day.
    • Being derailed in the middle of flow, for whatever the reason, is horrible.
    • In hard focus, I look at my task list to decide what to do. In flow, I look at my task list to mark off things I’ve done. The next step is always so obvious.
    • I’m actually more on top of twitter etc when I’m in “flow” because I have more compile time, more waiting on submit scripts. Distractions are less interesting than what I’m doing, so they never really take me away from it.

    Anyway, what can you do? Learn from it, and move on. After a day off, I’m heading back in search of flow.

  • How Not To Get Things Done

    How Not To Get Things Done

    Twitter Error Message
    Credit: Flickr / programwitch

    I have had a pretty appalling week in terms of the difference between what I wanted to achieve, and what I did achieve.

    Things outside my control:

    • Re-aggravating shoulder injury. So much pain. Increased sleeping due to pain killers. Two trips to chiro (feeling a lot better now – finally).
    • Car is broken and needs a bunch of work, so we have to decide – do we buy a new one?
    • Server issue on something I was working on sent me down a rabbit hole where I assumed it was my fault.
    • Hotel sent me away with someone else’s bill (turns out, you can’t use that to do your expense report).
    Things I planned/did badly:
    • Did not plan for a 4-day week (supposed to be on holiday today. Instead I will try and do a couple of hours work whilst packing).
    • Did not plan for sorting things out in order to go away. Including – checking everything for an event we’re running the week I return.
    • Did not plan for coming back after a week away.
    • Agreed – in fact, suggested – that I should go back to New York for two days, the week I get back.
    • Got overwhelmed and panicked.
    • Did not break what I was doing up well.
    • Did not say no. The biggest stress has come from working on something for my old team. A series of events have meant that I wasn’t able to make much progress on this until Monday afternoon. I’ve been stressed by and resenting that what I’m doing is some way away from the circumstances I agreed to. Could also have postponed a couple of meetings.
    • Prioritized that over the one thing that I really hoped to achieve for myself and my new team this week – getting readability.
    • Broke my email once a day as I tried to get through the backlog before I go away. Probably necessary, but could have structured it better rather than just going to email “between” things or instead of thinking about what to do next.
    Things that worked well:
    • Broke things up better once it was apparently that someone else was going to have to finish what I started.
    • Was transparent about what I wasn’t going to get done to my new team.
    • Have amazing colleagues who are taking control of the event stuff whilst I’m gone.
    • Spoke to another amazing colleague so she can finish the feature I’ve been working on. Outlining what was happening and how it was working made me feel more capable of doing it myself in the short amount of time left!
    • Very lucky that my chiro was willing to be flexible and fit me in.
    • When working through the evening, (9pm Wednesday, 11pm Thursday) took a break for dinner. Wednesday was just a sandwich and some time with my book, Thursday I went out with work colleagues. Reminded me how much I love my job and how awesome most of the people I work with are.