Gribouillis 1,391 Programming Explorer Team Colleague

This may help: http://stackoverflow.com/questions/488449/can-a-python-script-persistently-change-a-windows-environment-variable-elegantl

The answer with the use of the setx.exe program looks interesting. If windows has a program to modify environment variables from the command line, a python script can easily call this program with the subprocess module.

Another direction is to use ironpython instead of python, and .net tools.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is another way to code this

import math

def fsum(f, g, pairs):
    return sum(f(x)*g(y) for (x,y) in pairs)

def one(x):
    return 1.0

def ident(x):
    return x

def square(x):
    return x*x

def plog(x):
    return x * math.log(x)

def fit(pairs):
    pairs = list(pairs)
    si, op, ii, ip, oi = [ fsum(f, g, pairs) for (f, g) in (
            (square, ident),
            (one, plog),
            (ident, ident),
            (ident, plog),
            (one, ident),
        )]
    den = float(oi * si - ii ** 2)
    a = (si * op - ii * ip)/den
    b = (oi * ip - ii * op)/den
    return a, b

def gen_pairs():
    n = 800
    p0 = (5*(10**6))
    decay = (1.16*(10**-3))
    print("expected b: %.16f" % (-decay * math.log(p0*math.e)))
    
    for i in range(n):
        y =  (p0 * math.e)**(-(decay * i))
        yield (i, y)
        
def main():
    a, b = fit(gen_pairs())
    print(a)
    print(b)
    
if __name__ == "__main__":
    main()

"""
my output -->
expected b: -0.0190529402256621
-2.40854223893e-16 # expected a is 0.0
-0.0190529402257
"""
Gribouillis 1,391 Programming Explorer Team Colleague

A simple way to call a c++ api from python is to use swig http://www.swig.org/

Gribouillis 1,391 Programming Explorer Team Colleague

You should use python setup.py install in a cmd tool. Also you should first move the pyasn1 folder somewhere else on your computer. The setup.py will copy the necessary files to site-packages automatically (you need administrator privileges). Also read the README and INSTALL files if any.

Gribouillis 1,391 Programming Explorer Team Colleague

Python's importer does not understand .tar.gz files. You should uncompress the files with 7zip and install the modules properly.

Alternately, you can extract them with python

import tarfile
tar = tarfile.open(mode= "r:gz", fileobj = open("path_to_tgz_file", "rb"))
tar.extractall("path_to_folder_where_to_extract") # for example "."
Gribouillis 1,391 Programming Explorer Team Colleague

You can use itertools.permutations to rotate over all the numbers

import itertools
for p in itertools.permutations(range(1, 5)):
    print(p)
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)
Gribouillis 1,391 Programming Explorer Team Colleague

After the first l.pop(0) , the list is ["asd'das",'qw','213'] , so the second item is 'qw'.

vegaseat commented: nice point +13
Gribouillis 1,391 Programming Explorer Team Colleague

Thanks a lot. Every input is helping me :) But, I am not clear why you mentioned about the circular import here. Does it mean that importing a function from the main module in another module leads to circular import?

It necessarily leads to circular import: if script2.py was executed while running script1.py, you must have written 'import script2' somewhere in script1.

A better solution is to create a separate module for the functions which must be used in both scripts

# miscelaneous.py

def mode_check(...):
   ...

# script1.py
from miscelaneous import mode_check

def main():
    ...
...

# script2.py
from miscelaneous import mode_check
...

status = mode_check(mode)
Gribouillis 1,391 Programming Explorer Team Colleague

And...
import in script2 worked fine when mode_check() was defined before main.

Please let me know, why is it wrong to define a function before main, if it is so? and why did it work now?

Your problem is a circular import like this

# in module A
import B

# in module B
import A # or from A import foo

You should not use circular imports, although it works partially. For example if the function foo() is defined in A before the 'import A' is executed in B, the A.foo may work. It's not difficult to create your programs to avoid circular imports. To start with, you should not import a function from the main module in another module.

Another unrelated tip: don't indent python code with tabs. Configure your editor to indent code with 4 spaces (the recommended spacing).

Gribouillis 1,391 Programming Explorer Team Colleague

