-2

Alright, this is a tricky one. I'm looking to make a function which takes an input string, and returns it with a grammatically correct appendix.

Examples (input -> desired output):

  • apple -> an apple
  • car -> a car
  • honour -> an honour

At first I empty-headedly wrote a simple-enough function to check for a vowel at the start of the word and return one of the appendixes based on that... but then I was reminded that this isn't the only time to return "an" instead of "a", and that really it's based on the sound of the start of the input word. So my question is; what would be a good approach to translating this into code, without having to hardcode in a bunch of "special-case" words (or an entire dictionary!)?

I'm working in C# for this. I would prefer to write the code rather than use an external library, provided it wouldn't take up a large amount of time. The less dependencies the better!

EDIT 1

The initial code:

public static string ChooseAppendix(string inputString, bool includeInputString = true, bool capitalizeAppendix = false)
{
    if (string.IsNullOrEmpty(inputString))
        throw new Exception("Cannot choose an appendix for an empty string!");

    char c = inputString.ToLower()[0];

    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
    {
        if (includeInputString)
            return capitalizeAppendix ? $"An {inputString}" : $"an {inputString}";
        else
            return capitalizeAppendix ? "An" : "an";
    }
    else
    {
        if (includeInputString)
            return capitalizeAppendix ? $"A {inputString}" : $"a {inputString}";
        else
            return capitalizeAppendix ? "A" : "a";
    }
}
Logix
  • 530
  • 6
  • 15
  • 1
    Please share what you have tried so far. Also, just so you are aware, for honor it should be a honor and not an. H is not a vowel. – tomerpacific Sep 25 '20 at 05:14
  • 5
    @tomerpacific The `an` is right. The 'h' is silent in `honour`, – 大陸北方網友 Sep 25 '20 at 05:20
  • 2
    Say "a honour" out loud - it's incorrect (see [https://writingexplained.org/a-vs-an-difference](https://writingexplained.org/a-vs-an-difference)). The code so far simply makes the string lower-case (to reduce the amount of code needed to process), extracts the first character then compares it with each of the 5 vowels. If it matches a vowel, it returns `$"an {inputString}"`, otherwise it returns `$"a {inputString}"`. – Logix Sep 25 '20 at 05:21
  • 1
    Maybe you can check this thread [How can I correctly prefix a word with “a” and “an”?](https://stackoverflow.com/questions/1288291/how-can-i-correctly-prefix-a-word-with-a-and-an). – 大陸北方網友 Sep 25 '20 at 05:31
  • 1
    Well, Kyle, given their semi-sarcastic answer... I certainly don't think that would be wise. "Download Wikipedia" is not something someone just does unironically, to achieve correct grammar. It does seem like this may be a tricky (if not unfeasible) task, though. I think for a lot of the function's use-cases, a simple vowel check would suffice. However, this is also part of an API. – Logix Sep 25 '20 at 05:36
  • 1
    I just noticed the link the accepted answer had to a NuGet package they've made. Seems overkill at a glance, certainly for something so seemingly-unimportant (I care about my program using correct grammar, not doing so is unprofessional - but node trees, ratios, Wikipedia dumps?), and it also installed one serious group of references to the project - more than I care to count (at a rough guesstimate, 27?). For now I will try this, but if a better solution comes along which doesn't require so much data, that'd be great. – Logix Sep 25 '20 at 05:44
  • 3
    **A hotel** chef says **an honest** option is to use **an herb**. Except the Queen of England would say *a herb*. You're gonna need a long list of the irregularities and then fall to the generic rule if no match *for the locale you're using* (which is also an important factor) – Caius Jard Sep 25 '20 at 05:47
  • A Herb I know always uses an herb. – Michael Geary Sep 25 '20 at 05:51
  • 2
    Hurrah, it's not raining; not needing **an umbrella** is some kind of **a utopia** indeed.. – Caius Jard Sep 25 '20 at 05:51
  • @Logix meh, references schmeferences - good job VS doesn't list all their dependencies (and all their their dependencies) right the way down to every c++ DLL in the operating system. That graph would be a mess. All comes back to one place in the end though! – Caius Jard Sep 25 '20 at 05:54
  • You will have to use lists of words with siltent h (honour, heir, hour...) , of 'non-vowel' vowles (utopia, universe..) and even letter which can be consonants or vowels (y).. Natural languages, sigh – TaW Sep 25 '20 at 07:31

1 Answers1

0

For now I've settled with using AvsAn on NuGet (Thanks to this answer on a related question which did not appear in the suggestions when I was asking this one(!)): StackOverflow: How can I correctly prefix a word with “a” and “an”?

I've still kept it wrapped in my own function, just to make things easier to control:

public static string ChooseAppendix(string input, bool includeInput = true, bool capitalizeAppendix = true)
{
    string a_or_an = AvsAn.Query(input).Article;

    return $"{(capitalizeAppendix ? a_or_an.ToUpper() : a_or_an.ToLower())}{(includeInput ? $" {input}" : string.Empty)}";
}
Logix
  • 530
  • 6
  • 15
  • 1
    (not CLS compliant but) Things might get a bit neater if you were to use method overloads/extensions to carry your "includeInput" and "capitalizeAppendix" - for example having normal methods `an()/AN()` that are include and are lower/upper, and similarly extensions that don't include you could have your strings like `$"IT IS {AN(thing)}"` or `$"it is {thing.an()} {thing}"` rather than `$"it is {ChooseAppendix(thing, includeInput: false, capitalizeAppendix: false} {thing}"`. I'm also struck that "Appendix" doesn't seem a good word to use (this is an Article, not an appendix) – Caius Jard Sep 25 '20 at 07:18