views:

61

answers:

2

I have opened a shelve using the following code:

#!/usr/bin/python
import shelve                   #Module:Shelve is imported to achieve persistence

Accounts = 0
Victor = {'Name':'Victor Hughes','Email':'[email protected]','Deposit':65000,'Accno':'SA456178','Acctype':'Savings'}
Beverly = {'Name':'Beverly Dsilva','Email':'[email protected]','Deposit':23000,'Accno':'CA432178','Acctype':'Current'}

def open_shelf(name='shelfile.shl'):
    global Accounts
    Accounts = shelve.open(name)          #Accounts = {}
    Accounts['Beverly']= Beverly    
    Accounts['Victor']= Victor


def close_shelf():
    Accounts.close()

I am able to append values to the shelve but unable to modify the values. I have defined a function Deposit() from which I would like to modify the data present in the shelve.But it gives me the following error:

Traceback (most recent call last):
  File "./functest.py", line 16, in <module>
    Deposit()
  File "/home/pavitar/Software-Development/Python/Banking/Snippets/Depositfunc.py", line 18, in Deposit
    for key in Accounts:
TypeError: 'int' object is not iterable

Here is my Function:

#!/usr/bin/python

import os                       #This module is imported so as to use clear function in the while-loop
from DB import *                       #Imports the data from database DB.py

def Deposit():
        while True:
                os.system("clear")              #Clears the screen once the loop is re-invoked
                input = raw_input('\nEnter the A/c type: ')
                flag=0
                for key in Accounts:
                        if Accounts[key]['Acctype'].find(input) != -1:
                                amt = input('\nAmount of Deposit: ')
                                flag+=1
                                Accounts[key]['Deposit'] += amt

                if flag == 0:
                        print "NO such Account!"    

if __name__ == '__main__':
        open_shelf()
        Deposit()
        close_shelf()

I'm new to Python.Please help.Correct me if I'm wrong.I need someone to give a little bit of explanation as to the functioning of this code.I'm confused.

+3  A: 

I think you'd have more luck like this:

for key, val in Accounts.iteritems():
    if val['Acctype'].find(input) != -1:
        amt = input('\nAmount of Deposit: ')
        flag+=1
        val['Deposit'] += amt
        Accounts[key] = val
hughdbrown
@Pavitar : This should work for you.
pyfunc
The pattern here is grab the entire shelved item, mutate it, write it back.
Steven Rumbalski
Traceback (most recent call last): File "./Depositfunc.py", line 26, in <module> Deposit() File "./Depositfunc.py", line 12, in Deposit for key, val in Accounts.iteritems():AttributeError: 'int' object has no attribute 'iteritems' This is the error I got,when I tried the code.I may be wrong in calling it.Is rest of my code ok?I mean the dictionary created and the function call?
Pavitar
It sounds like you are calling `Deposit()` while `Accounts==0`. That suggests that `Deposit()` is either working on `Accounts` before it is turned into a dictionary by the `open_shelf()` call or `Deposit()` is working on some other `Accounts` object.
hughdbrown
@Steven Rumbalski: yes, that's what I meant. Thanks.
hughdbrown
@hughdbrown -- Thank you.It served my purpose. :) +1
Pavitar
+1  A: 

Firstly, don't use a global for Accounts, rather pass it back and forth. Using the global caused your error. Like this:

def open_shelf(name='shelfile.shl'):
    Accounts = shelve.open(name)          #Accounts = {}
    ...
    return Accounts

def close_shelf(Accounts):
    Accounts.close()


def Deposit(Accounts):
    ...   

if __name__ == '__main__':
    Accounts = open_shelf()
    Deposit(Accounts)
    close_shelf(Accounts)

Secondly, don't redefine built-in functions. In Deposit(), you assign the result of raw_input to a variable named input:

input = raw_input('\nEnter the A/c type: ')

Four lines later, you try to use the built-in input function:

amt = input('\nAmount of Deposit: ')

But that won't work because input has been redefined!

Thirdly, when iterating over shelved items, follow the pattern of 1) grab shelved item, 2) mutate item, 3) write mutated item back to shelf. Like so:

for key, acct in Accounts.iteritems():  # grab a shelved item
    if val['Acctype'].find(input) != -1:
        amt = input('\nAmount of Deposit: ')
        flag+=1
        acct['Deposit'] += amt          # mutate the item
        Accounts[key] = acct            # write item back to shelf

(This third bit of advice was tweaked from hughdbrown's answer.)

Steven Rumbalski
@Steven Rumbalski-- Thank you.It served my purpose :) +1
Pavitar