Thursday, June 21, 2018

Python List Exercises

There are hundreds of list exercises in Python.
Here are just a few of them.
I'm just working from web pages I found on the internet.
I intend to add to this over time.

# Print the last element on the list
# len[alist] prints the length
mylist = ['a', 'b', 'c', 'd']
print ("last element: ", mylist [len(mylist)-1])
last element:  d

# Find last but one in a list
# [Ummm, this is clearly harder in other languages]
mylist = ['a', 'b', 'c', 'd']
print ("last element: ", mylist [len(mylist)-2])
last element:  c

# Find the ith element of a list where the first one starts at 1
i=7
mylist = ['a', 'b', 'c', 'd','e','f', 'g', 'h', 'i', 'j', 'k']
print(mylist[i-1])
g

# Find the number of elements of a list.
mylist = ['a', 'b', 'c', 'd','e','f', 'g', 'h', 'i', 'j', 'k']
print("Number of elements in list is: ", len(mylist))
Number of elements in list is:  11

# Reverse a list.
mylist = ['a', 'b', 'c', 'd','e','f', 'g', 'h', 'i', 'j', 'k']
# this works in place so you can't print it all on the same line
mylist.reverse()
print (mylist)
['k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

# Test if a list is a palindrome
# palindrome check - this is more convoluted than some but it helps to see the steps detailed
# Check if a given list is a palindrome
# Check indexes from 0 to the middle of the list
# Check if first index = last index, then move in by one
# Some diagnostics left in as comments

def palcheck(mylist):
NotAPal = 0
#print("Middle is: ",int(len(mylist)/2))
#print ("Length of list: ", len(mylist))
#print ("Last index: ", len(mylist)-1, "Contains: ", mylist[len(mylist)-1])
lastindex = len(mylist)-1
for i in range (0, int(len(mylist)/2)):
if (mylist[i] != mylist[lastindex-i]):
print(mylist, "is not a palindrome")
NotAPal = 1
break
if (NotAPal == 0):
print (mylist, "is a palindrome")

palcheck ([1,2,3,4,5,4,3,2,1])
palcheck ([1,2,3,4,2,3,2,1])
palcheck ([1,1,1,1])
palcheck ([1,2,3,2,1])
palcheck ([1,4,4,2,1])

[1, 2, 3, 4, 5, 4, 3, 2, 1] is a palindrome
[1, 2, 3, 4, 2, 3, 2, 1] is not a palindrome
[1, 1, 1, 1] is a palindrome
[1, 2, 3, 2, 1] is a palindrome
[1, 4, 4, 2, 1] is not a palindrome

Sunday, June 17, 2018

Swap Two Integers without using a Temporary Variable

This is an older exercise, but it still comes up.
This falls under things you wouldn't bother worrying about in real life.

Swap Two Integers without using a Temporary Variable

The idea is to just add the two integer variables and then subtract each piece out in turn.

Say you have x=5 and y=9.

If you are using Python you can just stop right here as "tuple unpacking" will so all the work for you.

x, y = (y, x)

and you are done. x is 9 and y is 5.

Let's assume you want to do it the harder way...

Replace x with the sum of x and y.

x = x + y

x = 5 + 9 = 14

Now you have "lost" x, but you still have y and you can deduce what your old x is.

For the new y take your total and subtract out y, which will leave you with the "old" x in y's place.

y = x - y

y = 14 - 9 = 5

Now to get the new x, take the total and subtract out the new y. which will give you the old y which goes in x's place.  It's more confusing to write it out in English that to just see the math.

x = x - y

x = 14 - 5 = 9

To Summarize

x = x + y   [x changes]
y = x - y    [y changes: Total minus original y]
x = x - y    [x changes again]

Tuesday, May 22, 2018

The Non-Dog Blog is Staying at Blogger for Now

I have WordPress installed on my new website. It's very nice, but the blogging has these odd limitations. Mostly it's my own ignorance, but some of it is from years of being designed a certain way. I have more than one blog, but in WordPress they like to assume one blog per website unless you use categorization. I have 500 posts in this blog and there's no way I'm going to spend weeks categorizing them all. There are other workarounds, but I'm not sure I want to work that hard since I can easily have as many blogs as I like on Blogger. The tools are more limited in Blogger which is sad. I will make my author blog on WordPress, but that's with a brand new domain.

So what I can do is link to this site and I will have control over my DNS CNAMEs again so I will be able to use nondogblog.frap.org again. (Network Solutions took my ability to control them away from me - hmphf.)

One thing that was something of a heavy camel back-breaking straw was petty, but showed a glaring limitation - possibly of the theme I had chosen. I wanted to add the background image that you see here, but I didn't want it to affect the whole website. Sorry. Argh.

This is frustrating as I was so proud that I figured out how to download and them import my entire blog from blogger to WordPress. Fortunately I kept this site while I messed around with the new one.

Sunday, January 14, 2018

Figured out My Ski Turning Problem

For years, I've been struggling with an annoying problem with my ski turns.
My turns look like backwards 2's.  An instructor and I took a look at my tracks. The turn to the left is nice and smooth. The one to the right is sharp and abrupt.

You turn a parabolic ski by putting pressure on the ball of your foot on the outside ski. You are essentially weighting the inside edge of that ski. It's quite subtle and my less-coordinated left foot doesn't know how to do it properly, so I end up stomping on that ski and the ski turns too sharply.

I need to spend a lot of time on a slightly advanced bunny (green) or an easy intermediate (blue) slope. A slope I spend a lot of time on is "Trailblazer" on Jerome Hill at Sugarbowl.
The Nob Hill slope also at Sugarbowl is nice too. White Pine is a little easy, but ok. You do need to have enough incline to learn anything, so places like the very top of Squaw near the higher building are actually too easy.

I figured this out by actually sitting down in a chair and watching my feet while I envisioned turning left (just wearing running shoes). My right foot's heel rose, and it rolled inward a little, and my weight shifted to be on the ball of that foot. It's hard to imagine all this subtly going on inside a ski boot.

My left foot is a little clueless about how all this works, but now I can spend a lot of time training it away from the pricy ski slope. I can start in a chair and then move to standing up.

I can tell you that turning improperly is very tiring and will shorten the time you want to spend on the slope.

When turning, you should unweight the inner ski. If you're turning properly, it should just follow along with the turn. That foot will be behind the other foot.

Friday, March 31, 2017

Going Beyond the Do-Not-Call List

You've listed all your phone numbers on the Do Not Call list and you're still getting phone calls that you don't want. I know you feel guilty about asking your favorite organization to stop calling every week and while you shouldn't feel guilty about asking for peace and quiet there are some relatively simple ways to achieve less interruption.

First double-check that your phone is on the do-not-call list by checking here:

https://www.donotcall.gov/
and you can verify your phone number (any phone number) or register an new ones.

The following strategy assumes:

- you have caller id. This is a fairly common, essential tool for avoiding phone calls you don't want to answer.

- you have a phone that can keep a history of phone calls. I use Panasonic for our house line, but most phones will work fine.

- you can use an answering machine for screening calls, but it's optional as most calling services do not leave messages.

Do this around once a week. Weekends are best since there is no one to answer the phone, but most of these types of places just answer with voicemail 24x7 so you shouldn't have to worry about that.

Take a look at your phone's call history.
When you see a number you don't recognize and there's no obvious name on the ID, call the number. Sometimes you will get a business name and a message about their service. If it's one of the many calling services, at the end of the message they will offer you an option to have your number removed from their service (e.g. "press 9 to be removed.") Since I leave my caller id exposed, I don't even have to enter my phone number as they already have it.

Some of the services won't even bother telling you who they are they just immediately offer you an option for removal (because that's the only reason you would be calling them.)

