Editing every 3rd line of file in vim - python

I was making a templated list of methods in vim for a python project. I added lines between each method and wanted to add a pass to each method for now-until I implement the method, this will still be interpretable python code. In vim I know how to edit spatially contiguous lines of a file using :10,17s/<search regex>/<substitute>/ but after doing my edits to add empty lines between methods, I needed to insert the a pass every 3rd line. The way I found to do this used pipes and & via:
:10s/<search regex>/<substitute>|13&|16& etc. I had maybe 15 of the ampersands chained together to get this to work. Is there a more succint way to get this behaviour in vim?
To address comment, here is a minimal example, in the file myfile.py I have:
def _fun1(self):
def _fun2(self):
def _fun3(self):
def _fun4(self):
...etc
On the 2nd line, the 5th line, the 8th line, etc. I want to insert pass (w/4 spaces before to keep consistent spacings), /i have this up to _fun15(self): so would like to get the behavior w/o 14 |lineNo&s chained together. Perhaps an incrementing feature w/a variable for the line numbers or some other code that creates the behavior.

Here is one possible way:
:g/def _fun/normal! opass
On each line matching def _fun…
open a new line below…
and insert pass.
If you want to have one single line between each stub:
:g/def _fun/normal! opass^OJ^Ox
On each line matching def _fun…
open a new line below…
insert pass…
leave insert mode for a single command…
join the line below with the current line…
leave insert mode for a single command…
and remove that pesky <Space>.

Record a macro
qajopass<Esc>jq
Now execute it by running #a (next time you can use ##).
As #midor said it can be then used with :g command in form of:
:g/def _fun\d\+/norm #a
To execute this macro on all matching lines.

To put 'pass' with indentation below each function definition I would use:
:g/^def/put =' pass'
^ ........... begining of each line
put ......... puts contents bellow
To squeeze blank lines:
:g/^$/,/./-1j
a global command the gets from each empty line ^$
until next non-empty line minus one, performs a join command

Related

Trying to transfer a file name to a different function

I am writing code for class and I'm stuck on just one problem. I'm supposed to use the main function to call to a different function called 'file2list' which will take the file (that I brought from main) and convert it to a list. I have everything needed to create the list, I just can't get the file to run. (also I'm new to programming, so there can also be some silly errors)
This is in my main function
#Call file2list
vt=file2list('vt_municipalities.txt')
nh=file2list('nh_municipalities.txt')
And then this is what my file2list function looks like
def file2list(muni_file):
#Create lists
muni_list=[]
#Open files
file=open('muni_file','r')
Basically, how can I bring the .txt file down to file2list? I get the error that muni_file doesn't exist. Thanks!
Your error is that you are trying to open the file with the name muni_file, as you surrounded it with ', making it a string. To reference the variable that was passed into the function, remove the quotation marks (') surrounding muni_file.
The file=open line should look something like this:
file=open(muni_file,'r')
you are passing to open() a string that contains 'muni_file' as value, to use the parameter that you recieve, you should pass without ' '

Populate wxChoice at Start of Program Run | Python

As soon as my program is run, I want my wxChoice to be populated with items from a list I designate. I am using wxFormBuilder to handle the GUI elements of my program.
My code:
def onDropDownSelection(self, parent):
#Open designated file
lines = tuple(open("/Users/it/Desktop/Classbook/masterClassList.txt", 'r'))
#Strips the first line of the file, splits the elements, assigns to "one"
lines[1].rstrip()
one = lines[1].split("|")
#My attempt to populate the wxChoice with my list "one"
self.firstChoice.SetItems(one)
This event is activated when the user clicks on the drop-down (wxChoice) menu, and re-populates every time it is clicked on.
Is there a way I can populate my wxChoice, only once, upon the initial opening/running of the program?
I have placed this code where the wxChoice is being created. However, I am now experiencing a "Unindent does not match any outer indentation level" on line 44. How do I fix this?
Check for your indentation. Some times if you copy paste, this can mess things up.
Just rewrite it or replace it with another statement. See here:
IndentationError: unindent does not match any outer indentation level
Problem is if you make your indentation with tabs and then copy-paste some code from an example page, where the indentation is made with spaces. Then you have mixed Indentations. I've had these a lot of times.

Extracting specific variables of a line with linecache