Strings are indexable. text[0] is the first symbol.

Gribouillis 1,391 Programming Explorer Team Colleague

You should perhaps call self.channel.close() on the server side after the #p was sent. Also on the client side, you could close the socket before exec(b). Did the client receive the whole code ?

Another tip (unrelated to your issue), you should call

server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

just after the socket creation. This avoids blocking the port between different executions of the server program.

Gribouillis 1,391 Programming Explorer Team Colleague

Among the possible issues:

1/ The threading.Thread class has a special rule: If the subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.. See http://docs.python.org/library/threading.html#threading.Thread .This is a frequent source of errors, so you should move line 14 immediately after line 11 in the server code

2/ socket.send() is not guaranteed to send all the data, you should use socket.sendall() instead

3/ The calls to recv() are not guaranteed to yield the same sequence of strings that were passed to send(). The client loop should probably be written

while True: 
   a = client.recv(1024)
   b += a
   if b[-2:] == "#p":
    break

4/ Why does your client code need to start a new thread ? The main thread could receive and execute the code. Otherwise you should wait for the child thread:

conn_thread = ConnectionThread()
conn_thread.start()
conn_thread.join()

Personnaly, I don't like to use raw sockets. You could have considered other solutions (like xmlrpc), which do all the sockets details for you.

Gribouillis 1,391 Programming Explorer Team Colleague

Google led me to wmi http://timgolden.me.uk/python/wmi/cookbook.html#list-all-running-processes which can help you explore running processes in windows. There are also old snippets http://code.activestate.com/recipes/303339-getting-process-information-on-windows/ and http://code.activestate.com/recipes/305279-getting-process-information-on-windows/.

I did not test all this myself, because I don't usually work on windows ...

Gribouillis 1,391 Programming Explorer Team Colleague

:)

Gribouillis 1,391 Programming Explorer Team Colleague

im using windows xp most of the time
i have not tried this yet

# windows
handle = subprocess.Popen("someprocess here", shell=False)
subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)

im going to but do you think if i terminate the process using it would the process show up again ?? because that is the problem

I don't know why your process shows up again, so try the recipes one after the other. If the other process was started from your python program with proc = subprocess.Popen(...) , you can also use proc.terminate() in recent versions of python. My second choice would be the method with ctypes.

Gribouillis 1,391 Programming Explorer Team Colleague

A list of old recipes.

# linux, mac
os.kill(pid, signal.SIGKILL)
killedpid, stat = os.waitpid(pid, os.WNOHANG)
if killedpid == 0:
print >> sys.stderr, "ACK! PROCESS NOT KILLED?"

# windows
handle = subprocess.Popen("someprocess here", shell=False)
subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)

#also
# Create a process that won't end on its own
import subprocess
process = subprocess.Popen(['python.exe', '-c', 'while 1: pass'])


# Kill the process using pywin32
import win32api
win32api.TerminateProcess(int(process._handle), -1)


# Kill the process using ctypes
import ctypes
ctypes.windll.kernel32.TerminateProcess(int(process._handle), -1)


# Kill the proces using pywin32 and pid
import win32api
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, process.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)


# Kill the proces using ctypes and pid
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process.pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
richieking commented: Santa python.... Keep it up buddy +2
vegaseat commented: thanks +13
Gribouillis 1,391 Programming Explorer Team Colleague

I could not parse it with csv, but if your string looks like python code, you can use python's own tokenizer:

# python 2 and 3
import sys
if sys.version_info < (3,):
    from cStringIO import StringIO
else:
    from io import StringIO
    xrange = range
from tokenize import generate_tokens


a = 'par1=val1,par2=val2,par3="some text1, again some text2, again some text3",par4="some text",par5=val5'

def parts(a):
    """Split a python-tokenizable expression on comma operators"""
    compos = [-1] # compos stores the positions of the relevant commas in the argument string
    compos.extend(t[2][1] for t in generate_tokens(StringIO(a).readline) if t[1] == ',')
    compos.append(len(a))
    return [ a[compos[i]+1:compos[i+1]] for i in xrange(len(compos)-1)]

print(parts(a))

