0

I'm trying to create a program that duplicates itself to another location and creates a batch file on the desktop. I can make it duplicate itself and I can create the batch file but I need some help with the paths.

I can find the path that my program is currently in. Both the direct path and the path to the directory. My problem lies in the fact that I want to place the file in (let's just say for simplicity) 'C:\Users\Me\Documents'. How would I edit the path? I want to be able to place this on a generic windows computer so I can't hard code the path in because each user will be different. This goes the same for placing the batch file and setting it for the right directory to run the python script in documents.

I have tried both

import os print os.path.dirname(os.path.abspath(__file__))

and

import os print os.path.abspath(__file__)

but am clueless as to how to edit the path. When I try googling for it and searching this wonderful site, all I get is stuff about configuring the Python path on windows and other stuff that I can't quite understand at my current level of Python.

Now I turn to you, can you help? Any input would be appreciated, if you could explain how it worked that would be even better!

<>

Due to some questions about my code (and a specific one to post it) Here it is

from sys import argv            # Imports module
import os

script, create = argv           # Gets script name and desired amount of copies

data = open(script)             # Creates a variable to store the script

indata = copy.read()            # Creates the data to be copied from the script


batData = """
echo off
%s
""" %                           # This is not finished, creating that batch file

createT = int(create) + 1
for i in range(1, createT):     # Runs a set amount of times
    copyName = "%s.py" % str(i) # Creates the name for the file
    copy = open(copyName, 'w+') # Opens/creates the file for editing
    copy.write(indata)          # Writies the indata to the file opened
    copy.close                  # Closes that file

    batName = "%s.bat" % str(i)
    bat = open(batName, 'w+')

It is not finished but hopefully you get the gist. The argv at the beginning is so I can change the amount of copies made, that will be deleted later as I evolve the code but for now I like it there.

I have currently tried the following to find the path:

import os
print os.path.abspath(__file__)
print os.path.dirname(os.path.abspath(__file__))
print os.path.dirname(__file__)

test = os.path.dirname(__file__)

a, b, c, d, e, f, g, h, i = test.split("\\")

print c

What I want to happen (or think I want to happen) is for the path to be found, then split into pieces (either each directory or break off everything after the username). Then I want to append the document folder tag to the end. For the batch instead of the document tag it will be for the desktop.

among a few others that people have posted. I hope this helps!

0m3r
  • 12,286
  • 15
  • 35
  • 71
Jake T
  • 5
  • 1
  • 5
  • And where is the relation to the batch-file tag? – jeb Jul 10 '15 at 21:37
  • I'm using: `batName = "%s.bat" % str(i); bat = open(batName, 'w+')` to create the file. Does that help? – Jake T Jul 10 '15 at 21:45
  • What do you mean by "edit the path?" Do you want to provide an entry field for the user to type in the new path, or do you want to extract it from the command line, or compute it somehow? How do you determine what the new path will be? – Paul Cornelius Jul 10 '15 at 21:48
  • I want a way to edit what I can take from `os.path.dirname(os.path.abspath(__file__))` I want it to be automatic, so when the program runs there is no need for any input. – Jake T Jul 10 '15 at 21:52
  • Possible duplicate of http://stackoverflow.com/questions/6227590/finding-the-users-my-documents-path – Laogeodritt Jul 10 '15 at 21:59
  • 1
    @JakeT, you probably didn't find anything by searching because of your terminology—"editing the path" usually means changing the system PATH (the OS's or Python's). In your specific situation, see the question I linked above; in general you can use the os.path methods—for example, you can use `os.path.dirname()` to go backwards one directory. The path is just a string, so you can add on path components by string concatenation (`... + '/build'`). Then you can pass that to `open()`, `os.chdir()`, etc., depending on what you want to do. – Laogeodritt Jul 10 '15 at 22:03
  • Apologies for that, I just checked it out but I can't seem to make sense of it. – Jake T Jul 10 '15 at 22:04
  • That is helpful. I will try to work with that right now. Let's hope it works – Jake T Jul 10 '15 at 22:05
  • I tried to use that until I already realized I was already using `os.path.dirname()`, how would I make it go back a directory? More specifically, how could I get it to stop before going into the 'Users' directory? – Jake T Jul 10 '15 at 22:21
  • I agree with @Laogeodritt, searching the words 'Python' and 'path' is not going to get you what you want. Try searching 'splitting file path' or 'creating file path'. – nalyd88 Jul 10 '15 at 22:23
  • @JakeT Suppose you have a path in the variable `file_path`. To go back a directory, `os.path.dirname(file_path)`. You can chain `os.path.dirname` multiple times to go back several directories. Use `os.path.split` to get the name of the last part of the path (e.g. `dir` in `/path/to/dir`) if you need to inspect it. However, to get the user's home directory, please see the other question I linked earlier—that is the correct way of doing it. (You can then use `os.path.isdir` to check if either `home_directory + "/My Documents"` or `home_directory + "/Documents"` exists). – Laogeodritt Jul 10 '15 at 22:29
  • I will try to understand the linked question but I fear that I won't understand it. If I were to do that repeated `os.path.dirname` , would I be able to stop it once it got down to the bottom three (the ones I care about)? Say using a looping statement that would keep stripping directories and checking to make sure that three weren't left? Once three were left it would return a true statement? Is there someway to test if it can be split into three and if not return false? – Jake T Jul 10 '15 at 22:47
  • @Laogeodritt Many thanks to you! It took some (okay a bit more than that) experimentation but I got it working (I think). Thank you! – Jake T Jul 10 '15 at 23:00
  • @JakeT - if one of the answers below helped you, please click the check mark next to the answer. – SomethingDark Jul 11 '15 at 06:50

3 Answers3

1

Your code snippet returns a string. Just take that string and edit to make the path you want. I'm on a mac so I can't test with an actual windows directory but I'll try to make it look Windows-ish. For instance, lets say this code:

directory_path = os.path.dirname(os.path.abspath(__file__))
print(directory_path)

gives you:

C:\Users\username\AppData

You can use the split function to break the path into pieces (docs).

stuff = path_string.split('\')
print(stuff)

Code output:

['C:', 'Users', 'username', 'AppData']

You can use the pieces create the path you want and then use it to write the file. So, if you want the username folder just loop until you find it. Some example code is below (just an example to get you started - read up on Python if you need help understanding the code).

username = ""
for i in range(0, len(stuff)):
    if stuff[i] == "Users":
        username = stuff[i + 1]

Not sure if that answers your question but hope it helps.

nalyd88
  • 4,940
  • 8
  • 35
  • 51
  • Thank you! I will try to use this as well, hopefully one of them will work, haha. – Jake T Jul 10 '15 at 22:06
  • I tried using the split function but am running into trouble when I need to specify a specific amount of values to unpack. I want to be able to run this from anywhere so I can't guess the values. This is on my thinking of splitting them up into parts of a, b, and c. a being the disk, b being users and c being the current user of the program. How can do this without encountering the ' need more than (random number) values to unpack? – Jake T Jul 10 '15 at 22:19
  • I'm not quite sure I understand when you are trying to do. Please post some more info, like code you are trying, possible inputs, and what you want the output to look like given a specific input. – nalyd88 Jul 10 '15 at 22:24
  • Also, it looks like you are new here. Welcome. Please try to give as much detail as you can and consider up-voting helpful comments, questions, and answers you find here. – nalyd88 Jul 10 '15 at 22:25
  • Thanks for noticing! I uploaded the code.. Now that I think about It all add some pseudo code of what I want to happen, thanks for the input. – Jake T Jul 10 '15 at 22:39
0

Am I correct that you are trying to figure out how to make a file path to some location on the user's directory without knowing who the user is going to be that is executing the program?

You may be able to take advantage of environment variables for this. For instance, I can get a file path to the C://Users/username/ directory of whoever is executing the code with:

my_path = os.path.join("C:\\", "Users", os.getenv("USERNAME"))

Where os.getenv("USERNAME") returns the value of the USERNAME environment variable (should be the name of the user that is currently logged on).

You can list all of the available environment variables and their values in Python with:

for key, val in os.environ.items():
  print("{} \t {}\n".format(key, val))  # or however you want to prettify it

You may get lucky and find an environment variable that gives you most of the path to begin with.

In general, os.path.join(), os.path.relpath(), and os.path.abspath() combined with some environment variables might be able to help you. Check out the os documentation and os.path documentation.

Engineero
  • 12,340
  • 5
  • 53
  • 75
0

Many times when modifying a path, I am looking to add/remove folders. Here is my simple method for adding a path, e.g. if I want to move the path of an object into a folder added_path='/train/.

Since my paths are usually uniform, I check the last split characters in the first file location. Usually, my experience is that windows have \\ at the end while Mac and Linux have `/', which makes this work across operating systems. (note: if the paths are not uniform, you obviously place the if-else in the for-loop.)

if '\\' in data[0].img_file:
    split_char = '\\'
else:
    split_char = '/'

for img in data:
    img_path = img.img_file.split(split_char)
    label_path = img.label_file.split(split_char)
    img.img_file = '/'.join(img_path[:-1]) + added_path  + img_path[-1]
    img.label_file = '/'.join(label_path[:-1]) + added_path  + label_path[-1]

So, this for loop uses all the folders up until the file name, where we insert the extra folder, and then, at last, add the file name.

Example input path: 'data/combined/18.png'

Example output path: 'data/combined/train/18.png'

Casper Hansen
  • 443
  • 3
  • 10