I am keeping a call log of the numbers I've requested removal from to see if they reoccur. One new trick I've seen is people using individual cell phone numbers. For now, I'm just writing those down to see if they reoccur and will report more if I learn anything new.

Monday, January 02, 2017

I Hate My Smart-ass Prius

My Prius is driving me crazy.

First that incessant reverse beeping which I realize I can get turned off, but that's just the beginning. I like how you just have to have the key on you. Until you actually need to find the key, which is usually during one of those times where my wife and I are out somewhere and I want to leave most of my purse in the car. Nope. Stop right there. Can't lock the door with a key inside. That's nice, but hey smart-thing can't you tell there's a key on the outside? So because we're late for our dinner reservations, we have to stop and search for which pocket (tm) the blasted Prius key has migrated to. Yes, it has a standard place in my purse, but it likes to travel like everything else.

I feel like I'm traumatizing the poor thing when it beeps back about that duplicate key, and refuses to lock the door and I start publically yelling "I hate this car." [Kick tire.] Or when I have the car on and running and I put it in Park to get out of the car to do something and it starts pathetically beeping because, horrors, its precious key has left the safety of the perimeter. There are other variations of this that get it upset. I think I should put it and I into therapy though it might try to have me arrested for being a bad, bad owner.

When driving it's usually fine except for all the times I drag it on the ground. If I could have another inch or two of clearance, our relationship would be all the easier. It's not like I'm going to stop trying to go all the places I need to go. Drag. Drag. Scrape.

