griswolf 304 Veteran Poster

And your question is?

griswolf 304 Veteran Poster

Think about the flow of logic: Why are you asking the user for a new pair of words on every line? Shouldn't you do that at the top, then just use them in the loop?

Here's a function that (almost) returns the line that is manipulated, but if there are multiple adjacent spaces in the line, they are replaced by one space, or if the line has indentation, it is lost.

def collapse_spaces(line):
    build = []
    for w in line.split():
        build.append(w)
    return ' '.join(build)

You should be able to modify this to get a 90% on the homework problem, maybe more if the grader misses the point about indentation. What they probably want you to use, though, is slice replacement, based on http://docs.python.org/library/stdtypes.html#str.find

griswolf 304 Veteran Poster
  1. You need to understand the with statement at my lines 5 and 8: not more important than def, but less likely to be covered in an intro course.

  2. You need to understand how to read the python manual: http://docs.python.org/index.html so as to make best use of the library features. You tried to use randint which is not best suited to this problem. It is mostly a matter of searching and then reading more than just a little bit.

  3. I don't understand "close". I suspect you're using Python in an environment other than the command line. I just use the command line so I'm not the person to ask about how to deal with your environment.

  4. In passing, the Python style guide: Indentation calls for using 4 spaces per indent level. It is very good to just grit your teeth and follow the style guide even if you have a different preference: It is practical, well thought out, everybody understands how to read it (and code reading happens much more than code writing). In particular, because tabs and spaces look the same on the screen, don't ever mix them, but to conserve screen space (width) do prefer spaces alone. Your editor will have a setting to help make that happen.

griswolf 304 Veteran Poster

This is not the most efficient or tight code, but it works. In particular, the function populate(...) could be shorter. In a real world situation populate() should raise a useful error if the files aren't found or aren't as expected (many more lines of code)

I have also deliberately made the output print incorrectly unless you are using Python 3. Note also that raw_input would be incorrect with Python 3.

I've broken the work into two functions and a driver loop. This is typical style for interactive programs; though usually the driver loop is also in its own function which is called from the bottom of the file.

import random
def populate(first_file_name, last_file_name):
    first_names = []
    last_names = []
    with open(first_file_name,'r') as f:
        for line in f:
            first_names.append(line.strip())
    with open(last_file_name,'r') as f:
        for line in f:
            last_names.append(line.strip())
    return first_names, last_names

def print_random_name(first_names,last_names):
    if not first_names:
        first_names = ['Henry']
    if not last_names:
        last_names = ['Jones']
    print(random.choice(first_names), random.choice(last_names))

first_names, last_names = populate('fname.txt','lname.txt')

response = 'y'
while response == 'y':
    print_random_name(first_names,last_names)
    response = raw_input('Print another? ').lower()[0]
griswolf 304 Veteran Poster

I see no need to make the deep copy. Pick an attr, save its value, try to change it, then if it changed, put back the original.

But I'm with lrh9: A function that does two different things is an odd duck: The code that calls it cannot depend on the return value to be what it expects. Why not always return a mutated copy rather than only sometimes?

griswolf 304 Veteran Poster

you use the * operator on the list: attr_gen = attrgetter(*my_list)

griswolf 304 Veteran Poster

Be sure to notice the method setdefault. Or use class Counter.

griswolf 304 Veteran Poster

Consider the decimal module.

griswolf 304 Veteran Poster

The Python break key word is a way to break out of a loop. Just that. So, for instance

result=None
for i in range(1000000000): # really long loop
    result = check_item(i)
    if are_we_done_looking(i, result):
        break # so we don't have to finish the loop
if result:
    generate_report(result)
else:
    print("Useful result not found.")

Please go read an introduction to Python programming. For instance these, though there are probably hundreds.

griswolf 304 Veteran Poster

No need for subprocesses to run things in sequence:

import os
os.sytem('music_player loud_music.mp3') # silly example
os.system('video_player spinning_things.mp4') # more silliness
# etc
griswolf 304 Veteran Poster

I think that you are posting in the wrong forum: How is this a Python question? Ignoring that issue, you are confused again: A "music file" doesn't "play all the way through" because it holds music, but does not play it. In general terms: To have something happen after something else, you create a supervisor program that tells the system what to do in what order, and you run that program.

griswolf 304 Veteran Poster

What you have shown so far will not run because indents matter in Python and your code shows none.

griswolf 304 Veteran Poster

Hmm. I thought I was being clear.

