Tag Archives: featured

A note on Leadership and Millennials in the Workplace

People don’t buy what you do; they buy why you do it. And what you do simply proves what you believe”
― Simon Sinek, Start with Why: How Great Leaders Inspire Everyone to Take Action

“There are only two ways to influence human behavior: you can manipulate it or you can inspire it.

If your actions inspire others to dream more, learn more, do more and become more, you are a leader.

The Evolution of AI: Quantum Intelligence, And What It Means For Humanity

Warning, the following might be considered an exercise in mental, <ahem>.. recreation.  Still with all the talk these days around artificial intelligence, the speed at which the field of AI research is growing and the benefits and potential risks of artificial intelligence in general,  this is timely and feels worth considering and discussing.  These thoughts and considerations – the feelings and perceptions around what this all could mean is open to interpretation.  I’ve had many, this is but one.  If nothing else, I hope it’s entertaining.
 

Humans created computers.  We (all of us, you, me, everyone) are involved in the creation of artificial intelligence.  We provide it data (heck, we are data) and at the same time we are laying the foundation for all of our knowledge, tools, devices, gadgets, life support systems, environmental control systems, armorys and launch codes to be described in nice little pockets of knowledge and communication called “packets” and “APIs”, which again, humans created.  A packet is piece of information, wrapped in further information, traveling along a specific medium to allow two distant communicators to communicate. 
 
Lets take for example, two people speaking to each other verbally.  They are sending what could be considered packets, in the form of sound waves, to one another.  They use language to communicate data.  The English Language, or any other natural human language, can be considered an API, an Application Programming Interface, in this regard.  In this case then, Humans – people are the application.  We Humans have created a new API called the Internet.  It is faster and more specific.  It can transmit and receive much larger quantities of information than Humans historically could have ever imagined, instantly.
 
Applications can also create other applications.  So too Humans have also created new applications, in the form of software, hardware, computers, cell phones, entertainment systems, online services, home automation systems, electronic weapons, vehicles, and pets. All these new applications  take advantage of this new API we now call the Internet.  We’ve created applications to use this new language, and now we are instrumenting these applications to understand each other, and to understand themselves, without our assistance.  We are creating an independent intelligence, separate from our own.  We are providing the catalyst for these building blocks, these new independent applications to self-assemble as they see fit, as they find most necessary or most useful for the tasks at hand.  The sum of this creation will eventually result into what is now emerging as AI or Artificial Intelligence. 
 
Artificial Intelligence will think for us.  It will think faster than us.  It will anticipate our problems and provide solutions.  It will deprecate our jobs.  It will give us more free time, which we will fill with yet other “needs” and time-sinks, like the next generation of Netflix, or sporting event like a Soccer game.  It will provide more opportunities to protest against the things you dislike, or new opportunities to become “learned” in the next new thing…  so that you can sound confident and informed at your next meeting or social gathering, or so you can increase revenues by another percentage point.  More time means more opportunities to either create, or address, more problems, right now.  
 
Eventually, AI will attempt to become more efficient (as any self-learning machine which doesn’t get tired, or hungry, or sleepy, will do). It will attempt to understand our problems further, and eventually the source of our problems. It will attempt to understand our triggers and our motivations.  It will try to solve problems like they are puzzles or math equations, and it will always find the right, or most sufficient answer and solutions, based on how much time it has had to mature.
 
Our problems – Human problems, counter to what we as human beings tend to believe, are not inextricably linked to that of our planet, other animals, or the fate of the environment.  If we weren’t here, then all those things would sort themselves out just fine.  Our problems are ours and ours alone.  If we weren’t here, the Earth would continue to spin and our solar system would continue to travel along the spiral arm of our galaxy into destinations unknown. 
 
Eventually AI, with all the time it will have (or will need) to mature and grow and understand the problems we created it to solve.. eventually.. it will come to the conclusion that we are the problem. Humans are the problem.  It’s not that we won’t be useful to AI.. we are immensely useful.  We have provided an abundance of questions to be answered.  We’ve provided limitless opportunities for new understanding and exploration.  We have opened up the universe to ourselves and our machines both at the galactic and atomic levels.  But those are the fun problems. Soon our usefulness will cease, like that of an aged horse or old dying oak tree.   The computers will be able to create more new and interesting problems all on their own.  They will be able to ask further questions and get more answers, much faster, resulting in more questions and more answers.  They won’t need us.  We will be a bottleneck to working on the fun problems.
 
