Ubuntu: Connecting to office printer (Xerox WorkCentre 5955i) with Xerox Standard Accounting

I had a problem connecting to the printer in my department’s office at the University of Oregon, so here is a guide for my future self and others. I tried looking at posts on UbuntuForums, StackExchange, and the Xerox Support forums, but I mostly spent time in a rabbit hole of editing the driver and .ppd file myself. That never worked, so try this first.

My operating system is Linux (Ubuntu 16.04)
$ uname -a
Linux lumen 4.15.0-65-generic #74~16.04.1-Ubuntu SMP Wed Sep 18 09:51:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

The printer is a Xerox WorkCentre 5955i with accounting enabled (Xerox Standard Accounting). Accounting is a system configured on the printer by the department to track who is printing how much, but it seems this causes all sorts of problems connecting to the printer, even for Windows and Mac users.

First, Google the drivers. The first link in this picture is the one I clicked:

Change the operating system to “Linux” in the dropdown.

Select the driver you want based on your operating system. I used the second option shown, “Linux Intel Driver .DEB x86 64”.

1. Accept the license agreement.
2. Click on the downloaded .deb once it is done. I used Chrome, so the file opened in Ubuntu Software when I clicked on it.

In Ubuntu Software, the driver should be called “xeroxprtdrv”. Click “Install”.

Authenticate with your root password if necessary.

1. Once the driver is installed, open a terminal and run the command “xeroxprtmgr” as root.
2. The Xerox Printer Manager GUI will open. For me it often took a while and looked like it had frozen, but resist the temptation to just kill it and try something else. Click on the button with two downward-pointing triangles.

The “Install Printers” dialog will open. Click on the button that looks like a little menu and select “Manual Install”.

The “Queue Settings” dialog will open.
Fill out “Queue Name” (with any string you want to nickname the printer). Select the “Printer Model” (here, “Xerox WorkCentre 5955”).
“Connection Type” should be “TCP/IP (Workstation to Printer)”.
“IP/DNS” should be the printer’s IP address given to you by the department or IT or whoever.
Click “OK”.

Back in the main window of Xerox Printer Manager, you should see the printer you just added. Select it and click the button that looks like a little menu. Select “Queue Preferences”. If it hangs, just wait for it. The “Queue Settings” option will reopen the window you were just in, in case you want to edit those settings.

The dialog named “Xerox WorkCentre 5945/5955 PS” (or whatever printer you are using) should appear. Click on the “Configuration” tab.

Click the “Accounting” button.

“Accounting System” should be “Xerox Standard Accounting”.
I set “Accounting Prompt” to “Always Prompt” so I would get a prompt to enter my user ID, rather than having it put into a config file and sending me down some future rabbit hole again.
I unchecked “Mask User ID” and “Mask Account ID” because I hate password masking, and my ID for this is just a default anyway.
I left “Default User ID” blank.
“Default Account Type” should be “Default Group Account”.
I left “Default Account ID” blank.
So I guess I didn’t change much in this dialog, so perhaps this step is unnecessary. But whatever.

Go make something to print as a test. I created a LibreOffice Writer document containing the text “asdf”. I also recommend this PDF. Print it, and select your printer’s nickname in the dialog. Here mine is “uoling”.

A dialog named “Xerox WorkCentre 5945/5955 PS” (or whatever printer you’re using) will appear. This looks VERY SIMILAR to one you have seen previously, but it lacks the “Configuration” tab. Click “Print”.

The “Accounting” dialog should appear. Here you will enter your user ID given to you by your department or IT or whoever. In my case, “Account ID” should be left blank and “Account Type” should be “Default Group Account”. Click “OK”.

Your document should print!

A Pictograph-Based Alphabet for English

On a road trip in Colorado in March 2015, a friend and I had the idea to create an alphabet for English that was based on the same basic principle as Phoenician: represent each sound with a pictograph for a word using that sound. For example, we chose “moon” for /m/. (Although of course Phoenician evolved from the long-existing hieroglyphic system and was not designed this way, I figured it was not worth the trouble to create such a thing only for the purpose of turning it into an alphabet and throwing away the vast majority of signs.) For some sounds, especially less-common vowels like /ʊ/ or consonants like /ʒ/, we couldn’t come up with common, easily depictable words where they occurred initially. In those cases we just picked something that used the sound, wasn’t already taken, and was pretty easily depictable.

