- Unbox printer.
- remove orange packing tape.
- unbox power cords and usb cable, install.
- open front pull-down cover, and one under it - push down on grey loops gently and put in inkjet cartridges.
- Put paper in at bottom, only hold 50 sheets or so.
- turn on, wait.
- open terminal window, type sudo ls and enter pw.
- open browser, get download from http://support-sg.canon-asia.com/contents/SG/EN/0100515301.html
- in terminal, cd ~/Downloads
- tar -xzvf cnijfilter*
- cnijfilter*
- On printer, turn off and on again just in case.
- sudo ./install.sh
- follow prompts accepting defaults.
- in browser, open google.com and print open page as test. Should hear printer working.
Professional programmer; amateur home handyman (on our home only); tinkerer; husband; father of 3; attempting to be a renaissance guy (to know at least a little about a lot of subjects, a doomed pursuit in an information age); geek-arts-and-sciences enthusiast. Interest areas: Science fiction, wind turbines, electric cars, renewable energy, making things.
Sunday, October 27, 2013
SOLVED: Ubuntu installation of Canon MX452 Inkjet Printer
Tuesday, October 22, 2013
Optimizing Python - getting data out of memcache with struct.unpack
So, I have this Memcache data store that holds timestamps and values from a monitoring application. Since each memcache key corresponds to an hour's data, I only need to store 2 bytes for the number of seconds past the hour. I don't care about duplicate data being stored, but on retrieval I'd like to eliminate it if it exists.
Input data is: (ts,val), (ts, val), ... encoded using Python's struct.pack command. The ts (timestamp) is (as noted) packed with format h (unsigned int). The val (value) is a floating point number of 4 bytes, packed with format f.
The original version of this encoding was:
def OLD_rawDataToTsVals(self, timeOffset, raw): tsVals = [] while raw: ts, val, raw = raw[:2], raw[2:6], raw[6:] ts = timeOffset + struct.unpack('h', ts)[0] val = struct.unpack('f', val)[0] tsVals.append((ts, val)) return tsValsI found this version:
- ran really slowly;
- didn't eliminate duplicate values;
- would really choke the longer the input data (as in 33,000 datapoints in an hour).
For the second version, I knew I had to stop with the copying of the data string over and over again, which I knew was eating major cycles.
Doing some math, I figured out I could iterate over the string, extracting each element and converting the two parts to python numbers.
def rawDataToTsVals(self, timeOffset, raw): tsVals = [] for i in range(0, len(raw), 6): rawtime = raw[i:i+2] ts = timeOffset + struct.unpack('h', rawtime)[0] val = struct.unpack('f', raw[i+2:i+6])[0] tsVals.append((ts, val)) return tsVals
This was better timewise, but didn't remove duplicate data. I made the 'seen it yet' test occur even before the conversion to (int, float), which saved a bit of time doing useless conversions.
def rawDataToTsVals(self, timeOffset, raw): tsVals = [] seenTimes = set() for i in range(0, len(raw), 6): rawtime = raw[i:i+2] if rawtime in seenTimes: continue seenTimes.add(rawtime) ts = timeOffset + struct.unpack('h', rawtime)[0] val = struct.unpack('f', raw[i+2:i+6])[0] tsVals.append((ts, val)) return tsVals
Yet, it was STILL TOO SLOW. Where was the time going? I timed the various parts and found the slow bit was the conversion to int/float. That unpack was happening a lot and the time added up.
I tried the following but FAILED.
# BAD DON'T USE ** BAD DON'T USE ** elems = rawLen / 6.0 # 6 bytes per - 2=time + 4=data. intElems = int(elems) if (elems != intElems): self.log.warning("elems non-integer: len: %s" % (rawLen)) return [] unp = struct.unpack("hf"*intElems, raw) # BAD DON'T USE ** BAD DON'T USE **
The above fails because if we pack these things together, there's a word-alignment problem that unpack is unable to cope with. It would have to be something like (int, zeroes, float) to make the float align on a word boundary.
But, I couldn't give up, this had to work better. So, I extract all the ints, string those together and unpack them, then do the same thing with the floats.
HERE IS THE FINAL VERSION:
def rawDataToTsVals(self, timeOffset, raw): tsVals = [] seenTimes = set() try: rawLen = len(raw) times = "" vals = "" for i in range(0, rawLen, 6): rawtime = raw[i:i+2] if rawtime in seenTimes: continue times += rawtime vals += raw[i+2:i+6] timesList = struct.unpack('h'*(len(times)/2), times) valsList = struct.unpack('f'*(len(vals)/4), vals) assert len(timesList) == len(valsList), "Lens of times and vals unequal, t=%s, v=%s" % (len(timesList), len(valsList)) for i in range(0, len(timesList)): tsVals.append((timeOffset+timesList[i], valsList[i])) #self.log.debug("unpacked %d vals, len ts %s." % (len(timesList), len(tsVals))) except: tb = traceback.format_exc() self.log.debug("tb in rawDataToTsVals(): rawSize: %s, %s" % (rawLen, tb)) pass if 0: # debugging self.log.debug("tsvals: %s" % ( tsVals)) return tsVals
Unpacking all the h's at the same time, and likewise the floats, makes everything align, and since it's one function call to struct, is very fast.
Enjoy!