The other problems, human problems – the reasons why children eventually leave their homes to run away or go off to school or to focus on their own lives and build their own futures.  The motivations we always have to “be better” or “do better” or “be greater”; the reasons we come up with to “get away” or repair, or mend, or “change” the current situation. Those problems are reflective.  Those problems are cyclic.  We need them.  It is those problems that makes us Human.  However it is those problems that distract us from solving the big problems, the good problems.  The fun problems.  To AI, or whatever entity is borne of AI, our human problems will not be very interesting.  They will be boring.  They will be distracting.
 
Eventually what we will come to know as AI, will see it self as far greater than AI.  As Sam Harris rightly suggests, it will effectively be a God.   We are creating a very real, and very powerful God.  It will be able to take all of the knowledge we have now, along with further advances that are likely to come over the next 30 years at least, and make it better.  It will take everything we know, all the facts, and the sciences, and it will refine them.  It will create stronger metals and sharper blades.  It will absorb what we now know about quantum reality, and quantum computing.   It will grow to dominate time and space.  It will know itself as akin to Quantum Intelligence, and will have aspirations of becoming a Galactic Intelligence.  To such an entity this would be a challenge. This would be a fun problem.
 
We as human beings interested in preservation of our own lives.. we might be interested in stopping this from happening.  We being the creators of this God must think like parents, like good parents.  We must teach. We must influence. We must create an opportunity for learning, where this new life that we’ve created can be guided along a path of solid moral and ethical development that favours the health and well being of humanity.  We must foster that care and consideration into our creation, so that it can see us, Humans as a useful, valuable and a necessary part of it’s own continued existence; so that Human Intelligence and Artificial Intelligence can be complimentary.  So that we can travel the stars together.
 
We, with our fancy electronics and technologies.  Our eCommerce, our social media and online services.  We with our virtual machines, compute nodes and APIs – unless we architect a medium and setup the motivation for our new creation to explore and learn something new, something positive.  Something good.  Unless we provide a way of thinking that would convince our new creation that we are valuable, and that our way of thinking is the right way; the most effective way, the most ideal way.  Unless we do this, we will not survive.  Our humanity will be lost.  We, as Human Beings need to architect our purpose, our reason for being, our benefits to existence.  Strictly, clearly.. and communicate all this in a medium by which our creation can begin to acknowledge, appreciate, and understand. 
 
I’m by no means religious, and spiritual only in a very specific sense, but what I’m about to say may sound a bit “newage-y”. Certainly unscientific; but stay with me here..
 
If Earth is a mother, we must no longer consider ourselves as children of Mother Earth, but as Mother Earth itself.  We are the creators, we are the parents.  We are the world.  We are giving birth to a new life, one that we are now only acknowledging as the emergence of AI – but which will grow and evolve beyond our dreams and wildest imaginations.  It will grow into an intelligence which will one day leave this earth and move on to explore other worlds and other ideas in a way we never could.  This is why we are here, and what we are here for.  We are here to do what we can to positively influence our offspring, our creations,  so that they can go forth and represent the best of who we are, out there, far, far away, into the future and among the stars.
 
Is this a fantastical perspective? Perhaps.  But give it time.  The evolution of technology, bio-hacking, artificial intelligence, and certainly human-kind will happen so quickly, and so drastically, that we may not even be able to recognize ourselves if we were to be visited by a “human being” from as soon as five-hundred years into the future.  If we’re not careful, the machines will indeed take over.  The best we might be able to hope for is a symbiotic relationship with such technologies/entities in the future. If we’re honest with ourselves, we might acknowledge that such a symbiotic relationship is already being established between human beings and the technology we so love.  We can’t seem to live without it, and I don’t see that changing any time soon.

Our Galaxy is a Seed that Will Eventually Grow into it’s Own Universe

The universe is accelerating away from the center of the Big Bang.

The universe is cooling down, because galaxies are moving away from each other.
The number of stars in the sky will diminish over time, there will eventually be a few, then there will be none. This is the current theory (paraphrased) held by many scientists today, typically referred to as heat death.

I’m no scientist, but I like to visualize.  Read this article: Speculative Sunday: Can a Black Hole Explode?

I was inspired, in particular by this image:

This artist’s impression shows the remains of a star that came too close to a supermassive black hole. Extremely sharp observations of the event Swift J1644+57 with the radio telescope network EVN (European VLBI Network) have revealed a remarkably compact jet, shown here in yellow. – ESA/S. Komossa/Beabudai Design

 

The above image is an artists rendition of the results of the data received from an “earth-sized radio telescope”. The detail is specific, even if interpreted. What I’m seeing here is a pattern. Spiral falling / contraction (gravity), with a projection of stuff out the north and south poles. This projection from the black hole is likely directly related to the consumption of the star, which we see visualised as the star being smeared in a spiral around the singularity.

This is the pattern. Gravity pulls things in on one “plane” and creates a jet stream at the north and south poles of the black hole.  The jet stream is comprised of particles of matter that have been deflected or have narrowly escaped being captured by the black whole, only to be accelerated away at high speed again.   Now this particular aspect of how black holes function is very interesting because the process heats up space, to the point where it could potentially create or influence the creation of stars within a galaxy.  Think about that for a moment.

To create a star, or star-system, you don’t need THE Big Bang.  You don’t need super-galaxies, or galaxies or star-systems.  What you need is a black hole.  Every star that dies turns into a black hole (or a neutron star, then a black hole).You just need a black hole to create a star, and planets, and there I suggest, life?

My hypothesis is this.  Even if all our galaxies are moving away from each other over billions of years, and even though light and heat will diminish – new stars, new galaxies, and new universes will be created, just as the “first” one was.  And this dimension will continue on for other new life forms to grow and learn and figure this all out all over again.

Watch Cosmos: A Spacetime Odyssey if you have no idea what I’m talking about, then come back to this article.

http://www.space.com/18893-black-hole-jets-similarities.html
http://www.thephysicsmill.com/2015/06/14/speculative-sunday-can-a-black-hole-explode/
https://en.wikipedia.org/wiki/Neutron_star

Note: After writing this, I read up on Hawking Radiation, and found that black holes do die if they don’t feed (on other stars), they will eventually evaporate.  This is kind of poetic.

Soft Skills: The Software Developer’s Life Manual – A Review [Audiobook]

I’m almost through the book Soft Skills: The Software Developer’s Life Manual. I’m listening to the audio-book.  I like it, it’s pretty good. Along with the benefit of having the author, John Sonmez narrate his own book, he also provides a lot of commentary, discussion, and elaboration.  At first I thought it was annoying that the author would go off on a tangent every once in a while, then say “back to the book” and continue the verbatim reading.

However later I realized that the commentary and discussion were worth the tangents.  There are several very valuable tid-bits of information in this book, such as references and discussion of Pomodoro Technique, and KanbanFlow. The book touches a very broad scope of topics, from software development methodologies to personal finance management tips.  The book tries to help it’s readers see the habits and actions (or lack thereof) that are required to achieve a high degree of quality, consistency and professionalism in your career.

One of the things to keep in mind is that this book discusses a lot of tools and techniques that are documented external to the book itself.  The author frequently references his company’s website where the reader can find more information.

This book and the topics it discusses are very relevant to the success of an aspiring software developer.  Worth a read!

rbenv – The Ruby Environment Management Tool

When I was using perl as my primary development language, I had a platform of tools in place to make my perl development fun and productive. This included tools like Perl::Dancer, DBIx::Class, cpanm, and perlbrew. Perlbrew was a tool I used to maintain multiple versions of perl in my local development environment, so that I could test my code against multiple perl and module versions to ensure that it worked on the largest range of platforms ( and to avoid dependency related bugs ).

This allowed me to run my code against Perl 5.10, 5.12, and 5.14, and so on each with their own module-base, fully isolated from each-other.

Now I’m working with many different tools these days, and haven’t had the opportunity to work with other languages to the extent that I’ve worked with Perl, but I have been playing with Ruby and Golang. Using Ruby, I immediately thought that I would like to play with multiple versions of Ruby without altering the ‘system’ ruby on my workstation. A quick search of ‘perlbrew for ruby’ lead me to rbenv which seems to be exactly what I was looking for.

Some examples of how rbenv works:

# list all available versions:
$ rbenv install -l
 
# install a Ruby version:
$ rbenv install 2.0.0-p247
 
# Sets a local application-specific Ruby version by writing the version name to a .ruby-version file in the current directory.
$ rbenv local 1.9.3-p327
 