""" my output -->
['par1=val1', 'par2=val2', 'par3="some text1, again some text2, again some text3"', 'par4="some text"', 'par5=val5']
"""

The other alternative is to use regular expressions.

Gribouillis 1,391 Programming Explorer Team Colleague

Try this

D = dict()
exec b in D

Also learn about code tags here http://www.daniweb.com/forums/announcement.php?f=8&announcementid=3 :)

Also note that network security rules prohibit using 'exec' on a piece of code received from a public network. This may potentially run arbitrary code on your computer.

Gribouillis 1,391 Programming Explorer Team Colleague

Use index = bisect.bisect(list, num) . The list must be sorted. Also, don't use 'list' as a variable name.

Gribouillis 1,391 Programming Explorer Team Colleague

Thanks Grib...

well, I dont know how to put the things in words.

The host I am running the 'top' command on is a proprietary unit of the company's client.

uname -a gives me just Linux XXXX, said to be having kernel version 0.3.4.

I don't know further details,but, top -n is not working :(

See if man top gives you useful options. Also, it's a little strange to run top through telnet. Can't you replace it with ps aux ?

Also you could save the output of top to a file and then cat the file. Google with save the output of top :)

Gribouillis 1,391 Programming Explorer Team Colleague
~ # top -n 3
top: invalid option -- n

got this............

Well, top -n 3 works for me (Mandriva Linux release 2010.2 (Official) for x86_64
Kernel 2.6.33.7-desktop-2mnb on a Dual-processor x86_64 / \l) but it seems that there are different versions of top, because online manuals don't have the same interpretation of -n as my manual. I have

-n : Number of iterations limit as:  -n number
            Specifies  the  maximum  number of iterations, or frames, top
            should produce before ending.

On the other hand, this link http://www.manpagez.com/man/1/top/ gives

-n <nprocs>
              Only display up to <nprocs> processes.

Note that the syntax top n 3 is accepted on my machine, as described here http://linux.die.net/man/1/top .
Try which top and check that your top is not a symlink.

Edit: I realized that the manpagez.com manual is for Mac OSX.

Gribouillis 1,391 Programming Explorer Team Colleague

Perhaps use top's -n option ?

Gribouillis 1,391 Programming Explorer Team Colleague

And here is a much shorter solution using itertools

# python 2 or 3
# solve SEND + MORE = MONEY by brute force
import itertools as itt

letters = ('s', 'm', 'e','n','d','o','r','y')
coefs = (1000, 1000-10000, 100+1-10, 10-100, 1, 100-1000, 10, -1)

def solve():
    for t in itt.combinations(range(10), len(letters)):
        for v in itt.permutations(t):
            if v[0] > 0 and v[1] > 0 and sum(v[i] * coefs[i] for i in range(len(coefs))) == 0:
                print(list(zip(letters, v)))
                return

if __name__ == "__main__":     
    solve()

""" my output -->
[('s', 9), ('m', 1), ('e', 5), ('n', 6), ('d', 7), ('o', 0), ('r', 8), ('y', 2)]
"""
Gribouillis 1,391 Programming Explorer Team Colleague

Alright, the reason that I'm using brute force is because I'm in a data structures class and this is the way that the teacher wants it done. I know that there are better methods, but I just need it to work for now.

Second, I tried your Str function in the first post and for some reason it returns duplicates of the letter configurations.

EX: When you run it it will display
{y=2,r=8,o=0,m=1,d=7,n=6,e=5,s=9r=8,o=0,m=1,d=7,n=6,e=5,s=9o=0,m=1,d=7,n=6,e=5,s=9}

And I'm not too experienced with python so I'm not sure what the other things you talked about do. Sorry.

I did not have the same problem with the __str__ function. You probably changed something else to the code.

To illustrate what I wrote above, I modified your code by eliminating the Env classes

# python 2 or 3
""" Purpose of the program is to decrypt the value of the letters in the equation
 Send + More = Money. Each letter having a unique single digit value.
 Does this using a tree and checking through different configurations of values
 for each letter until the goal is found"""


