I'm trying to make a simple script which takes a list of names off the clipboard formatted as "Last, First", then pastes them back as "First Last". I'm using Python 3 and Pyperclip.
Here is the code:
import pyperclip
text = pyperclip.paste()
lines = text.split('\n')
for i in range(len(lines)):
last, first = lines[i].split(', ')
lines[i] = first + " " + last
text = '\n'.join(lines)
pyperclip.copy(text)
When I copy this to the clipboard:
Carter, Bob
Goodall, Jane
Then run the script, it produces: Bob CarterJane Goodall with the names just glued together and no new line. I'm not sure what's screwy.
Thanks for your help.
Apparently I need to use '\r\n' instead of just '\n'. I don't know exactly why this is but I found that answer on the internet and it worked.
To include newlines in your file, you need to explicitly pass them to the file methods.
On Unix platforms, strings passed into .write should end with \n. Likewise, each of
the strings in the sequence that is passed into to .writelines should end in \n. On
Windows, the newline string is \r\n.
To program in a cross platform manner, the linesep string found in the os module
defines the correct newline string for the platform:
>>> import os
>>> os.linesep # Unix platform
'\n'
Souce: Illustrated Guide to Python 3
Related
I have a problem with Python and need your help.
Take a look at this code:
import os
os.chdir('''C:\\Users\\Admin\\Desktop\\Automate_the_Boring_Stuff_onlimematerials_v.2\\automate_online-materials\\example.xlsx''')
The os.chdir() did not work because the directory I put in between the ''' and ''' is considered as raw string. Note that a line is no more than 125 characters, so I have to make a new line.
So how can I fix this?
You can split your statement into multiple lines by using the backslash \ to indicate that a statement is continued on the new line.
message = 'This message will not generate an error because \
it was split by using the backslash on your \
keyboard'
print(message)
Output
This message will not generate an error because it was split by using the backslash on your keyboard
Lines can be longer than 125 characters, but you should probably avoid that. You have a few solutions:
x = ('hi'
'there')
# x is now the string "hithere"
os.chdir('hi'
'there') # does a similar thing (os.chdir('hithere'))
You could also set up a variable:
root_path = "C:\\Users\\Admin\\Desktop"
filepath = "other\\directories" # why not just rename it though
os.chdir(os.path.join(root_path, filepath))
Do these work for you?
I'm also curious why you have to chdir there; if it's possible, you should just run the python script from that directory.
This is in Python 3.4.
I'm writing my first program for myself and I'm stuck at a certain part. I'm trying to rename all of my audio files according to its metadata in python. However, when I try to rename the files, it doesn't finish renaming it sometimes. I think it is due to an invalid character. The problem is that I don't know what character it is. To me, it looks like a space but it isn't.
My code is here:
from tinytag import TinyTag
import os
print("Type in the file directory of the songs you would like to rename and organize:")
directory = input()
os.chdir(directory)
file_list = os.listdir(directory)
for item in file_list:
tag = TinyTag.get(item)
title = str(tag.title)
artist = str(tag.artist)
if artist[-1] == "\t" or artist[-1] == " ":
print("Found it!")
new_title = artist + "-" + title + ".mp3"
#os.rename(item, new_title)
print(new_title)
This is the list that it outputs:
http://imgur.com/tfgBdMZ
It is supposed to output "Artist-Title.mp3" but sometimes it outputs "Artist -Title .mp3". When the space is there, python stops renaming it at that point. The first entry that does so is Arethra Franklin. It simply names the file Arethra Franklin rather than Arethra Franklin-Dr.Feelgood.mp3
Why does it do this? My main question is what is that space? I tried setting up a == boolean to see if it is a space (" ") but it isn't.
It ends the renaming by stopping once it hits that "space". It doesn't when it hits a normal space however.
It's possible that the filename has some unicode in it. If all you are looking for is a file renamer, you could use str.encode and handle the errors by replacing them with a ? character. As an example:
# -*- coding: utf-8 -*-
funky_name = u"best_song_ever_пустынных.mp3"
print (funky_name)
print (funky_name.encode('ascii','replace'))
This gives:
best_song_ever_пустынных.mp3
best_song_ever_?????????.mp3
As mentioned in the comments, you can use ord to find out what the "offending space" really is.
I am using minidom parser to read the xml. The problem I am facing is that it is not reading end of line character when it is done reading the line. For example my xml file is something like :
<?xml version="1.0" ?><ItemGroup>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">setlocal
C:\Tools\CMake2.8\bin\cmake.exe C:/tb/Source/../</Command>
</ItemGroup>
and my python code looks something like :
dom = xml.dom.minidom.parse(fileFullPath)
nodes = dom.getElementsByTagName('Command')
for j in range(len(nodes)):#{
path = nodes[j].childNodes[0].nodeValue
if nodeName == 'Command':#{
pathList = path.split(' ')
for i in range(len(pathList)):#{
sPath = pathList[i]
if sPath.find('\\n')!=-1:
print 'sPath has \\n'
#}
#}
#}
(Please ignore/point out any indentation errors)
now even though setlocal and C:\Tools\CMake2.8\bin\cmake.exe have a newline character in between them in the xml file, my code is not able to read it and I don't know why. Can somebody help ?
update :
I am trying to split the <Command> into ['setlocal', 'C:\Tools\CMake2.8\bin\cmake.exe', 'C:/tb/Source/../']
Another possibility, considering line separators independently of
the particular OS, might be the following, using the in operator
and os.linesep. I also tried this code using '\n' (without escaping
the backslash) instead of os.linesep. Both versions worked.
(My shell didn't take running xml.dom.minidom.parse(...), therefore
there are some changes in the imports you may ignore.)
from xml.dom.minidom import parse
import os
dom = parse(fileFullPath)
nodes = dom.getElementsByTagName('Command')
for node in nodes:
path = node.childNodes[0].nodeValue
if node.nodeName == 'Command':
for path in path.split(' '):
if os.linesep in path:
print r'Path contains \n or whatever your OS uses.'
I also left ' ' inside the split, as it seems that having setlocal in your list of paths
is not your aim.
EDIT:
After I noticed your comment stating that you actually want to have setlocal in your
list, I would also say that checking for \n is redundant, because splitting
by all whitespaces of course also considers line separators as whitespaces.
'a\nb'.split()
gives
['a', 'b']
Instead of splitting the text value on a space (' '), you want to split it on all white space and since these look like command lines, they should be split using a proper parser. You want to change:
pathList = path.split(' ')
for i in range(len(pathList)):#{
sPath = pathList[i]
if sPath.find('\\n')!=-1:
print 'sPath has \\n'
To:
import shlex
pathList = shlex.split(path, posix=False)
This will give you:
['setlocal', 'C:\\Tools\\CMake2.8\\bin\\cmake.exe', 'C:/tb/Source/../']
NOTE: If any of your paths contain spaces and are not properly quoted, they will be split incorrectly. E.g., 'C:\\Program Files' would be split to ['C:\\Program', 'Files'] but '"C:\\Program Files"' will be split to ['C:\\Program Files'].
Also, your code could use a little cleaning because Python is not C,
Javascript, etc.
import xml.dom.minidom
import shlex
dom = xml.dom.minidom.parse(fileFullPath)
nodes = dom.getElementsByTagName('Command')
for node in nodes:
path = node.childNodes[0].nodeValue
pathList = shlex.split(path, posix=False)
print pathList
I like to remove the empty line after my output:
#!/usr/bin/python
os.system("find /home/pi/bsp/musik/musik/ -name ""*.mp3"" | shuf -n 1 > /home/pi/bsp/musik/musik/track")
I get:
>>>cat track
/home/pi/bsp/musik/musik/2/Little Green Bag - George Baker Selection - Reservoir Dogs.mp3
But when I print the file in Python it's a different story:
>>>sudo python play.py
/home/pi/bsp/musik/musik/2/Lilly Allen - Fuck You.mp3
>>>>
...with a extra line in the end.
I like to pass a track to OMXPlayer, but with the additional line at the end there is no way...so I thought it can´t be to hard to get rid of it:
I tried to save a to a new file and remove the empty line with:
os.system("sed '/^$/d' /home/pi/bsp/musik/track > /home/pi/bsp/musik/tt")
os.system("mv /home/pi/bsp/musik/tt /home/pi/bsp/musik/track ")
Or remove it right in the pipe with:
sed '/^$/d'
Or remove it from the sting with:
text = os.linesep.join([s for s in text.splitlines() if s])
Or:
track[:track.rfind('\n')]
And after all nothing worked so far.
How can I do it?
Assuming play.py is printing the contents of the file, the extra line at the end is coming from the print statement. If you need to output the contents of the file with Python, you can use sys.stdout.write instead of print, or rstrip('\n') the string, or put a comma at the end of the print statement, or use the print function with end=''. If you're directing input to OMXPlayer with shell redirection or something like that, it'll probably work fine without any extra effort.
import sys
sys.stdout.write(file_contents)
or
print file_contents.rstrip('\n')
or
print file_contents,
or
from __future__ import print_function
print(file_contents, end='')
text = track.rstrip()
"Return a copy of the string with trailing characters removed. If
chars is omitted or None, whitespace characters are removed."
I build one web and user can enter directory path in form.
My program will extract the path and write into one file.
My question is when the path include some special word such as \t \n, the program can't write file correctly.
For example:
C:\abc\test will become C:\abc[TAB]est
How can I change the string into other type like raw string and write file correctly ?
Thank you for your reply.
Use r'C:\abc\test' or 'C:\\abc\\test' when you enter your strings
... user can enter directory path in form.
...
My question is when the path include some special word such as \t \n, the program can't write file correctly.
Uh, no. Python is perfectly capable of distinguishing between '\t' and '\\t' unless you are doing something to confuse it.
>>> raw_input()
<Ctrl-V><Tab>
'\t'
>>> raw_input()
\t
'\\t'