Coming out of University, having taken Cleanroom Development and Software Construction courses, I had a fairly regimented DRY view on duplication of code - never do it.
Consider a (presumably common) scenario where you have an application (MyApp) that relies on one or more other Python services (Svc1, Svc2). You want to run your application against instances of those services.
Last year, I subscribed with IDNotify because it was included in a package I bought from TurboTax.
Yesterday, MongoDB announced their new backend as a service, MongoDB Stitch. Eliot Horowitz ran through the service with a blog accepting comments.
As software engineers, we care about detail. We care about precision. We care about cleanliness and purity. So when we’re accepting a pull request in GitHub and we’re offered the option to Squash and Merge, to take the contribution and compress it into one clean commit right on the stack of commits, we’re tempted to elect that option. There are several reasons I hope will persuade you to avoid using this option except in the most constrained environments.
As a software engineer, I’m always looking for ways to optimize the tedious tasks and repetition out of my workflow, and one of these repetitive tasks is building and maintaining Python packages - you know, the repositories that get uploaded into devpi or PyPI as libraries or applications.
Today I migrated my blog to Github. Although Blogger and LiveJournal were nice, they also left me with a feeling of lack of ownership in my content, and worry about the implications if the service were to be discontinued (especially with Blogger).
So I've been using a Mac Mini hosted with macminivault.com. I've been using it remotely with the iRAPP client.
That whole arrangement has been a convenient way to get my feet wet.
It's also allowed me to encounter some of the early problems I would encounter in an attempt to transition.
Today, I found that I'm unable to pair the OS X with Exchange and that it's a known problem. The reported workarounds didn't work for me. Therefore, I can't configure mail or contacts.
I've also found that common keyboard shortcuts use different keys. Copy is Windows+C instead of Ctrl+C. Same for Paste, Undo.
These challenges seem small, but add a pretty large impediment to having a partial transition.
If that's confusing, don't fret. The details aren't important, because what I'm presenting here is a technique that's engineered to be safe in all cases without baking in the details of the parent class.
def __new__(cls, *args, **kwargs):
super_new = super(SomeClass, cls).__new__
if super_new is object.__new__:
return super_new(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
super_init = super(SomeClass, self).__init__
if super_init.__objclass__ is object:
The above example presents a generic, trivial implementation of a subclass of SomeParentClass that overrides both __init__ and __new__. It does not add any custom behavior (as a typical override would), but instead focuses on the technique on passing through the calls of __init__ and __new__ to the parent class in a safe way.
If you're overriding __new__ or __init__, especially in a subclass of a class over which you do not have control over the implementation, it is important that you check that the parent call will not invoke __new__ or __init__ with parameters. Otherwise, you may run into one of the following errors when constructing your subclass:
TypeError: object.__init__ takes no parameters.
TypeError: object.__new__ takes no parameters.
1. Locate or file a ticket describing the issue. First search the history to see if the issue has already been reported. If you cannot find an existing issue, then create one. It's okay if you create a duplicate - the project maintainers can link the tickets, but doing a little research up front will save everyone time.
2. In the ticket, describe the problem as you faced it. Include how you encountered the issue and in what environment. Try to include enough detail to allow another person to replicate your findings. If possible, distill the problem down to a minimal program that triggers the failure. If a minimal program cannot be created, try to characterize the issue such that another reader can understand the failure. Include error messages, stack traces, and other detail in their entirety.
3. Research the project-specific contribution policy. Many projects explicitly advertise a contribution policy as a CONTRIBUTING file in the root of the repository, or in other documents such as README. If you're new to a project or unfamiliar with its nuances, doing a little research up front could save you some time and trouble.
4. Start small. Unless your name already carries widespread reputation within the community, your first contribution is likely indistinguishable from that of any other contributor. If you start with small changes, you can establish a rapport with the project and avoid wasting precious time and effort.
5. Prepare your fork of the code for contribution. You haven't committed any code to your fork of the code yet, but you're about to do so. Because you've already been troubleshooting the problem, you may have already even drafted a fix. Set aside those changes (using your DVCS tools) and work from a clean copy of the code as found with the project.
6. Avoid making stylistic changes. This step, while a non-operation, is important. Try to avoid applying your preferred style (regardless how authoritative that style may seem) to the code. Adopt the style of the project as much as possible. In rare cases, your editor will automatically make some stylistic changes when saving (such as removing trailing whitespace from lines). If that is the case, either disable that feature in your editor or commit the stylistic changes separately and prior to any substantive changes. Doing so will allow the reviewers to accept or reject the stylistic changes separately and not be distracted by them.
7. Write a test to capture the desired behavior. If possible, write a test in the test suite of the target project that captures the failure or intended new behavior. Often, the distilled program from above can be re-purposed to accomplish this goal. Commit this change prior to any substantive changes. This newly-created test will now fail at that revision, proving that the issue is fixed in subsequent commits.
8. Implement your suggested fix. Try to minimally adjust the arrangement of the code. If the change is more than a few lines fix, consider making several incremental commits working toward the ultimate solution. For example, if the fix includes extracting a method from a larger method, consider doing that extraction as a separate commit. Then, each commit describes the contributor's thought process working toward the solution. Most code review tools will allow the reviewer to see the commits in aggregate or separately, so more incremental contributions give the reviewer better visibility without compromising the big picture.
9. When committing your changes in (5) and (6), consider using commit messages that reference the ticket number. Both GitHub and Bitbucket can automatically link commits to a ticket if the commit message properly references the ticket. Follow the example of prior commits in that project to be consistent. Creating these references means you'll get the best attribution for your contribution and means less work for the reviewer. Use casual references for incremental commits and then use phrases like "Fixes #NNN" for the commit that actually fixes the issue.
10. Create the pull request referencing the ticket. The pull request should include a description referencing the ticket it fixes and any other information that will help the reviewer understand your thought process. Highlight any areas that you think might be controversial or incomplete and give additional justification for those areas here, along with any factors that mitigate those concerns.
If you do all of these things while creating your pull request, a reviewer will find it hard not to accept your contribution. Not all of these steps are necessary to accept a contribution. Sometimes a test suite isn't available in a project, or the contribution doesn't justify a test. Perhaps you only have enough experience to write the ticket or the test, but not implement the solution. Use your best judgment and contribute what you can. In the open-source world, good project managers understand that we have limited resources and capabilities and will make the best of any contribution.
Finally, don't be offended if your pull request is rejected. Different projects and their maintainers have different standards for accepting contribution. Hopefully, they will provide constructive criticism that will help you improve your contribution. If not, ask for specific feedback on how you can improve your contributions for the future.
First a brief introduction. I'm a software engineer and director of DevOps at my company. I have a masters degree in computer science with emphasis on secure networks and cryptography.
I recently encountered a fundamental problem with the password policy of Apple IDs. My password was "disabled for security reasons", allegedly due to to many incorrect password attempts, even though I assure you I did not enter the incorrect password even once on any of my devices.
So it seems that someone or something else has triggered the disabling of my account. As a result, I was forced to change my password.
In other words, because someone failed to guess my secure password, you force me to change it to something else. And furthermore, Apple refuses to tell me anything about when or where (physically or virtually) the failed attempts originated.
Do you see the problem with this scenario? Something completely out of my control causes me to have to reset my password (and never use that password again). Every time this happens, as a user, I'm going to be more inclined to choose a less secure password than before, because obviously the security of the password is irrelevant, but if it's going to be changed arbitrarily, I don't want it to choose something hard to remember or mutate.
To make matters worse, I changed my password on Thursday night, but by Friday night, my *new* Apple ID password was no longer recognized.
According to the support representative I talked to today, this issue was my fault because I failed to sign out and sign back in with the new password on each application that uses my AppleID. Let me just briefly list all of the places I've discovered (so far) where I'm supposed to change my password every time my password is arbitrarily disabled and reset:
- App Store (iPhone)
- App Store (iPad)
- iMessage (iPhone)
- iMessage (iPad)
- FaceTime (iPhone)
- FaceTime (iPad)
- iCloud (iPhone)
- iCloud (iPad)
- Game Center (iPhone)
- Game Center (iPad)
- Web Browser (Windows Desktop)
- Web Browser (Windows Laptop)
- Web Browser (Mac Laptop)
- iTunes (Windows Desktop)
- iTunes (Windows Laptop)
- iTunes (Mac Laptop)
- iCloud Control Panel (Windows Desktop) [and it loses the settings when I sign out and sign in]
And there are probably other places I haven't yet remembered. But you see, according to the rep, it's my responsibility to change it in all of the places it exists, or else Apple will disable my account again, and I will be forced to change my password again, and the process starts anew (plus one more burned password).
What makes matters worse is I tried to resolve this situation using online resources, and then e-mail support, and then genius bar, and then phone support, but none of these avenues was able to answer my questions (why did this happen?) or allow me to resolve the situation to my satisfaction (restore my account with the secure password I've used for some time or my new secure password and prevent this situation from happening in the future). In fact, I was told I can expect this to happen again unless I change my Apple ID (and that's the same answer they'd give to Tim Cook). What a terrible experience.
I'm really regretting buying into the whole Apple ID. Please route this message to the appropriate department so these issues can be considered for improvements to the Apple ID password policy.
In the meantime, I'll try to forget the hours of grief Apple has cost me this weekend.
I didn't mention in the letter that I asked what would happen if someone had my Apple ID and was causing my password to get disabled. The representative indicated I would have to get a new Apple ID. That's right folks. Keep your Apple ID secret (the username). Hide your screen when you're prompted to enter your Apple ID password. Because if the wrong people get a hold of that Apple ID, and (ab)use Apple's site to burn your password, you'll be forced to go through the whole mess outlined above.
Which begs the question - does Tim Cook have to deal with this problem if someone gets his Apple ID? I'm not suggesting that anyone should track down Tim Cook's Apple ID and try bogus passwords until his account is locked out, but I suspect if that happened often enough, Apple would probably devise a better solution than what they have now (which is bullsh**).
There are many reports out there of how an upgrade from Snow Leopard to Lion corrupts a Windows Boot Camp partition (usually beyond repair). This happened to me this weekend. I went to the Apple Store to find out what options I had to upgrade my Boot Camp drivers, and he said my only option to get ongoing upgrades for Boot Camp was to upgrade to Lion. So I did, but instead of getting the drivers I needed, I lost my Windows partition.
This is an issue that was reported last year when Lion was released, but Apple seems to have just ignored the problem, allowing their software to corrupt Windows partitions created by the Boot Camp assistant.
This disdain for your Windows users is reprehensible. That you could allow your software to continue to corrupt installations like this for 10 months after the issue was reported is nothing short of irresponsible.
At the very least, the Lion upgrade should detect a Boot Camp installation and warn that it might corrupt the Windows partition. Even better would be to safely resize it rather than writing over it. What good is a recovery partition if it's written over the data you care the most about?
For me, this is the end of my relationship with Apple for my computing platform. I am selling my MacBook Air and will be getting a Windows laptop. While the hardware is nice, it's not worth the grief of actively destructive software.
I do advanced software and systems work. I've done custom partition management on PCs for years. I've upgraded Windows operating systems for years. Still, I've never encountered a situation where an operating system would overwrite a user's partition without extensive warnings and prompts. Apple is now permanently on my black list.
I tend to use Windows and I've been programming in Python since 1997. I also tend to use a lot of Unix conventions, especially where they don't create a major incompatibility with Windows. I don't use compatibility layers like Cygwin, though. I find they create more trouble than they're worth. So where possible, I use native implementations of everything. I'm a command-line junkie, and I try to automate everything. One of the best things about Python is its cross-platform support. I've never encountered a better general-purpose language for cross-platform development.
So over the years, I've developed some routines to automate the installation and configuration of Python on my systems. Ever since Python 2.6 and Windows Vista, life has been pretty good. Vista added support for symbolic links and Python 2.6 had excellent 64-bit support.
Since then, I've install almost exclusively 64-bit versions of Python. In this article, I will assume one is using Windows 7 x64, although the routines generally translate to x86. The biggest challenge to using 64-bit Windows is access to compiled modules. To the best of my knowledge, it's not possible to compile 64-bit extension modules without the full version of Visual Studio.
Most Python programmers will find that having several different Python versions present is useful if not necessary. I typically install the latest Python 2 and the latest stable Python 3.
As any Python programmer knows, having distribute is a nearly essential part of any Python installation, so the installation routines should include support for installing distribute as well.
So to accomplish all of this, I needed a scripting language that comes pre-installed with Windows. Originally, I used cmd scripts, but found those not quite adequate. Bundled with the fact that PowerShell 2 comes with Windows 7, it became the language of choice. I developed this script. If you run that script in a PowerShell, it creates three functions:
- InstallPythonMSI $installer, $target
- get-python-version $version
get-python-version completely automates installing a single Python version to an appropriate location in $env:ProgramFiles. The script assumes 64-bit, but can be easily modified to support 32-bit. It then also installs distribute by executing the bootstrap script directly from the server, enabling support for setuptools-packaged files.
Finally, bootstrap-python sets up some symbolic links and resets the file associations to create an authoritative (default) Python installation. By default, Python installs into C:\Python27 or similar. I've argued that this location is not appropriate and that the proper location for programs (including Python) is $env:ProgramFiles, so that's where I install it (after all, how do you differentiate between 32-bit and 64-bit versions of Python 2.6?). However, it is useful to have a symbolic link from an easy-to-type location. So bootstrap-python creates a symlink at C:\Python which refers to the "active" version of Python. It then installs jaraco.windows and uses one of its command-line scripts to set some environment variables (such as adding the Scripts directory to the path and registering .py files as executable scirpts). Then, bootstrap-python resets the file associations by calling this Python script.
What this all means is that running Python.exe or running scripts installed in the Scripts directory will use the active version of Python (whatever C:\Python points to). This configuration also means that one can easily switch the entire system Python environment from one version of Python to another by just repointing a symlink. To automate this process, I've created this Python script, which I call 'pythonver.py'. I usually place this script in a separate location somewhere on the search path (C:\Windows would work). The script searches $ProgramFiles and $ProgramFiles(x86) for PythonXX directories and then allows the user to select one of those, then repoints the C:\Python symbolic link at that version.
The end result is one can install multiple versions of Python in both 32-bit and 64-bit versions and rapidly switch the active version. Of course, it's also possible to select a specific version directly using its canonical location (e.g. C:\Program Files\Python32\python.exe).
With these few scripts, I can rapidly install, bootstrap, and switch between Python versions.
I hope sharing some of these techniques will give some useful techniques that I enjoy using to automate deploying Python on my Windows servers and workstations.
I've managed to work around most of the rough edges running Windows on this hardware, but there are still three issues that regularly annoy me, and which give me great hesitance when considering another Macbook.
Swap Fn and Ctrl Keys. If the Macbook would provide a way to switch this in hardware. My fingers are trained to find Ctrl in the corner. That's where it is on my desktop keyboard. I'd like it to be in the same place on my laptop.
Clumsy Trackpad driver. The Boot Camp driver for the trackpad has some poor behaviors (compared to any other pointing device I've used).
No HiFi Bluetooth Audio support. I recently found there is no A2DP support for the bluetooth adapter integrated with the Macbook Air (or any MacBook on Windows for that matter).
If Apple were to fix these three issues, it would shift the balance in my hesitance and I would rush out and upgrade my laptop now to another piece of Apple hardware.
Consider this simple example. There appears to be no specification for the hashbang, but after some searching, I did find a page that indicates there is no supported mechanism for specifying a space in the interpreter name.
That's a shame. That limitation then bleeds through to almost every other aspect in Unix programming that it basically means Unix does not support spaces in filenames.
I had in mind pretty much what I wanted: a lightweight, about 12" laptop with decent specs. It should run 64-bit Windows with 64-bit VMs, have at least 4GB of RAM, a video camera, gigabit LAN, and an SSD. I searched online and browsed the stores when I went by, but nothing stood out at me... except the Macbook Air.
I had heard good things about the multi-touch trackpad. I'd seen the space-age MagSafe power connector. I could use my iPhone headset directly in the headphone jack as a headset. And the profile just looked right. I was worried that the no-button touchpad might be a problem, but according to reviews, the Bootcamp drivers gave multitouch support in Windows, and the consensus seemed to say it was a suitable, though expensive, platform for Windows.
I looked seriously at the Asus laptops, but they were lacking the gigabit LAN and I couldn't find one with an SSD. Everywhere else I looked, it seemed like the vendors (Dell, for example) were failing in their sales of ultraportables, in large part because they couldn't compete with the Macbook Air.
So I caved. I decided I could do without gigabit LAN and I bought a Macbook Air 13" to replace my Dell Latitude X1. It's a little bigger than I would have liked, but the 256GB over 128GB storage and an SD slot made it an easy choice.
When I got it, the first thing I did was shrink the MacOS partition to 20GB and install Bootcamp and Windows. It worked fairly well at a basic level. It was super fast. The Bootcamp 3.2 drivers supported all of the hardware. I was up and running in just a few hours. Almost immediately, though, I started to run into problems.
Right off the bat, the space bar was intermittent. I thought at first I was just not used to hitting the space bar in the right place, but when I went to the store, I found other Macbooks did not have this problem. So I exchanged it for another.
The replacement had a nice solid spacebar, but the up key scrapes against the metal keyboard frame. It's irritating, but bearable.
keys to the kingdom
Another surprising thing is the laptop doesn't have any indicators other than capslock. There's no power light, no hard drive light, no number lock (in fact no number pad). And speaking of missing buttons, the macbook is missing a whole lot of keys. There's no button for "page up", or "end", "backspace". The bootcamp drivers substitute "delete" for backspace an then expose Fn+delete as delete, but it's a clumsy hack. Many of the buttons are available as combinations with the Fn key, but there are some keys (Pause/Break, number pad) which aren't available at all.
I know the laptop wasn't manufactured for running Windows, but if you are used to running Windows on a PC, the Alt and Windows keys are switched (and in my opinion, the Fn and Ctrl keys could be switched too). Sure, there are programs to switch the keys in software, but these programs affect all hardware, so I can't easily alternate between an external keyboard and the internal keyboard.
This is the same complaint I've had about the mobile devices - they don't expose enough user interface for a professional developer to really excel.
how are you with keyboard shortcuts?
As if the problems with the keyboard weren't bad enough, there appears to be a bug in the trackpad driver that causes it to fail occasionally when coming out of standby. I contacted their customer care about it, but they insist it's a Microsoft problem and refuse to support it. So I just have to randomly restart my computer about once out of every 10 uses.
There also appears to be an issue with charging the laptop. I'll have the laptop in standby (with the lid closed) and then plug it in to charge. After a minute of two of charging, the laptop will come out of standby, even if it's zipped up in its insulated bag. It'll then sit there and cook inside the bag, even if the power is subsequently disconnected. It's done this several times and gotten the temp to be untouchably hot. I've learned not to plug the laptop in unless I have it on a suitable surface for running and to double-check that it's suspended before packing it up. Of course, without any indicators, it's all but impossible to know for sure.
One of the major reasons I selected the Macbook was because I could see the superior manufacturing quality. Or at least, I convinced myself of such. The devices are beautiful and elegantly engineered, but when it comes to durability, it's another story.
Only a couple of months into owning the laptop, the screen died. If you divide the screen into 6 even vertical segments, the second of these segments stopped functioning. This happened while I was using the device while sitting in bed. I had the laptop on a smooth surface, so it was running cool. It was stable and had taken no abuse. Then spontaneously, the screen failed.
I do give kudos to Apple for a rapid replacement. I took the screen to the store on Saturday afternoon and it was repaired with a new screen by Sunday morning.
Still, I feel the Apple quality is mostly superficial and doesn't go deep to the underlying hardware.
Overall, I'm pleased with the device. It serves its purpose (as a secondary, portable workstation). I acknowledge that some of these shortcomings are because I want to run Windows on the device, but many of these would apply even if I were running MacOS.
As a professional, I feel the Mac platform just doesn't cut it. It hides and abstracts too much of the system, sacrificing functionality for simplicity. I was not aware I was making this compromise when I purchased the Macbook Air... and I'll think long and hard next time I have this choice to make.
Yesterday, I won an item for my grandma on eBay. After winning, I used the eBay iPhone application to checkout. As I do, I'm not given the opportunity to change the shipping address. Apparently, one must change one's shipping address before winning an item, or it will be shipped to the default shipping address. ...and if you're keen enough to realize that you haven't been given the opportunity to have the item shipped to your preferred destination after checking out, eBay makes it difficult to find the contact information for your seller, adding extra hassle and delay in resolving the issue.
Here's the chat transcript. Please pardon the formatting - the eBay chat system didn't let me retrieve the chat transcript in any nicely-formatted format.
Initial Question/Comment: Bidding/Buying
Thank you for contacting eBay Live Help!
Please hold for the next available Live Help Agent.
We appreciate your patience. Please continue to hold for the next available representative.
We apologize for the wait. Please continue to hold while we connect you to an agent. You should be connected soon.
Mel M. has joined this session!
Connected with Mel M.
16:33:39 AgentMel M.
Hello, thanks for waiting and welcome to eBay Live Help! My name is Mel. How may I help you? We are currently experiencing an unusual high chat volume. We thank you for holding and we are sorry for the inconvenience.
Hi Mel. I bought an item on eBay and checked out using the eBay app for the iPhone.
When I paid, I don't think I was given the opportunity to select another shipping address (or if I did, it was hidden).
After a night's sleep, I realized that the incorrect address was on the shipment.
So I attempted to contact the seller... but I only received a generic response 8 hours later saying the item was shipped.
16:35:12 AgentMel M.
I understand you would like to edit that shipping address, right?
I'm really frustrated that I think now the item is going to be shipped to my home instead of to my grandma.
16:36:00 AgentMel M.
May I have the item number please so I can check?
16:36:46 AgentMel M.
Thank you. I'd be happy to look into this for you and do you have an additional question I can check as well?
No. just that.
16:38:56 AgentMel M.
May I have your current shipping address please?
Albuquerque, NM 87105
That's the address i want it shipped to.
The address that was on the payment receipt is
Washington, DC 20009
16:41:16 AgentMel M.
Indeed that **HOME** address is the one showing in the order details page.
16:43:06 AgentMel M.
The item is not showing as shipped yet. I'd suggest to call the seller. I'll show you how to get his phone number.
16:43:51 AgentMel M.
It's easy to request for your seller's phone number. Here's how:
1. Click "Advanced Search" at the top of the eBay.com homepage.
16:44:06 AgentMel M.
2. Click the "Find Contact Information" link on the left side of the Advanced Search page.
16:45:06 AgentMel M.
3. Enter the seller's User ID and the item number.
alright. I did that.
It says it's sending me an e-mail.
16:46:46 AgentMel M.
Please check your email and the phone number will be there.
aah. great. Thanks.
I'll give her a call. I hope there's a way to stop the shipment.
16:48:21 AgentMel M.
He hasn't printed shipping label yet so most probably it's not yet shipped.
In the meantime, is there any way I can simulate paying for another item, so I can determine where I went wrong paying for this item?
16:50:52 AgentMel M.
Let me check your shipping address on file if it's current.
I just called and the package has been shipped.
Perhaps she didn't print the shipping label through eBay.
In any case, it's already gone to the post office and has a tracking number.
Unfortunately, the post office won't let me do anything with the package until I receive it, so I'll have to pay to ship it again to my grandma.
I'm really frustrated that by checking out on my iPhone, I don't remember seeing any place to set the shipping address before completing the transaction.
What's even more frustrating is that I tried to find the best contact information for the shipper this morning, but all I found was the e-mail address. I didn't know I could call the shipper.
16:53:56 AgentMel M.
I understand where you're coming from but since your shipping address on file is **HOME** Washington DC, that's what was reflected on the order details.
Exactly. That's where I would normally have things shipped, but for this order in particular, I wanted to have it shipped to my Grandma in NM.
16:55:43 AgentMel M.
Before purchasing an item, check the shipping address on file if that matches the address you want an item be shipped. If not, you need to change it prior to purchasing the item.
Do you mean it needs to be changed before winning an item or before making payment.
16:56:48 AgentMel M.
My concern is that i checked out using the eBay app on the iPhone, and i don't think I was given the opportunity to change the shipping address while making the payment.
If I was given that opportunity, it wasn't obvious how.
16:57:49 AgentMel M.
You need to change the shipping address prior to bidding on the item.
That doesn't make sense.
What if I'm bidding on two items that need to go different places? I've never had to change my shipping address prior to bidding.
16:58:24 AgentMel M.
Once you win it, regardless if you're using a desktop or ebay mobile, changing the address won't be an option anymore.
That's a horrible system.
16:59:04 AgentMel M.
You need to contact the seller immediately to let them know that it should be shipped on anther address as it will show the address on file.
It's too late - I don't think you're reading my messages.
I contacted the seller and the item has already been dropped off at the post office and the post office is closed.
16:59:45 AgentMel M.
I am understanding it.
17:00:10 AgentMel M.
For that shipped item, it can't be stopped anymore but if this happens again, that's what I am referring to.
I'm really disappointed with eBay.
17:01:47 AgentMel M.
I'm sorry to hear about the frustration that this matter caused you. But this is how the bidding and buying works.
1) I couldn't change the shipping address on checkout. (2) I couldn't easily contact the seller after I realized that the wrong shipping address was used.
These are both things that eBay could have facilitated, but didn't. This results in me having the hassle and expense of having to re-ship the item.
17:03:11 AgentMel M.
Contacting the seller is easy but the seller should immediately read the email you sent.
The seller prepared the shipment last night, but did not read e-mail all day today.
So you're saying the seller is required to check e-mail before finalizing shipment? Are you saying that this situation was caused because the seller didn't read e-mail?
17:07:06 AgentMel M.
The seller is encouraged to check emails but we don't have control on when they will check their emails.
Right. So if eBay had given me the choice to select a shipping address or if eBay hadn't made it so difficult to find the seller's phone number, this situation could have been avoided.
For that reason, I would like eBay to refund my shipping charges (as a courtesy for me having to re-ship the item myself).
17:11:18 AgentMel M.
We do not give credits for this kind of situation.
17:11:43 AgentMel M.
As a buyer, you updating shipping address is a must if you want an item to be shipped to the right address.
Very well. Thanks for the hassle. I'll be sure to warn others about the dangers of buying through eBay. eBayer beware.
17:14:34 AgentMel M.
You're very welcome. It's been a real pleasure chatting with you today and I am glad to explain this issue on a wrong shipping address. We value your business and have a great night.
17:14:34 AgentMel M.
Thanks for using eBay Live Help! To close this chat window, go ahead and click on the "Exit" button whenever you're ready.
Mel M. has left this session!
The session has ended!
The session has ended!
Session ID: 25724844
Pick one of the following options:
However, I wanted the ability to save my session on demand. It turns out Firefox has a setting for this too, which just saves the session state for the current session (one restart, then revert to default behavior).
Since I wrote the bookmarklet, I also found Save Session, which appears to do the same in an Add-On. Good luck and happy session saving.
Fast forward to today, where I was stuck with a problem. I had a four-page real estate agreement that I needed to customize, but I only had the scanned copy. I ran it through Acrobat's OCR and tesseract-ocr, neither of which created results even close to usable (the corrections process would have taken longer than retyping the documents by hand).
I tried typing the document by hand, but i found typing a single paragraph took me approximately 10 minutes, so I felt it would be worth my time to investigate a process that would be repeatable.
So I thought I would give the Turk a try. I registered and started to create my first Human Intelligence Task (HIT). Since HITs work best when they're balanced and small, I decided to break up my job into four HITs (one for each page). I would have preferred to break it up into even smaller chunks (just paragraphs), but that would have required more intelligent processing, but the pages I could separate mechanically.
The Amazon sample HIT templates didn't include anything for typing a page (most samples are for small things like "answer a simple question" or "flag questionable content"). So I created my own template. It was simple and easy. I used their HTML editor to create some short instructions, an iframe to contain the PDF page, and a text box below to enter the text. At Amazon's suggestion, I also included a comment box at the end where the worker could include whatever feedback they wanted. The template contains exactly one variable, "PAGE_URL" which is the URL to the PDF PAGE to be displayed.
In order to create each of the HITs, I had to do two things:
- Split the document into separate pages.
- Supply Amazon with a CSV containing the PAGE_URL values. Since a CSV with only one field is trivial, I just needed a text document containing the word PAGE_URL, followed by each of the urls on separate lines.
Finally, I loaded $4.40 into my amazon turk account and created the HITs (worth $1 each plus Amazon takes $.1). I wasn't sure at that price if the job would get done, but in less than two hours, I had all four pages typed, each which took the workers an average of 45 minutes each to type. Two of the workers responded that they hoped I was happy with the job and were eager to do more.
Then, Amazon gives me a link to the results which is returned as a comma-separated file, with one of the columns containing the full text of the page that was hand-typed by the worker.
I was so happy with the results, I swiped my credit card for another $4 and gave a $1 bonus to each worker.
But what a bargain. Instead of typing something up, I got to program in Python and create something that was repeatable, while at the same time trading approximately 3 hours of typing for an hour of programming and $8.40.
The next step, of course, is to learn the Amazon Turk API and set up a site so others can upload their scanned PDFs and they can swipe their credit card with me (for the service of handling the pages and brokering the exchange).
In case you're the recipient of one of these malformed URLs, I've created a simple utility to repair the URLs for you. Just copy the URL you received with all of the ugly line breaks into the text box, and you get a nice link to the target URL at the end.
It's not very robust, but it gets the job done.
(And now I hope others won't feel inclined to forward e-mails to me so that I'll do this for them manually).
God doesn't have to give reasons for his actions, but this time he does. He explains through his prophet that he's very proud of us. We've done a spectacular job at inhabiting the Earth and populating it's "corners". In fact, we've populated it so well that it's now time that copulation be limited.
Except for very special, church-sanctioned, public events, only couples of the same sex are allowed to engage in sexual activities. The church events, God explains, are to promote the ongoing maintenance of the population without undue growth.
God acknowledges that through the transition, he understands some people might have difficulty accepting this new edict, so he offers a special prayer that individuals can invoke before gender-reassignment surgery to bless the change in the eyes of the Lord.
After God's great announcement, how would your behavior change? Would you question your own sexuality? Would you seek treatment to help you accept your new proclaimed affinity for members of the same sex? Would you consider the reassignment ritual? Or would you simply adopt separate bedrooms from your former partner and remain celibate?
Would you encourage your children subtly or explicitly to be fond of members of the same sex? Would you be disappointed or reproachful if they found themselves attracted to members of the opposite sex? Would you protest to your congressmen or town hall to have marriage re-defined as only between two people of the same gender?
I look forward to your responses.
Since I run a Windows web server, and I already run my CherryPy web site behind IIS with isapi-wsgi, and MoinMoin has WSGI support, I thought it might be possible to serve MoinMoin from IIS.
As it turns out, it's not that difficult. This article describes the steps I took.
Before we get started, you need to install some prerequisites to match my configuration. These are not requirements, but what I used to make this work.
- Windows Server 2008 SP2 64-bit
- Python 2.6.4 64-bit
- pywin32 214 64-bit
First, you want to install the MoinMoin package somewhere. For simplicity, and because I already have distribute in my Python 2.6 install, I just ran 'easy_install MoinMoin==1.8.5'. Distribute found the tar file, unpacked it, and added it to my installation. Note that a better approach might be to keep MoinMoin installed outside of your core Python install, but that's outside the scope of this article.
I then downloaded the MoinMoin 1.8.5 tar.gz distribution and expanded the /moin-1.8.5/wiki directory to c:\InetPub\DemoWiki. If you don't already have 7-zip, I highly recommend it for .tar.gz files and similar. It's possible you could also have copied the wiki files from %python%\lib\site-packages\moin-1.8.5-py2.6.egg\share, but I haven't tried. The files don't have to be in C:\InetPub, but they will have to be accessible by the anonymous IIS user and the Application Pool Identity, so unless you know what you're doing, I recommend creating the site in C:\Inetpub.
The next step was to configure the site in IIS. If you're an IIS user, you've probably done this a hundred times. Here's what I did on my Windows Server 2008 running IIS 7. In the Internet Information Services Manager, I created a new site called "My Demo Wiki", and set the home directory to C:\Inetpub\DemoWiki (or wherever the wiki files were expanded in the previous step).
Next, you need a hook script that the pywin32 isapi module will use to launch the wsgi app. This script does a few things:
1. Handles command line arguments to install and uninstall the ISAPI Extension dll to/from the web site.
2. When the __ExtensionFactory__ is called, links to the MoinMoin configuration, creates the WSGI app, wraps it using isapi-wsgi, and returns it to IIS as an extension.
The script I ultimately created can be found at moin-isapi-wsgi.py. Note that this file cannot contain a period before the .py extension or it will fail.
This script was set up to install the wiki to the root of the newly-created web site. This all would work very well except that the MoinMoin wsgi server isn't set up to serve the static content. The Apache docs describe how to configure Apache to serve the static content, so I decided to work out how to get IIS to do the equivalent.
The default ISAPI-WSGI handler automatically passes all requests to the WSGI application, so I wanted a way to allow certain URLs to be bypassed by the ISAPI Extension. I found a great example of this in the redirection samples in the pywin32\isapi\samples. Based on these samples, I implemented a isapi_exclude module, which I placed in the same directory as the hook script (though I could have installed it anywhere in the Python path). This module defines a PathExclusionFilter, which will wrap an isapi ThreadPoolExtension and will defer any requests that match specified URLs to the lower-priority handlers. In other words, it allows paths to be ignored by the wrapped extension.
Next, the PathExclusionFilter was applied to the WSGI handler in moin-isapi-wsgi.py configured to ignore /moin_static185 (the path that MoinMoin expects by default to access static content).
Next, since /moin_static185 doesn't exist in the IIS site, use IIS Manager to create a virtual directory in the site to C:\InetPub\DemoWiki\htdocs.
Then, give the IIS anonymous user ("IUSR") and also the Application Pool Identity (in this case, "IIS AppPool\My Demo Wiki") appropriate permissions to \InetPub\DemoWiki. For simplicity, I install Full Permissions. It's likely some more limited set would be adequate, but for now I install excessive permissions for simplicity. These commands will assign those permissions.
icacls C:\Inetpub\DemoWiki /grant "IIS AppPool\My Demo Wiki:(OI)(CI)(IO)(F)"
icacls C:\Inetpub\DemoWiki /grant "IUSR:(OI)(CI)(IO)(F)"
Finally, install the extension. To do this, run "moin-isapi-wsgi.py install".
This final step copies a .dll to the DemoWiki directory, and installs it into IIS. Make sure you've stopped other web sites in IIS and enabled the My Demo Wiki site. Finally, you should be able to access http://localhost and get the MoinMoin welcome page.
My plans now are to contribute these various scripts back to the various projects and create a more simplified process. In the meantime, feel free to use any of these files or techniques to get MoinMoin running on your IIS server.
First, based on the Upgrade Advisor and on feedback from another upgrade experience, I had to uninstall two applications I use frequently: VMWare Workstation and Daemon Tools. This seems reasonable, since both products use custom drivers to emulate system hardware. I was able to install both products after the upgrade with no problems. Even the VMWare Workstation license and configuration was maintained. If you're using Daemon Tools on Windows 7, be sure to install the SPTD 1.62 or later _first_ and then ignore the warning that Daemon Tools is incompatible. It works fine for me but YMMV.
After the upgrade, I found that many of my symlinks were gone. This caused a number of my applications to break, but since I know my systems well and I create these symlinks on other systems frequently, I hadn't lost anything critical.
The next issue arose when I went to connect my media center (XBMC) to my system to watch movies yesterday evening. I turned on my set top box and pointed it at my movies share, and it prompted me for a username and password (which is normally cached). Turns out the problem was pretty simple. Although Windows maintained the network shares on the machine, it reset the permissions on the files. After re-authorizing the media center account, I was able to connect to the shares again.
I've also encountered some minor issues with focus follows mouse and the private status of VPN network connections without a default gateway.
Despite these minor issues, the experience was generally good. Windows updated IIS, including the WebDAV functionality, which was previously installed by a hotfix (I use WebDAV to host my own XMarks bookmarks and passwords). Almost all of the 160 programs in my Add/Remove Programs control panel were kept in tact by the upgrade process. Microsoft engineers missed a few edge cases, but on the whole, the upgrade process was smooth and a huge time saver.
A few months ago, I started working on Python issue 1578269. I have a symlink implementation for windows in jaraco.windows. I suggested porting that implementation into core Python so that os.symlink would work in Windows as well as Unix-based OSs.
As I started developing the patch, I soon found that a Subversion checkout and periodic patch generation was inadequate for maintaining a record and undo capability. I needed the ability to tentatively commit to an implementation, try a potential new approach, and possibly roll-back or commit the new change. This capability is difficult to accomplish with Subversion (without commit access).
The suggested remedy was to use Mercurial. So I cloned the Python Mercurial repository and applied my sequence of patches to the working copy and committed each to my local repo. I found I was then able to easily perform the same operations with rollback, commit, etc, that I was used to with a subversion repository, without impacting other projects.
The first problem came when I tried to apply the patches. It turns out that while Subversion supports native line ending translation, Mercurial does not (or didn't at the time). The prescribed solution was to just use Unix LF endings, so I had to convert my patches before applying them.
The real problems came months later, however, when I wanted to merge changes from the parent repository. I had tried in the past performing a proper merge, but I found that technique clunky. In retrospect, perhaps that would have been the correct action.
In any case, I also found there's a rebase operation. This was reported to do exactly what I wanted: update my local changes to appear as if they were against the latest changes in the parent. I found that the rebase option isn't enabled by default. I had to edit my mercurial.ini file (in the user's home directory, WTF) to enable the rebase capability. After adding rebase, I pulled the latest revisions from the parent repo and rebased the repo.
As expected, there were conflicts... except that when the conflicts were opened in TortoiseMerge, no red lines were displayed. In other words, it appeared as if Hg or Tortoise had successfully reconciled all changes. I was shown the same conflict resolution window many times, but I dismissed it each time, as it had no conflicting changes.
Perhaps I should have been taking a different action, because I found that the rebased code had destroyed my revision history. Many of the revisions I had made to one file had been lost. Indeed, TortoiseHg now showed some "revisions" that had the proper comment, but apparently no change.
Furthermore, the rebased repo appeared now to have reverted some changes that were made in the parent repo. I never felt like I had been given adequate ability to review these potentially disasterous changes, but they were already written. There was no going back.
Fortunately, I still had the majority of the changes documented through the bug tracker. In particular, patch 6 was made using Mercurial. So I did some searching to find out how to apply a patch to an Hg repository. What I found was an article describing the ten steps to apply a patch.
Unfortunately, applying this patch to the repo, even with it stripped to the revision from which it was made, failed to apply with lots of "HUNK #n FAILED at nnn" messages.
To reiterate, using Hg, I was unable to apply a patch created by Hg to a repo against which that patch was created. I tried analyzing the problem, and the patch appears fine. The line numbers appear to reference the proper lines and the reference content appears to match.
I suspect the problem again is due to platform linebreaks. I've confirmed that both the source and the patch use LF linebreaks. I'm able to apply the rejected patches to the source manually if I pass the --binary option. i.e.
patch --binary -i ntpath.py.rej ntpath.py
Although the resulting output appears to have the native line endings (CR/LF), so I have to manually correct that.
In any case, there are several shortcomings of Hg/TortoiseHg that prevent it from being a user-friendly DSCM:
- Robust line-ending support (should behave reasonably across platforms)
- Merge support (TortoiseHg should have merge support; command-line should not require a 10-step process)
- Rebase support (Rebase should be robust, should warn the user if it's about to destroy revision history, and should more clearly communicate conflicts).
Given that Mercurial was selected for its Windows platform support, I cringe to think what my experience might have been in Git.
This worked great except for a couple use cases. First, my XBox 360 can't see media on a computer unless it's on the LAN. This meant that my XBox either had to be on the WAN or it couldn't get media from my workstation (where I keep most of my media).
Second, I have lots of virtual machines that I boot up from time to time. Because the workstation that hosts them was on the WAN, this necessarily meant that the virtual machines could not communicate with other LAN hosts. Generally, this was not a problem, but it was undesirable.
To address this, I've made ComCast the only connection on the WAN, and moved the Speakeasy service (with multiple static addresses) to the LAN. This means that on the LAN now, there are unroutable private addresses (10.x.x.x) and real routable addresses. A host can be configured for either or both. In the case of my server and workstation, I've configured them for both. Then, by default, clients use the ComCast for internet connectivity, but a few select hosts get the Speakeasy service. This seems to work fairly well except for one annoying problem.
The Broadxent modem used by Speakeasy has a built-in DHCP server that can't be disabled. This DHCP server wreaks havoc on the standard DHCP server that exists on the LAN. This was much less of an issue when the modem was on the WAN (and probably for most people). Not only does it issue a useless IP address (usable only to configure the modem) to unsuspecting clients, but it also seems to cause the DHCP server on my router to disable itself; apparently my router is too polite.
The solution, I found, was to use ebtables to block the DHCP traffic from the modem. Since my router runs a linux variant (similar to OpenWRT), I have full access to the IP stack, including the link layer. Four simple commands prevent DHCP traffic from passing on the LAN.
ebtables -A INPUT --in-interface vlan1 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A INPUT --in-interface vlan1 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --in-interface vlan1 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --in-interface vlan1 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
I get the feeling that these rules are a bit more than is absolutely necessary. Nevertheless, after issuing these commands, DHCP traffic no longer traverses the LAN except from the built-in DHCP daemon.
Yesterday, my primary Internet connection went down, apparently due to a physical problem with the line. Even though I pay $85/month for Internet access (for 3Mbit downloads), I only get the same consumer response time to investigate the problem (8 hour window the following day).
Since my main mail server is now hosted here at my residence, I could not afford the 36-hour downtime, so I moved my server over to my backup ComCast service. I put the server behind a router, set it up as the DMZ host, reconfigured my DNS settings and thought I was done.
Turns out that's not the case. Because ComCast blocks CIFS, I had to remote to all of the client computers (everybody who uses jaraco.com for their e-mail) and reconfigure the Outlook clients to use RPC over HTTPS.
Then, e-mail was coming in nicely, and the clients could connect. Still, all was not well.
Turns out outgoing e-mails were being blocked by blocklists, causing the recipient servers to reject delivery outright. All Comcast addresses are on blocklists because they're considered consumer-grade addresses, and mail should not be delivered from these addresses. Note that although this problem is created by the industry, it's fully supported and encouraged by Comcast, whose policies explicitly forbid "servers".
So, I took advantage of a sendmail server I had lying around. I opened up the firewall to port 25, reconfigured the service to bind to all interfaces and not just localhost, and enabled relaying from my mail server. I then reconfigured my mail server to send all outgoing mail through the relay. Because that server is hosted at a datacenter somewhere in Florida, e-mail servers allow mail from it.
Still some things don't work, but at least mail is working again (although it's dependent on the relay server).
By the end of the day, I hope to undo all of this and revert to my previous configuration. What a waste of a day.
The aphorism does apply to some very good examples. Consider parameter passing to a function.
print_string("my dog has fleas", True)
It's pretty clear from the name of the function and the string argument passed in that the function will likely print out the string, but it's quite unclear what the purpose of the second parameter is. I've intentionally not defined it previously to exaggerate the point.
This ambiguity can be lessened by the caller by explicitly including the name of the second parameter.
print_string("my dog has fleas", append_newline=True)
And indeed, that's the canonical example that illustrates how Python's ability to be explicit about parameter names improves the potential readability of code over other languages including C++, Java, and C#.
But when the aphorism "explicit is better than implicit" is treated instead like a guiding principle, it misleads. It generally purports that the programmer should do more work in the name of clarity. C#, Java, C++, and assembly, for that matter, are much more explicit than Python. It's the duck-typing and high-level abstraction and dynamic nature of Python that gives it all its power and attraction. It's the use of previously-implicit white space to designate syntactical delimiters that removes the need for the explicit line terminators and logical block delimiters.
The ability to introspect a class or method or function and use its name instead of having to explicitly define the same string of characters as a member means less clutter and more consistency. When an ORM can dynamically create classes to match the names of tables in a database (without having to generate any code), this is a powerful construct.
All of these examples go against the aphorism. This contradiction is easily satirized.
So the question I pose, dear reader: Does "explicit is better than implicit" have more clearly beneficial examples, or is maybe this aphorism ready for the dustbin?
# the question is, what mathematical operation or operations,
# each used only once, on the four numbers 2,3,4,5 will result
# in the number 26
from __future__ import print_function
import itertools, operator
Return a function that will cycle through the functions
for each set of arguments passed in.
>>> funcs = apply_funcs([operator.add, operator.sub])
>>> reduce(funcs, [1,2,3,4]) == 1+2-3+4
functions = itertools.cycle(functions)
return lambda *args: next(functions)(*args)
def calculate_result(numbers, ops):
return reduce(apply_funcs(ops), numbers)
numbers = map(int,'2345')
ops = [getattr(operator, op) for op in 'add sub mul truediv pow'.split()]
n_ops = len(numbers)-1
candidates = itertools.product(
is_target_result = lambda candidate: calculate_result(*candidate) == 26
target_combinations = filter(is_target_result, candidates)
((3, 2, 5, 4), (<built-in function truediv>, <built-in function add>, <built-in
((5, 2, 3, 4), (<built-in function pow>, <built-in function sub>, <built-in function add>))
((5, 2, 4, 3), (<built-in function pow>, <built-in function add>, <built-in function sub>))
This decision may herald the enlightenment when it comes to high-speed broadband service. While I'm not particularly affected by the issue that brought this decision into the public spotlight (peer-to-peer services), I am hoping it will extend to their unreasonable blocking of traffic on port 445 (Windows Domain Services) without an exception process.
If so, this will make their service much more attractive to me.
Thanks FCC, for standing up for the minority.
I've been using Comcast as a backup internet connection because DSL is unreliable and that's the only alternative I have available is this under-developed part of the country.
I continue to find limitations and active censorship of data transmission on the comcast network. I hear reports of unreliable IRC connectivity (which I seem to be experiencing this morning). I have complained about their denial of allowing certain legitimate traffic, but they refuse, claiming it's better for the common good.
Of course, in the corporate realm, this practice is perfectly acceptable, even though it goes against the principles of the country in which this company operates.
I have a good deal of respect for the considerations companies have to make. Nevertheless, I feel that Comcast is willfully censoring and degrading their service, and while this practice may be good for their company, it's detrimental to my situation and detrimental to their customers.
So F*** Comcast.
When's metro 2.0 coming?
(link no longer available)
I guess I can't just leave port 9100 open to the world anymore. I had for the past 5 years with minimal problems. That meant I could print from anywhere, and when I got home, the printout would be waiting for me.
I'll probably open it back up again later, perhaps with some gerry-rigged authentication.
I was on travel (as I often am in dreams). I was also playing some sort of frisbee game, some cross between ultimate and frisbee golf. I was playing with novices, so I was playing less competitively than I otherwise could have played. There was water all around, like in Hangzhou West Lake or Venice. One player jumped from one surface to another, and two players, including myself, called a "travel" on that player. Everyone was a little confused, so I explained the rule.
At one point, we climbed out of boats and Barenaked Ladies were performing Auld Lang Syne over the PA. Someone asked what "Auld Lang Syne" meant. I didn't know, but an older man seemed to know. It means "Aunt Susan". He proceeded to make a joke about their family's actual Aunt Susan, who wasn't present.
At this point, I woke from my dream and realized that my brain was trying to trick me into remembering the incorrect meaning for "Auld Lang Syne".
Since -quote-Comments or Questions must only contain the following characters a-z A-Z 0-9 , . - ! ?-quote-, I-apostrophe-m going to encode my message by replacing disallowed punctuation with the name of the appropriate punctuation enclosed in dashes.
I-apostrophe-m having difficulty changing my address through your web site. Your website seems to not accept my address. My correct mailing address is-colon-
PO Box 96503 -number sign-41825
Washington, DC 20090-6503
When I try to enter the address correctly, I get an error. The error message appears behind the form, so I-apostrophe-m unable to read it, but I suspect the problem is the number sign -open parenthesis--number sign--close parenthesis- in the address. So I try this address-colon-
PO Box 96503 No. 41825
Washington, DC 20090-6503
This address is accepted without error, but it replaces the address with an incorrect address -open parenthesis-it removes the -quote-No. 41825-quote--close parenthesis-. Apparently any address with a PO Box in it removes all other information in the address.
Finally, I tried one more address-colon-
PO Box 96503-41824
Washington, DC 20090-6503.
It accepts this address, but it strips off the -plus-4 of the zip code. While this is probably acceptable and may get to me, it will likely be delayed due to the fact that the post office box number can't be matched to the zip code.
Can you please see that my address is updated in the system with the correct address? You may have to forward this to the web developers or the core system developers for it to accept my address.
Now with DRM, we're bringing back those good ol' days.
Recently, I bought Catan, a remake of the Settlers of Catan board game, for the XBox 360. It was 800 points (or about $10). After I downloaded the game, I found out it only allows multiplayer online. In other words, you can play against the computer or against random strangers. If you want to play with 4 people in your home, you have to have 4 xboxes, 4 tvs, and 4 subscriptions to xbox live.
Because that's how I wanted to use the game, I called customer support, but they were unforgiving. After you've paid your points, they're gone for good... and you can't re-sell the product either.
Furthermore, she let me know that they had passed on my suggestions to the QA department (particularly having troubleshooting tips on the web site), and these suggestions would likely be implemented in some fashion.
She went on to tell me that my issue should have been resolved, the blind was shipped UPS next day air yesterday, and should have arrived today. It didn't, but I suspect that's because of problems with our building security, and completely out of their control.
Finally, she let me know they would be sending me a check to compensate me for my time and trouble on the matter.
In other words, Levolor has gone far beyond my expectations and even beyond my stated request. They seem to care greatly about the end consumer and his satisfaction. I am confident that the problems I've received were isolated and that any systemic problems that caused the issue are being addressed to a great extent.
I would highly recommend Levolor blinds. I've always been pleased with the quality of their product, and I believe their ultimate customer service to be outstanding.
By the way, I did submit a compliant to BBB, for which Levelor is a certified member, but it appears the BBB does not deal with consumer-getting-jerked-around-by-member-company complaints, so they've let me know.
From: Jason R. Coombs
Sent: Monday, 12 March, 2007 14:55
Subject: RE: Levolor.com: Slat mis-cut
I have to say I am extremely unhappy with the service I have
received from Levolor.
It's taken every ounce of self-control I have not to write a letter
with gross explicatives.
When I first received my blinds, there was a manufacturing defect.
A single slat had the notches mis-cut, so the slat rested 1/2" out of
alignment with the others, causing the other blind to run into it when drawn
up or down.
I first contacted Levolor via e-mail. The first representative
indicated that I needed to provide the correct measurements from another
slat so they could properly replace the slat. These blinds are very large,
so it was a difficult job to measure the slat, but I did do so. I
double-measured to be sure to provide precise and accurate measurements. I
sent the results via e-mail to ensure accuracy.
I then received a response in which the representative required me
to get the all of the numbers from the inside of the head rail. I
reluctantly performed that task this morning, which involved the following
- going downstairs to retrieve my ladder
- removing my TV screen mounted in front of the blinds
- releasing the first valence clip
- moving the ladder
- releasing the second valence clip
- moving the ladder
- releasing the third valence clip
- moving the ladder
- releasing the fourth valence clip
- releasing one blind retention clip
- moving the ladder
- releasing the second blind retention clip
- moving the ladder
- removing the blinds from the headrail and reading the numbers to
my girlfriend; this is very difficult as the blinds weigh around 50 lbs
- replacing the blinds
- moving the ladder
- engaging the first blind retention clip
- moving the ladder
- engaging the second blind retention clip
- replacing the first valence clip
- moving the ladder
- replacing the second and third valence clips
- moving the ladder
- replacing the fourth valence clip
- replacing the TV screen
- returning the ladder to the storage unit
I then call the phone number that the previous rep had given me and
I explain the situation. All she requires is the bill of lading number,
which is on three different pieces of paper I had sitting around the house.
I mentioned nothing of my previous contacts with representatives, and she
was able to complete the process without any mention of touching the blinds.
In other words, I probably didn't have to get up from my desk. The
entire process could have been completed easily if
- the _first_ or _second_ representatives I had worked with had used
the order number I supplied to determine the bill of lading
- the _first_ or _second_ representatives I had worked with has
simply asked me for the information they needed
- or your web site had a form that provided detailed instructions on
how to get these sorts of problems resolved
- or my problem was handled by the same person each time, rather
than a different person with a different approach each time
- or your QA team had caught the error in the first place
Needless to say, I've spent too much time on this already.
If you would like to keep me as a happy customer, I request that you
apologize for the actions of your staff and provide me evidence that this
problem will be resolved for you customers in the future.
If this is not possible, you can compensate me for my time and
trouble. A check for $100 would satisfy me and assure me that this is not
business-as-usual. Considering that I've already spent $2000 toward Levolor
blinds, this is not an unreasonable request.
If you need to take this request to your supervisor, please do so.
If you need to contact me to resolve this matter, also please do so. My
phone number is 505.459.6655.
If you don't care to settle this matter with me directly, I will be
happy to take my complaint to the better business bureau and to post my
detailed experiences publically. I can't be sure that doing so will resolve
the problem for future customers, but I will at least feel as if I'm not the
only one taking the hit.
Jason R. Coombs
From: LV Info [mailto:Info@levolor.com]
Sent: Monday, 26 February, 2007 16:12
To: Jason R. Coombs
Subject: RE: Levolor.com: Slat mis-cut
Thank you for choosing Levolor / Kirsch. Our goal is to provide our
customers with the highest quality and service. I apologize for the
inconvenience you have experienced. My name is David and I will be
assisting you in resolving this situation.
Additional information is needed in order to properly assist you with
your repair. You will need to take your blind down out of the window
and have all the numbers that are on the sticker in the head rail ready
for us when you call. This will help us with our repair process.
You will be able to speak to any of our representatives and they will be
able to help you.
Please contact our Consumer Service Department at 1-800-538-6567.
If I can be of further assistance, please contact us at
Levolor / Kirsch Customer Service
From: Jason R. Coombs [mailto:firstname.lastname@example.org]
Sent: Sunday, February 25, 2007 1:24 PM
To: LV Info
Subject: RE: Levolor.com: Slat mis-cut
Dear Crystal or other customer service representative:
Thanks for your response. I had a very busy week and so am just now
around to measuring the slat.
Measuring from the left, the notch positions are:
6", 25.25", and 45.25". The total slat width is 50.75".
Please let me know if I can provide more information, and thanks for
Jason R. Coombs
From: LV Info [mailto:Info@levolor.com]
Sent: Monday, 19 February, 2007 14:20
To: Jason R. Coombs
Subject: RE: Levolor.com: Slat mis-cut
Thank you for choosing Levolor / Kirsch. Our goal is to provide our
customers with the highest quality and service. My name is Crystal and I
will be glad to assist you.
Additional information is needed in order to assist you properly. Please
respond via email with the notch measurements on the slat. The way these
need to be measured is starting from the far left of the slat to the
center of the 1st notch, then from far left to the center of the 2nd
notch and so on to the last notch. Once we get that information we can
send you out a new slat and that should fix your problem.
If I can be of further assistance, please contact us at
Levolor / Kirsch Customer Service
From: Jason R. Coombs [mailto:email@example.com]
Sent: Saturday, February 17, 2007 3:27 PM
To: LV Info
Subject: Levolor.com: Slat mis-cut
Hi. I'm writing regarding order 02203362. I have a single slat that
wasn't cut correctly in my blind. It's the second to the bottom on
the left blind.
It appears the right and left notches were cut about 1.5cm off. The
center notch is probably okay. This causes the blind to rest off
center and the right blind to run into it.
Can you please send a replacement slat for this set?
I can make photos available. I can also provide additional
information if necessary. Please don't hesitate to contact me if you
need additional information.
Jason R. Coombs
Subject: Slat mis-cut
Reason: Product Support, Parts, Repairs, Warranty
Product: Wood Blind (Real & Faux)
Purchase Date: February 2007
First Name: Jason R.
Last Name: XXXXXX
Postal Code: XXXXXXXXXX
Country: United States
So I thought I'd go to eBay and buy one. I figured I'd pay $5-10 for one, but it looks like they're selling for around $70 each.
I'm not going to go into the details, but I've escalated my complaints. If they don't reach a satisfactory end, expect to see some flaming posts detailing my experiences.
The other week, I was sitting in a training course with a number of my peers. I mentioned that I don't run a firewall on my computer. Their immediate response was, "Then how do you protect from hackers, viruses, ...?"
I tried to explain (by going on my usual tirade) that a firewall is nothing but a crutch. It's a bandaid put over a non-existent (or unidentified) sore in the hopes of preventing infection.
This is all fine and well, and for the general public tends to do quite a bit of good. The problem is, it does act as a crutch, and for agile or power users, does more harm than good.
As a crutch, the firewall acts to provide a false sense of security. It provides a security perimeter, but this perimeter is only effective while the adversary (or adversarial code) remains outside the perimeter. Because of this fact, firewalls have been drawn closer and closer to the core of the problem (the buggy kernel or application code). While developers eventually address the core problem (these days typically in a very short time), firewall developers and other security "experts" leave behind a trail of broken implementations to "mitigate risk".
One of these broken implementations has been to disable network transport on "uncommonly used" ports. While this approach seems reasonable, it has a particularly crippling effect on Internet development, and with little ultimate benefit for even the general consumer.
Consider, for example, the fascist policy Comcast applies to its customers, that of blocking both incoming and outgoing traffic on port 445. This practice still persists and prevents legitimate use of the Internet. It is a forcibly applied firewall and there is no exemption process.
Practices like these have little benefit for the consumer because although they protect a particular vector of attack, they do not resolve the essential problem, and another vector can exploit the same weakness. And because that channel has been limited for legitimate as well as illegitimate use, the industry will simply create another channel to accommodate the limited functionality. This new channel is often just as weak as the original.
The grand effect of this is a temporary benefit to security but an ultimate degradation in the quality of the network. Instead of using the network in the way it was designed and implementing over-arching security protocols (such as IPSec), developers are utilizing one-time security protocols over web transport (such as Skype does for voice communication).
The biggest cost, however, is that which we can't see. It's the applications that aren't developed because of these limitations and the functionality that doesn't exist because this increased variance in Internet functionality has raised the bar beyond that attainable by many. Additionally, it's increased the amount of effort required for all users to effectively operate in this environment. Time that would otherwise have been spent improving the system or creating new products is instead spent jumping through hoops in the name of security.
I would say that for me, my average productivity in an IT environment has been reduced by about 50%, in both professional and personal areas, as a result of information security practices, and that the advantages of these practices are minimal.
So anyway, this weekend I was visited by friends (without blogs) (seriously?) (yeah, no blogs; and they're young blokes).
We decided to go to the Arlington Cemetary. You see, since I'm a native now, I can't do tourist things unless my friends visit me (hint, hint).
So, we went to the cemetary. I made some bad jokes about cemetaries, goths, and death. I got bad looks, but had a good time. I wasn't too obnoxious.
During our visit, there was also a spectacular Air Force Memorial Opening. We were not at the memorial dedication, but we did see some of the arial displays, including a fly-over of a Stealth Bomber. The sight was ominous and spectacular. I imagined that a flyover of an earlier plane would have been similarly ominous in earlier decades.
In addition, they had some air stunts, flyovers of various Air Force models, most of which I could not accurately identify. It was quite a good day to be in D.C..
When I bought it, I noticed they had a cabinet mount option. You could buy a hood (for about the cost of the oven itself) that would allow one to mount the oven under a cabinet.
"Fabulous," I thought, but never settled into a place where I thought I'd buy one.
Well, I recently have begun settling into such a place.
And guess what?
They've phased them out. It appears, although I have not authoritatively confirmed, that there are no new under-cabinet-mountable toaster ovens for sale.
This has me sad. I was really looking forward to _finally_ mounting my toaster oven (to the underside of my cabinet).
I've sold my old toaster oven (as part of the move), and so will probably have to accept the wicked fact that my toaster oven must rest on my kitchen counter. C'est la vie.
If you don't already have a PayPal account, I'd recommend you get one. It's one of the few services that allow people to send money electronically the way it should be done.
If you already have a PayPal account, check out the link above for more information about the free credit alerts.
But today, I experienced an interview that reminded me of a polygraph exam, only more thorough.
You see, earlier this week, I changed the address for my credit card so I could have items shipped there.
Subsequently, I started getting errors from Microsoft Money (the error message was incorrect, it seems, stating "The user cannot signon because of invalid user ID or password, or host is unavailable". It turns out the user id and password were correct and the host was available. The real problem was I changed my address. So, rather than contact me or send me a message, my credit card company (Chase) simply decides to block access to my transactions. I guess they figure if they do that, I'll call in eventually.
Curiously, they didn't stop me from purchasing lots of new items and shipping them to the new address. They didn't even block the login from the website. I was only blocked from downloading transactions into my account. So if my card was stolen, I might not have noticed unauthorized transactions being posted.
Well, I called in. To verify my identity, they asked for the following items:
- My name
- My SSN
- My DOB
- My Mother's Maiden name
- My New Address
- My Old Address
- My Phone Number
- My Work Phone Number
- My address in Socorro, NM (multiple choice)
- My brother's age (multiple choice)
- Verify my last transaction on the account
After they verified this information, they unblocked my account, but I they will not restore access to the downloaded transactions for 48-72 hours. I could fly to manhattan and get the transactions faster.
If you extrapolate this trend, I will probably have to verify the first four lines of the first C program I wrote next time I move. I have a digital ID, but no one ever asks for it. Indeed, I don't think I'll ever be asked for my digital ID.
* sigh *
I was leaving work carrying only my laptop in a small, discrete black bag. It's one of those small cases that's barely larger than the 3 lb laptop itself with reinforced sides and two handles. It's no more than 5cm thick and can't weigh more than 4 lbs with the laptop.
As I was walking out to my car, which I usually park far from the building to avoid getting dinged, I realize I had covered the car earlier that day. There is no reasonable place to set a laptop, so I rested it against the wheel of the car. I wanted to put it someplace I could remember it while I removed the cover from the car.
I then remove the cover, get in the car, and head home.
It normally takes me about 10 minutes to get home.
I walk in the front door and then realize I'm not carrying my laptop. I check my car; it's not there.
I quickly decide to make a phone call to a friend at work who often works late. I ask him to go out to the parking lot and see if my laptop is there (I'm pretty sure it is).
Later, he tells me the rest of the story. As he is walking across the front lobby out toward the parking lot, the security guard warns him that there is a bomb squad outside and to be careful. Quickly putting the two together, he says that everything is okay, and he knows what is going on.
He steps outside and there is a full bomb squad and fire truck in the mostly empty parking lot. There are many security-related people standing around but away from a small, flat, black object on the tarmac with four orange cones placed evenly around it.
As my friend approaches the situation, the he indicates that he is aware of the object's origin and its harmlessness. While the security officers believed my friend, they urged him to walk very slowly toward the "object" when retrieving it.
Ultimately, the laptop was retrieved without further fuss. The bomb squad and security force returned to their normal operations. The laptop was fine, too.
My biggest worry about all of this is that it's fed by a fear that's been taught to the American public and self-perpetuated by the public. We have taken extensive measures to counter terrorist activity, to the point that everyone believes we're perpetually in the cross hairs of a terrorist attacker. A little common sense says that it is no more likely that someone would leave a bomb in front of this building before 9/11 than after.
I understand there may be legitimate concern for additional security measures for known _terrorist_ measures. However, it's also clear that the U.S. has a couple of advantages. Our first is our distance from the terrorists and the sheer logistical difficulty of carrying out a terrorist act of global notoriety. The second is our and our allies' extensive intelligence and their ability to detect these things.
The heightened fear of the public or the eulogistic cries to 9/11 are not helping, and instead only dampen our spirits and lower the quality of life for everyone.
I've had a lot of things going on. I still do, but I'm unloading a lot of that real soon.
I've taken a job in D.C. I'll be out there sometime in October.
I'm selling my house and most of my stuff.
I'm getting healthy again, and I feel like I have more free time and energy. Things are going great. D.C. ought to be quite interesting. I'll be living in a real city. I'm still not entirely sure what that means. One thing I know, I'll be able to get high quality broadband from Speakeasy (now Megapath) at one of their major hubs. That should mean sub 40ms ping times to anywhere in the U.S. My ping time to the ISP router is 90ms+ right now, so that'll be a major improvement.
Anyway. Just checking in.