If you chant myscript.py with no further arguments, then sys.argv has just one list element: "myscript.py". If you chant myscript.py argumentOne then sys.argv has two list elements: "myscript.py" and "argumentOne" ... and so forth for any number of command line arguments. Your script requires that you invoke it with exactly three arguments. If you were to invoke it with, say, two arguments or four arguments, it would fail. I'm not really sure what part of what I said was a problem. Does this help?

griswolf 304 Veteran Poster

Either it isn't in your python path (examine sys.path) or it isn't being recognized as a module. Most modules are a file, such as in your case a file named mechanize.py if you have a directory, then to find files within it, you need a file named __init__.py (which might be empty).

griswolf 304 Veteran Poster

First, let me recommend to you that you use the (CODE) button. Either click it and then paste your code between the tags, or highlight your code and click it. This is prettier

# Get command line arguments from the sys module 
from sys import argv
# ...

than yours, don't you you agree?

Second, for future reference. Note the "mark thread as solved" link near the bottom of the page. Only you, the original poster, can see that link. Using it after the thread is solved helps keep DaniWeb functioning smoothly.

Finally: Your comments are not quite right. For one thing, no real programmer would over-comment so much, but ignore that: You are indicating your understanding of the code, not "real comment"ing. The issue I still have is that you are skipping over how things are put into sys.argv When I invoke a python script from the command line: python myscript.py some subsequent words the python interpreter puts the script name into sys.argv[0] and any subsequent arguments into the rest of the sys.argv list. So from the command line above, you would end up with sys.argv == ['myscript.py', 'some', 'subsequent', 'words'] If you don't put exactly three arguments on the console command line when invoking your script, you will get a failure. Your comment almost seems to imply that the program interacts with the user to get the values. Not true.

griswolf 304 Veteran Poster

from sys import argv Says: From the module named sys (which, if it were in a file would be in a file named 'sys.py') import the thing named 'argv' into the current name context. That makes it possible to refer to 'argv' without having to mention the module it came from. If you had instead said import sys then you would have all the things in sys available, but you would have to access them scoped by their module name. For instance script, first, second, third = sys.argv script, first, second, third = argv Says: unpack into the four named variables, the values contained in the variable named 'argv'. Python allows you do do simultaneous assignments so v_1,v_2 = "one",2 for instance works as if you said both v_1="one" and v_2=2 This is one of the cool syntactical features of Pyrhon. The quoted line assumes that argv holds exactly 4 values which can be unpacked into the four named variables. In real code, that assumption would be a very bad idea. print whatever You are using a 2.x version of Python which has an operator named print. Versions 3.x and above have a function named print. The difference is that operator print prints everything that follows it on the line: print "Hello", "world" whereas function print requires the things to be printed be passed as parameters in a function call: print("Hello","world") There is no urgent reason to choose Python 3.x over Python 2.x. Whichever one you have …

griswolf 304 Veteran Poster

Because Python has 2.x and 3.x versions, it is wise to mention the python version in the module comment or string

It would be nice of you to print a summary of the state of the game in the game loop. Such as print("Correct guesses: %s; Wrong guesses: %s"%(correct_guesses, wrong_guesses)) To avoid having duplicate code to accept the user's guess, I usually use a loop like this

prompt = "Guess a letter " # note the trailing space
while True:
  # display
  print(whatever)
  # ask
  answer = input(prompt)
  # analyze
  # 
  if [I]end_condition[/I]:
     break
  # get ready for next loop, for instance:
  prompt="correct prompt for this loop"

Your line 64 is redundant. Just the if/else is enough.

Usually, you don't require the user to end the game unless the "leave the game" condition is inside the game loop. Or unless the game is running inside a window that will close when the code stops.

