0

So first off I'm a complete newb at Python so sorry if my code is horrible. This is just for a proof of concept, the actual code doesn't really matter, just the function.

So I'm trying to create a directory by specifying a name for it. I want the program to check if a directory with that name already exists and if it does, ask for a new name and create that directory. The checking bit works fine, but when it loops around to ask for a different name it seems to be storing the original one (the duplicate), which then overwrites the new name when it gets returned. This means I keep getting the old directory name returned instead of the new one (hope that makes sense?)

def casefile():
    print '\n\nPlease enter a case name/reference: '
    case_name = raw_input()
    if not os.path.exists('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name)):
        os.mkdir('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name))
        print '\n{} case file created. All logs will be saved to C:\Users\laura17\Documents\ProgrammeOutput\{}' \
            .format(case_name, case_name)
    else:
        print '\n**Case already exists. Please choose a different case name.**'
        casefile()
    return case_name

As an example, I printed out case_name just before the return function to see what was happening:

def casefile():
    print '\n\nPlease enter a case name/reference: '
    case_name = raw_input()
    if not os.path.exists('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name)):
        os.mkdir('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name))
        print '\n{} case file created. All logs will be saved to C:\Users\laura17\Documents\ProgrammeOutput\{}' \
            .format(case_name, case_name)
    else:
        print '\n**Case already exists. Please choose a different case name.**'
        casefile()
    print case_name
    return case_name

And this was the output: Output with print case_name

Any help would be much appreciated. Thank you.

ilim
  • 4,477
  • 7
  • 27
  • 46
elarinya17
  • 57
  • 3
  • 8
  • You might also want to take a look here regarding file paths: https://stackoverflow.com/questions/13944387/why-use-os-path-join-over-string-concatenation – Simon Apr 21 '18 at 01:37

3 Answers3

1

Problem

When you are calling the function recursively, you are not returning from the previously called function.

What happens is, when you call the casefile first time and enter an existing name i.e Case1, an entry is created in the stack for it. Lets call it casefile{1}. At the line casefile() in the else statement, the function will be called recursively.

Now, due to this recursive call, another entry for the function is created in the stack. Lets call this casefile{2}. Now the controlled would be passed to this function, but note that casefile{1} has not yet run its course - you have not returned from it.

So now the control is at casefile{2}. This time you enter a non-existing name i.e Case2. The casefile{2} does not go to the else branch and thus no more recursive calls would be made. So not it prints the name just like you asked it to (which in the scope of casefile{2} happens to be Case2, and returns the name.

But now the control goes back to casefile{1}, which will now exit the else statement and run the next line: print case_name, which for the scope of casefile{1} happens to be Case1. So it prints it and returns.

Solution

You should return after calling the function recursively. Please change the code to this:

def casefile():
    print '\n\nPlease enter a case name/reference: '
    case_name = raw_input()
    if not os.path.exists('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name)):
        os.mkdir('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name))
        print '\n{} case file created. All logs will be saved to C:\Users\laura17\Documents\ProgrammeOutput\{}' \
            .format(case_name, case_name)
    else:
        print '\n**Case already exists. Please choose a different case name.**'
        return casefile()
    print case_name
    return case_name

Please note that i have changed the line casefile() in the else statement to return casefile().

This would only print/return the name being passed to it by its recursively called functions.

Hope this helps. Cheers!

Danny
  • 691
  • 4
  • 6
  • Thank you so much!! This totally solved my problem! And thank you as well for the detailed explanation, this will help me when I'm having to explain to people why my code is how it is! Thank you so so much. – elarinya17 Apr 21 '18 at 17:05
0

What your code goes into recursion hence it returns both names. The following code first tries to make directory with the given name, if it cannot it will ask for another input till it is able to create one. Finally, it returns the name of the directory which is created. For python 2 please use raw_input() and for python 3, input().

Hope this helps!

import os

def casefile(path):
    while(True):
        try :
            # raw_input() for python 2
            case_name = input("Enter the case: ") # for python 3
            os.makedirs(path+case_name)
            return (case_name)
        except:
            pass

Open this to see output of my terminal

  • As written your code DOES-NOT-WORK. I would down vote you but you're at 1 point so you have nothing to lose and I would lose 2 points. You need to provide workable solutions/examples. – Michael Swartz Apr 21 '18 at 02:09
  • @MichaelSwartz It DOES WORK on my terminal. I have added a snapshot of my terminal. I am new here so I guess I messed up with indentation in the above code but this is just for reference and not for copy and paste. – Jasmeen Patel Apr 21 '18 at 03:25
  • Users will copy and paste your code to see if it works. The whole point of posting a solution is to post a working solution, not a theoretical solution. And if your code doesn't work it might get down voted. The problem with your code is that you have an infinite loop. See if you can find it. – Michael Swartz Apr 21 '18 at 03:28
  • I know I have created an infinite loop and its because i have passed True in while loop but the function won't run for infinite time if it can create directory. The original question states that user wants to check for any duplicate directory. The while loop ensures that it should keep on ask for new input until it is able to create the directory. The loop does not run forever you can see it in my output. – Jasmeen Patel Apr 21 '18 at 03:38
-1

Use os.makedirs to create directory, use try except to catch any error.

In [11]: import os

In [12]: try:
    ...:     os.makedirs('/Users/abc/projects')
    ...: except OSError:
    ...:     print('Already exists')
    ...: else:
    ...:     print('Directory created')
    ...:
Already exists
Nishant Nawarkhede
  • 8,234
  • 12
  • 59
  • 81
  • Don't just blurt out code! Adding some text to explain how this best answers the question will improve the long-term value of the answer and help to prevent it from being deleted during review. – IvanH Apr 21 '18 at 11:33