Nogg
Nogg

Reputation: 337

New to python, write function

I'm attempting to learn a few languages and as such I am doing the same problem on different languages. Here is my code:

def read_one_file():
    with open('C:\Python27\inventory.dat', 'r') as f:
        invid = f.readline().strip()
        invtype = f.readline().strip()
        price = f.readline().strip()
        stock = f.readline().strip()
        title = f.readline().strip()
        author = f.readline().strip()
        published = f.readline().strip()

        return invid, invtype, price, stock, title, author, published


def write_one_file(holdId, holdType, holdPrice, holdStock, holdTitle, holdAuthor, holdPublished):
    with open('C:\Python27\inventory.dat', 'w') as f:
        invid = holdId
        price = holdPrice
        newstock = holdStock
        published = holdPublished
        f.write("Item Id: %s\n" %invid)
        f.write("Item Type: %s\n" %holdType)
        f.write("Item Price: %s\n" %price)
        f.write("Number In Stock: %s\n" %newstock)
        f.write("Title: %s\n" %holdTitle)
        f.write("Author: %s\n" %holdAuthor)
        f.write("Published: %s\n" %holdPublished)
        return

invid, invtype, price, stock, title, author, published = read_one_file()

print "Update Number In Stock"
print "----------------------"
print "Item ID: ", invid
print "Item Type: ", invtype
print "Price: ", price
print "Number In Stock: ", stock
print "Title: ", title
print "Author/Artist: ", author
print "Published: ", published
print "----------------------"
print "Please Enter New Stock Number: "
newstock = raw_input(">")


write_one_file(invid, invtype, price, newstock, title, author, published)

EDIT: I've tried using str() to convert but still doesn't run. EDIT2: I ended up changing %d to %s and seems to work. The only issue is when I run it, it tends to put book on line with 123456.

What ends up happening in the console

    Update Number In Stock
----------------------
Item ID:  123456book
Item Type:  69.99
Price:  20
Number In Stock:  
Title:  Walter_Savitch
Author/Artist:  2011
Published:  
----------------------
Please Enter New Stock Number: 
>

this is the .txt file:

123456book 69.99 20

Walter_Savitch 2011

something with a newline?

Upvotes: 2

Views: 8412

Answers (4)

wim
wim

Reputation: 362557

The file handle expects a string object, and you are giving it a tuple object.

import os

def write_one_file(a, b, c, d, e, f, g, fname=r'C:\Python27\inventory.dat'):
    with open(fname, 'w') as f:
        f.write('Item ID: {}{}'.format(a, os.linesep))
        # etc..

Note you don't need a return statement in your function, since you aren't returning anything.

Upvotes: 2

Weeble
Weeble

Reputation: 17890

You seem now to be having trouble with reading your file. It appears not to be in the format you think it is.

I'm assuming this is the content of your file, and that Stackoverflow mangled it a bit when you put it in your question:

123456book
69.99
20

Walter_Savitch
2011

If your file really has no new-line between "123456" and "book", it's not surprising that it is read as one line with readline. Is the file supposed to be like that? Did you create it specifically for this purpose, or is it obtained from somewhere else and in a format that you don't control? Does this code need to work with other similar files? If so, what layout do they have? Without more information, it's hard to guess exactly what the common layout of your files is.

  1. You could edit the file to put a new-line between "123456" and "book", so that it matches the format expected by your program.

  2. If the format of your first line is guaranteed to be a six digit ID followed by arbitrary text, you could split it up like this:

    idline = f.readline().strip()
    idnumber = idline[:6]
    idtype = idline[6:]
    # Now idnumber == "123456"
    # and idtype == "book"
    

    See an explanation of "slice notation" here: http://docs.python.org/tutorial/introduction.html#strings

  3. If the format of your first line is guaranteed to be an arbitrary number of digits followed by an arbitrary number of lower-case letters, you could split it up with a regular expression:

    import re
    
    ...
    
    idline = f.readline().strip()
    idnumber, idtype = re.match("([0-9]*)([a-z]*)", idline).groups()
    

    See http://docs.python.org/library/re.html

Upvotes: 1

Weeble
Weeble

Reputation: 17890

The write method takes a single string as an argument. You can format a string with a number variable in any of these ways:

f.write("Value :%d" % number)
f.write("Value :%s" % number)
f.write("Value :" + str(number))
f.write("Value :{}".format(number))

If the variable you want to insert is a string, try any of these:

f.write("Value :%s" % string)
f.write("Value :" + string)
f.write("Value :{}".format(string))

Note that the "%d" format specifier is for inserting numbers in decimal format. It will cause an exception if you provide a string instead.

See here for a description of the % operator: http://docs.python.org/library/stdtypes.html#string-formatting

See here for a description of the format method on strings: http://docs.python.org/library/string.html#formatstrings

The format method is generally preferred.

Upvotes: 2

Noah
Noah

Reputation: 22636

f.write() expects a string as an argument. You're defining invid, invtype, etc as tuples, which are not automatically converted to strings. You can either explicitly convert them, using the str() function, or more likely what you'd like is to use some string formatting, e.g.:

"Number in stock%d"%nrStock

where "%d" indicates that nrStock is an integer.

You'll note that I've renamed your d variable to nrStock. It's typically good practice to use descriptive variable names, or an even better idea might be to use a dictionary.

Upvotes: 5

Related Questions