Have a blog? Use it

Craig Maloney - Fri, 09/22/2017 - 12:25

I just noticed some behavior on Twitter that I find rather revolting.

An author decided to post an entire blog-post's worth of material (as replies) to their Twitter stream.

Which under normal circumstances I can appreciate and relate. I've had ideas that were started on Twitter and because a series of @replies to myself. But that was because I was in the heat of the moment and was formulating these replies "in-the-moment". There was a pause in between each @reply.

Not this author. They literally had it set up where the entire posting was scheduled in such a way where my entire timeline was nothing but their post. Worse, it was still coming.

Why?

Why would you do this to your ostensible readers?

I'm assuming you, dear author, have a blog or some place where you can post these ideas. And if you, dear author, have such a platform then why the fuck didn't you use it and then use Twitter / other social medium to direct readers to that instead of using Twitter as your diuretic for pushing it out one tweetstorm at a time?

Seriously, Twitter is a shitty blog. Stop using it as such.

(Insert separate rant about not using RSS for your blog either).

Categories: LugNut Blogs

Interview Questions: Tell me about a project you are proud of and why?

Craig Maloney - Wed, 08/23/2017 - 12:15

An interview question I've received a lot during my interviewing is "Tell me about a project you are proud of and why are you proud of it". It's one of those "think about your career and tell me what one project stood out for you, and why it stands out" questions that feels like it is a good measure of interview candidates.

But one of the downsides is it's also a question that gets self-edited to the bits that I can show a potential employer.

At my last job I created a sort of "stylesheet for Excel" using openpyxl. Unfortunately the only thing I can show you is a gist that I posted to the openpyxl mailing list. The maintainer of the project didn't know what to do with it (and frankly I'm not sure the problem translated outside of the project that I was working on) but it worked and helped me style some pretty hoary spreadsheet reports.

But is that the project that I tell people about? Nope. Why? Because there isn't that much code there to show folks. And frankly it isn't an interesting story. "I made a configuration system to style Excel Spreadsheets so people could take these and pass along to our customers" isn't the sort of thing that excites people.

So what story do I tell? I tell them about the time when I created some photobooth software for a friend's wedding. He was getting married and wanted some more features for his Raspberry Pi project. Unfortunately it was taking longer than he anticipated so I wrote a new photobooth for him in Pygame. You can take a look at the code right now (Pygame Photobooth) and see what I did. Why am I proud of it? Because I helped out a friend during his time of need and it was cool to see people playing with it. It's still in use today.

That's a story! It has conflict! Drama! A climax! A happy ending! Exclamation points! And you can see the code!

Is it the project I'm most proud of? Possibly. There's a few other projects that I've done over the years that I can't show people. Projects like the system that completely automated mailing surveys for a customer. Projects that rewrote a Visual Basic system that was never going to work as written (and re-wrote it for the web). Projects like the imagemap that showed rooms that needed service.

But I can't show you the code that I wrote. You'll just have to take my word that they're awesome and made people happy. All of that code sits on disks behind firewalls; save for the little bit that I liberated on a mailing list.

And that's why you get the project that did make people happy; the project that made a friend's wedding all the better. Did it save the company money? Who cares? Did it surprise and delight the customer? I'd like to think so. Did it arrive on-time and under-budget? Well, they used it for their wedding so you tell me.

Questions like this favor people who can tell good stories about their projects. They also have a high bias towards projects where the person involved felt happiest while doing the project. They also tend to favor projects where the person can show you the code.

What about the times when the developer was on a death-march and everything was going wrong for them? What about the projects where the customer said "that's nice" and when the developer left the project died (that was the Visual Basic project that I worked on). What about the times when the developer didn't listen to management and took advantage of a brief window where they re-wrote the whole system and put it up on the web (That Visual Basic project again).

You're not going to get those stories out of an interview question like this. You're only going to get the highlight reel. And much like sports highlight reels you're going to get the stories that have the best visuals. You're going to get the ones that have the best stories to tell, with code that can be shared.

What are some of the stories that you have about developing projects?

Categories: LugNut Blogs

Facebook's React patent grant is disingenuous and harmful

Craig Maloney - Sun, 08/20/2017 - 15:34

