Matching a word in any number of characters

I have need of some code to match any of a number of words in any number
of characters from the beginning of the word between the smallest number
of characters that will uniquely identify it and the total number of
characters in the word. My solution so far has been a set of kind of
ugly, but conceptually simple, regular expressions:

def expand_attribute_arg(attr)
  if attr.to_s.downcase.match(
    /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/
  )
    return 'Strength'
  elsif attr.to_s.downcase.match(
    /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/
  )
    return 'Dexterity'
  elsif attr.to_s.downcase.match(
    /^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/
  )
    return 'Constitution'
  elsif attr.to_s.downcase.match(
    /^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/
  )
    return 'Intelligence'
  elsif attr.to_s.downcase.match(
    /^w[i]?[s]?[d]?[o]?[m]?$/
  )
    return 'Wisdom'
  elsif attr.to_s.downcase.match(
    /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/
  )
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit(1)
  end
end

The code works fine, but it just looks ugly and redundant to me, and I
wonder if there’s some simple, elegant approach that escapes me at the
moment. Does anyone have any (fairly simple) ideas for how to tidy that
up a bit? I keep staring at it and thinking “There should be a way to
do
this with an array of the terms to match that doesn’t involve eval,” but
it’s just not coming to me.

I have need of some code to match any of a number of words in any number
of characters from the beginning of the word between the smallest number
of characters that will uniquely identify it and the total number of
characters in the word. My solution so far has been a set of kind of
ugly, but conceptually simple, regular expressions:

There is nothing “kind of ugly” about it and it doesn’t “work fine”. The
regexps are very ugly and as you can see below, they’re ugly enough
that it is hard to see that they’re wrong and fit to match a lot more
than they should. I edit one step at a time and describe each step above
the method.

original - flog: 35.1

def expand_attribute_arg1(attr)
if attr.to_s.downcase.match(
/^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/
)
return ‘Strength’
elsif attr.to_s.downcase.match(
/^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/
)
return ‘Dexterity’
elsif attr.to_s.downcase.match(
/^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/
)
return ‘Constitution’
elsif attr.to_s.downcase.match(
/^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/
)
return ‘Intelligence’
elsif attr.to_s.downcase.match(
/^w[i]?[s]?[d]?[o]?[m]?$/
)
return ‘Wisdom’
elsif attr.to_s.downcase.match(
/^ch[a]?[r]?[i]?[s]?[m]?[a]?$/
)
return ‘Charisma’
else
puts “#{attr} is an invalid attribute value.”
exit(1)
end
end

remove stupid formatting and align - flog: 35.1

def expand_attribute_arg2(attr)
if attr.to_s.downcase.match /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/
return ‘Strength’
elsif attr.to_s.downcase.match /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/
return ‘Dexterity’
elsif attr.to_s.downcase.match
/^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/
return ‘Constitution’
elsif attr.to_s.downcase.match
/^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/
return ‘Intelligence’
elsif attr.to_s.downcase.match /^w[i]?[s]?[d]?[o]?[m]?$/
return ‘Wisdom’
elsif attr.to_s.downcase.match /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/
return ‘Charisma’
else
puts “#{attr} is an invalid attribute value.”
exit 1
end
end

remove unnecessary to_s.downcase.match - flog: 9.7

def expand_attribute_arg3 attr
if attr =~ /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/i
return ‘Strength’
elsif attr =~ /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/i
return ‘Dexterity’
elsif attr =~ /^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/i
return ‘Constitution’
elsif attr =~ /^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/i
return ‘Intelligence’
elsif attr =~ /^w[i]?[s]?[d]?[o]?[m]?$/i
return ‘Wisdom’
elsif attr =~ /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/i
return ‘Charisma’
else
puts “#{attr} is an invalid attribute value.”
exit 1
end
end

remove unnecessary regexp [c][a][s][e][s] - flog: 9.7

def expand_attribute_arg4 attr
if attr =~ /^st?r?e?n?g?t?h?$/i
return ‘Strength’
elsif attr =~ /^de?x?t?e?r?i?t?y?$/i
return ‘Dexterity’
elsif attr =~ /^con?s?t?i?t?u?t?i?o?n?$/i
return ‘Constitution’
elsif attr =~ /^in?t?e?l?l?i?g?e?n?c?e?$/i
return ‘Intelligence’
elsif attr =~ /^wi?s?d?o?m?$/i
return ‘Wisdom’
elsif attr =~ /^cha?r?i?s?m?a?$/i
return ‘Charisma’
else
puts “#{attr} is an invalid attribute value.”
exit 1
end
end