The display is a little busy, but I've switched it to something more tolerable.
The vent placement is terrible for me but that's probably just me.
The rear window doesn't count as a window at all and why bother have a windshield wiper that can only cover half of the windshield?

And who put on contract out on this car? It's been hit three times. All brilliantly repaired, but what a horrible CarFax report. My Scion xB has only been hit once and when that happened they totaled it. No ding and swak sorry-about-that-didn't-see-you nonsense. Next hoity-toity ecologic car is going to be bright yellow or hot pink. Something that says "Don't touch me. I'm poisonous. ."

But this isn't meant as a car review--more like how a Toyota car designer and I need to have a long talk about usability and doing what's easier on the can it not necessarily easier on the person.

Tuesday, December 13, 2016

Python 3 Prime Number Checker

Doing basic math is good exercise when working out the details of a programming language.
This one is using Python to check for prime numbers from 2 up to whatever value we have chosen. In this example, it is up to 50, but you can choose whichever value you wish.

This is using Python 3.
If you're transitioning from Python 2 you can use this acronym to remember the basic differences.

DRIP
Division is true division 2/3 = 1.5
Range is a generator, and there is no more xrange.
Items will help you get to Dictionary elements, you do not need iteritems
Print() is a function and no longer a statement. you need those parens
if you want to not print a newline,
instead of a comma, you need to use end="" You can put a character in the ""

Prime Number Checker

max = 51
print ("Prime numbers up to", max)
for i in range(2,max):
#skip evens
if i % 2 == 0:
# 2 is our first prime number, print it out
if i == 2:
print (i, end=" ")
continue
# check each value is divisible by 3 up to the value being checked itself. (from 3 -> the value in question
# if the value being checked it 9 then check 3,4,5,6,7,8,9
# we don't need to check using 2 because we already excluded the even numbers above
evennum=False
for k in range (3,i):
if i % k == 0:
evennum=True
break
if evennum==True:
continue
else:
print(i,end=" ")