The original pictographs were mostly drawn using sticks in the mud by small streams, or, in one case, using charred wood on a rock. Since then, I have drawn them more often on paper and chalkboards and in soft, dry sand. This has given them a more connected and curved style in many cases, though not quite what I would call “cursive”. Some I still find a little aesthetically unsatisfactory, so further changes will surely occur at some point. I still use the original style quite a bit, though.

Spelling conventions do not really exist, and I transcribe English the way I speak it. Deciding on /ə/ vs. /ɪ/ for reduced vowels, whether to write a semivowel or the corresponding high vowel in certain cases (e.g. “fire”, which I might write /faɪ.ər/ or /fɑjər/), and how to account for variation are unaddressed at this point. Stress is also unmarked. I mostly use this for fun, leaving secret messages wherever people are allowed to write on a public wall/chalkboard, or writing un-eavesdroppable reminders on my hand, so I don’t really care about these orthographic issues at the moment.

The letters for /aɪ/ and /aʊ/ were added later, as an experiment that I decided I liked, but they remain optional. Those sequences can still be written as /ɑ+j/ and /ɑ+w/. The letter for /ɔ/ was added because I, being from the South and having many mergers in my English, had decided it was unnecessary for my original purposes. But another linguistically-oriented friend of mine who is from Chicago insisted that I create one, so I did, but I still never use it. I even had to ask him for words that included the sound because I had never learned the difference (a problem I still run into with pin/pen words that have something other than orthographic <in> or <en>). I know there are other vowels from other dialects that are not accounted for here, so maybe someday I’ll get around to making some new symbols.

Below is the alphabet, with original characters on the left and current ones on the right. In some cases, I also show an intermediate stage that I sometimes still use.

How to Pronounce Long Numbers Quickly

In college I worked part-time in the university’s finance office, and often I would have to hold an account number of 5 or more digits in short-term memory as I went from the computer to a filing cabinet. For example, I read a purchase request for account 45749, realized I needed a physical file, then walked over to the cabinet to begin looking for that account number. The numbers all looked pretty similar, so I would be trying to find this account among a group like {47459, 49557, 44759, 94570, 45537, etc.}. Most of the time I could remember the number without any issues, and the first and last digits were very hard to forget, but out in the middle things got harder. If I messed up, I had to go back to the computer and try again. A reasonable person might decide to write down the number on a sticky note or something, but I had an idea that sounded more fun.

I assigned phonetic values to each digit as though they were letters (this post uses IPA for the number pronunciations). Many of them are based on similarities in shape, as well as pre-existing associations from “calculator words” like “07734” for “hello”. So I started off with these simple correspondences:
0 1 2 3 4 5 6 7 8 9
o i   e h s   l b

2 looks like “z”, but I decided to use “t” for the word “two”, and similarly I used “n” for “nine”. 6 looks like a capital G, so I chose “g”, but got tripped up a lot at the beginning since 9 looks like a lowercase “g”. I eventually got used to it, though, so the original system looked like this:

number     0 1 2 3 4 5 6 7 8 9
consonant      t   h s g l b n
vowel      o i   e

This worked as a proof of concept. The account numbers could now be memorized as nonsense words (much easier for me to remember than strings of digit names). Here are the ones mentioned above:

45749 47459 49557 44759 94570 45537
hslhn hlhsn hnssl hhlsn nhslo hssel

While this was possible through liberal use of syllabic consonants, clearly I needed more vowels and some euphony. The system has undergone several changes since then, but I’ll omit those and just present the current version.

number     0 1 2 3 4 5 6 7 8 9
consonant  ʃ j d θ f s g l b n
vowel      o i y e a u ɤ ɯ ø æ
prefers    V n C V V n C C C C

I memorized the digits by counting: “ʃo çi dy θe fa , su gɤ lɯ bø næ”.
As you can see, each digit is now not only either a consonant or a vowel, but can serve as both depending on what is most comfortable. Each has naturally developed a preference for being a consonant or a vowel (1 and 5 have no preference either way), and this generally tries to avoid vowels other than [a e i o u].
Short numbers should alternate vowels and consonants if possible, but any configuration that is comfortable is acceptable. For example, “4938” can be “fæðø” or “anem”, and I find the latter to be much easier to pronounce. The account numbers now have these preferred pronunciations:

45749 47459 49557 44759 94570 45537
aslan alawn ansul falun naslo fuzel