switch to case - flog: 9.6

def expand_attribute_arg5 attr
case attr
when /^st?r?e?n?g?t?h?$/i
return ‘Strength’
when /^de?x?t?e?r?i?t?y?$/i
return ‘Dexterity’
when /^con?s?t?i?t?u?t?i?o?n?$/i
return ‘Constitution’
when /^in?t?e?l?l?i?g?e?n?c?e?$/i
return ‘Intelligence’
when /^wi?s?d?o?m?$/i
return ‘Wisdom’
when /^cha?r?i?s?m?a?$/i
return ‘Charisma’
else
puts “#{attr} is an invalid attribute value.”
exit 1
end
end

now that it is a lot less complex, you can see a lot more clearly

that the regexps involved match a lot more than intended. eg: stgth

either, you need s(?:t(?:r(?:e(?:n(?:g(?:t(?:h)?)?)?)?)?)?)? (ugh)

or you need an entirely different approach: - flog: 13.6

def expand_attribute_arg6 attr
{
“strength” => 1,
“dexterity” => 1,
“constitution” => 2,
“intelligence” => 1,
“wisdom” => 1,
“charisma” => 2,
}.each do |str, len|
return str.capitalize if attr.size >= len and
str.index(attr.downcase) == 0
end
end

or:

require “abbrev”

attribs = %w(strength dexterity constitution intelligence wisdom
charisma)
ATTRIBS = Abbrev::abbrev attribs

use abbrev - flog: 2.6

def expand_attribute_arg7 attr
ATTRIBS[attr.downcase]
end

P.S. NEVER exit from a library method. Raise and exit above.
Rescuable, testable, maintainable.

On Fri, Mar 18, 2011 at 05:15:08PM +0900, Ryan D. wrote:

There is nothing “kind of ugly” about it and it doesn’t “work fine”.
The regexps are very ugly and as you can see below, they’re ugly
enough that it is hard to see that they’re wrong and fit to match a lot
more than they should. I edit one step at a time and describe each step
above the method.

I find your attitude distasteful. Have you tried being a pleasant human
being and found it not to your liking, or have you simply never tried
it?

. . . and you did not actually show that they match more than they
should.

[snip]

remove stupid formatting and align - flog: 35.1

“Stupid formating” is “limit column width”, which is helpful in a number
of environments in which the code needs to be read and/or edited,
including email.

remove unnecessary to_s.downcase.match - flog: 9.7

Actually, the to_s.downcase was moved elsewhere in the code anyway
shortly after I sent this email. In fact, I thought it had been changed
before I pasted into the email, but apparently I did that in the wrong
order. The to_s is not unnecessary, though, considering certain
non-string values are possible in the method argument (something I did
not explain in the previous email, but that I figured anyone with half a
brain might figure out from the presence of the to_s message). The
downcase is more explicit and noticeable than the regex “i” at the tail
end of an ugly regex. In Ruby code, I prefer .match over =~, because I
prefer to write Perl only when writing Perl, and not when writing Ruby.

remove unnecessary regexp [c][a][s][e][s] - flog: 9.7

Yeah, I don’t know what I was thinking with the brackets. I had a brain
fart. Thanks for pointing out that boneheaded maneuver on my part.

Strangely, two people who can write Perl in their sleep and are more
intimately familiar with regex syntax than with their wives also looked
at this code and completely failed to notice the unnecessary brackets.
I
don’t know how that happened.

switch to case - flog: 9.6

Now the .match method becomes unnecessary. Good call, going with the
case statement.

"intelligence" => 1,

attribs = %w(strength dexterity constitution intelligence wisdom charisma)
ATTRIBS = Abbrev::abbrev attribs

use abbrev - flog: 2.6

def expand_attribute_arg7 attr
ATTRIBS[attr.downcase]
end

Thanks for that. The first, especially, is the kind of solution I
wanted.

P.S. NEVER exit from a library method. Raise and exit above.
Rescuable, testable, maintainable.

P.S. Never be an asshole. It tends to make people ungrateful even when
you’ve helped them. Your opening made you come off like a jackass with
an urge to belittle people, who offers helpful coding advice only as an
unintended side-effect of serving that urge.

Your opening made you come off like a jackass with
an urge to belittle people, who offers helpful coding advice only as an
unintended side-effect of serving that urge.

