How to delete from an object - python

import pickle
class TasksError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class Task(object):
def __init__(self, task = () ):
if task ==():
raise TasksError('Empty task.')
self.name = task[0]
self.date = task[1]
self.priority = task[2]
self.time = task[3]
self.type = task[4]
self.comment = task[5]
def __str__(self):
output = '''Name: %s
Date: %s
Priority: %s
Time: %s
Type: %s
Comment: %s
''' % ( self.name,
self.date,
self.priority,
self.time,
self.type,
self.comment)
return output
class Tasks(object):
def __init__(self, container = []):
self.container = [ Task(todo) for todo in container ]
def delete(self):
x = 0
for todo in self.container:
x = x + 1
print "Task Number",x,"\n", todo
delete = raw_input("what number task would you like to delete")
if delete == "y":
del todo
############
#x = 0
# for task in self.container:
# x = x+1
#print "Task Number",x,"\n", task
#delete = raw_input("what number task would you like to delete")
#if delete == "y":
#del(task)
def add(self, task):
if task == '':
raise TasksError('Empty task')
self.container.append( Task(task) )
def __str__(self):
output = '\n'.join( [ str(todo) for todo in self.container ] )
return output
if __name__== "__main__":
divider = '-' * 30 + '\n'
tasks = Tasks( container = [] ) # creates a new, empty task list
while True:
print divider, '''Make your selection:
1. Add new task
2. Print all tasks
3. Save tasks
4. Load tasks from disk
5. Find high priority tasks
6. Sort by date
7. Delete task
<ENTER> to quit
'''
try:
menu_choice = int(input("Select a number from the menu: "))
except:
print 'Goodbye!'
break
if menu_choice == 1:
task = raw_input (">>> Task: ")
date = raw_input (">>> Date as string YYYYMMDD: ")
priority = raw_input (">>> Priority: ")
time = raw_input (">>> Time: ")
Type = raw_input (">>> Type Of Task: ")
comment = raw_input (">>> Any Comments? ")
todo = (task, date, priority, time, Type, comment)
tasks.add( todo )
print tasks
elif menu_choice == 2:
print divider, 'Printing all tasks'
print tasks
elif menu_choice == 3:
print divider, 'Saving all tasks'
tasks.save()
elif menu_choice == 4:
print divider, 'Loading tasks from disk'
tasks.load()
elif menu_choice == 5:
print divider, 'Finding tasks by priority'
results = tasks.find_by_priority(priority='high')
for result in results: print result
elif menu_choice == 6:
print divider, 'Sorting by date'
tasks.sort_by_date()
print tasks
elif menu_choice == 7:
tasks.delete()
I have deleted parts of my code (hopefully nothing important).
Im having trouble getting python to delete my tasks once added.
Both methods defined as "def delete" give the error message type error: task/todo object does not support deletion.
Does anyone know a way around this?

You don't delete from list like that... Your code have 2 problems:
if you use for to loop through a iterable, you should not change it inside the loop.
to del from list you should use index.
Try this:
index = 0
while index < len(self.container):
delete = raw_input("what number task would you like to delete")
if delete == "y":
del self.container[index]
else:
index += 1

Related

finding the highest hour in a list