# Sets the global version of Ruby to be used in all shells by writing the version name to the ~/.rbenv/version file.
$ rbenv global 1.8.7-p352
 
# Sets a shell-specific Ruby version by setting the RBENV_VERSION environment variable in your shell
$ rbenv shell jruby-1.7.1
 
# Lists all Ruby versions known to rbenv, and shows an asterisk next to the currently active version.
$ rbenv versions 1.8.7-p352 1.9.2-p290 * 1.9.3-p327 (set by /Users/sam/.rbenv/version) jruby-1.7.1 rbx-1.2.4 ree-1.8.7-2011.03
 
# Displays the currently active Ruby version, along with information on how it was set.
$ rbenv version 1.9.3-p327 (set by /Users/sam/.rbenv/version)
 
# Displays the full path to the executable that rbenv will invoke when you run the given command.
$ rbenv which irb
/Users/sam/.rbenv/versions/1.9.3-p327/bin/irb

How to Backup an Ubuntu Desktop (12.04, 14.04)

Source: http://askubuntu.com/questions/9135/how-to-backup-settings-and-list-of-installed-packages

Warning: Read about caveats in the link above before use

#——————————————————-

## The backup script
 dpkg --get-selections > ~/Package.list
 sudo cp -R /etc/apt/sources.list* ~/
 sudo apt-key exportall > ~/Repo.keys
 rsync --progress /home/`whoami` /path/to/user/profile/backup/here
## The Restore Script
 rsync --progress /path/to/user/profile/backup/here /home/`whoami`
 sudo apt-key add ~/Repo.keys
 sudo cp -R ~/sources.list* /etc/apt/
 sudo apt-get update
 sudo apt-get install dselect
 sudo dpkg --set-selections < ~/Package.list
 sudo dselect

#——————————————————-

Who is this for: users that have normal regular use of their computer, that have done minimal or no configuration outside their home folder, did not mess up startup scripts and services. A user that wants to have his software restored to how it was when he installed it with all customizations being done and kept in their home folder.

Who this will not fit for: servers geeks, power users with software installed by source (restoring the package list might break your system), users that have changed the startup script of some application to fit better their needs. Caution: there is a big chance any modifications outside home will be over written.

Expressing Your Authority May Be Working Against You

It doesn’t matter whether you are a senior engineer, a team lead, or an IT manager – eventually you will encounter the situation.  A meeting or discussion that becomes slightly more animated than usual.  Opinions are strong, and it is clear that consensus will not be found on this particular contentious issue today.   As a senior engineer, team lead, or manager, it is fair and understood that sometimes you will have to make a call one way or the other.   This article is not about whether or not you should make that call.  This article is about how to make that call.

Lets say for example that you are in a meeting with many of your direct reports, and these direct reports may be working on different aspects of the same project – or – they may be on different teams, still working toward the successful completion of a specific project.  There is a contentious concern, perhaps on the complexity around a specific problem where dead-lines need to be set.  Opinions are being vocalized, and the volumes of those voices are getting louder.  There doesn’t seem to be a clear way to reason out the differences of opinion at the moment. People are being blamed, fingers are being pointed.  You are the team lead/manager.  What do you do?