I had some word-spew on Twitter about Facebook and their React.JS patent grant and decided to put it into a blog post:

Find it super interesting that the discussion about the React License has boiled down to resharing two Medium articles. The "Paper Tiger" and the "Startups should avoid React" articles. Depending on what you believe reflects which article gets reshared. Unfortunately I think both articles don't concentrate on the point of the patent exemption and why it's a real sticking point for developers and that's this: Facebook is trying to take their software and carve out a competitive edge in the software patent minefield. It's not that Facebook will steal your patents, or that Facebook will make you have to rewrite your software if they compete with you - It's that Facebook is taking a popular library / framework they wrote and are using it to deflect some of their legal pain. They're taking a nominally open source product of theirs and neutering patent lawsuits against Facebook (or at least diffusing them); giving folks pause about using their software patents because they could run afoul of a patent grant. I'm no fan of software patents (I think they're anathema to software development) but Facebook's Patent Grant does not solve the problem - it exacerbates the problems between intellectual property and intellectual freedom. It carves an exemption for Facebook alone. It's disingenuous of Facebook and creates a "I've got mine; sucks to be you" mentality that I find abhorrent in FL/OSS. This is not liberty.

Categories: LugNut Blogs

Raindrops puzzle on Exercism

Craig Maloney - Tue, 08/15/2017 - 11:28

One of the puzzles on Exercism is the Raindrops Puzzle. In this puzzle you find the numbers that divide into the original number (aka: factors). An example of this is the number 28 where 28 can be divided by the following numbers: 1, 2, 4, 7, 14, 28. (Remember that 1 divides into all numbers, and all numbers are divisible by themselves).

The challenge is to output one of the following:

  • If 3 is one of the numbers that are divisible by the original number then display "Pling"
  • If 5 is one of the numbers that are divisible by the original number then display "Plang"
  • If 7 is one of the numbers that are divisible by the original number then display "Plong"
  • If the number is not divisible by any of the above display the original number.

So in the case of 4 we factor that (1, 2, 4) and see that 3, 5, or 7 are not in those factors and display 4. For a number like 5 we note that (1, 5) are its factors and since 5 is in that set of factors we display "Plang". In the 28 example above we note that 7 is one of the numbers, and display "Plong".

Where it gets interesting is a number like 15. 15's factors are (1, 3, 5, 15). In this case we first check if the number 3 is one of the factors. 3 is present in the factors so we display "Pling". But note too that 5 is also one of the factors, so we also need to display "Plang". The correct output is "PlingPlang", and we display "PlingPlang" instead of the number 15.

With that in mind I started to attack the problem. This problem was part of the Scheme track so I started thinking how I'd approach this.

The first part was getting the factors out. That suggested "recursion" but my recursion is rusty. I knew that I could easily blow the stack with larger numbers so it would need to be tail-recursive. And that's about where my brain said "do you know how to write a tail-recursive routine because I sure don't?". So I checked Google and found a few examples (one of which lead me down figuring out how to use let to create a loop, so that was interesting).

Just for grins I wrote an iterative version in Python:

def factor(n): factors = [] for i in range(1, n+1): if (n % i == 0): factors.append(i) return factors def main(): print(factor(28)) print(factor(34)) if __name__ == "__main__": main()

Hmm, maybe I don't need recursion after all. This seems to be quick and does the trick. But is that Scheme? Scheme tends to favor recursion over looping (in my experience) so I needed a different approach, and with code that I could ultimately understand.

I found a Prime Decomposition in Scheme on Rosetta Code:

(define (factor number) (define (*factor divisor number) (if (> divisor number) (list number) (if (= (modulo number divisor) 0) (cons divisor (*factor divisor (/ number divisor))) (*factor (+ divisor 1) number)))) (*factor 2 number)) (display (factor 28)) (newline)

Ah, that sort of does what I want. I played with it a bit and came up with my own factorization algorithm / program:

(define (factor number) (define (*factor divisor number) (if (>= divisor number) (list number) (if (= (remainder number divisor) 0) (cons divisor (*factor (+ 1 divisor) number )) (*factor (+ divisor 1) number)))) (*factor 1 number)) (display (factor 28)) (newline)