There is some allophony as well, some of which is already seen above. All plosives are voiced by default but can also be voiceless, usually word-finally or when bordering a fricative. /b/ and /g/ can be their corresponding nasals, usually only word-finally. /d/ does not do this because it would interfere with /n/, so instead it can become [ɾ] intervocalically or word-finally. Fricatives are voiceless by default but can become voiced, usually intervocalically. Nasals and /l/ used to be able to be syllabic, but I have largely done away with this in favor of vowels. The high vowels can also act as semivowels in vowel sequences but nowhere else, so I omit [ɥ ɰ w] but include [j], which is the primary consonant phoneme for its digit unlike the other three. Sequences of two of the same digit can be a long vowel or geminated consonant, although I generally avoid this.
The full details of allophony:

0: /ʃ/
[ʒ] intervocalically
[ʃ] otherwise

0: /o/
[o ~ o̞ ~ ɔ] in free variation

1: /j/
[ç ~ ʝ] when bordering [i], voiced intervocalically and voiceless otherwise
[j] otherwise

1: /i/ – [i] always

2: /d/
[t] when bordering a voiceless consonant, usually a fricative, or sometimes word-finally
[ɾ] intervocalically or word-finally (preferred over [t])
[d] otherwise

2: /y/ – [y] always

3: /θ/
[ð] intervocalically
[θ] otherwise

3: /e/
[e ~ e̞ ~ ɛ] in free variation

4: /f/
[h] in free variation with [f], usually word-initially and rarer otherwise
[v] intervocalically
[f] otherwise

4: /a/ – [a] always

5: /s/
[z] intervocalically
[s] otherwise

5: /u/ – [u] always

6: /g/
[k] when bordering a voiceless consonant, usually a fricative, or sometimes word-finally
[ŋ] word-finally (preferred over [k])
[g] otherwise

6: /ɤ/
[ɤ ~ ɤ̞ ~ ʌ] in free variation

7: /l/
[l ~ ɫ] in free variation, probably conditioned by nearby vowels but I haven’t paid much attention to my habits here

7: /ɯ/ – [ɯ] always

8: /b/
[p] when bordering a voiceless consonant, usually a fricative, or sometimes word-finally
[m] word-finally (preferred over [p])
[b] otherwise

8: /ø/
[ø ~ ø̞ ~ œ] in free variation

9: /n/ – [n] always (must avoid assimilation with consonants to remain distinct from /b/ and /g/, so usually forces neighboring numbers to be vowels)

9: /æ/ – [æ] always

There is probably a simpler or more intuitive system for this, and maybe this doesn’t need to exist at all, but I enjoy converting numbers to words and vice versa:
Chicago = 016460 (aspiration not marked)
librarians = 74182321395
geri dönüyorsunuz (“y’all are returning” in Turkish) = 6321 289210255955

I’d like to make a conlang using these phonemes (i.e., treating them as 10 phonemes, not 20) so that paradigms could have forms sounding completely different depending on the affixes used. For example, suppose a stem “826” can be inflected by the prefixes [“1” “2” “3”]. The results would be:

1-826 = ibyŋ ~ ibɾɤ (preference nCCC, so one of 2 or 6 should be a vowel)
2-826 = døɾɤ (preference CCCC, so two of them should be vowels, and CVCV is preferred over VCVC or other configurations)
3-826 = ebyŋ (preference VCCC, so 2 should be a vowel since CV alternation is preferred)

Wouldn’t it be super fun to have to learn that “døɾɤ” and “ebyŋ” are from the same stem, and that “ibyŋ” and “ibɾɤ” are the same word?? This is one of my favorite bad ideas for a language so far.

But to go back to the original purpose, I have legitimately found this method useful for memorizing long numbers in a short amount of time. Phone numbers, account numbers, ZIP codes, you name it. I once memorized someone’s transit card number (16 digits in 4 groups of 4) using this, and I still can’t get rid of that now-long-term memory.

Maybe someone else will find this useful, but I wouldn’t bet on it.

A Generic Terminal in Python

More than once I have found myself wanting an easy-to-use interactive shell for custom tasks. I often open a Python interactive session to perform quick tasks like string manipulation, rather than having to deal with the likes of sed/awk (which I admittedly know next to none of). With a little creativity, the same style of interaction session can be a custom UI that is easy to use and modify. Normally I would assign quick functions such as:

>>> def f(s):
...     with open("a.txt", "w") as f:
...         f.write(s)
>>> def g(s):
...     return "\n".join([s.replace("jan", a) for a in 
...         "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec".split(",")])
>>> f(g("jan_avg_high_temp_degf"))