Well, good advice is good advice and Ryan gave you plenty, for free. In
this
case being an asshole is just damaging him, since you pretty much got
what
you wanted and he’s the one who came off as high and mighty.

I honestly feel that we, as programmers, don’t need all that “feel good”
bullshit that permeates pretty much all other engineering fields. Ryan’s
been
an “asshole” on this list to me too, but a right asshole and that is
all
that matters to me.

Please don’t be offended by this kind of behaviour, it’s what keeps our
craft
afloat and alive.

Andrea D.

On Mar 18, 2011, at 02:18 , Chad P. wrote:

Even when I come off as arrogant and self-righteous, I am not an asshole;

I was gonna let this thread go until you said that.

Actually on many occasions I’ve thought you were an asshole (and I’m
not the only one, believe me)… I’ve even called you out for it on this
very list. Despite that, I decided to respond to your mail anyways… Go
figure. So now you’re an asshole AND a hypocrite. Oh, and saying
“thanks, asshole” is not exactly a form of gratitude (not that I thought
I’d get any from you (or wanted any for that matter)).

Believe it or not, but my response wasn’t really to help you improve
your code. It was more for the other readers out there who could look
upon the steps one by one and see the thought process behind it.

Now you can have the last word. again. because for some reason you need
it.

On Fri, Mar 18, 2011 at 05:59:20PM +0900, Andrea D. wrote:

Well, good advice is good advice and Ryan gave you plenty, for free. In
this case being an asshole is just damaging him, since you pretty
much got what you wanted and he’s the one who came off as high and
mighty.

I agree – but:

I honestly feel that we, as programmers, don’t need all that “feel good”
bullshit that permeates pretty much all other engineering fields. Ryan’s been
an “asshole” on this list to me too, but a right asshole and that is all
that matters to me.

Meanwhile, I was trying to be helpful, if not particularly diplomatic in
the process, by pointing out that being an asshole has consequences. I
also thanked him a couple of times where good advice was given, and
while I was undiplomatic I was also not taking a belittling attitude
toward him.

Please don’t be offended by this kind of behaviour, it’s what keeps our craft
afloat and alive.

No, it’s not. I have pretty thick skin; I can take it. I do not think
that being an asshole helps keep “our craft afloat and alive”, though.
I
think being right does not necessitate being an asshole. Even when I
come off as arrogant and self-righteous, I am not an asshole; I do not
start out in a response to someone who is geinuinely asking for help and
willing to admit the faults in his or her code by trying to make him or
her feel stupid and unworthy. I only try to make people feel stupid and
unworthy when they demonstrate a relentless desire to ignore any and all
good advice.

Ryan may be knowledgeable, and he did give me some good advice. On
the
other hand, he made unwarranted assumptions about the needs of my code,
conflates his own personal desire to write Perl in Ruby with a One True
Coding Style, and acted like a grade A shitheel. I know programmers who
are probably twice the programmer he is (at minimum) who give better
advice and are much nicer about it, proving that being an asshole is not
a prerequisite for being good.

Here’s a nice test of whether he’s also a hypocrit:

Will he take good advice (stop being an asshole) after I took his own
good advice (without taking his bad advice)?

In any case, it’s worth noting that my thanks were genuine. I’m glad he
responded with some good advice buried amidst his eagerness to behave
badly, and made use of that advice. I’d be happier getting more asshole
attitude coupled with good advice from him than getting a good attitude
with no good advice. I don’t see why that would mean I shouldn’t point
out when he’s being an asshole, though.

On Fri, Mar 18, 2011 at 06:46:20PM +0900, Ryan D. wrote:

this very list. Despite that, I decided to respond to your mail
anyways… Go figure. So now you’re an asshole AND a hypocrite. Oh, and
saying “thanks, asshole” is not exactly a form of gratitude (not that I
thought I’d get any from you (or wanted any for that matter)).

Really? Please direct me to where I was being an asshole. If it’s on
this list, there should be a record of it somewhere on the Web. I’m
curious, and would like to know whether I actually did such a thing so I
can perhaps avoid it in the future. I frankly do not remember you ever
talking to me before this, though, so I’m a little skeptical of the
claim
that you’ve called me on being an asshole on this list before. It must
have been a long time ago.

I thanked you for good advice when it was given. I called you an
asshole
when you were an asshole. There’s nothing unreasonable about thinking
you’re an asshole and thinking you gave good advice.