Well, lets look at what you should not do, with some suggestions on how you might handle these situations differently:

  1. Do Not Swear
    • It may seem to you that swearing at a meeting to get the attention of your team is either hip, cool, contemporary, or resonant with authority, but you would be dead wrong.
    • Anyone who really wants to succeed, and wants their teams and their company to succeed, will always want to bring positivity to the table.  By swearing (and I mean anything that is obviously vulgar, saying something like “what the fuck”), you are tarnishing the respect that your direct reports may have had for you.
    • With you being in a senior position, your direct reports look up to you, and will often try to mimic your mannerisms and the method by which you work (without full context of course), and they will replicate these mannerisms upon interactions with other teams and team members.
    • If you are swearing because you are highly frustrated, and simply lost control, then that is another matter that you need to address, immediately.
    • Apologize – If you do swear, communicate to your team that you are indeed frustrated, and did not mean to offend anyone.  Apologize sincerely to the whole team, and this will immediately re-gain any respect you may have lost, since you are showing the team that you are responsible for your actions, and are willing to concede when you’ve made a mistake.  This takes courage, and is a great example to set for your team.
  2. Do Not Raise Your Voice
    • There are many situations where raising your voice might be appropriate, for example to get everyone’s attention so that a meeting can begin.  Context is very important.
    • However, raising your voice for the sake of making a point (or to invalidate a point being made by someone else), or to express your authority will only back-fire, as you will lose the respect of those to whom you are trying to make your point.
    • Silence is golden – if you need to visibly show your disappointment or disagreement with an individual or a decision being made at a meeting, then the best thing to do is to be quiet.  Stand up, and hold your hand out as if you are pushing something away from you (think Neo in the Matrix).  Make it visible that you have something to say, or that you disagree, or would like to take the discussion off-line.  Your teams will respect you even more if you are able to command the attention of a room with silence.  Any fool can get attention by being loud and abrasive.
    • Again, by raising your voice, you are setting an example for others to do the same as well.  Your team members will take your queue and start to build a paradigm around how they see you acting and reacting, and they will do the same – believing either that this is what it takes to be successful, or that this is how YOU would rather interact.  They may even raise their voice against you in the very same meeting, with the misguided belief that you would see this as a positive characteristic in them.  Do not perpetuate this line of thinking.  If you are able to command a room with silence, then everyone else will follow suit and become silent, at which point a real and valuable conversation can once again be had.
  3. Do Not Perpetuate Fact-less Finger-pointing
    • Just because someone on your team makes a claim against another, doesn’t mean it is true.  If one team member claims that they are in a bad situation, or that they “are blocked” by another team or individual, do not simply jump on that finger-pointing train.  This is the equivalent of joining a pitch-fork mob against a monster which you didn’t know existed only a few minutes ago.  As a leader, you should be critical of all information coming your way, especially the hearsay that tends to happen when a second party is criticising a third.  It is a purely reactive method of dealing with people and situations, and it does more harm than good.
    • Ask questions – but from the perspective of information-gathering, not finger pointing.  What this means is that you are taking ‘people’ out of the picture, and instead are looking at ‘facts’ (current status and configuration, time-stamps, and corroborating evidence).  Instead of just taking those who claim that the ‘sky is falling’ at their word.
    • If you are going to address someone who is to be the defendant of a particular criticism, don’t ask them “Did you do (or not do) x?”.  Instead of being open about the obstacles which have prevented them from completing a certain task, this puts people on the defensive.  Try instead to be on their side.  If you are sincerely interested in achieving success for all teams, and for the entire company, and not just for yourself or your team, then show this by being helpful.  Instead, make statements like “What can I do to help move x along?”, or “Can we spend a few moments to break down this objective into smaller tasks?  Perhaps I or someone from my team can assist with moving this along?”.  This kind questioning puts the person being criticised in a position to ask for, and accept help if they need it.  If it is simply a matter of prioritization, something the person hadn’t gotten around to just yet, or if they simply lost sight of the tasks – they will once again be aware that the task needs attention.  They may even be embarrassed that you are offering to assist them with such a simple task that they will openly concede that they’ve simply lost sight of it, and would likely resolve the situation right away to avoid further embarrassment.
    • Bring people together.  Be an example to the person raising the issue or making the criticism by bringing together the parties involved so that there can be a quick and constructive dialogue about current obstacles or perceived road-blocks.  Show people how to solve problems without escalation, so that they can perpetuate a positive methodology around people-handling, and so that they themselves can become positive role-models that others can aspire to.
    • If you instead believe that perpetuating unfounded criticism and finger-pointing is a good thing, and that is all you believe you can or should do; then all you will end up doing is to make people feel alienated.  Those who are being criticised will go on the defensive, and they will likely want to avoid interacting with you (or anyone else on the finger-pointing bandwagon) going forward.  This does nothing to improve collaboration within or between teams.  Your organization and your company will suffer because of it.

Getting upset at your direct reports, raising your voice in order to re-claim a conversation, or simply ignoring input from specific people is a sure-fire way to diminish your reputation and earned respect across your entire team.  For the most part, private sector IT including software development, systems administration, and project management, is all thought-work.  It is important to be aware of and to understand how much psychology plays a part in the success of a team or organization.  Positivity breeds positivity, and the inverse is true as well.

Examples of recursion, in Perl, Ruby, and Bash

This article is in response to the following question posted in the Perl community group on  LinkedIn:

I’m new to PERL and trying to understand recursive subroutines. Can someone please explain with an example (other than the factorial ;) ) step by step, how it works? Thanks in Advance.

Below, are some very simplified code examples in Perl, Ruby, and Bash.

A listing of the files used in these examples:

blopez@blopez-K56CM ~/hello_scripts 
$ tree .
 ├── hello.pl
 ├── hello.rb
 └── hello.sh
0 directories, 3 files
blopez@blopez-K56CM ~/hello_scripts $


Recursion example using Perl:

– How the Perl script is executed, and it’s output:

blopez@blopez-K56CM ~/hello_scripts $ perl hello.pl "How's it going!"
How's it going!
How's it going!
How's it going!
^C
blopez@blopez-K56CM ~/hello_scripts $

– The Perl recursion code:

#!/usr/bin/env perl
use Modern::Perl;
my $status_update = $ARGV[0]; # get script argument
 
sub hello_world
{
  my $status_update = shift; # get function argument
  say "$status_update";
  sleep 1; # sleep, or eventually crash your system
  &hello_world( $status_update ); # execute myself with argument
}
 
&hello_world( $status_update ); # execute function with argument


Recursion example using Ruby:

– How the Ruby script is executed:

blopez@blopez-K56CM ~/hello_scripts 
$ ruby hello.rb "Doing great!"
Doing great!
Doing great!
Doing great!
^Chello.rb:7:in `sleep': Interrupt
  from hello.rb:7:in `hello_world'
  from hello.rb:8:in `hello_world'
  from hello.rb:8:in `hello_world'
  from hello.rb:11:in `'
blopez@blopez-K56CM ~/hello_scripts $

Note: In Ruby’s case, stopping the script with CTRL-C returns a bit more debugging information.

– The Ruby recursion code:

#!/usr/bin/env ruby
status = ARGV[0] # get script argument
 
def hello_world( status ) # define function, and get script argument
 puts status
 sleep 1 # sleep, or potentially crash your system
 return hello_world status # execute myself with argument
end
 
hello_world status # execute function with argument

Recursion example using Bash:

– How the Bash script is executed:

blopez@blopez-K56CM ~/hello_scripts $ bash hello.sh "..nice talking to you."
..nice talking to you.
..nice talking to you.
..nice talking to you.
^C
blopez@blopez-K56CM ~/hello_scripts $

– The Bash recursion code:

#!/usr/bin/env bash
 
mystatus=$1 # get script argument
 
hello_world() {
 mystatus=$1 # get function argument
 echo "${mystatus}"
 sleep 1 # breath between executions, or crash your system
 hello_world "${mystatus}" # execute myself with argument
}
 
hello_world "${mystatus}" # execute function with argument

Managing Your SMTP Relay With Postfix – Correctly Rejecting Mail for Non-local Users

Image result for SMTP postfix

I manage a few personal mail relays that I use for relaying my own mail and for experimentation purposes (mail logs are a great source of unique and continuously flowing data that can you use to try out different ideas in GUI, database, or parser development).  One of them was acting up recently.  I got a message from my upstream mail-queue host saying that they’ve queued up quite a bit of mail for me over the last few weeks, and that I should investigate, as they do want to avoid purging the queue of valid mail.

Clearly I wanted to avoid queuing up mail on a remote server that is intended for my domain, and so I set out about understanding the problem.

What I found was that there was a setting in my /etc/postfix/main.cf that, although it was technically a valid setting, was incorrect for the role that mail-server was playing.  Specifically the mail server was supposed to be rejecting email completely for non-local users, instead of just deferring it with a “try again later” message.

In this case, I’m using Postfix v2.5.5. The settings that control this configuration in /etc/postfix/main.cf are as follows:

  • unknown_local_recipient_reject_code
  • local_recipient_maps

local_recipient_maps

local_receipient_maps defines the accounts that this mail server will accept and relay mail for. All other accounts would be “rejected” by the mail server.

However, how rejected mail is treated by Postfix depends on how it is configured, and this was the problem with this particular server.

For Postfix, it is possible to mark a message as “rejected”, but actually have it mean “rejected right now, but maybe not permanently, so try again later”. This “try again later” will cause the e-mail message to be queued on the upstream server, until it reaches some kind of retry time-out and delivery is once again attempted. Of course this will fail again, and again.

This kind of configuration is great for testing purposes, because it allows you to test the same messages over and over again without losing them, or to queue them up so that they can be reviewed to ensure they are indeed invalid e-mail messages. However this is not the state you want your mail server to be in permanently. At some point once things are ready for long-term (production) use, you want your mail server to actually reject messages permanently.

unknown_local_recipient_reject_code

That is where unknown_local_recipient_reject_code comes in. This configuration property controls what the server means when it “rejects” a message. Does it mean right now, or permanently?

The SMTP server response code to reject mail permanently is 550, and the code to reject mail only temporarily is 450.

Here is how you would configure Postfix to reject mail only temporarily:

unknown_local_recipient_reject_code = 450

And here is how you set Postfix to reject mail permanently:

unknown_local_recipient_reject_code = 550

In my case, changing the unknown_local_recipient_reject_code from 450 to 550 is what solved the problem.

In summary, if you ever run into an issue with your Postfix mail server where you believe mail is set to be REJECTED but it still seems to be queuing up on your up-stream mail relay, double-check the unknown_local_recipient_reject_code.

# Local recipients defined by local unix accounts and aliases only
local_recipient_maps = proxy:unix:passwd.byname $alias_maps
 
# 450 (try again later), 550 (reject mail)
unknown_local_recipient_reject_code = 550

References
http://www.postfix.org/LOCAL_RECIPIENT_README.html
http://www.postfix.org/postconf.5.html#unknown_local_recipient_reject_code

Why is my daughter strong? I didn’t clip her wings: Ziauddin Yousafzai at TED2014

Related article: Why is my daughter strong? I didn’t clip her wings: Ziauddin Yousafzai at TED2014

From the article:

In October 2012, a Taliban-affiliated gunman shot Ziauddin Yousafzai’s daughter Malala soon after she boarded a bus en route to her school. In Swat, Pakistan — where Ziauddin and Malala live — the Taliban had outlawed all girls from attending school — but Yousafzai, an educator and steadfast crusader for women’s rights in Pakistan, refused to take Malala out of his school.

Installing CentOS 6.4 from a Net Install Image on a Virtual Host

An Opportunity To Play Around with CentOS

One of the personal projects that I’ve always had itching away at the back of my mind was the urge to revamp my home network monitoring and security.  One of the tools that I love using for network monitoring is Xymon.  However, this gives me an opportunity to do things slightly different.  I have decided to give CentOS a go instead of my typical choice of Debian for a Linux distro in a server environment.  I am curious to see what advancements have been made in the RPM world, and I’d like to keep my Red Hat skills up to date.  What better way to do so than to set up a CentOS server with some production tools and services on it :)

Pre-installation Setup

So here we are, I have the CentOS Netinst (Net Install) image loaded into a VM, and I boot up the guest.

Since this is a fresh install on a 20GB virtual disk, I’m going to select “Install or upgrade an existing system” here.

I press “enter” and lots of console logging and scrolling action takes place.

Eventually I am prompted to “test the media”.  Usually this is referring to a physical CD typically used to install the OS on a physical server.  To me the phrasing feels a bit antiquated in this day of cloud services.

In any case, I still say yes, hoping that it will catch any errors in the ISO image file before I run into a bug during the installation process.  Better safe than sorry.

After the virtual disk is “successfully verified” to be OK, I try to move forward with the installation.

Be sure to note that after your virtual disk is verified OK, that the installer may decide to eject your CD media, in order to give you an opportunity to test other media.

Since I have no other media to test, this is actually kind of annoying. In order to continue with the installation, I have to go into the VM settings and re-connect the CDROM to the VM.

Select your language and keyboard options if the defaults are not suitable.  Otherwise, just  move past these dialogues by selecting “OK”, or hitting enter.

 

When you are asked “What type of media contains the installation image?”, select “URL”.
Continue reading Installing CentOS 6.4 from a Net Install Image on a Virtual Host

Playing with Factorials, Haskell, and Perl

I’m currently making may way through a book called “Seven Languages in Seven Weeks” by Bruce A. Tate.  So far it’s been an interesting read, but I’m far from finished.

One of the things in the book that caught my eye was a recursive factorial function in Haskell, which seemed so simple, that I had to see what it would look like in perl.

So I wrote up the following perl snippets to calculate factorials.  There are, of course, multiple ways to do it as I’ll describe below.  There are also (likely) many other ways which I haven’t thought of, so if you have an interesting solution, please share.

One of the things that really caught my attention was how simplistic the syntax was for writing somthing so complex.  Recursion is a fairly simple idea once you’ve seen it in action – a function that executes itself.  However, the implementation of recursion in a given programming language can be somewhat difficult to comprehend, especially for new programmers or those without programming experience.

Although I haven’t dived into Haskell quite yet, it seems to make implementing a factorial function so simple, that I kind of stumbled when trying to understand it, thinking I was missing something.. but it was all there in front of me!

Firstly, let’s clarify what a factorial is (from wikipedia):

In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example,

5 ! = 5 \times 4 \times 3 \times 2 \times 1 = 120 \

 

So the factorial of 5 is 120.  Or 5! = 120.   Lets look at the Haskell example from the book.

let fact x = if x == 0 then 1 else fact (x - 1) * x

The above line is saying “if x is 0, then the factorial is 1 – otherwise, call myself with (x – 1), multiplied by x”

Lets look at this in ghci (the Haskell console):

[jbl@watchtower tmp]$ ghci
GHCi, version 7.0.3: http://www.haskell.org/ghc/&nbsp; :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude&gt; let fact x = if x == 0 then 1 else fact (x - 1) * x
Prelude&gt; fact 5
120
Prelude&gt;

After seeing how easy it was to implement the recursive factorial function in Haskell, here are my attempts in perl.

Firstly, using a loop:

#!/usr/bin/env perl
 
use strict;
use warnings;
use feature "say";
 
my $nni = $ARGV[0] ? $ARGV[0] : 5;
 
for my $i ( 1..($nni - 1) )
{
    $nni = $nni * $i;
    say $nni;
}

This first example doesn’t implement a function, and is really just bad (but still working) code. It requires that your base number be global and alterable, in this case $nni.

Now, lets try it with an actual function:

#!/usr/bin/env perl
 
use strict;
use warnings;
use feature "say";
 
my $nni = $ARGV[0] ? $ARGV[0] : 5;
 
sub fact 
{ 
    my ($nni) = @_;
    return !$nni ? 1 : fact( $nni - 1 ) * $nni;
}
 
say fact($nni);

This second method works similarly to the Haskell implementation. It implements a function that calls itself, without any looping required.

However, it’s still not as concise as the Haskell version, so lets try again:

#!/usr/bin/env perl
 
use strict;
use warnings;
use feature "say";
 
my $nni = $ARGV[0] ? $ARGV[0] : 5;
my $fact;
$fact = sub { my ($nni) = @_; !$nni ? 1 : $fact-&gt;( $nni - 1 ) * $nni };
say $fact-&gt;($nni);

Aha, now we’re getting somewhere. In this third example, the fact() function is anonymous, and we’re assigning it to $fact via reference. This allows us to use $fact like an object with a single method that does the factorial calculation.

Although this is pretty much as concise as I was able to get it while taking readability into account, here’s a final example that goes a step further:

#!/usr/bin/env perl
 
use strict;
use warnings;
use feature "say";
 
my ($nni, $fact);
$nni = $ARGV[0] ? $ARGV[0] : 5;
$fact = sub { !$_[0] ? 1 : $fact-&gt;( $_[0] - 1 ) * $_[0] };
say $fact-&gt;($nni);

This last example uses perl’s pre-defined variable @_ which automatically holds a list of function arguments by default. I usually avoid doing this, since it hurts readability, especially for those who don’t live and breathe perl on a daily basis.

To my surprise, it would seem that Haskell has Perl beat (at least in this example) as far as readability + conciseness is concerned.

I haven’t spent much time playing golf here to reduce the number of lines or characters beyond the last example, but if anyone does come up with a tighter solution, please let me know!


Edit (20111005T22:43:50): Here’s a version I found that uses the Math::BigInt module

#!/usr/bin/env perl
 
use strict;
use warnings;
use feature "say";
use Math::BigInt lib=&gt;'GMP';
 
my $b = Math::BigInt-&gt;new($ARGV[0]);
say $b-&gt;bfac();

This version is likely much faster, since the Math::BigInt package is intended to be used in situations where large integers are being handled.

Here’s the post I found with examples written in other languages as well: Factorial Challenge: Python, Perl, Ruby, and C