But wait~ There's more.
If a number is not prime then it has factors and for each two factors, one of them is below the square-root of the value you are checking. We only care if one of the factors exists (which will make the value not prime. As a result, we only have to check the values up to the "floor" (truncated integer) of the square-root of the value we're checking.

Example. Let's look at 36 which is not prime (we'll ignore that it's an even number and won't ever show up on our list.

sqrt(36) = 6
36 has other factors
2x18
3x12
4x9

If we find even one of these factors we know it's not prime.
See how the factors distribute themselves around the squart-root
One is always lower and the other is always higher than 6.

So instead of for k in range (3, i)
we can do for k in range(3, math.floor(math.sqrt(i))
Since we're now doing math functions, we need to include the math module.

Here is a good reference (scroll down):
http://stackoverflow.com/questions/5811151/why-do-we-check-up-to-the-square-root-of-a-prime-number-to-determine-if-it-is-pr

Here's the full code:
import math
max = 51
print ("Prime numbers up to", max)
for i in range(2,max):
#skip evens
if i % 2 == 0:
# 2 is our first prime number, print it out
if i == 2:
print (i, end=" ")
continue
# check each value is divisible by 3 up to the value being checked
# we don't need to check using 2 because we already excluded the even numbers above
# NOTE we only need to check if there's a factor up to the square-root of the series
# (See the text for an explanation)
endval = math.floor(math.sqrt(i))
evennum=False
for k in range (3,endval):
if i % k == 0:
evennum=True
break
if evennum==True:
continue
else:
print(i,end=" ")

Thursday, October 20, 2016

Trump's Popularity Shows We Need Better Education in the US

The 2016 presidential campaign is nearing its end and for weeks, if not months, we've see how Trump can outright lie to his supporters. The many egregious moments (famous and too many to list) have cost him the election, but the number of moments were far above what would have cost another candidate the election. There is something that he is able to tap into that makes his fans mentally overlook his many flaws. Perhaps it is star power or just the pure chutzpah, but the fact that he can directly lie to his fans is disturbing.

Hillary says she wants to raise taxes on those making over \$250,000.
Trump says to everyone: Hillary is going to raise your taxes.
And that's the most innocent example.

Bragging about sexual assault in general and then claiming that it never actually really happened (even if one incident has witnesses), is amazing.

You can say that that is a matter of opinion, but then he claims that he never said that climate change is a hoax perpetuated by the Chinese. Never mind that he tweeted about it more than once.

His most ardent supporters (there are fortunately fewer and fewer of them) are happy to ignore these shortcomings. No amount of facts seems to make any difference. His woeful ignorance on foreign policy and on basic things like how nuclear weapons work is just painful. His fans seem to have no filters. No inquisitive distance at all.

His presence in the election, and his popularity is casting a glaring light on the lack of education and educational opportunities in this country. Post-secondary education needs to be free, and the quality of the current free secondary education needs to be improved. Anyone with a high school diploma (even younger) should be able to discern that something is very wrong with Trump's many claims.

Sunday, August 14, 2016

The Fibonacci Sequence in Six (plus) Languages

The Fibonacci Sequence in Six (plus) Languages
Python, C, Java, Node.js, Javascript, Powershell

I wanted to write a blog post that shows how to generate the Fibonacci sequence (0;1;1;2;3;5;8;13;21;34;55;...) in ten languages. Then I realized I would have to relearn some older language's syntax and that would mess up my current knowledge. So this is now down to five languages.

You should see output like:
First 10 Fibonacci numbers
1
2
3
5
8
13
21
34
55

Some of the scripts put the numbers on one line.

I had to encode all the less than and greater than's to keep the browser from interpreting them.

Python 2
I ran this in my Mac terminal with: python fibo.py

# fibonacci series generator for the first 10 numbers

# Seeds 0 and 1

x=0
y=1

print "First 10 Fibonacci numbers"

for i in range(1,10):
t = x + y
x = y
y = t
print t

Python 3
Then I rewrote it all in Python 3, and it uses fancy tuple unpacking which avoids needing a temporary variable. Putting in the end=" " keeps the series all on one line.

# fibonacci series generator for the first 10 numbers
# using tuple unpacking
# for Python 3

# Seeds 0 and 1

x=0
y=1

print ("First 10 Fibonacci numbers")

for i in range(1,10):
print (y, end=" ")
x, y = y, (x+y)

C
You need to compile this with a C compiler.

```#include <stdio.h>

int main ()
{
int x=0;
int y=1;
int i,t;
printf ("First 10 Fibonacci numbers\n");

for (i=0;i<10;i++)
{
t = x + y;
x = y;
y = t;
printf ("%d ",t);
}
printf("\n");

return (0);
}
```

Java
Probably should have it be more object oriented, but that doesn't save any lines in this case.
You do have to have the Java dev kit installed on your system.
```#include <stdio.h>

int main ()

{
int x=0;
int y=1;
int i,t;
printf ("First 10 Fibonacci numbers\n");
for (i=0;i<10;i++)
{
t = x + y;
x = y;
y = t;
printf ("%d ",t);
}
printf("\n");
return (0);
}
```

Node.js
Node is kind of like Javascript without needing a browser. It's a nice, refreshing language.
You have to have Node locally installed and then run it in the terminal with
node fibo.js.

fibo.js:

x=0
y=1
console.log ("First 10 Fibonacci numbers.")
for (i=0;i<10 font="" i="" nbsp="">
{
t = x + y
x = y
y = t
console.log (t);
}

Javascript Load this one into a browser. Getting this to even show up in the browser was a pain. Had to remove all the html and script tags. Tag: means the tag inside of angle brackets. Close tag: means use the closing tag which is the tag proceeded with a forward slash.
```Tag: html
Tag: body
Tag: script
x=0
y=1
document.write("First 10 Fibonacci numbers.")
for (i=0;i<10;i++)
{
t = x + y
x = y
y = t
document.write(t," ");
}

Close tag: script
Close tag: body
Close tag: html
```

Powershell
```\$x = 0
\$y = 1

\$enditer = 10

for (\$i=0;\$i -lt \$enditer;\$i++)
{
\$t = \$x + \$y
write-host \$t " "
\$x = \$y
\$y = \$t
}

write-host "End of series"
```

Saturday, July 16, 2016

Redwood Park: Goats at Work

East Bay Regional Park is hiring cheap labor. Really cheap, but they do a job that few of us would want to do. Eat flammable underbrush. Lots of it. Enter the goats who will eat many things save for poison oak.

 This is right beside the West Ridge Trail, near Moon Gate
They get to keep their horns. Hope they don't get hooked up on a tree.

Some sit down on the job.

Facial hair is ok.

But they're very clear about not eating poison oak.

Sunday, April 17, 2016

Walking with a Cell Phone is a bit Silly

People who walk while talking on their cell phones make me laugh.     Often.

Wednesday, March 23, 2016

No Joy in the Writing Contest

Of course, I didn't get any placement in the previous writing contest and I will get used to it, but there is a free humor poetry writing contest called the Wergle Flomp Humor Poetry Contest so I entered Poetry Smokes because there wasn't a publishing restriction on the entry.

You can enter the contest here:
Deadline is April 1st, 2016 and winning entries announced Aug 15, 2016, so breath holding is not advised.

AND there another fiction and "very short" (300-3000 words) fiction contest put on by Glimmer Train. Here is the entry form: https://glimmertrainpressinc.submittable.com/submit
I guess I'll let "The Road, The Tree, and The Human" have a go at the very short one. there is a \$21 or \$16 "reading fee" for these contests. (The poetry one is free).

https://winningwriters.com/our-contests/wergle-flomp-humor-poetry-contest-free/wergle-flomp-humor-poetry-contest-confirmation
The publishing restriction is that it can't have appeared in a print form, so online is ok.

Wednesday, December 02, 2015

Another Blog - Oh no!

Publishers are encouraging authors to start blogging. Ok fine, no problem.
But for me there is a catch. The Non-Dog Blog is for everything that isn't about dogs. So what's the problem? Well... my book very much involves dogs, you really can't call it the "Non-Dog Blog" but it seems so unfair that after more that 500 posts, I have to start another one. Sigh. Well not yet. I think I can copy selected posts from the blog into the new one which is likely going to bear my name - how boring is that?

[Now 2018]
I have created a writer's blog just for the getting published process and to talk about all the odd things I have to research as a writer. that blog is Ellen Writes Dogs. https://ellenwritesdogs.blogspot.com/

Baby's First Writing Contest Entry

So apart from trying to find a book agent, I noticed that Writer's Digest is having a short story contest. I keep thinking that I don't have a clue as to how to write a short story, but I look back at what I've written before and I'm such a liar. Sure enough, I have more than one short story. And one of them is actually not a bad one either, so I spent time cleaning up the punctuation, and submitted it. It is a \$25 entry and I know that some say you should never pay to enter a writing contest, but I really like Writer's Digest and it seemed reasonable enough.

This is very much a long shot and I think, if anything, I can hope for coming in 30th place or whatever, but at least I've done it instead of just dreaming about it, so it's a good confidence builder if anything. I will hear on Feb 16, 2016, so I can forget all about it until them.

After that, maybe I can publish the story assuming that it didn't win anything.

Job hunting and Agent querying are nearly the same thing

I am currently looking for another day job as well as looking for a book agent for my novel, and I’m noticing that querying book agents and submitting job applications are remarkably similar.

You are asking a complete stranger for attention and the odds are likely that you will be either rejected or ignored. In a way, the rejections of book agents are more useful than the silence that you often get from prospective employers. At least from a book agent, you often get a response, sometimes even a useful one. It’s actually less demoralizing than it used to be. The problem with employers is that technology has made applying for jobs very easy, but this means that HR depts get overwhelmed with many, many resumes--many of them irrelevant as people have taken to scattershotting applications which doesn’t help anyone, and sometimes they completely overestimate their capabilities: sure I can be the CEO, no problem.

The best way is to be organized about what and who you applied to, be it employment or a book agent. Keep a document or a spreadsheet that notes the day, and who you applied to, and any special requirements like “first 5 pages in the body of the message” and any response that you got. I use Google Drive for this so I can get to it from anywhere.

To find agents who are looking for people you can get the list from

Wednesday, October 21, 2015

Reprint: When the Anti-Virus won't run: Manual Virus Removal

Briefly back to tech.
This is also available online but it bears repeating here.
It's also a bit dated since it was written in the days of XP and will work with Windows 7, but getting into Safe Mode for Windows 8 and 10 is another blog post entirely.

When the Anti-Virus Software Won't Run -

Manually Disabling Viruses in Windows
by Ellen Clary

Note this was written for Windows XP (last edited Jan 2012)
Windows 7 is similar, but will vary
Many of us are now our family's and friends' designated "computer expert" despite whatever you have claimed.  If a computer owned by someone you know is misbehaving you will often get the phone call for help.

If the computer is running erratically and slowly without the person having done "anything," then one possibility is that the computer has a virus or worm.  So you have them run Symantec (or other) Anti-Virus and you find that it is running very slowly or not at all, or it may run for a short while and then crash.  You are now in what my brother refers to as a chicken/egg situation where the cure for the virus is being hampered by the virus itself.

There are some strategies for manually disabling the virus(es) and thus allowing the Anti-Virus software to run.  These are often presented as last resort options, but I've found that you will save a lot of time if you opt to do them sooner rather than later as many viruses are surprisingly easy to disable (though not all).

Viruses often have two common features.
- they tend to take up a lot of the cpu.
(which actually makes them a poor model of a virus as a virus should hide itself.)
- they often (though again, not always) use the same area in the registry to start up at boot time.

First try the Simple Solution
Before you embark on all this, first see if the Anti-Virus software will work in Safe Mode.
It's been my experience that while the AV software will run in Safe Mode it will not necessarily find all the viruses in that mode.

To boot into Safe Mode, press F8 while Windows is starting up, and select Safe Mode with Networking (which turns on some services).  The system should not be running slow at this point, if it is then you likely have a larger problem.

Run an Anti-Virus scan and see if it locates anything.

Reboot the system before the next section.

Killing the running virus
If a computer is running slowly, then it's possible that the system is being hampered by a virus or worm or spyware.  If you suspect this and the anti-virus software won't run or is running slowly enough to make it unusable, then first try to kill the viral process by using the Task Manager.  Press Control-Alt-Delete, and click on Task Manager.  You will likely see a list of processes.  First let's check the obvious.  Click on the Performance tab.  Is the graph maxed out at 100% and staying there?  Now, no offense to those users, but it is rare for someone who is asking you for help to run applications so CPU demanding to max out the computer (unless the computer is really, really old), so it is likely a virus or other unwelcome program.  Click on the Processes tab to get back the list of processes and then click on the "CPU" heading to sort the display by CPU load (not CPU time).  Look at the process list and see if there is a process besides the "System Idle Process" that has a high percentage (like over 80%) of the CPU.  If so, click on that process (this may take a few tries as the process list tends to change quickly) make a note of the name and the Data line and then select "End Process" (and click on Yes if it asks "Are you sure?").  You are not doing permanent damage as this is only affecting what's running on the system right now.

Now see how the computer is behaving.  First look at the Performance graph again by clicking on the Performance tab in the Task Manager and see if the graph is no longer stuck at 100%.  If it is looking more normal then try some basic things and see if the computer is behaving as expected.  If so, then run the Anti-Virus program (make sure the virus definitions are current) and it should find the virus and remove it.  If the Anti-Virus program didn't find it, then manually search for the program and rename it (or if it's something obvious like msblast.exe then just delete it.)

If the computer is not working as expected then reboot it and you will be back to the same broken virus state as before.

If the suspect program is a part of Windows (e.g. explorer.exe) then you may have a program that has been "Trojaned" meaning it has been altered to misbehave.  Either that or you have a virus that is using a program of the same name, but located in a different place.  If it is explorer (the Windows File manager - aka "My Computer"), then to tell the difference, kill the explorer in the Task Manager (yes, you can do this) and see how the system behaves.  If it behaves better, then relaunch the explorer by double clicking My Computer and see if the poor performance returns.  If it does, then sorry, but you will have to reinstall or repair windows via the Windows installation CD (if you have a bootleg copy go to the store and buy a real copy and consider this your penance).  If it is still ok, then the original Windows program is fine, but you will need to find the viral one and delete it.  This is best left to an Anti-Virus program and, as they say, is beyond the scope of this article.  (We're here to cope, finessing is best left to the experts.)

Get it before it Starts - Editing the Registry
While editing the registry is generally not for the timid, it's often the best way to stop things from going awry at startup.

[New] The faster way to find unwanted viruses is to use Start-run-msconfig while still in Safe Mode.
Click the Start Up tab and see if something looks amiss.  Unfortunately it does take an experienced eye to know what that is.  Google can help you identify well know, but strangely named programs.  If something doesn't look right it will tell you where in the registry or file system the program is located.

Start up the Registry Editor by clicking Start-Run and entering: regedit

First back up the registry in case you make a mistake (not likely, but it can happen).
Make sure "My Computer" at the top of the left window panel is highlighted (so you get a copy of the full registry and not just a part of it.)  Select Registry-Export Registry File, and give it a name that you'll recognize and put it in a location where you can find it if need be.

While viruses can and do use other start up areas, I'm going to list the most common ones, the first being where 70-80% or more of them start up.

Navigation note.  To open a subfolder click the + sign next to the name.
• Find the area called HKEY_LOCAL_MACHINE
• Navigate to: Software-Microsoft-Windows-CurrentVersion-Run
• Make a list of what you see on the right hand window panel including the Data field of what you don't recognize. It's often a good idea to type this up in your favorite text editor as you can cut and paste from it and avoid typos.  Many of the items you'll recognize and don't worry about "Default" as that should be there.
• If you find that certain programs are Spyware, Adware, Worms, or Viruses, delete them from the registry which prevents them from starting up at boot time.  This will not remove the virus, best to let an Anti-Virus program delete or you can search for it manually and rename or delete it.
• Exit regedit and reboot the system.  Hopefully the computer will be running much better.
Another area to check (though much less commonly used) is:
HKEY_CURRENT_USER-Software-Microsoft-Windows-CurrentVersion-Run

Conclusion
Remember that this is just a way to cope.  Once the machine is running well enough, download new virus definitions for their Anti-Virus program (or make them go out and buy one as payment for your time - negotiate lunch out of the deal too) and run a full scan, or if they have a fast internet connection you can have the system scanned online via the Symantec site.  Likely the software will find inactive viruses as well and if you manually renamed the ones you found it should find those as well as well as the ones that you merely disabled.  A reputable spyware remover is a good investment too (I've just heard that one person tried Spybot and Pest Patrol and Spybot found many things that Pest Patrol did not).

Give them the usual lecture about not clicking on attachments that they don't expect even from people that they know.  And check on (via separate email or phone) ones that they received from people that they do know.  And never open a .pif or .scr attachment as I've never seen a legit program use them.  Viral emails often have a certain vague, generic look to them that over time they should be able to spot.

If it was a worm that was causing the problem then consider helping them to install a personal firewall like Zone Alarm or if you're really feeling kind (to them and yourself), configure a screening router for them.

Good luck and know that even if this took some time you have spent a good deal less time on it that waiting for the Anti-Virus software to run on an infected system.  And you probably learned something in the process.  And there's always lunch.

In the Future

To prevent further mahem, some relatively simple things that you can do:
• Demote yourself.