Believe it or not, but my response wasn’t really to help you improve
your code. It was more for the other readers out there who could look
upon the steps one by one and see the thought process behind it.

I believe it. I believe you would rather set me on fire than actually
help me. Regardless, you still helped me, so thanks. I appreciate it,
regardless of your desire to help or harm me.


Chad P. [ original content licensed OWL: http://owl.apotheon.org ]

unworthy when they demonstrate a relentless desire to ignore any and all
good advice.

I probably expressed myself badly. Certainly, being an asshole is not a
necessary requirement for being a good programmer. Also, I didn’t mean
to say
that behaving the way Ryan (and many others in the field) usually does
is a
good thing.

I believe that when somebody behaves the way Ryan did is usually out of
personal insecurity (i.e. I’m afraid I don’t know enough so I shoot down
to
anyone I can to make myself feel a little more secure). Let me also tell
you
Ryan is very good, I’ve read the code, but if he’s the way I am no
amount of
positive feedback is going to soothe that need to get better: I was like
that
in my younger years, I want to believe I’ve grown out of it at least for
what
concerns the attitude towards other people… but I know where that’s
coming
from. So I’m telling you to avoid taking it personally, because it’s
not.

Will he take good advice (stop being an asshole) after I took his own
good advice (without taking his bad advice)?

In any case, it’s worth noting that my thanks were genuine. I’m glad he
responded with some good advice buried amidst his eagerness to behave
badly, and made use of that advice. I’d be happier getting more asshole
attitude coupled with good advice from him than getting a good attitude
with no good advice. I don’t see why that would mean I shouldn’t point
out when he’s being an asshole, though.

When I’m saying that this kind of behaviour is what “keeps our craft
afloat and
alive”, I refer to the attitude, not to the socially inappropriate
behaviour.
Okay, it’s annoying, but I think that this “I don’t give a fuck if you
take it
personally” attitude is great to have and I’m happy to pay the little
price of
having someone offend me personally every now and then. I’ve worked in
fields
where it’s the other way around (so, content doesn’t matter as long as
you
present it in a “politically correct” fashion) and, let me tell you,
it’s much
much better this way.

Also, again, it’s really nothing personal. Don’t feel bad because it’s
not
really towards you. I know it sucks and it’s annoying but I think it’s
very
important that the community keeps focused on code and on ideas and not
on who
writes them… and I think that “enforcing” politeness doesn’t help in
that
matter.

Andrea D.

On Fri, Mar 18, 2011 at 07:38:56PM +0900, Chad P. wrote:

I’m not the only one, believe me)… I’ve even called you out for it
the claim that you’ve called me on being an asshole on this list
before. It must have been a long time ago.

Okay, never mind – I found one instance where you called me an “ass”.
I
pointed out to someone that his pointlessly hostile commentary on Perl
was unnecessary, and in so doing suggested that one of his comments
might
be a “personal problem”. You took exception to that, though if that was
asshole-ish of me, it was so mildly asshole-ish that I strongly suspect
your real motivation was to support claims that Perl is stupid and
should
die. Given the circumstances, where my comment was only in response to
someone else being kind of borderline asshole-ish, I think my behavior
there was more akin to my behavior here (simply being a little impolite
in how I point out you’re being an asshole) than like yours (actually
being an asshole who delights in slinging insults). I suppose your
interpretation may vary, but from where I’m sitting my comment doesn’t
look too hypocritical.

(link to archive of thread elided to protect the guilty)

Further searching for cases where both our names come up only yields
threads where, for instance, I offer a salient response to the
originator
of a thread about Web development in Ruby without using Rails, and you
get called a troll for being an unpleasant asshole to people.

Like I said, though, I suppose your interperetation of my behavior might
be different than mine. I accept that, in your opinion, I might have
been an asshole in the past. I hope you accept that, as explained
above,
the definition of “asshole” I used in this thread does not cover the
behavior in the discussion of Perl’s mythic failings where you called me
an “ass” and asserted that Perl cannot be parsed.

I’m going to bed now, so if you have something else to say, I encourage
you to get the last word.

Strangely, two people who can write Perl in their sleep

Hmmmm…perl.

On Fri, Mar 18, 2011 at 07:18:23PM +0900, Andrea D. wrote:

her code by trying to make him or her feel stupid and unworthy. I
only try to make people feel stupid and unworthy when they
demonstrate a relentless desire to ignore any and all good advice.

