Search code examples
pythonloopsfile-handling

Loop Not Functioning well


Guys i'v got a little problem with my code. The code is supposed to check a list of numbers and group them in a text file provider based but doesn't work as expected. It only saved a single number in a file for each provider instead of multiple ones. This is my code , if anyone could help i'd be grateful.Sorry if my code is too traditional

def main():
     dead = open('invalid_no.txt', 'a+')
     print('-------------------------------------------------------')
     print('-------------------------------------------------------')
     list = input('Your Phone Numbers List : ')

     base_url = "http://apilayer.net/api/validate"

     params = {
         'access_key': '3246123d1d67e385b1d9fa11d0e84959',
         'number': '',
               }

     numero = open(list, 'r')


     for num in numero:
         num = num.strip()
         if num:
             lines = num.split(':')
        
             params['number'] = lines[0]
        
             response = requests.get(base_url, params=params)
             
             print('status:', response.status_code)
             print('-------------------------------------')

             try:                 
                 resp = response.json()
                 print('number:', resp['valid'])
                 print('number:', resp['international_format'])
                 print('country:', resp['country_name'])
                 print('location:',resp['carrier'])
                 print('-------------------------------------')    
                 mok = open(resp['carrier'],'w+')      
                 if resp['carrier'] == mok.name:
                    mok.write(num +'\n')
             except FileNotFoundError:
                 if resp['carrier'] == '':
                    print('skipping')
                 else:
                    mok = open(resp['carrier'],'w+')
                    if resp['carrier'] == mok.name:
                     mok.write(num)
                    else:
                     print('No')
if __name__ == '__main__': main()

Solution

  • Opening a file with mode "w" will erase the existing file and start with an empty new one. That is why you are getting only one number. Every time you write to the file, you overwrite whatever was there before. There is no mode "w+". I believe that ought to cause a ValueError: invalid mode: 'w+', but in fact it seems to do the same as "w". The fact that "r+" exists doesn't mean you can infer that there is also an undocumented "w+".

    From the documentation for open():

    The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.

    So, no "w+".

    I think you want mode "a" for append. But if you do that, the first time your code tries to write to the file, it won't be there to append to, so you get the file not found error that you had a problem with.

    Before writing to the file, check to see if it is there. If not, open it for writing, otherwise open it for appending.

    if os.path.exists(resp['carrier']):
        mok = open(resp['carrier'],'a')
    else: 
        mok = open(resp['carrier'],'w')
    

    or, if you have a taste for one-liners,

    mok = open(resp['carrier'],'a' if os.path.exists(resp['carrier']) else 'w')
    

    Also your code never calls close() on the file after it is finished writing to it. It should. Forgetting it can result in missing data or other baffling behaviour.

    The best way not to forget it is to use a context manager:

    with open(resp['carrier'],'a' if os.path.exists(resp['carrier']) else 'w') as mok:
        # writes within the with-block here
    # rest of program here
    # after the with-block ends, the context manager closes the file for you.