Stacked IF NOTs - python-3.x

dd = (re.findall(r'">County<(.*?)</td>', lmth2))
if not dd:
dd = (re.findall(r'<small>Location in <a(.*?)</td>',lmth2)
if not dd:
county.append("")
fin.append(name[o]+';'+address[o]+';'+city[o]+';'+stateorg[o]+';'+county[o]+';'+phone[o]+';'+website[o])
continue
else:
ee = (re.findall(r'title="(.*?) County', dd[0]))
county.append(ee[0])
fin.append(name[o]+';'+address[o]+';'+city[o]+';'+stateorg[o]+';'+county[o]+';'+phone[o]+';'+website[o])
I'm trying to stack IF NOTs together to find the find result. If
If dd does not come up as a match then I want to try the second scenario. If that doesn't come up with a match then I want, for right now, for it to show it as nothing comes up and to set up the line to be saved to the file. If it does come up with a match than I need it continue on find the second level of the search with ee = (re.findall...)
Until I found the second possible scenario to search for everything had been working find but then I found another possible thing I need to look for so I'm trying to add it into the program and I keep getting an Invalid Syntax coming back on the : on the second
if not dd:
This is one that is WAY beyond me. I'm not use to having this trouble with stacked if's when I use to use VB6. Python seems to be handling things a bit differently.

Indentation is syntactically significant in Python. Unlike languages where blocks are determined by tokens like begin and end or { and }, in Python blocks are determined by indents and dedents.
As such, you cannot arbitrarily indent Python code. Whenever Python encounters a line that is indented further than the line above it, it expects that to be the first line of a new block. The issue you have is that inside the first if statement you have already established the indentation level of that block with the line dd = ..., and then you've indented the next if statement even further, while it should be at the same indentation level.
If you remove the extra indent on the second if not dd: line, it should no longer have a syntax error.

Related

Is there an end= equivalent for inputs?

So as I'm sure you know there's a specific operator for print() functions called end.
#as an example
print('BOB', end='-')
#would output
BOB-
So is there something like this for inputs? For example, if I wanted to have an input that would look something like this:
Input here
►
-------------------------------------------------------
And have the input at the ► and be inside the dashes using something like
x = input('Input here\n►', end='-------')
Would there be some equivalent?
EDIT:
Just to be clear, everything will be printed at the same time. The input would just be on the line marked with the ►, and the ---- would be printed below it, but at the SAME time. This means that the input would be "enclosed" by the ---.
Also, there has been a comment about curses - can you please clarify on this?
Not exactly what you want, but if the --- (or ___) can also be on the same line, you could use an input prompt with \r:
input("__________\r> ")
This means: print 10 _, then go back \r to the beginning of the line, print > overwriting the first two _, then capture the input, overwriting more _. This shows the input prompt > ________. After typing some chars: > test____. Captured input: 'test'
For more complex input forms, you should consider using curses.
When using basic console IO, once a line has been ended with a newline, it's gone and can't be edited. You can't move the cursor up to do print anything above that last line, only add on a new line below.
That means that without using a specialized "console graphics" library like curses (as tobias_k suggests), you pretty much can't do what you're asking. You can mess around a little with the contents of the last line (overwriting text you've already written there), but you can't write to any line other than the last one.
To understand why console IO works this way, you should know that very early computers didn't have screens. Instead, their console output was directly printed out one line at a time on paper. While some line printers could print several characters on the same spot (to get effects line strikethrough or underline), you couldn't unprint anything once it was on the paper. Furthermore, the paper feed only worked in one direction. Once you had sent a newline character that told the printer to advance the paper, you couldn't go back to an old line again.
I believe this would solve your problem:
print(f">>> {input()} ------")
OR
print(f"{input(">>>")} ------")
F-strings are quite useful when it comes to printing text + variables.

What do I need to change to get rid of this syntax error that seems to jump from line to line?

I've written a program for a class and I am getting a syntax error that makes no sense on this portion:
"""Output Area"""
#self.outputArea
self.outputArea = self.addTextArea("", row = 3, column = 0)
The syntax error is on the """Output Area""" line, but when I delete that portion, the syntax moves to the "#self.outputArea" line. Then if I delete that line, the syntax error will move down to the "self.outputArea = self.addTextArea". Then down to the function below this line. This is the only error in the entire code and it just seems to keep jumping around.
I'm incredibly confused as I am new to programming. Am I just overlooking something?
This is a common siutation. The issue most likely lies in the block before """Output Area""".
The exact issue is difficult to guess. Some of the common ones off the top of my head are:
Incorrect indentation (correct setup of an editor is important here.)
Trailing comma
Incorrect implementation of exception handling.
The list goes on. As I said, it's difficult to surmise.

Place-holders used as construct name compromise correct indentation

I wrote a Vim script for the autocompletion of Fortran program units, type definition and so on, taking the cue from vim-latex plugin.
At the moment, if I strike <F5> while the cursor is on the word program, I get the following
PROGRAM <+program_name+>
USE <+used_module_name+>
IMPLICIT NONE
<++>
END PROGRAM <+program_name+>
with the first <+program_name+> visually selected and Vim in select mode. And this is perfect for me.
The problem arises when I use such a placeholder as a label for the IF construct. When I expand if I get
<+name+>: IF (<+logical expression+>) THEN
<++> ! this line is not indented => in turn the following are negative indented
ELSE IF (<+logical expression+>) THEN
<++>
ELSE
<++>
END IF <+name+>
where the second line is not indented due to the fact (at least I suppose!) that the string <+name+> is not a valid name. As a consequence, the following lines move back (obviously when the if is in the first column, the second line is the only one to be wrong).
This also happens for the DO construct, but, strangely, doesn't happen for the SELECT CASE construct:
<+name+>: SELECT CASE (<+case expression+>)
CASE (<+case selector+>)
<++>
CASE DEFAULT
<++>
END SELECT <+name+>
And this is why I think a soultion must exist and be not so complicated.
I decided to solve the problem in the "dirty" way, that is, by inserting spaces in proper position in the command sequence generating the the IF...THEN...ELSE...END IF and DO...END DO constructs. This is not an elegant solution, but I don't think that has so much drawbacks. The only thing to change would be the number of spaces to add manually to the command sequences according to shiftwidth.
As #SatoKatsura suggested in a comment, it'd be better to abandon this road and use existing snippet solutions.

Converting header or text file information to code using Linux/Vim

I found myself writing a really simple conversion from OpenCL error codes to a human readable string. The 50 or so different codes are defined in a header file like this:
...
#define CL_INVALID_CONTEXT -34
#define CL_INVALID_QUEUE_PROPERTIES -35
#define CL_INVALID_COMMAND_QUEUE -36
#define CL_INVALID_HOST_PTR -37
...
I put all of these in a huge switch/case using expert copy/pasting:
...
case CL_INVALID_CONTEXT:
return "CL_INVALID_CONTEXT";
case CL_INVALID_QUEUE_PROPERTIES:
return "CL_INVALID_QUEUE_PROPERTIES";
case CL_INVALID_COMMAND_QUEUE:
return "CL_INVALID_COMMAND_QUEUE";
case CL_INVALID_HOST_PTR:
return "CL_INVALID_HOST_PTR";
...
Since I've recently started to use Vim, I am thinking there might be a way to do this in a more efficient way using Linux command tools and Vim. There was a similar post here where someone claimed to have done it with Emacs. Any ideas on how to avoid wasting 15 minutes with a similar task next time?
(I know that oclErrorSting() might exist but let's disregard that for generality's sake!)
You can do this in Vim with a search and replace:
%s/#define \(\w\+\).*/case \1:^M return "\1";/g
The trick to getting the ^M in the output is to type CTRL-V and then Enter where you want put a newline in the output.
This will do the replacement on the entire file.
This works by doing a seach which matches the entire line and replacing it with your desired text. Each name is captured into a group in the search, that's what the \(\w\+\) is doing, then the matched text is used twice in the replacement.
The other generic solution for repetitive tasks is to use macros, or complex repeats are they are called in help.
Basically you start recording your inputs in a register, create a single case, and then go to the next line of your define.
See :help q for more details.

Remove Various Whitespaces While Editing in Vim

So oftentimes, while editing with Vim, I'll get into a variety of situations where whitespace gives me hassle. For example, say I have a comment like this:
#This program was featured on the Today show, it is an algorithm for promoting world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
If I want to, for example, trim the lines so they go to X characters, I end up putting a newline somewhere in the middle of the top line to get this (after hitting the newline and auto-indenting):
#This program was featured on the Today show, it is an algorithm for promoting
world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
I then add a # to the beginning of the line, and that's all well and good, but then I want that line to line up, too. To do so, I have to delete the newline, all the whitespace for the indent on the next line, and then the commenting # mark. It doesn't take an awfully long amount of time to do that, but this and similar situations all add up over a day's worth of coding.
Now the example above is pretty specific, but my question isn't. What's a good way in Vim to delete all whitespace INCLUDING NEWLINES up until the next non-whitespace character? If Vim already has movements that do that, that would be awesome, but if not, does anyone have a favorite Vim function they use to do the above that could be mapped to a key? At the very least, am I missing some Vim usage idiom that prevents me from even having to worry about this case?
EDIT: Formatting to width, while useful and applicable to the case above, isn't the focus of this question. I'm concerned more with whitespace removal that doesn't stop at the end of a line, but instead carries on to the first non-whitespace character of the next line.
You really just want to reformat that comment to fit the current 'textwidth'. If the comment is a paragraph (i.e., separated by a line of whitespace above and below), then you can just use gqip (gq is the reformat command, ip is the "inner-paragraph" text object) to reformat it. If it's not a standalone paragraph, you can visually select those lines and then use gq.
This likely also relies on having 'formatoptions' set correctly to make sure the comment characters are handled properly, but in many cases the ftplugin has already done that.
This is a while later, but I found that there is a command that does what I need to in 90% of circumstances:
J -- join line below to the current one
This command seems to work:
:.s/\W*$\n\W*//g
it uses a replace to remove whitespace up to end of line and the new line at the end.
In this example:
testting aad $
asdjkasdjsdaksddjk$
(to see meta characters in vim use the command :set list)
if you place the cursor on the first line and use the first command it will delete everything from aad to $ (not including aad but including $ and a newline.)
Also, note for what you are doing it is far more efficient to use an external program to format comments for you. In particular, par is a great small C program that edits text and wraps it to desired lengths.
If you have par in your path, to do what you are trying to do is as easy as selecting the block of comment with Shift+v and running the command
:!par 40pgr
where 40 is the desired width in columns.
If you are feeling hackish, write your own program in C/perl/C++/python that edits comments however you like, then put it in path and use the external filter command :! to process blocks of text through it.

Resources