My code works, but the aesthetic of the code seems to need some real work. The logic is simple enough: 


Create three lists of words that will be used throughout the conversion
Create three functions: 

One for sub-1000 conversion
Another for 1000-and-up conversion
Another function for splitting and storing into a list of numbers above 1000.



First the code:

# Create the lists of word-equivalents from 1-19, then one for the tens group.
# Finally, a list of the (for lack of a better word) "zero-groups".

ByOne = [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen"
]

ByTen = [
"zero",
"ten",
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety"
]

zGroup = [
"",
"thousand",
"million",
"billion",
"trillion",
"quadrillion",
"quintillion",
"sextillion",
"septillion",
"octillion",
"nonillion",
"decillion",
"undecillion",
"duodecillion",
"tredecillion",
"quattuordecillion",
"sexdecillion",
"septendecillion",
"octodecillion",
"novemdecillion",
"vigintillion"
]

strNum = raw_input("Please enter an integer:\n&gt;&gt; ")

# A recursive function to get the word equivalent for numbers under 1000.

def subThousand(inputNum):
    num = int(inputNum)
    if 0 &lt;= num &lt;= 19:
        return ByOne[num]
    elif 20 &lt;= num &lt;= 99:
        if inputNum[-1] == "0":
            return ByTen[int(inputNum[0])]
        else:
            return ByTen[int(inputNum[0])] + "-" + ByOne[int(inputNum[1])]
    elif 100 &lt;= num &lt;= 999:
        rem = num % 100
        dig = num / 100
        if rem == 0:
            return ByOne[dig] + " hundred"
        else:
            return ByOne[dig] + " hundred and " + subThousand(str(rem))

# A looping function to get the word equivalent for numbers above 1000
# by splitting a number by the thousands, storing them in a list, and 
# calling subThousand on each of them, while appending the correct
# "zero-group".

def thousandUp(inputNum):
    num = int(inputNum)
    arrZero = splitByThousands(num)
    lenArr = len(arrZero) - 1
    resArr = []
    for z in arrZero[::-1]:
        wrd = subThousand(str(z)) + " "
        zap = zGroup[lenArr] + ", "
        if wrd == " ":
            break
        elif wrd == "zero ":
            wrd, zap = "", ""
        resArr.append(wrd + zap)
        lenArr -= 1
    res = "".join(resArr).strip()
    if res[-1] == ",": res = res[:-1]
    return res

# Function to return a list created from splitting a number above 1000.

def splitByThousands(inputNum):
    num = int(inputNum)
    arrThousands = []
    while num != 0:
        arrThousands.append(num % 1000)
        num /= 1000
    return arrThousands

### Last part is pretty much just the output.

intNum = int(strNum)

if intNum &lt; 0:
    print "Minus",
    intNum *= -1
    strNum = strNum[1:]

if intNum &lt; 1000:
    print subThousand(strNum)
else:
    print thousandUp(strNum)


Sample run:

&gt;&gt;&gt; 
Please enter an integer:
&gt;&gt; 95505896639631893
ninety-five quadrillion, five hundred and five trillion, eight hundred and ninety-six billion, six hundred and thirty-nine million, six hundred and thirty-one thousand, eight hundred and ninety-three 
&gt;&gt;&gt;


Issues:

Basically, the peeves I'm having are as follows:


My first two functions seems to be taking up too many lines. The first one, subThousand, seems to be this way because of the check made against the last digit of a number from 20 to 99. The logic I applied was, if it ends in 0, use the ByTen list. If it doesn't combined ByTen and ByOne. While effective, I feel like it could use some real work since I think it qualifies as a DRY-violation. Even the final part checking for numbers from 100 to 999 seems to follow the same pattern. Alas, I've tried paring it down but I've honestly hit a roadblock on this one insofar as trying to come up with a creative and clean solution.
My second function, thousandUp is quite the disaster. I tried coming up with a looping function that creates a list of one to three-digit numbers, so that I can call subThousand on each of them from the front to the back (hence the arrZero[::-1]. At the same time, after converting each element in the list to a word, I concatenate it with the appropriate equivalent in the zGroup list, or the list of the "zero-groups". However, I personally can't find a safer and more precise way of landing on the "correct" spot in the zGroup list to start concatenating.

To get around this, I took the length of the splitByThousands array, adjusted for 0-index, and used it to get the appropriate "zero-append" (zap). Before the loop ends, I subtract one from its current value so that it's adjusted accordingly.
In addition, as I'm attempting to make the output as clean as possible, I add a " " to the wrd variable so it doesn't concatenate poorly with the zero-append, as well as add a ", " to the zero-append to separate it from the next zero-group. However, there will be instances that there are no values for some zero-groups. To avoid showing stuff like zero million, I added a check inside. This is the part that makes me die a little inside:

for z in arrZero[::-1]:
    wrd = subThousand(str(z)) + " "
    zap = zGroup[lenArr] + ", "
    if wrd == " ":
        break
    elif wrd == "zero ":
         wrd, zap = "", ""
    resArr.append(wrd + zap)
    lenArr -= 1



It works, but it just doesn't look good. Is it possible to do this in list-comprehension form or a better for-loop without turning it into more confusing mush?

I must admit as well that the last part of the code sucks a little. I've done a lot of str--&gt;int conversions inside the functions, then I did one more outside of them. On top of that, my approach to negative numbers is hackish at best (print "Minus").


Question: Log4j2 not logging to console
Answer: Loading your file and configurations on my machine works.

This was the class I used:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Test
{
    private final Logger logger = LogManager.getLogger(Test.class);

    public Test(String serialPortName) {
        System.out.println(logger.isInfoEnabled());
        logger.entry();
        logger.info("info! {}", serialPortName);
        logger.error("error! {}", serialPortName);
        logger.debug("debug! {}", serialPortName);
    }

    public static void main(String args[])
    {
        Test h1 = new Test("1001");
    }
}


This is the log4j2.xml:


   

   &lt;ThresholdFilter level="all"/&gt;

 &lt;Appenders&gt;
   &lt;Console name="STDOUT" target="SYSTEM_OUT"&gt;
     &lt;PatternLayout pattern="%d %-5p method: [%t] %C{2} (%F:%L) - %m%n"/&gt;
   &lt;/Console&gt;
 &lt;/Appenders&gt;
 &lt;Loggers&gt;
   &lt;Root level="all"&gt;
     &lt;AppenderRef ref="STDOUT"/&gt;
   &lt;/Root&gt;
 &lt;/Loggers&gt;




and finally, this is the output:

true
2014-05-29 12:19:15,266 TRACE method: [main] Test (Test.java:10) - entry
2014-05-29 12:19:15,268 INFO  method: [main] Test (Test.java:11) - info! 1001
2014-05-29 12:19:15,269 ERROR method: [main] Test (Test.java:12) - error! 1001
2014-05-29 12:19:15,269 DEBUG method: [main] Test (Test.java:13) - debug! 1001


One common error when using Log4j2 is placing the log4j2.xml in a file that is not in the classpath.

To diagnose if that is the problem, change the line 

logger.info("Opening serial port {}", serialPortName);


to

logger.error("Opening serial port {}", serialPortName);


If you see any output it is because log4j can't load your file. This is because the default log level when the file is not found is ERROR, not DEBUG.

The location of the log4j2.xml on my project (Maven) is in src/main/resources, which I know it is in my classpath.