the variable name wordTuple is misleading because it is not a tuple: word_from_tuple might make sense, but I would prefer to_guess , or target (I don't expect perfect English). Every variable should be a good name that you never have to think about how it is spelled or what it means. Standard Python naming prefers that classes be named in CamelCase; and that variables and functions should have words_separated_by_underbars. Note that good variable names are much better than comments for self-documenting code: The variable name is seen everywhere it is used, but …

griswolf 304 Veteran Poster

Please use the CODE button to show indents, line numbers, syntax coloring...

Hints:

  • You can get the list of words by simply saying words = sentence.split()
  • You need to think about punctuation, in case user inputs some. For instance, if you got the words from the first sentence of this hint, "punctuation," and "some." have trailing punctuation.
  • I would write the function english_to_piglatin so the parameter is a single word rather than a list of words.
  • The usual idiom for modules that need to (also) run as a script is if __name__ == "__main__": main() You might as well get into the habit of invoking main() that way.
griswolf 304 Veteran Poster

It means that the replace function expects a string (or string-like object) as the first parameter, but you passed it an integer. Line 17 should be board = board.replace(str(comp), "O") .

Note that the semicolons at lines 7, 12, 17 are not needed, though they are not illegal.

griswolf 304 Veteran Poster

Your question is not precise. You two kinds of access:

  1. You obtain permission to access the service, which may require some form of authorization, signing a EULA, or other legal issue.
  2. You make a connection with the service

I am not able to give you details about this, partly because I simply don't know: What web service, how VB deals with internet connections; and partly because DaniWeb is a place where we HELP you do the work, not do it for you.

griswolf 304 Veteran Poster

It sounds to me as if you have done the first (easy) half of your choice already: You want to do something that helps in the public sector and makes use of AI / natural language; and has the potential to be beneficial to many people. "But I don't know what they need". What do you do when you have a question about what some group needs? Research. Have you done that research? What do they (think they) need?

Just for the fun of it:

  • Something that reads traffic and store signs, translates them, and speaks them in any language.
  • Something that helps poor people cope with government forms
  • A tool that takes phone calls, emails, printed material and consolidates it all into a report about which parts of the city need what services, based on complaints.
  • A much much better phone answering system instead of one of those horrible phone trees: Let me explain what I want and the tool directs me to the right place. This would be a bad idea because it takes away a job, except that job is already gone, and being done so poorly already.
  • A tool that tells technicians what the problem is likely to be, and points them to the likely location of the problem. (Phone or networking outages, for instance). Speaking so they can use their eyes on the job while listening
  • A robot tutor for one or more subjects
  • A device that generates "good" test questions for exams, …
griswolf 304 Veteran Poster

I speak no VB, so in general terms:

  1. You open a connection to (some web service)
  2. You provide your bona fides to that server
  3. You make your request
  4. You receive and parse the data
  5. You close the connection
  6. You massage the new data
  7. You display the massaged data

Repeat

There are several places where this can be troublesome.

  • Opening the connection: VB will have some way to do it
  • Providing your bona fides: Each service has its own requirements. Probably a username and password. You don't want to send that in the clear, so think about it first.
  • Sending requests and receiving data: You will need to understand the service requirements in both directions
  • Parsing: You have to handle what they send you. Probably XML or json. VB has parser tools, I'm sure.
  • Closing the connection: They are a scarce resource, so when you're done for the moment, close it.
griswolf 304 Veteran Poster

The print function by itself adds a newline at the end. I suspect you are doing something like this (though you showed no code, so I am guessing)

asterisks = '*'*5
print(asterisks+'\n')
print(asterisks+'\n')

This will work just fine without the explicit newline.

Of course if you want an embedded newline, you have to be explicit: print(asterisks+'\n'+asterisks) And if you are reading lines from a text file, they arrive with their newlines intact, so you need to bear that in mind.

griswolf 304 Veteran Poster

A single line. OK then the code reads in the one line from the file, into a variable. Say list_as_string = f.readline() . Then you convert that string into an actual list: actual_list = eval(list_as_string.strip()) and finally, you deal with the list elements however you want. Perhaps

with open('output','w') as ofile
  ofile.write('\n'.join(actual_list)+'\n')

This will only work if

  • The data is in fact all on one line
  • The data is correctly formatted as the string representation of a list

Before you try to use this code, ask yourself if you understand it. If not, read about the with statement and string's join method

griswolf 304 Veteran Poster

First: Please learn to use the CODE button so your code has line numbers, indentation, etc. Very helpful.

Second, I am not sure of the actual format of the file 'temperature data extracted.dat' That is the key. You must deal with that exact format, whatever it is. I begin to think it is just one very long line, with commas and single quote marks in that line (as well as the "real" data). Is that true?

Third: You need to understand what you want, what you have, and what steps to take to convert from 'have' to 'want'. Just waving someone else's code at it is unlikely to work, much less work well.

Fourth and last: It is important when thinking, and when writing, to keep categories clear; A list is not a file is not a string. For example, thinking about a file while calling it a list leads to confusion for both yourself and your readers.

griswolf 304 Veteran Poster

macros do not honor any kind of scoping. Somewhere in the include files the token 'sec' is being converted to the manifest constant 3600. This is one reason that we have all agreed that macros will always be CAPITALIZED since that much reduces the chance of such conflicts. Better yet, make the macro your own so there is almost no chance of conflict; and while doing that, make it self documenting:

#define ACECHAUHHAN_SECONDS_PER_HOUR 3600

More carefully

#ifndef ACECHAUHHAN_SECONDS_PER_HOUR
#  define ACECHAUHHAN_SECONDS_PER_HOUR 3600
#endif

between lines 2 and 3, you can force an error if you need your own macro and no other.

griswolf 304 Veteran Poster

You can convert the list to a string with one item per line like this:

my_list = [ ... ]
my_list_as_string = '\n'.join(str(x) for x in my_list)

Then you simply write that string to the file. Be careful about adding a newline after the last element. You can use a format specifier instead of str(x) if you need to control the precision.

Alternatively, you can iterate through the list, writing each element to the file:

with open('somefile','w') as f:
  for item in my_list:
    f.write("%.2f\n"%item) # or whatever format works

This one automatically puts the newline after the last item.

Edit: On second look, I see that the values are already strings. That simplifies things. The first example simply uses '\n'.join(my_list) and the second just writes each item (with newline).

griswolf 304 Veteran Poster

That has to do with the flow of control (logic) of the program as a whole: Something you did not show us.

griswolf 304 Veteran Poster

I have no idea what you mean by your question. How is line 145 now an "output"? It looks like a calculation. There's no print statement, no return statement so nothing is being put "out".

What do you man "make it an input"? Input is data that comes into the program from somewhere (file, keyboard, ...).

You could call f with the value of the calculation on line 145: f(u+alpha*d_k) but your f function is pretty useless as shown; though I suppose that is a simplification of the real f .

griswolf 304 Veteran Poster

Why a text file? If you simply want to preserve information from session to session, there are three ways

  1. What you suggested: Write the data to a text file
  2. Pickle , Python's object serializer module (actually: Use cPickle)
  3. Use a database

I recommend you use pickle. However if you choose to move ahead with option 1, note the "%r" formatting directive for example:

s = {'one':'uno', 2:'dos', 'cat': 'gato'}
print ("%r"%s)

You can then use the eval builtin function to recover the data. Beware of quote issues.

griswolf 304 Veteran Poster

Actually, the first option (keep track of pennies using a (long) integer) is a better choice almost always. If you use floats representing dollars, you are subject to rounding error even if being very careful. This is because a penny ($0.01 decimal) is in fact an infinite repeating binary fraction, but the register is finite, so there is always a little difference between the intended value and the value actually stored... and worked with in the next step which leads to more error, etc. Whereas if you just store an integer count of pennies, there is no rounding error, no fractions to deal with etc. You can get a nice string value (without commas) using this

def dollarStringFromPennies(p):
  stringpennies = '%d'%p
  return '$%s.%s'%(stringpennies[:-2],stringpennies[-2:]

If you want to make a class to handle all this, it is pretty easy, and you can even provide a __str__(self) method that does the above.

griswolf 304 Veteran Poster

Sounds pretty hard for me. (not to good at math). But i'm the only one who wants to apply some programming in my class. Which means I don't have allot of help.

By the way the points would be the location of a persons house, and the restaurant ?

Well, you have the formula now, so the math is "done". All you need is to fill in the x and y values. And deal with conversions, of course: What coordinate system does Arcgis use? There are basically only three options:

  1. (Easiest for you) There is some point on earth that is (0,0) and everything is measured from that point by how many (units) east or west and how many (units) north or south. You use the formula I gave, then divide by units per mile (or multiply by miles per unit). This is pretty accurate, barring the fact that the earth's surface is pretty much a sphere; but it is unlikely that the data is in this format.
  2. (nearly as easy) The locations are in degrees E/W and degrees N/S. For that, you have to do the conversion first: convert the two differences by multiplying by miles per degree at your latitude and longitude (these conversion factors are likely different numbers for E/W and for N/S), then do math.aqrt(convertedx**2+convertedy**2) This works "close enough" as long as the distance is less than a couple hundred miles or so. This also suffers from spherical distortion and from the approximation of miles …
griswolf 304 Veteran Poster

Because the clock() function returns the time that the processor uses [Ifor this task[/I] and not for the amount of elapsed time. The perceived need, when it was written, was to understand how much CPU-time each particular task was using. Elapsed time has only a vague connection to that (elapsed time can never be less than CPU time).

griswolf 304 Veteran Poster

The radius is simple math (Pythagorean theorem): the distance between two points (x0,y0) and (x1,y1) is math.sqrt((x0-x1)**2+(y0-y1)**2) (If you want to think about distance along a path, such as a road, then you are working on a much larger problem)

I presume that the Arcgis data contains the restaurant information, so you need to extract that, do the math calculation, and display the results "somehow".

griswolf 304 Veteran Poster

Consider using gettimeofday() which keeps track of seconds and microseconds since the epoch. To compare them, subtract the two fields individually, then multiply one (or divide the other) and add the differences; then convert as needed.

griswolf 304 Veteran Poster

Start hanging out here and at StackOverflow. Discipline yourself to log in at least three times a day to each. Answer questions (or ask them) every time you visit.

Go to Google Code, Source Forge, and other places where you can see professional grade code. Download and figure out how things work (choose things that interest you). Modify them to work "better" for your own interest. Discuss your changes with the committers for the projects. Check in your changes.

Go to school, study Computer Science. With your degree in hand, look for work.

Commit to a friend or relative to create some software for them. Force yourself to do it, because you promised (or they offered pay).

griswolf 304 Veteran Poster

I'm pretty sure it is already there. What makes you think it isn't?

griswolf 304 Veteran Poster

One possible way is as you suggested in your first post: Build a massively parallel recognizer system and train it on data that you have screened yourself. This is a non-trivial task.

Another is to try to build a recognizer using grammar rules. In my experience, that can be done, though not easily and not perfectly. There have been many many programmer years expended on each of these two options.

The idea that tweets are in english (or any spoken/written language) is pretty funny. ROFLMAO. Speaking of which: Is "LOL" a positive comment, a negative one, or neutral? Probably depends on context, eh?

I was once tasked with building a filter to remove objectionable words from tweets. I suggested to my manager that the task was impossible, but he persisted. Being a manager, he didn't even understand my point when I told him FUH Q. Sigh.

griswolf 304 Veteran Poster

Only a masters degree? :)

griswolf 304 Veteran Poster

sed would be perfect for this. You could also use cut -c if all the tuple-numbers are one digit, or cut -f twice: Once with -d ',' and once with -d ')'

griswolf 304 Veteran Poster

Your loop at line 26 opens and closes the csv reader and writer "l" times, a considerable waste of effort. And in each pass through the loop, at line 35 and 36, you print every line that is (so far) in the csv file: Probably not what you want.

I think that what you really want (not sure) is code like this:

number = readNumberOfLinesFromUser()
writeRandomLines(number)
readLinesFromFileAndPrintThem()

Of course I've written function calls, but these are simple things, and not really re-used so you can just write them in line (as you have done) instead.

griswolf 304 Veteran Poster

apparently my lack of output has to do with platform or something. You never close the open file from line 9, so on my OS, it doesn't flush, and the subsequent read gets nothing. If I modify lines 9,10,11 to this code, then I get output, but a failure on (my) line 31 (I/O operation on closed file):

with open('test2.csv','wb') as wr:
  c = csv.writer(wr)
  dialect = csv.QUOTE_MINIMAL
  c.writerow([x])

The join is doing nothing because the row is a list holding a single string, when seen by csv.reader() Replace line 16 with this: print "RAW: %r"%row to see it

griswolf 304 Veteran Poster

(complete change by edit from my original post)
Hmm. I would have though ', '.join(aRow) would do it, but apparently not. Interestingly, when I run your code I get this:

940% python phelp.py
How many rows?
9
done

In other words: No output.

I see you are using the builtin input() function. That is deprecated in Python 2.x. You should almost always use raw_input() which returns a string that must be converted to a number if you need a number. It is about robust code in the face of possibly malicious user input.

I'm going to just post this now and poke at the code a bit before I respond again.

griswolf 304 Veteran Poster

First, you need to use the CODE button to maintain indents when you paste your code (you also get code coloring and line numbers, also good things). With Python particularly indent matters. Here is what I think you meant:

#!/usr/bin/env python

import csv
import random
alpha = 'abcdefghijklmnopqrstuvwxyz'
e = range(0,99)
x = random.sample(alpha,14)
y = random.sample(e,14)

c = csv.writer(open("test2.csv", "wb"))
c.writerow([x])

cr = csv.reader(open("test2.csv","rb"))

for row in cr:
  print row[1], row[1]

print "How many rows?"
l = input()

k = 1

while k < int(l):
  c = csv.writer(open("test.csv", "wb"))
  c.writerow([y])
  cr = csv.reader(open("test.csv","rb"))

  for row in cr:
    k +=1
    print row[k], row[-k]

print "done" 

Second: You get that result because on line 31, the index is out of range (of course): Which in this case means that the length of the row is less than k.

I would also restructure the program so you don't have to keep opening the csv.reader over and over again; and you should close it after each open. I suspect that may be a root of your difficulty?

griswolf 304 Veteran Poster

its all about the result not how you got it in programing isnt it ???

In the real world of professional programming you are both right and wrong. Yes, its really only the results that matter, but "results" aren't just the output of the program...

A huge part of the effort over the life of a piece of software is put into initial programming, but maintenance (and documentation). You will find yourself doing maintenance on code that someone else wrote (maybe yourself, but you don't remember details now) for most of the time you spend programming. So good self-documenting code that is well formatted, appropriately commented and uses best practices costs a little extra in the initial coding phase, but it saves time (and time == money) day after day during the lifetime of the code. Managers care about maintenance costs.

Code that gets the right answer but takes more computer resources costs those extra resources every time it runs. Managers care about resources. Even if your code is only part of what is going on, if it is not efficient it might be the reason that the machine needs to be upgraded for speed or size.

Even efficient and well documented code, if it does something very odd, may be hard to maintain: Doing things the way maintainers expect them to be done is usually better than something idiosyncratic that is otherwise just as good.

If you are wondering "why is maintenance so important?" you …

griswolf 304 Veteran Poster

I would start out slightly differently:

cur_min = first-number-in-the-array 
cur_max = first-number-in-the-array

This way you don't have to guess at a hopefully large/small enough number. And the first number in the array could be the largest or smallest. And it's part of the list anyway.

Sure, but (and slightly mis-using 'my way' and 'your way' to make the discussion simpler):

  • Your way fails for an empty array, mine works and sets the min and max "returns" to obvious sentinel values.
  • If you know the type of the array you can guarantee sentinel values that cannot be exceeded. INT_MAX for instance, and similarly for minimums and other types.
  • My way makes a redundant check that sets the min and max to the 0th value inside the loop. Your way makes a redundant check that the 0th values are not greater or less than themselves (or it pays a price in extra logic to be sure there's another value to check)

I made a deliberate choice, thinking that my explanation was simpler. I'm not entirely sure it isn't better too, but I doubt it matters much one way or the other.

griswolf 304 Veteran Poster

The usual way of computing min and max goes like this, in pseudocode:

cur_min = a-number-at-least-as-big-as-the-data-minimum // INT_MAX works
cur_max = a-number-at-least-as-small-as-the-data-maximum // INT_MIN works
for every number in the array do this:
  it the_number > cur_max then cur_max = the_number
  if the_number < cur_min then cur_min = the_number
  // You can do other stuff too while looping
end-of-loop

I have looked (briefly) at your code and to be honest, I don't know what it does. Looks like you are trying to re use some kind of sorting algorithm maybe? I think, without spending much time on it, that your code might find the min and max if the data were monotonic, or maybe piecewise monotonic. Maybe?

Let me also point out a few things you might want to think about changing

  • explicitly declare main as int main()
  • compile with warnings set pretty strong: It is good that the compiler tells you what might not work as you expected.
  • declare locale variables one per line (except loop counters, maybe). Comment to explain their use in the scope
  • pre-increment by habit: ++i rather than i++ . Post-increment requires a temporary variable to hold the old value. Most compilers have peephole optimizers that make this unimportant for integers and pointers, but you might as well say what you mean; and someday it might matter.
  • where you say n = i; return n; why not just return i; instead?
  • name your variables something useful. We all use i,j,k for …
griswolf 304 Veteran Poster

OK, I see the red code (by the way, how did you manage to get code without line numbers? The appropriate thing to do is press the (code) button, then paste your code between the tags... or paste first, highlight it all, then press the button)

Based on the red text, I figure that has to be the problem area. But you never said what the problem actually is: Does not "work fine" isn't a very specific issue.

griswolf 304 Veteran Poster

What is the value of savingsRate when you calculate pmt on line 21?

griswolf 304 Veteran Poster

You want datetime.date.strftime() (and follow the link for details)