Ok so I'm working on an address book app in python. the user writes contacts into a txt file and can search for it and everything.(run the code yourself if you want to see what it does)

now for my problem,

under "#if editing"
i want have the user search for a contact and delete that line. but i have no clue how to use remove(x), or pop(x) when working with files. Thanks


Below is my code

#what to do
print ""
action=raw_input("Are you [1]Creating/Editing entrys or [2]Searching for an existing entry? ")

# IF Creating or editing
if action=='1':
	action2=raw_input("Would you like to create a [1]new entry or [2]edit an existing one? ")

#if creating new
	if action2=='1':		
		fob=open('/Users/NSutton/Simple Adress/bookdata.txt','w')
		fname=raw_input("First Name: ")
		lname=raw_input("Last Name: ")
		pnum=raw_input("Phone: ")
		email=raw_input("Email: ")
		address=raw_input("Adress: ")
		fob.write(fname + " " + lname + ", " + pnum + ", " + email + ", " + address)
		fob.write("\n")
		fob.close()

#if editing
	if action2=='2':
		fob=open('/Users/NSutton/Simple Adress/bookdata.txt','r')
		searchcriteria=raw_input("Enter the name of the contact you'd like to delete: ")
		for line in fob:
			if searchcriteria in line:
    				print line
    	#confirm this is the contact you want to delete
    		confirmdel=raw_input("Is That the contact you wish to delete? [yes or no]")
    		if confirmdel=="yes":
    			
    			
    		
#IF searching
if action=='2':
	fob=open('/Users/NSutton/Simple Adress/bookdata.txt','r')
	searchcriteria=raw_input("Enter your search criteria (name,phone ect.): ")
	for line in fob:
		if searchcriteria in line:
        		print line
         #If no data matches search
   		else:
    			print "Error: No contact matching search."

I do not recommend working disk file. Usually computers have enough memory to keep full copy in memory.If you need to not read all db in memory, You can use special char as first in line and by pass it in your operations. Also editing can be interpreted as adding changed line at the end and marking eld one deleted..

First it is good to introduce the purpose of the program, own exercise or school exercise or final work to school

I do not recommend working directly with disk file. Usually computers have enough memory to keep full copy in memory.