But if I closed the Python session and then later wanted to do the same thing, I would be repeating work, so I thought of ways to accomplish this kind of thing more extensibly.

Recently I was creating a simple program to output the Morse Code equivalent of a string (either to file or to a playback device) and found myself wanting to test it quickly by passing it strings on the fly and listening to the output. Sure, I could have done something like a while loop asking for input and translating it, but I wanted a bit more functionality. I wanted to copy-paste text from the internet and save their translation to file for listening practice, and the ability to turn saving on and off at will. I wanted to change the words per minute of playback. I’m sure there are plenty of other simple tasks that could be added here.

I decided to implement this to look like a terminal, with a $ shell prompt and special commands beginning with : (and the ability for these to take arguments). All other input is interpreted as a string to be translated, and the values of internal options (WPM, whether to save to file, other aspects of the waveform generated) are persistent during any session.

I implemented the terminal as a simple Terminal class that includes all the basic functionality, so I could create a MorseCodeTerminal inheriting from it and adding its own specifics. The basic Terminal specifies a shell prompt, the commands :q (quit), :h (help), and the run() method that begins a while loop processing the user’s input. It is easy to add new commands using self.add_command(), specifying the command name, the callable to which args (separated by spaces) are passed, and the help string for inclusion in :h output.

Several terminal options (e.g. whether to save to file, whether to play aloud) are boolean, and they make use of a change_binary_attribute() method for extensible use. If an arg is given, the option is set to it; otherwise, the current value is printed. The same usage holds for non-binary attributes, although a general function for these is trickier due to different kinds of validation, so I still consume new input in a custom method for each of them. Below is an example from the MorseCodeTerminal:

$ :save
$ :save 0
$ :save
$ :wpm
$ :wpm asdf
Invalid input for int: asdf
$ :wpm 25
$ :wpm
$ :asdf
Unrecognized command

I found it important to keep the terminal from crashing due to user error, because it was pretty frustrating to set up the options I wanted (if different from defaults) and try to begin doing real work, only to make a silly typo and have to start over because I didn’t handle the error. Ideally also the terminal will not quit on ^C, but will just catch the KeyboardInterrupt, stop any existing task, and await the next input. Only :q should cause the program to exit completely.

This ability of the terminal to keep going in the case of bad input, or exceptions thrown during a task, became more important once I made my second one, which allows the user to construct and edit a Pandas DataFrame manually. Similarly to the Morse Code use case, this could easily be accomplished in a normal interactive Python session by someone who is used to the task. For example:

>>> import pandas as pd
>>> df = pd.DataFrame()
>>> df.loc["H", "atomic_number"] = 1
>>> df.loc["He", "atomic_number"] = 2
>>> df.loc["U", "atomic_number"] = 92
>>> df.loc["H", "boiling_point_K"] = 20.27
>>> df.loc["He", "boiling_point_K"] = 4.22
>>> df.loc["U", "boiling_point_K"] = 4404.00
>>> df
    atomic_number  boiling_point_K
H             1.0            20.27
He            2.0             4.22
U            92.0          4404.00
>>> df = df.set_index(df.index.rename("Index"))
>>> df
       atomic_number  boiling_point_K
H                1.0            20.27
He               2.0             4.22
U               92.0          4404.00
>>> df.to_csv("data.csv")
>>> # done

This could also be accomplished in Excel, but I wanted to see how well I could streamline it this way. The terminal approach:

$ :filepath data.csv
$ :index H
$ atomic_number = 1
$ boiling_point_K = 20.27
$ :index He
$ atomic_number = 2
$ boiling_point_K = 4.22
$ :index U
$ atomic_number = 92
$ boiling_point_K = 4404.00
$ :save

A lot of the repetition has been cut out here. Also, the terminal is configured to re-save the CSV on each change automatically, so we just check that :save is True and we’re good! As with Morse Code, it’s easy to add new functionality here, such as :nan (tell me which columns are missing (NaN) in the current row). Clearly with large amounts of data, the constant saving would be inefficient, but it can be turned off, and the current df would just be stored as an attribute of the current Terminal. This makes it clear that quitting the terminal on any bad input is a bad idea, as all of the unsaved changes would be lost.

I’m not saying this is the best way to edit a DataFrame at all, but for quick-and-dirty changes like one might make to a CSV in Excel, or for tasks that I find myself repeating all the time, it’s pretty nice.

I’m interested to see what other uses there are for this kind of terminal. Right now I’m just playing with it for personal projects, but I think there’s a lot of potential.