I'm currently using the python linecache module to grab specific lines from a given text document and create a new file with said line. For example, part of the code looks like:
cs = linecache.getline('variables.txt', 7)
cs_1 = open("lo_cs", "w")
cs_1.write(str(cs))
cs_1.close()
The problem is that within variables.txt, line 7 is given by:
variable7 = 3423
for instance. I want the new file, lo_cs, however, to contain only the actual value '3423' and not the entire line of text. Further, I want to insert the whole 'getline' command into an if loop so that if variable7 is left blank, another action is taken. Is there a way to use linecache to check the space following 'variable7 = ' to see if there is anything entered there, and if so, to grab only that particular value or string?
I know (but don't really understand) that bash scripts seem to use '$' as sort of a placeholder for inserting or calling a given file. I think I need to implement something similar to that...
I thought about having instructions in the text file indicating that the value should be specified in the line below -- to avoid selecting out only segments of a line -- but that allows for one to accidentally enter in superfluous breaks, which would mess up all subsequent 'getline' commands, in terms of which line needs to be selected.
Any help in the right direction would be greatly appreciated!
You can use the following method to wrap the functionality you need:
def parseline(l):
sp = l.split('=')
return sp[0], int(sp[1]) if len(sp) > 1 else None
or if you don't need the variable name:
def parseline(l):
sp = l.split('=')
return int(sp[1]) if len(sp) > 1 and sp[1].strip() != '' else None
and then use:
csval = parseline(linecache.getline('variables.txt', 7))
You can later place conditions on csval to see if it's None, and if it is, take another action.

Highlight specific line of output

I'm building a piece of educational software and I have pseudocode on the output where I would like to highlight a specific line of code depending on which piece of code is running.
First round()
.....
--> highlight this line and the next after it moves
Output: First round has just started
The furthest I got was doing some bash highlighting but that required me to print out the line twice. Once in black and second in a different colour. Any suggestions on how to highlight a specific line? Any help is appreciated.
EDIT: I'm using Pyqt as my GUI toolkit so my output will be displayed in a textbox
You have to get the QTextBlock object that correspond to the line (*) you want to highlight or unhighlight and use a QTextCursor to change the format of that line:
def setLineFormat(self, lineNumber, format):
cursor = QTextCursor(self.textEdit.document().findBlockByNumber(lineNumber))
cursor.setBlockFormat(format)
# with
format = QTextBlockFormat()
format.setBackground(Qt.yellow)
# or
format.clearBackground()
If you are using QSyntaxHighlighter, you could also store the state of the line in the QTextBlock with QTextBlock.setUserState() or setUserData, handle that state in the QSyntaxHighlighter.highlightBlock() method as part of the syntax highlighting, and force the previous and the current lines to be repainted with QSyntaxHighlighter.rehighlightBlock().
*: lines==blocks unless you use a custom document layout

Split words and creating new files with different names(python)

I need to write a program like this:
Write a program that reads a file .picasa.ini and copies pictures in new files, whose names are the same as identification numbers of person on these pictures (eg. 8ff985a43603dbf8.jpg). If there are more person on the picture it makes more copies. If a person is on more pictures, later override earlier copies of pictures; if a person 8ff985a43603dbf8 may appear in more pictures, only one file with this name will exist. You must presume that we have a simple file .picasa.ini.
I have an .ini, that consists:
[img_8538.jpg]
faces=rect64(4ac022d1820c8624),**d5a2d2f6f0d7ccbc**
backuphash=46512
[img_8551.jpg]
faces=rect64(acb64583d1eb84cb),**2623af3d8cb8e040**;rect64(58bf441388df9592),**d85d127e5c45cdc2**
backuphash=8108
...
Is this a good way to start this program?
for line in open('C:\Users\Admin\Desktop\podatki-picasa\.picasa.ini'):
if line.startswith('faces'):
line.split() # what must I do here to split the bolded words?
Is there a better way to do this? Remember the .jpg file must be created with a new name, so I think I should link the current .jpg file with the bolded one.
Consider using ConfigParser. Then you will have to split each value by hand, as you describe.
import ConfigParser
import string
config = ConfigParser.ConfigParser()
config.read('C:\Users\Admin\Desktop\podatki-picasa\.picasa.ini')
imgs = []
for item in config.sections():
imgs.append(config.get(item, 'faces'))
This is still work in progress. Just want to ask if it's correct.
edit:
Still don't know hot to split the bolded words out of there. This split function really is a pain for me.
Suggestions:
Your lines don't start with 'faces', so your second line won't work the way you want it to. Depending on how the rest of the file looks, you might only need to check whether the line is empty or not at that point.
To get the information you need, first split at ',' and work from there
Try at a solution: The elements you need seem to always have a ',' before them, so you can start by splitting at the ',' sign and taking everything from the 1-index elemnt onwards [1::] . Then if what I am thinking is correct, you split those elements twice again: at the ";" and take the 0-index element of that and at that " ", again taking the 0-index element.
for line in open('thingy.ini'):
if line != "\n":
personelements = line.split(",")[1::]
for person in personelements:
personstring = person.split(";")[0].split(" ")[0]
print personstring
works for me to get:
d5a2d2f6f0d7ccbc
2623af3d8cb8e040
d85d127e5c45cdc2

Categories