class volunteerList:
def __init__ (self, groupName):
self.__vList = []
self.__groupName = groupName
def setGroupName (self, newGroupName):
self.__groupName = newGroupName
def getGroupName (self):
return self.__groupName
def getvList (self):
return self.__vList
def addVolunteer (self, volunteer):
self.getvList().append(volunteer)
def highestHour (self):
details = ""
highestHourList = []
highest = self.__vList[0].getHourContribution()
for volunteer in self.__vList:
hour = volunteer.getHourContribution()
if hour == highest:
highestHourList.append(hour)
elif hour > highest:
highestHourList = [hour]
highest = hour
#highestHourList.append(hour)
if volunteer.getType().lower() == "f":
details = details + "{} - {} years old - flood volunteer".format(volunteer.getName(), volunteer.getAge()) + "\n"
elif volunteer.getType().lower() == "p":
details = details + "{} - {} years old - pandemic volunteer".format(volunteer.getName(), volunteer.getAge()) + "\n"
elif volunteer.getType().lower() == "e":
details = details + "{} - {} years old - earthquake volunteer".format(volunteer.getName(), volunteer.getAge()) + "\n"
elif volunteer.getType().lower() == "t":
details = details + "{} - {} years old - tsunami volunteer".format(volunteer.getName(), volunteer.getAge()) + "\n"
return details
def main ():
groupName = input("Enter your group name: ")
newGroup = volunteerList(groupName)
print ("\n")
choice = menu()
while choice != "0":
if choice == "1":
name = input("Name of volunteer? ")
age = int(input("Age? "))
volunteerType = input("Type of volunteer ('F/P/E/T'): ")
volunteerType = volunteerType.lower()
while volunteerType not in "fpet":
print ("Invalid type! Please enter again!")
volunteerType = input("Type of volunteer ('F/P/E/T'): ")
volunteerType = volunteerType.lower()
hourCont = int(input("Contribution hour? "))
while hourCont <= 0:
print ("Invalid value! Please enter again!")
hourCont = int(input("Contribution hour? "))
newGroup.addVolunteer(volunteer(name, age, volunteerType, hourCont))
print ("... Volunteer has been added successfully.")
print ("\n")
choice = menu()
elif choice == "6":
print ("Volunteer with highest contribution hour:")
print (newGroup.highestHour())
print ("\n)
I'm not sure the code on highestHour() correct or wrong. I was planning to find the highest hour of the volunteer(s). If there are more than 1 highest hour of volunteer (same hour), display everything. My output was only one highest hour of volunteer or display 2 same line of statement instead of the example before.
Wondering how to display all volunteer that are highest hour?
The display sample will be:
a - 36 years old - pandemic volunteer
b - 25 years old - flood volunteer
Here you go:
class volunteer:
def __init__ (self, name, age, type, hourContribution):
self.__name = name
self.__age = age
self.__type = type
self.__hourContribution = hourContribution
def getHourContribution (self):
return self.__hourContribution
class volunteerList:
def __init__ (self, groupName):
self.vList = []
self.__groupName = groupName
def highestHour (self):
highHourList = []
hourList = []
for volunteer in self.vList:
hourList.append(volunteer.getHourContribution())
highest = max(hourList)
for hour in hourList:
if hour == highest:
highHourList.append(hour)
print(highHourList)
new = volunteerList("one")
vol1 = volunteer("", 1, "", 5)
vol2 = volunteer("", 1, "", 10)
vol3 = volunteer("", 1, "", 10)
vol4 = volunteer("", 1, "", 10)
vol5 = volunteer("", 1, "", 1)
new.vList = [vol1, vol2, vol3, vol4, vol5]
new.highestHour()
Alternative highestHour function
def highestHour (self):
highHourList = []
largest = self.vList[0].getHourContribution()
for volunteer in self.vList:
hour = volunteer.getHourContribution()
if hour == largest:
highHourList.append(hour)
elif hour > largest:
highHourList = [hour]
largest = hour
print(highHourList)
Needs some cleaning up, but you get the idea.

Increase the first 15 digits of a 16 digit number by 1 within a range

Background
I am trying to ensure I am generating a unique credit card number. The credit card number needs to be 16 digits long with the last digit equal to the checksum which in this case is self.checksum = 1.
The first 6 digits of the credit card number must be 400000.
Since the last digit must be equal to the checksum or 1 in this case, I believe I need to implement a range in my code somehow to indicate when the maximum credit card number has been issued. In this case, the maximum credit card number is 40000009999999991. Anything after that would change the first 6 digits.
While the current solution "works" it does so by only adding 10 to the first possible credit card number initialized in the __init__ as self.credit_card_number = 4000000000000001.
Help needed
I am looking for help taking my existing code and implementing a range of some sort that can alert when the last credit card number in the range has been issued.
from random import randrange
class Accounts:
def __init__(self):
self.accounts_list = []
self.all_accounts = dict()
self.balance = 0
# Initial credit card number
self.credit_card_number = 4000000000000001
# Checksum is the last digit (16th) in the credit card number.
self.checksum = 1
# Pin number is generated in account_creation
self.pin = None
def main_menu(self):
while True:
main_menu_choice = input('1. Create an account\n'
'2. Log into account\n'
'0. Exit\n')
if main_menu_choice == '1':
self.account_creation()
def account_creation(self):
# Create credit card number ensuring it is unique by adding 1 to initialized value.
if len(self.accounts_list) == 0:
self.credit_card_number = self.credit_card_number
else:
self.credit_card_number = self.credit_card_number
self.credit_card_number = self.credit_card_number + 10
# Create pin number.
pin = int(format(randrange(0000, 9999), '04d'))
# Add credit card number to list used in the above if statement.
self.accounts_list.append(self.credit_card_number)
# Add the credit card number, pin, and balance to dictionary.
self.all_accounts[self.credit_card_number] = {'pin': pin, 'balance': self.balance}
# Print the output to make sure everything is OK.
print(self.accounts_list)
# Print the output to make sure everything is OK.
print(self.all_accounts)
print(f'\n'
f'Your card has been created\n'
f'Your card number:\n'
f'{self.credit_card_number}\n'
f'Your card PIN:\n'
f'{pin}'
f'\n')
Accounts().main_menu()
Can you update your init to generate credit cards:
def __init__(self):
# do you stuff
self.credit_card_first_6 = '400000'
self.checksum = '1'
# this will be used to create a unique credit card
self.count = 0
# middle numbers MUST be smaller than this
self.max_count = 1000000000
def account_creation(self):
#### do your stuff
# for this user they have a unique 9 digits in the middle
# this is then zero padded using zfill
unique_id = str(self.count).zfill(9)
# create the full credit card number
# note: store each bit as a str so we can concat then convert to int
credit_card_number = int(self.credit_card_first_6 + unique_id + checksum)
self.count += 1
# update your init values when your limit is reached
if self.count >= self.max_count:
self.count = 0
self.credit_card_first_6 = str(int(self.credit_card_first_6) + 1)
Since you marked Matt's answer as a valid I've added a quick refactor with some extra code that might be use full to you.
class Account:
balance = 0
__pin = None # this are
__number = None # private members
def __eq__(self, other):
return self.__number == other
def is_pin(self, pin):
return self.__pin == pin
def number(self):
return self.__number
# adding a 'is not none' makes
# it a 'write only once' variable,
# if a 'none' text is added as a input
# text is added not a None type
def set_pin(self, pin):
if self.__pin is None:
self.__pin = pin
return True
return False
def set_number(self, num):
if self.__number is None \
and len(str(num)) == 16:
self.__number = num
return True
return False
# eeextra simple checksum
def checksum(self):
ck_sum = 0
for i in str(self.__number):
ck_sum += int(i)
return int(str(ck_sum)[-1])
class Accounts:
base_num = 4000000000000000
def __init__(self):
self.accounts = []
self.num_offset = 0
#staticmethod
def dialog_choice():
choice = input(
'1. Create an account\n'
'2. Log into account\n'
'0. Exit \n \n'
)
return choice
def next_card_num(self):
self.num_offset += 1
return self.base_num + self.num_offset
def dialog_acount_creation(self):
card_pin = input('New pin ->')
card_num = self.next_card_num()
print('Card number ->', card_num)
return card_num, card_pin
#staticmethod
def dialog_login():
card_num = input('Card number ->')
card_pin = input('Card pin ->')
return int(card_num), card_pin
#staticmethod
def dialog_error(*args):
print('Error on acount', args[0])
def main_loop(self):
dia_map = {
'1': self.dialog_acount_creation,
'2': self.dialog_login,
}
cho_map = {
'1': self.account_creation,
'2': self.account_login,
}
err_map = {
'1': self.dialog_error,
'2': self.dialog_error,
}
while True:
o = self.dialog_choice()
if o == '0':
break
if o in cho_map:
q_dialog = dia_map[o]()
q_done = cho_map[o](*q_dialog)
if not q_done:
err_map[o](*q_dialog)
else:
print('Invalid option')
def account_login(self, num, pin):
for acc in self.accounts:
if acc == num and acc.is_pin(pin):
print('You are logged in !')
return True
return False
def account_creation(self, num, pin):
new_accaunt = Account()
new_accaunt.set_number(num)
new_accaunt.set_pin(pin)
self.accounts.append(new_accaunt)
return True
if __name__ == '__main__':
h_acc = Accounts()
h_acc.account_creation(4000000000000000, '1234')
h_acc.main_loop()

Outputting only the objects with "readas" false

Using my current setup on my code; how do i output only the False objects ("hasBeenRead = False")
#An SMS Simulation
SMSStore = []
unreadMessage = []
class SMSMessage(object):
def __init__(self, messageText, fromNumber):
self.hasBeenRead = False
self.messageText = messageText
self.fromNumber = fromNumber
def markAsRead(self, hasBeenRead):
hasBeenRead = True
def add_sms(self):
newMessage = (self.hasBeenRead, self.messageText, self.fromNumber)
return SMSStore.append(newMessage)
def get_count(self):
return len(SMSStore)
def get_message(self, q):
print (SMSStore[q][1])
self.get_hasBeenRead()
def get_hasBeenRead(self):
self.hasBeenRead = True
def get_unread_messages(SMSStore):
counter = 0
if SMSStore[counter][0] == False:
print "From: " + SMSStore[counter][2]
print "Message: " + SMSStore[counter][1]
counter = counter +1
def remove(self, i):
return SMSStore.remove(i)
#sample = SMSMessage("Hello friend!", 0742017560)
userChoice = ""
while userChoice != "quit":
userChoice = raw_input("What would you like to do - read/send/quit?")
if userChoice == "read":
i = int((raw_input("Please enter which messsage number you want to read: ")))
messageText = "null"
fromNumber = "null"
newObject1 = SMSMessage(messageText, fromNumber)
newObject1.get_message(i)
readUnread = raw_input("Would you like to read the unread messages: yes/no?")
if readUnread == "yes":
newObject1.get_unread_messages()
else:
print "All messages have been read"
elif userChoice == "send":
messageText = raw_input("Please type in your message: ")
fromNumber = raw_input("Please type in the number it was sent from ")
newObject = SMSMessage(messageText, fromNumber)
newObject.add_sms()
print str(newObject.get_count()) + " is now the new length of the list"
elif userChoice == "quit":
print "Goodbye"
else:
print "Oops - incorrect input"
As you can see i am quiet a beginner at coding but using what i have setup is it possible to only output objects from the list that have False?

Trouble understanding with getting a unique instantiation in Python

I have an employee class which has an init method that reads an employees record in from a file. I also have an employees class which has an init_ method that attempts to read in all of the employee records.
I am having trouble with init for the employees class. Here is my code:
class EmployeeList():
records=[]
def __init__(self):
with open(database) as fp:
emp=employee(fp)
while (emp.id > 0):
print(emp)
self.records.append(emp)
emp=employee(fp)
The print(emp) is there for error checking, it shows that the records are being read in properly. When the EOF is reached, the init method for the employee sets the id to 0 and the name of the employee to "". I have two problems:
After the loop, all of the employees in employees.records are the same - id 0 and blanks for names. I am assuming that that emp is not creating a new instance each time it is called, and so all of the employees are being set to that one instance of emp, the very last one from when EOF is reached.
I doubt my code is "Pythonesque"; suggestions for improvement are welcome.
P.S. database is globally defined to the file name.
The entire code is here, sorry about the length:
class employee:
count = 0
def __init__(self,f=None):
if (f==None): # a user is inputting the employee
self.lastname = input("Employees last name:")
while type(self.lastname)!=type("1"):
print("Your input needs to be a name\n")
self.lastname = input("Employees last name:")
self.firstname = input("Employees first name:")
while type(self.firstname)!=type("1"):
print("Your input needs to be a name\n")
self.firstname = input("Employees first name:")
self.payrate = float(input("Employees pay rate:"))
while type(self.payrate)!=type(0.0):
print("Your input needs to be a pay rate\n")
self.payrate = float(input("Employees pay rate:"))
employee.count = employee.count + 1
self.id = employee.count
else: # the employee is being read in from the database and f is a file pointer
# read in an employee record and return false for end of file.
checkEOF = f.readline().rstrip('\r\n') #check for end of file
if (checkEOF != ""):
employee.id = int(checkEOF)
employee.firstname = f.readline().rstrip('\r\n')
employee.lastname = f.readline().rstrip('\r\n')
employee.payrate = float(f.readline().rstrip('\r\n'))
else:
employee.id = 0
employee.firstname = " "
employee.lastname = " "
employee.payrate = 0.0
def __hash__(self):
return hash(self.id)
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.id == other.id
return NotImplemented
def __str__(self):
return "Employee " + str(self.id) + " is "+self.firstname + " "+self.lastname+" and their pay rate is "+str(self.payrate)+"\n"
def __lt__(self, other):
if (self.lastname < other.lastname):
return True
elif (self.lastname > other.lastname):
return False
else: #same last names
if (self.firstname < other.firstname):
return True
elif (self.firstname > other.firstname):
return False
else: #same names
if (self.id < other.id):
return True
else: # note that ids cannot be the same
return False
def __gt__(self, other):
if (self.lastname > other.lastname):
return True
elif (self.lastname < other.lastname):
return False
else: # Same last names
if (self.firstname > other.firstname):
return True
elif (self.firstname > other.firstname):
return False
else: # Same names
if (self.id > other.id):
return True
else: # note that ids cannot be the same
return False
def payraise(self,payraise):
self.payrate = self.payrate+payraise
def saveemployee(self,fp):
fp.write(str(self.id)+"\n")
fp.write(self.firstname+"\n")
fp.write(self.lastname+"\n")
fp.write(str(self.payrate)+"\n")
class EmployeeList():
records=[]
def __init__(self):
with open(database) as fp:
emp=employee(fp)
while (emp.id > 0):
print(emp)
self.records.append(emp)
emp=employee(fp)
def __str__(self):
employeesprint = ""
for emp in self.records:
employeesprint = employeesprint + str(emp)
return employeesprint
def save(self):
self.records.sort()
with open(database,"w+") as fp:
fp.seek(0)
for emp in self.records:
emp.saveemployee(fp)
def menu():
print("\n")
print(choices[0]+". Add another employee")
print(choices[1]+". Print employees")
print(choices[len(choices)-1]+". Quit")
print("\n")
employees = EmployeeList()
choices = ["A","B","C"]
ch = "N"
while (ch != choices[len(choices)-1]):
menu()
ch=input("Make your choice ")
while not (ch in choices):
menu()
ch=input("Make your choice ")
if (ch == choices[0]):
employees.records.append(employee())
employees.save()
if (ch == choices[1]):
print(employees)
Sample output: You can see the two employees correctly being printed as they are read in:
Employee 1 is jane bob and their pay rate is 1.0
Employee 2 is jim bob and their pay rate is 3.4
A. Add another employee
B. Print employees
C. Quit
Make your choice B
Employee 0 is and their pay rate is 0.0
Employee 0 is and their pay rate is 0.0
your code:
if (checkEOF != ""):
employee.id = int(checkEOF)
employee.firstname = f.readline().rstrip('\r\n')
employee.lastname = f.readline().rstrip('\r\n')
employee.payrate = float(f.readline().rstrip('\r\n'))
else:
employee.id = 0
employee.firstname = " "
employee.lastname = " "
employee.payrate = 0.0
change 'employee' to 'self', 'employee' is the name of the class.

How to get user inputs into python database?

Why the menu does not start (solved by Roman Susi)
Why the menu do not work as expected (error below)
How do I solve the error in my foo.add code?
Traceback (most recent call last):
File "C:\Users\User\Desktop\phonedatabase.py", line 81, in <module>
openphonedb()
File "C:\Users\User\Desktop\phonedatabase.py", line 23, in openphonedb
for entry in foo.add(name, number, showtype):
TypeError: 'NoneType' object is not iterable
This error happens when adding a new user, after typing in the 'Type'
import shelve
import string
UNKNOWN = 0
HOME = 1
WORK = 2
FAX = 3
CELL = 4
def openphonedb():
foo = phonedb()
print "What would you like to do?"
print "Add = 1, Lookup = 2, Exit = 3"
entry = int(raw_input('>> '))
if entry == 1 :
namelookup = raw_input('Please enter a name: ')
for entry in foo.lookup(namelookup):
print '%-40s %s (%s)' % (entry.name, entry.number, entry.showtype() )
elif entry == 2:
name = raw_input('Name: ')
number = raw_input('Number: ')
showtype = input('Type (UNKNOWN, HOME, WORK, FAX, CELL): \n>> ')
for entry in foo.add(name, number, showtype):
print '%-40s %s (%s)'% (entry.name, entry.number, entry.showtype() )
elif entry == 3:
print "Close Successful"
quit
else:
print "Invalid."
openphonedb()
class phoneentry:
def __init__(self, name = 'Unknown', number = 'Unknown',
type = UNKNOWN):
self.name = name
self.number = number
self.type = type
# create string representation
def __repr__(self):
return('%s:%d' % ( self.name, self.type ))
# fuzzy compare or two items
def __cmp__(self, that):
this = string.lower(str(self))
that = string.lower(that)
if string.find(this, that) >= 0:
return(0)
return(cmp(this, that))
def showtype(self):
if self.type == UNKNOWN: return('Unknown')
if self.type == HOME: return('Home')
if self.type == WORK: return('Work')
if self.type == FAX: return('Fax')
if self.type == CELL: return('Cellular')
class phonedb:
def __init__(self, dbname = 'phonedata'):
self.dbname = dbname;
self.shelve = shelve.open(self.dbname);
def __del__(self):
self.shelve.close()
self.shelve = None
def add(self, name, number, type = HOME):
e = phoneentry(name, number, type)
self.shelve[str(e)] = e
def lookup(self, string):
list = []
for key in self.shelve.keys():
e = self.shelve[key]
if cmp(e, string) == 0:
list.append(e)
return(list)
#edit
if __name__ == '__main__':
openphonedb()
Maybe, you just forgot to call the openphonedb()?
Add to the end:
if __name__ == '__main__':
openphonedb()
Also, what "quit" is doing there?
code has other issues, but with regard to the first part of the question, what about comparing entry as a string (so if an user types "a" you don't get an error)?
def openphonedb():
foo = phonedb()
print "What would you like to do?"
print "Add = 1, Lookup = 2, Exit = 3"
while True: # note this
entry = raw_input('>> ') # removed int()
if entry == '1' :
namelookup = raw_input('Please enter a name: ')
for entry in foo.lookup(namelookup):
print '%-40s %s (%s)' % (entry.name, entry.number, entry.showtype() )
elif entry == '2':
name = raw_input('Name: ')
number = raw_input('Number: ')
showtype = input('Type (UNKNOWN, HOME, WORK, FAX, CELL): \n>> ')
for entry in foo.add(name, number, showtype):
print '%-40s %s (%s)'% (entry.name, entry.number, entry.showtype() )
elif entry == '3':
print "Close Successful"
exit() # note this also
else:
print "Invalid."

Categories