class Config(object):
    letters = ('s', 'm', 'e','n','d','o','r','y')
    math = (1000, 1000-10000, 100+1-10, 10-100, 1, 100-1000, 10, -1)
    __slots__ = ('values', 'pos','unused')

    def __init__(self, values, pos, unused):
        self.values = values
        self.pos = pos
        self.unused = unused

    def solve(self):
        """Return a solution Config or None if no solution"""
        if self.isGoal():
            return self
        else:
            for child in self.successor():
                solution = child.solve()
                if solution:
                    return solution

    def isGoal(self):
        ''' Checks …
Gribouillis 1,391 Programming Explorer Team Colleague

You can test the number of children elements and the type of an element

data = """<item>
    <title>mytitle</title>
    <link></link>
</item>"""

from xml.dom.minidom import parseString, Element

def genSimpleData(element, tag):
    """yield the string data for all subelements with the given tag
    which have a single text node child"""
    for node in element.getElementsByTagName(tag):
        if len(node.childNodes) == 1 and node.firstChild.nodeType == Element.TEXT_NODE:
            yield node.firstChild.data

def main():
    doc = parseString( data )
    items = doc.getElementsByTagName('item')

    titles = []
    links = []

    for i in items:
        titles.extend(genSimpleData(i, 'title'))
        links.extend(genSimpleData(i, 'link'))

    return dict( {'title' : titles, 'link' : links } )

print main()

""" my output --->

{'link': [], 'title': [u'mytitle']}
"""
Gribouillis 1,391 Programming Explorer Team Colleague

You can use this

# python 2
A = "gtggcaacgtgc"
B = "gtagcagcgcgc"
C = "gcggcacagggt"
D = "gtgacaacgtgc"

def cromo(a, b):
    assert len(a) == len(b)
    return sum(a[i] != b[i] for i in xrange(len(a)))
    
print cromo(A, B)

Boolean values can be summed, with True=1 and False=0.

Gribouillis 1,391 Programming Explorer Team Colleague

Use a regular expression (module re)

import re
digits_colon_re = re.compile(r"(?P<digits>\d+)\:")

data = """
4:14.4-17M,5:14.4-2e13M,6:14.4-4e9M,7:14.4-8e,22:28.4-35M,23:28.4-2e30M,
24:28.4-4e26M,25:28.4-8e18M,26:28.4-16e2M,27:28.4-18e,28:14.16-36M,29:14.16-2e32M,
30:14.16-4e28M,31:14.16-8e20M
""".strip().replace("\n", "").split(",")

print([int(match.group("digits")) for match in (digits_colon_re.search(s) for s in data)])

""" my output --->
[4, 5, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
"""
Gribouillis 1,391 Programming Explorer Team Colleague

Here is a working __str__ function

class NonEmptyEnv(object):
    __slots__ = ('letter','digit','rest')

    def __init__(self,letter,digit,rest):
        self.letter = letter
        self.digit = digit
        self.rest = rest
        

    def __str__(self):
        result = self.letter + "=" + str(self.digit)
        if isinstance(self.rest, NonEmptyEnv):
            result += ',' + str(self.rest)
        return result

Otherwise, your solution is overly complicated. You are using NonEmptyEnv instances as stack elements and you traverse the stack recursively for each lookup. It looks like a lisp program. Did you consider storing intermediary states in a list or a tuple or a dict or a collections.deque object ? For example you could have [('n', 6),('e',5),('s',9)] as an intermediary state.

Another interesting tool for this problem is the function itertools.combinations() . For example

>>> from itertools import combinations
>>> combi = combinations(list(range(10)), 8)
>>> for i in range(15):
...  print next(combi)
... 
(0, 1, 2, 3, 4, 5, 6, 7)
(0, 1, 2, 3, 4, 5, 6, 8)
(0, 1, 2, 3, 4, 5, 6, 9)
(0, 1, 2, 3, 4, 5, 7, 8)
(0, 1, 2, 3, 4, 5, 7, 9)
(0, 1, 2, 3, 4, 5, 8, 9)
(0, 1, 2, 3, 4, 6, 7, 8)
(0, 1, 2, 3, 4, 6, 7, 9)
(0, 1, 2, 3, 4, 6, 8, 9)
(0, 1, 2, 3, 4, 7, 8, 9)
(0, 1, 2, 3, 5, 6, 7, 8)
(0, 1, 2, 3, 5, 6, 7, 9)
(0, 1, 2, 3, 5, 6, 8, 9)
(0, 1, 2, 3, 5, 7, 8, 9)
(0, 1, 2, 3, 6, 7, 8, 9)

Finally, there are probably better approaches than brute force for this problem, so you should think a little more about the algorithm.

Gribouillis 1,391 Programming Explorer Team Colleague

I found a solution :)

a=str(obj).split(';')
                for vals in a:
                        print vals

gives me:

1+1 Protection
 East-West
 East-East
 Spiral Search
 ............
 ...........

any better solutions are welcome...

I think your solution is excellent, although I fail to see how str(obj) could print Null('') while str(obj).split(';') prints all this stuff :)

Gribouillis 1,391 Programming Explorer Team Colleague

@Grib........

value=varBinds[0][1].get()
AttributeError: OctetString instance has no attribute 'get'

Did you try

print dir(obj)

?

Gribouillis 1,391 Programming Explorer Team Colleague

There is also a method get(), you could try

value = obj.get()
print value
print value.__class__
Gribouillis 1,391 Programming Explorer Team Colleague

@Grib....

Python gave me this:

<type 'instance'>
pysnmp.proto.rfc1902.OctetString

With this output, google led me to http://twistedsnmp.sourceforge.net/pydoc/pysnmp.proto.rfc1155.html#OctetString . The class has __len__ and __getitem__ methods. so you should try

# obj is your octet string object
for i in range(len(obj)):
  item = obj[i]
  print i, item
  print item.__class__

to see what the object contains. Please post the output here (in code tags).

Gribouillis 1,391 Programming Explorer Team Colleague

thanks for the reply...but it's not helping me :(

What did python print ? If you don't know the python class of your 'octet string', you won't be able to convert it to anything.

Gribouillis 1,391 Programming Explorer Team Colleague

To see if an object can be converted to something else, you must find its class and look in the object's class documentation, so try this first:

print(type(obj))
print(obj.__class__)
Gribouillis 1,391 Programming Explorer Team Colleague
Gribouillis 1,391 Programming Explorer Team Colleague

I know there must be something pretty simple, but it's blocking me, need help :)

You must use delimiter=',' .

Gribouillis 1,391 Programming Explorer Team Colleague

Why not

for row in reader:
    for item in row:
        print item

?
Also learn about code tags here http://www.daniweb.com/forums/announcement.php?f=8&announcementid=3.

Gribouillis 1,391 Programming Explorer Team Colleague

simple format print

stuff="""
      Hi folk, I fairly new to Python 2.7 and Python 3 and
      like to find out how I would get a print to appear in
      the middle of the output screen without putting in a
      load of spaces into a print statement. Please keep it
      simple for me.
      """
print("%20s"% stuff) ## increase the figure  for more indentation

flavours ;)

@richieking : your method works for literal strings only, while textwrap.fill() works for any string (eg dynamically generated strings). In fact, you're formatting the string by hand :)

Gribouillis 1,391 Programming Explorer Team Colleague

Hi folk, I fairly new to Python 2.7 and Python 3 and like to find out how I would get a print to appear in the middle of the output screen without putting in a load of spaces into a print statement. Please keep it simple for me.

Thanks for you time.


The textwrap module can be useful too. Here is an example

>>> from textwrap import fill
>>> s = fill("""Hi folk, I fairly new to Python 2.7 and Python 3 and like to find out how I would get a print to appear in the middle of the output screen without putting in a load of spaces into a print statement. Please keep it simple for me.""", initial_indent=" "*15, subsequent_indent= " "*15, width = 70)
>>> print(s)
               Hi folk, I fairly new to Python 2.7 and Python 3 and
               like to find out how I would get a print to appear in
               the middle of the output screen without putting in a
               load of spaces into a print statement. Please keep it
               simple for me.
Gribouillis 1,391 Programming Explorer Team Colleague

Functions are not executed until you call them. So, if you want to execute f1 with the output of f2 as argument, you write

result = f1(f2(value))

You should post the whole code, it would be easier to debug.

Gribouillis 1,391 Programming Explorer Team Colleague
print "the total number of animals is", sum(animals.values())
Gribouillis 1,391 Programming Explorer Team Colleague

$? is a shell variable. Each time you call os.system, python creates a new shell. Anyway, os.system() is deprecated, use subprocess.Popen

import subprocess as sp
process = sp.Popen("cd /foo; echo $?", shell=True, stdout=sp.PIPE, stderr=sp.PIPE)
print process.communicate()

""" my output -->
('1\n', '/bin/sh: line 0: cd: /foo: Aucun fichier ou dossier de ce type\n')
"""
# (my shell speaks french :) )

I also wrote a small Command class which does about the same. See http://www.daniweb.com/code/snippet257449.html

Gribouillis 1,391 Programming Explorer Team Colleague

It's very easy

def read_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile:
            scores = scorefile.readlines()
    except IOError:
        scores = []
    return [int(s) for s in scores]

def display_scores(): # could be improved
    print("\n".join(str(s) for s in read_scores()))

def save_scores(score):
    scores = read_scores()
    scores.append(score)
    scores.sort()
    with open('scores.txt', "w") as scorefile:
        scorefile.write("\n".join(str(s) for s in scores[:5]))
vegaseat commented: great +13
Gribouillis 1,391 Programming Explorer Team Colleague

So write one function for displaying and one function for writing. Should I split up save_scores(score) in terms of reading and writing then? Have it read at the beginning and write after the player wins?

Yes, you could have a function read_scores() which returns a list of scores. When a feature is needed in two different places, it is always good to write a function.

Gribouillis 1,391 Programming Explorer Team Colleague

thanks Grib....

I need to maintain a list of servers that host the software release folders. I need my script to be generic, i.e., it can be run on any of the servers.
I need to check the ip address of the host on which am running the script, and for the servers in list other than my host, i need to do a telnet to connect to it and get the folder,if present do an FTP upload.

I got this Crude method of creating a dummy socket and getting my IP address from ASPN Python cookbook

import socket

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('google.com',80))
return s.getsocketname()[0]

and it helped me....

It's getsockname(). Nice trick, I'll add it to my notes.

Did you try to run ifconfig or ipconfig with subprocess.Popen ?

Gribouillis 1,391 Programming Explorer Team Colleague

Where would be a better place to call it? I would prefer to have the top scores display at the beginning of the game. Which would mean I need to call save_scores(score) before I call print_board(board).

Displaying scores and saving scores are 2 different things. You should write 2 functions. The new score must be saved after the game.

Gribouillis 1,391 Programming Explorer Team Colleague

I definitely think placement is off. It seems to not be storing anything for me. I just get back zeros.

the placement of the def save_score does not matter as this function does not use any global variable. There must be another problem in your code. The only call to save_score() is at line 102, just after you defined score=0. This is probably the problem.

Gribouillis 1,391 Programming Explorer Team Colleague

So if I wanted to print the lowest five scores would I print(tempo)?

Yes why not. You could also add a print(entry) in the last for loop (although i'd prefer to separate writing the file and printing because printing is slow).

Gribouillis 1,391 Programming Explorer Team Colleague

Okay. So I didn't get any error messages with that. Which give me hope! But is there anyway to print these scores in a way that I tried in my last 'def save_scores(score):' code? I'd like for it to have the five lowest scores shown in order. Is there a way to do that in this same function?

I added a line (forgot to append the score). In principle, this function should store the 5 lowest scores in order. An error in your previous code was the 2 variables new_scores and newscores.

Gribouillis 1,391 Programming Explorer Team Colleague

If you want to read and then rewrite the file, you must open the file twice. You could use

def save_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile: # this will automatically close the file
            scores = scorefile.readlines()
    except IOError:
        scores = []
    scores.append(score)
    tempo = sorted(int(line) for line in scores)
    with open('scores.txt', 'w') as scorefile:
        for entry in tempo[:5]: # the five lowest scores ?
            scorefile.write("{e}\n".format(e=entry))