So, i would say that do list(open('/Users/NSutton/Simple Adress/bookdata.txt') and work with the list and write back.

I would also recommend not to use absolute path but simple 'bookdata.txt' which should suffice in case the file is kept in same directory with the program. Also I would not use tabulators, but spaces in code. If you have unfinished statement in program you can put pass in its place (the if statement is illegal in your code).

This should be the case in your db which contain only one record. You can input all info once and program stops. Next run it finds that one line OK by searching. Also if run directly it does not stop before exit to actually show the information. If you want to be able to undelete the records, consider putting this status character also with other lines, say ' '.

Also comma separated values is OK, and nice when humans read information, saving space and so on, but for database the clever choice is fixed length data (if not doing everything in memory like I recommended. Then in following strategy you can easily reclaim to use deleted records and can edit in place without doing new record at the end of db. Also it is usually worthwhile to keep records in sorted order as that is mostly required. If you need some archiving of db activity, it is good to include time stamp of information change.

Anyway if you want still to do it hard way for what ever reason.
If you need to not read all db in memory, you can use special char as first in line and bypass those lines in your operations. Also editing can be interpreted as adding changed line at the end and marking elder one deleted. Then usually it would make sense to add reorganize command to sort and move the data to take out the unused space.

Do little more effort and let's see again your more finalised work.

There is many variations, but considering the style of your code, I would say (if you have not limitations declared by teachers) work with data in memory.

Tony

Edited 6 Years Ago by pyTony: n/a

tonyjv you gotta break that down..I have no idea what you mean. (am N00b)

and it for myself. i dont take programming classes.

Open the file and place it in a list (this puts the file in memory). From that list, keep track of your location in the list. If the item is found, confirm the delete request, then delete the list item (line).

For example:

#if editing
    if action2 == '2':
        foblist = []
        for line in open('/Users/NSutton/Simple Address/boodata.txt', 'r'):
            foblist.append(line)
            pass

        searchcriteria = raw_input("Enter the name of the contact you'd like to delete: ")
	loc = 0 # This keeps track of the location in the list.
        for line in foblist:
	    if searchcriteria in line:

    	        #confirm this is the contact you want to delete
    	        print line
    		confirmdel = raw_input("Is That the contact you wish to delete? [yes or no]")

    		if confirmdel == "yes":
                    foblist.del(loc)

                    # Write the data from memory back to the file
                    f = open('/Users/NSutton/Simple Address/boodata.txt', 'w')
                    for line in foblist:
                        print >> f, line
                        pass

                    f.close()

                    break # We're done with the delete process, break out of loop.

            loc += 1 # searchcriteria not in line...update location.
            continue

        pass

Edited 6 Years Ago by Hummdis: Correction...

Heres the update version of that code block.


I saved it to 'temp1' and normaly you would delete lines like so, "temp1[2]='sdfase' " and change it that way. BUT i dont know the list number of the contact so im lost one again...

#if editing
	if action2=='2':
		fob=open('bookdata.txt','r')
		searchcriteria=raw_input("Enter the name of the contact you'd like to delete: ")
		temp1=fob.readlines()
		for line in temp1:
			if searchcriteria in line:
    				temp1[list]=""
    	#confirm this is the contact you want to delete
    		#confirmdel=raw_input("Is That the contact you wish to delete? [yes or no]")
    		#if confirmdel=="yes":

If you set the line to a blank line, you still have your line in the text file. By putting the file into a list, removing the list item, then saving the while list back to a file you remove the empty lines.

For example, if you have a contact list of five people, then delete number three by erasing that line, you'll have a blank line.

====
John Doe
Jane Doe
Bo Doe
Joe Doe
Frank Doe
====

Your list looks like this:

temp1 = [ 'John Doe', 'Jane Doe', 'Bo Doe', 'Joe Doe', 'Frank Doe' ]

Then, delete #3 by just setting it to '' will make the list be:

temp1 = [ 'John Doe', 'Jane Doe', '', 'Joe Doe', 'Frank Doe' ]

Then when you write the file, you'll get:

=====
John Doe
Jane Doe

Joe Doe
Frank Doe
=====

By actually deleting the list item, you remove not just the contact, but the whole entry as well. This:

temp1 = [ 'John Doe', 'Jane Doe', 'Bo Doe', 'Joe Doe', 'Frank Doe' ]

Becomes this:

temp1 = [ 'John Doe', 'Jane Doe', 'Joe Doe', 'Frank Doe' ]

Make sense?

So according to my uncle a season programmer (not in python)
I should make a class to hold an objects and each object is a individual contact.

But it still isn't working. Im getting SO FRUSTRATED!! arhg i need help...

#MyContact CLASS
class MyContact():
	firstName=""
	lastName=""
	Phone=""
	Email=""
	Address=""

#what to do
    
print ""
action=raw_input("Are you [1]Creating entrys or [2]Searching for existing entrys? ")

				
# IF Creating or editing
if action=='1':
	action2=raw_input("Would you like to create a [1]new entry or [2]edit an existing one? ")

#if creating new
	if action2=='1':
		while 1:
				contact = MyContact()
				contact.firstName=raw_input("First Name: ")
				contact.lastName=raw_input("Last Name: ")
				contact.Phone=raw_input("Phone: ")
				contact.Email=raw_input("Email: ")
				contact.Address=raw_input("Adress: ")
				fob=open("bookdata.txt",'w')
				fob.write("\n" + contact.firstName + ", " + contact.lastName  + ", " + contact.Phone + ", " + contact.Email  + ", " + contact.Address + "\n")
				fob.close()
				#creating another contact
				cont=raw_input("Would You Like to create another Contact? [yes/no]")
				if cont=='no':
					break
				else:
					pass

Make a class when you need a class. Think of a class as a section of code that is separate from the rest of the code.

For example, I develop an operating system with global variables (Ethernet settings, preferences, etc). I don't need the global data all of the time, but when I do I need them available. A class works well for that since the global data is for all functions to the operating system. It's a single class that runs before anything else in the OS, but is called on many times from other functions and files because of what it does.

In this case, however, the data is an address book. You're using that address book the whole time the application is open. If you use a class, use the class to open the address book and to save the address book. The class should not contain the deletion process unless you want to.

It's important to remember that you can program how you want with Python. There are the way that work, the ways that don't and the ways you *should* to something and the ways you *should not* do something.

If your uncle is a seasoned programmer in any form of C, then remember that C is NOT Python. Low-level programming versus high-level programming. Two very different things. You can do things in Python that a C programmer would have a fit over. Does that make it wrong? No. The languages are not the same.

It's very easy for a seasoned programmer in any language to just tell someone to "oh, just make a class, that's the easiest way." Yes. It's the easiest way when you know what you're doing. You must first learn how to do something before you can learn what types of data management works best (i.e. classes, functions, files, etc).

I have made many programs do many things. I have rarely used classes. Does that mean I should be using them? No, but I bet it may make things easier.

Get the code working first, then decide what you should be placing inside of classes. Since you're new to Python, classes are probably a bit over your head right now because they add a level of complexity that you may not yet be ready for.

Create one function for editing; create a function for searching; one for deleting; one for adding. Get the code to work first. I suggest that each function be passed arguments (i.e. the data from the address book) that needs to be added, altered or removed.

One other thing, most (but not all) Python programmers use a tab space of 4, not 8. Your code will be easier to read without having such large indents.

I encourage a two-spaced indent.

class MyContact(object):
  def __init__(self,fn = "", ln = "", ph = "", em = "", ad = ""):
    self.firstName=fn
    self.lastName=ln
    self.Phone=ph
    self.Email=em
    self.Address=ad

#what to do
action=raw_input("Are you [1]Creating entrys or [2]Searching for existing entrys? ")

        
# IF Creating or editing
if action=='1':
  action2=raw_input("Would you like to create a [1]new entry or [2]edit an existing one? ")

#if creating new
  if action2=='1':
    while 1:
      contact = MyContact()
      contact.firstName=raw_input("\nFirst Name: ")
      contact.lastName=raw_input("Last Name: ")
      contact.Phone=raw_input("Phone: ")
      contact.Email=raw_input("Email: ")
      contact.Address=raw_input("Address: ")
      fob=open("bookdata.txt",'w')
      fob.write(",".join((contact.firstName,contact.lastName,contact.Phone,contact.Email,contact.Address)) + "\n")
      fob.close()
      #creating another contact
      cont=raw_input("Would You Like to create another Contact? [yes/no]")
      if cont.lower()=='no':
        break
      else:
        pass
elif action=='2':
    #why name it fob?
    fob = open("bookdata.txt",'r')
    for line in fob.readlines():
        contact = MyContact(*line.split(","))
        print contact.firstName, contact.lastName
    fob.close()

The program structure could be changed, though.
If you like classes, you can use lots of classes, just like C#.
Python can be used for Object Oriented, or it can be used for scripting.
Of course, if you have a class that just contains values (kinda like a Structure in C#, C++, or C), you are better off just using a list or a dictionary.

Edited 6 Years Ago by jcao219: n/a

Here some code as beginning point suggestion from me for user interaction (do not ask obvious questions, if user uses program, he wants to see the data and probably add to it also).

After you complete other parts, maybe this part must change but here is beginning. I put tabs instead of comma for separating fields as comma is common inside addresses, so using that mix up things. You must do only split('\t') not split() as that separates words from address or parts of phone number also.

You could also consider Tkinter user interface, check for example http://www.daniweb.com/forums/post1196358.html#post1196358.
Saving each record as separate file is stupid in most cases, however.

import os
#what to do
def new_data(db=[]):
    print 'Taking data until First Name = q'

    fname=raw_input("First Name: ")
    while not fname or fname not in 'qQ':
        data=[fname,
              raw_input("Last Name: "),
              raw_input("Phone: "),
              raw_input("Email: "),
              raw_input("Adress: ")]
        print '-'*40
        db.append(data) ## add the new record as new list at the end of the db list of lists
        fname=raw_input("First Name: ") ## because I did not do while True and break loop

    dbfile=open('bookdata.txt','w')
    for d in db:
##        print d
        dbfile.write('\t'.join(d)+'\n')
    return db

def show_db(db):
    print 'Address book has',len(db),'entries'
    for i,d in enumerate(db):
        print i,':\t','\t'.join(d).rstrip() ## take out white space and newlines in the end
    print '-'*40
    
more='y'
db=[]

if os.path.isfile('bookdata.txt'):
    q = raw_input("Database found, do you want to load it (Y/n)? ").lower()
    if not q: q='y' ## nothing entered => default
    if q and q[0] != 'n': ## default is to use old db
        db=open('bookdata.txt','r').readlines()
        db=[d.split('\t') for d in db]
        show_db(db)
        more = raw_input('Do you want to give more data (Y/n)?')

if not(more and more in 'nN'):
    print "** Enter data **"
    db=new_data(db)

    show_db(db)
    
q=''

while not q:

    ## Here actions to use db
    print "Your actions"
        
    ## continue?
    q=raw_input('Empty line to continue,\nanything else to quit: ')

Ok, i wanna learn C languages next so im going to start using classes and objects now.

class collect_data():
   def collect_data():
        first name?
       last name?
       ect.

class menu():
  def what_todo():
      "create code? or search?"


class search():
  def searching():
      #search algorithem


collectObject=collect_data()
collectObject.collect_data

In bad pusedo code is that how you use classes?

Would you put the classes outside the main block of code and use objects to acsess the functions inside the classes?

couldn't you just define functions and skip all the classes?

couldn't you just define functions and skip all the classes?

You can do that, but everything is just a lot less organized that way.

Classes are object-oriented programming!
OO is great, because look around you!
Everything is an object!

With classes and OO, you can create your own object, and use that object with its attributes and do whatever you want with it.

You say you are learning another language next.
Don't learn C, since C really doesn't have classes.
I recommend C#, since if you learn C++, you'll have to deal with low level stuff like pointers a lot.

Python is a great way to start learning programming.
In C#, even a basic hello-world program requires a class.

Take a look at this:

using System;

public class HelloWorldProgram
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}

A direct translation of that to Python would be something like this:

class HelloWorldProgram(object):
    @staticmethod
    def Main():
        print "Hello World!"

HelloWorldProgram.Main()

Also take a look at this extended C# example:

using System;

public class HelloWorldProgram
{
    private static string name;
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        greet();
        Console.WriteLine("Bye " + name);
    }
    private static void greet()
    {
        Console.Write("What is your name?  ");
        name = Console.ReadLine();
        Console.Write("Hello! " + name);
    }
}

In Python, an almost direct translation would be:

class HelloWorldProgram(object):
    @staticmethod  #rarely used, don't worry about it
    #just for the sake of C#->Python comparison
    def Main():
        print "Hello World!"
        name = HelloWorldProgram.greet()
        print "Bye", name
    @staticmethod
    def greet():
        name = raw_input("What is your name?  ")
        return name

HelloWorldProgram.Main()

I hope the strange ugliness of the C# code should deter you from abandoning Python anytime soon. :)

Anyways, as you can see, in languages that support Object-Oriented programming, classes are a universal way to save state, since let's say you have a brick, and you paint it red.
That brick is an object, and you just changed its color to red.
Then, in the program, whenever you decide to access the brick,
it turns out to be red.
That's a basic explanation of object oriented programming,
and I added some comparison with C# (a famous object-oriented language) since you seemed to be interested in learning another language after Python.

Edited 6 Years Ago by jcao219: n/a

In bad pusedo code is that how you use classes?

So you open Python's command line.
Let's say you wanted a fish object:

>>> class Fish(object):
...     pass
>>>

You have just defined what a Fish is.
Of course, that Fish is not much of a fish.
You can add a constructor like this:

>>> class Fish(object):
...     def __init__(self,habitat):
...         self.habitat = habitat

Well now you have defined what a Fish is,
how do you use it?

nemo = Fish("anemone")

There, a new Fish is created, and it is bound to the name "nemo".
Also, the constructor __init__ method was called, with an argument "anemone".
Now where does nemo live?

>>> print "Nemo lives in",nemo.habitat
Nemo lives in anemone
>>>

Great! the nemo (which is a Fish object) has an attribute "habitat" which was set in the constructor.

Now you can even change where nemo lives:

>>> nemo.habitat = "fish tank"
>>> print "Nemo now lives in", nemo.habitat
Nemo now lives in fish tank
>>>

Interesting?
You can also make methods like this:

>>> class Fish(object):
...     def __init__(self,habitat):
...         self.habitat = habitat
...     def eat(self):
...         self.habitat = "stomach"

Now let's make a catfish and eat it.

>>> catfish = Fish("plate")
>>> print "The catfish is on the",catfish.habitat
The catfish is on the plate
>>> catfish.eat()
>>> print "The catfish is in my",catfish.habitat
The catfish is in my stomach
>>>

Do you understand now?

Yep. I think i got a good idea on classes now and shall be using them more to organize my code. thanks you very much jcao219

I encourage a two-spaced indent.

No and no no.

Python programmers should read Pep 8 and try to follow advice that is given there.
Use 4 spaces per indentation level.

No and no no.

Python programmers should read Pep 8 and try to follow advice that is given there.
Use 4 spaces per indentation level.

Yes, follow the style guide.
But 2 spaces is so much easier to type, and easy enough to read for me, so I break the rules for that reason.
Of course, I use 4-spaces if the IDE (Visual Studio) does it for me.
You are right though, Python programmers should follow the style guide. I was wrong to encourage it, but I still admit to doing it :).

Yes, follow the style guide.
But 2 spaces is so much easier to type, and easy enough to read for me, so I break the rules for that reason.
Of course, I use 4-spaces if the IDE (Visual Studio) does it for me.
You are right though, Python programmers should follow the style guide. I was wrong to encourage it, but I still admit to doing it :).

My code is so ugly. Its good that im using classes to organize it so i dont get lost when im error correcting. Normally my indents are 1 tab space but i got lazy.

Thanks to everyone who helped me. Wrting it in class is so much better and easier to understand. Thanks once again.

This question has already been answered. Start a new discussion instead.