They may look similar but the key difference is in the (cons divisor (*factor (+ 1 divisor) number )) line (and the (*factor 1 number) instead of 2 line). The original algorithm cut the space for searching in half (which is great if you're looking for primes). But in the case of 28 I wanted 2 * 14 = 28. I wanted 4 * 7 = 28 (7 being one of the factors that causes "Plong" to occur). Instead I got '(2 2 7 1) which sort-of-works, but isn't what I wanted. With the re-worked algorithm I got what I wanted:'(1 2 4 7 14 28).

Next came learning how to append strings in Scheme. That wasn't nearly as difficult as I thought it would be ((set! outstring (string-append outstring "Foo")), but what was slightly non-obvious to me was determining if an element is in the list.

Scheme has a function called memq which will find an element and return the rest of the list. So if I have a list '(1 2 3 4 5) and I want to see if 4 is in that list I can use (memq 4 '(1 2 3 4 5)) and get '(4 5) as the result. If I do the same for 6 ((memq 6 '(1 2 3 4 5))) I get back #f. In Scheme the presence of a list can be tested using if, so checking if we have a list or don't becomes (if (memq 3 factors) ...).

Appending a string in

Here's the completed code (and a link to comment on Exercism):

(define-module (raindrops) #:export (convert)) (define (factor number) (define (*factor divisor number) (if (>= divisor number) (list number) (if (= (remainder number divisor) 0) (cons divisor (*factor (+ 1 divisor) number )) (*factor (+ divisor 1) number)))) (*factor 1 number)) (define (convert number) (let ((outstring "") (factors (factor number))) (if (memq 3 factors) (set! outstring (string-append outstring "Pling"))) (if (memq 5 factors) (set! outstring (string-append outstring "Plang"))) (if (memq 7 factors) (set! outstring (string-append outstring "Plong"))) (if (string=? outstring "") (number->string number) outstring ) ) )
Categories: LugNut Blogs

100 day challenge: Final results

Craig Maloney - Sat, 08/12/2017 - 08:48

In the spirit of the 100 day challenge I wrote a quick program to parse the tags of the 100day challenge and note which tags were most often used.

#!/usr/bin/env python from collections import Counter def main(): tag_counter = Counter() with open('100day_tags', 'rt') as infile: for line in infile.readlines(): line = line.strip().lower() (filename, spacer, tag_string) = line.split(':') tags = [x.strip() for x in tag_string.split(',')] for tag in tags: tag_counter[tag] += 1 del tag_counter['a day in the life'] del tag_counter['100day'] for i in tag_counter.most_common(): print("{tag}: {counter}".format( tag=i[0], counter=i[1])) if __name__ == '__main__': main()

The tags are from a simple grep 100day *.md > ~/100day_tags command in my Pelican directory.

programming: 39 scheme: 29 racket: 16 javascript: 10 python: 5 godot: 3 guile: 3 pyohio: 2 css: 2 c: 1 html: 1 html5: 1

It looks like Scheme / Racket were the ones that got the most attention. After that is JavaScript, then some Python and a few mentions of Godot.

Not sure if this means anything in particular but it's interesting to me.

Categories: LugNut Blogs

Day 70ish/100: Fin?

Craig Maloney - Thu, 08/10/2017 - 22:30

Apparently this is the second time that I can't count, and have double-counted days.

It's also another day where "life has become rather chaotic and programming was the last thing on my mind".

So I'm thinking about calling this done for now. I'm not planning on abandoning daily programming for now. But putting it as part of the daily challenge? That's becoming a bit much.

That and I'm feeling guilty about not blogging about other things that are happening.

So, it's done for now. Won't say this is the last time this will happen, but frankly I think it's run its course.

Categories: LugNut Blogs

Day 69/100: More reading / more Exercism / Hacker Rank

Craig Maloney - Wed, 08/09/2017 - 22:28

Worked a little on Exercism today. One of the problems I was working on required the use of factoring a number to find all of the divisors (eg: 4 can be divided by 4, 2, and 1). It's a recursive solution but I didn't know offhand how to write it in Scheme (shameface) and looked one up online. That got me down a rabbithole of trying to figure out what the solution I found was doing. That lead to trying to figure out how the debugger in Guile worked, which lead me to try the debugger in DrRacket instead (pro-tip: The IDE debugger in Racket is quite good.).

I also played around a bit with HackerRank. Expect a blog post on why I think HackerRank has its heart in the right place but the implementation needs a lot of work.

Categories: LugNut Blogs

Day 68/100: Reading / Exercism

Craig Maloney - Tue, 08/08/2017 - 22:23

Did a quick play around with Exercism and some reading.

Here's my solution for RNA Transcription in Python:

def to_rna(dna): dna_rna_trans = {'G': 'C', 'C': 'G', 'T': 'A', 'A': 'U'} rna_strand = [] dna_list = list(dna) for dna_nucleotide in dna_list: if dna_nucleotide not in dna_rna_trans: return '' else: rna_strand.append(dna_rna_trans[dna_nucleotide]) return ''.join(rna_strand)
Categories: LugNut Blogs

Day 68/100: Off my game / Reading

Craig Maloney - Mon, 08/07/2017 - 23:23

Today I was pretty well off my game. Did a lot of administrative work for MUG and what-not, but didn't get to doing much programming. Hoping to rectify this tomorrow (before the MUG meeting. :) )

Did a little reading here and there. Did a little reading of the Guile Manual. Still love this manual.

Categories: LugNut Blogs

Day 67/100: ...

Craig Maloney - Sun, 08/06/2017 - 23:34

...

(Yes, not a lot happened today).

Categories: LugNut Blogs

Day 66/100: Just some reading

Craig Maloney - Sat, 08/05/2017 - 23:03

Did some more reading, but not a whole lot else.

Categories: LugNut Blogs

Day 65/100: More Godot

Craig Maloney - Fri, 08/04/2017 - 22:31

Today I watched a few introductory videos to learn more about Godot. The more I look at this engine the more I'm falling in love with it. I can't wait to put together and release a game with it. Thinking about doing a Kaboom-style game with it.

Categories: LugNut Blogs

Day 64/100: Pangram

Craig Maloney - Thu, 08/03/2017 - 22:12

Today I worked on the Pangram solution for Exercism. Didn't quite get an hour in programming today but close enough.

Categories: LugNut Blogs

Day 63/100: Off-by-one error?

Craig Maloney - Wed, 08/02/2017 - 23:26

I think I managed to have two day 59s. Not sure if this means something is screwed up but whatever. I'm willing to call it good if you are. ;)

Today I worked on the Exercism problem called "Bob". This was a hard problem for me but I think I managed it well.

Here's a link to my solution to the Bob problem.

Categories: LugNut Blogs

Day 62/100: Working on other things

Craig Maloney - Tue, 08/01/2017 - 23:06

Today I had a few other things to work on, so I didn't get to programming. More to come.

Categories: LugNut Blogs

Day 61/100: Getting back into the swing

Craig Maloney - Tue, 08/01/2017 - 09:27

Day 61 was dedicated to catching up from the weekend. Now I need to get back into the swing of coding again. PyOhio is a great motivator to get the programming juices flowing again.

Categories: LugNut Blogs

Day 60/100: Decompression

Craig Maloney - Tue, 08/01/2017 - 09:25

Day 60 was traveling and decompression.

Categories: LugNut Blogs

PyOhio: Introduction to Debugging in Python Presentation

Craig Maloney - Mon, 07/31/2017 - 16:43

It looks like the video for my PyOhio presentation "Introduction to Debugging on Python" is up.

You can follow along with the slides and the sample code.

Hope you enjoy!

Categories: LugNut Blogs

Day 59/100: PyOhio Presenting

Craig Maloney - Sun, 07/30/2017 - 21:48

I gave a presentation at PyOhio today about the Python Debugger (here is a link to the slides). Had a great time, and am looking forward to the next PyOhio already.

Not a lot of "proper" programming today, but looking forward to getting back to it tomorrow.

Categories: LugNut Blogs

Day 59/100: PyOhio fun

Craig Maloney - Sun, 07/30/2017 - 11:54

Spent the day at PyOhio. Lots of interesting talks to digest. More later when I have some time to decompress.

Categories: LugNut Blogs

Pages