I probably expressed myself badly. Certainly, being an asshole is not a
necessary requirement for being a good programmer. Also, I didn’t mean
to say that behaving the way Ryan (and many others in the field)
usually does is a good thing.

Thanks for clarifying that. I was uncertain how you meant what you
said,
so I just went with the literal grammatical meaning; apparently, that
was
not representative of your intention, and I apologize for my error of
interpretation.

I believe that when somebody behaves the way Ryan did is usually out of
personal insecurity (i.e. I’m afraid I don’t know enough so I shoot
down to anyone I can to make myself feel a little more secure). Let me
also tell you Ryan is very good, I’ve read the code, but if he’s the
way I am no amount of positive feedback is going to soothe that need to
get better: I was like that in my younger years, I want to believe I’ve
grown out of it at least for what concerns the attitude towards other
people… but I know where that’s coming from. So I’m telling you to
avoid taking it personally, because it’s not.

I’m not sure that’s the case, at least for me, given his follow-up
response to me. He claims to recall some past exchange with me (though
I
wonder if he’s confusing me with some other Chad) as being unpleasant,
and uses that to make some claims about my character, et cetera. Still,
it only bothers me in that:

  1. it obscures the positive content he contributes

  2. it makes Rubyists in general look bad

He hasn’t yet said anything that actually bothers me for the effect it
has on me, though I reserve the right to change my opinion on that if
he starts claiming some kind of criminal behavior on my part or
something
equally prone to damaging my reputation. Mere insulting treatment from
Internet strangers is no big deal.

Ryan may be knowledgeable, and he did give me some good advice. On
the other hand, he made unwarranted assumptions about the needs of my
code, conflates his own personal desire to write Perl in Ruby with a
One True Coding Style, and acted like a grade A shitheel. I know
programmers who are probably twice the programmer he is (at minimum)
who give better advice and are much nicer about it, proving that
being an asshole is not a prerequisite for being good.

Here’s a nice test of whether he’s also a hypocrit:

(oops, typo)

When I’m saying that this kind of behaviour is what “keeps our craft
afloat and alive”, I refer to the attitude, not to the socially
inappropriate behaviour. Okay, it’s annoying, but I think that this “I
don’t give a fuck if you take it personally” attitude is great to have
and I’m happy to pay the little price of having someone offend me
personally every now and then. I’ve worked in fields where it’s the
other way around (so, content doesn’t matter as long as you present it
in a “politically correct” fashion) and, let me tell you, it’s much
much better this way.

Oh, yeah, I’m a big believer in “tell it like it is, and if you take it
personally that’s your problem”. He goes well beyond that, though, at
least in his responses to me.

Also, again, it’s really nothing personal. Don’t feel bad because it’s
not really towards you. I know it sucks and it’s annoying but I think
it’s very important that the community keeps focused on code and on
ideas and not on who writes them… and I think that “enforcing”
politeness doesn’t help in that matter.

I think that peppering his response with distracting personal jabs (and
he really does seem to be targeting me personally; see above) is
actually
doing us a disservice. If he says “Oh, damn, you have some big problems
in this code,” then points them out, fine. If he says “You’re an idiot,
fuck off, and let me tell you why you’re an idiot,” that actually serves
to obscure the positive value he might provide – not only to readers,
but to him as well. He was so invested in pointing out I’m inferior to
him that he made unwarranted and incorrect assumptions about the needs
of
my code, and thus “corrected” things that were not incorrect.

If he had laid off the laser focus on being an asshole, he might have
provided better advice. My taking exception to his approach was
entirely
predicated upon agreement with your idea that “it’s very important that
the community keeps focused on code”.

In short: you don’t have to be polite, but don’t let an overzealous
desire to be rude distract you from being correct.

. . . and like I pointed out, I don’t feel bad. It was actually kind of
gratifying to see him step on his own dick in the mad rush to ridicule
me, so I’m feeling pretty good; I got an answer to my question and I
saw an asshole make an ass of himself in the process.

I guess next time I should just avoid trying to give advice about how to
give better advice and avoid looking like an asshole, though.

On Sat, Mar 19, 2011 at 08:15:59AM +0900, 7stud – wrote:

Strangely, two people who can write Perl in their sleep

They may be able to write perl in their sleep, but they don’t know jack
about regexes. Anyone who doesn’t use /xms flags and then format their
regexes properly is not a regex expert.

. . . or, like me, they were suffering insomnia and overlooked that
part.

Are you learning how to be a pleasant human being from Ryan?