MS Word has an ‘ignore this error’ thing in the grammar checker that I use fairly regularly — technical writing has syntax that reads as wrong, grammatical errors for impact, or informal writing where I don’t much care for some rules of grammar … I don’t want to turn off the grammar checker, but I do want to stop seeing a squiggly line under a specific sentence that I don’t want to change. Turns out Pylint has something similar:
Category: Coding
PIP SSL Error
Upgraded pip today, and I pretty quickly regretted it. SSL Error attempting to install anything from the Internet (and, amazingly, some things where I downloaded the wheel file). The answer is to downgrade PIP until you hit a version that doesn’t have the error. Annoying. Not sure what the latest rev I could have used was — going back one level and getting the error in loop was more time than I could devote to the project, so I just jumped back six months. Had success with 20.0.2 and left working alone.
Everything from 20.3.1 through 21.0.1 has this failure:
D:\tmp\5\pip>pip install basic_sftp
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, ‘[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1076)’))’: /simple/basic-sftp/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, ‘[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1076)’))’: /simple/basic-sftp/
WARNING: You are using pip version 20.3.1; however, version 21.0.1 is available.
You should consider upgrading via the ‘c:\programs\anaconda3\python.exe -m pip install –upgrade pip’ command.
Using an ampersand in the Oracle LISTAGG function
Python — dis
Oracle Where Like Condition Using Column Values
I wanted to filter my result set to items where a column contained a value from another column — not that it was equal, but like. CONCAT allows me to do this:
nlA.clli_code LIKE CONCAT('%', CONCAT(nle.exchange_area_clli ,'%'))
Alternately, using ||
nlA.clli_code LIKE ('%' || nle.exchange_area_clli || '%')
VSCode Search/Replace Using Regex Capture Groups
Regex adds a lot of flexibility to search/replace operations. Capture groups allow you to manipulate the found data in the replacement text. As an example, I have simple mathematical equations that are not spaced out reasonably. I could replace “+” with ” + “, “-” with ” – “, “*” with ” * “, “/” with ” / “, and “=” with ” = “, but using a capture group to identify non-whitespace characters and the range of operators allows a single search/replace operation to add spaces to my equations.
Selecting the regex option (in blue below), I can use the regular expression (\S+)([\+,\-,\*,\/])(\S+)=(\S+) as my search string. This means the first capture group is one or more non-whitespace characters, the second capture group is one of the characters +,-,*,/, the third capture group is one or more non-whitespace characters, there’s an equal sign (which I could make into a fourth capture group), and the fourth capture group is one or more non-whitespace characters.
An alternate regex finds zero or more whitespace characters — (\S*)([\+,\-,\*,\/])(\S*)=(\S*)
The replacement text then uses each capture group — $1 $2 $3 = $4 — to add spaces around the operators and around the equal sign.
Updating JQuery
We’ve got to upgrade some Javascript modules at work — JQuery, Bootstrap, etc. Problem is that changes between the versions mean there’s a lot of rewriting required before we can update. And we pull in these modules using a shared header file. While we could stage all of the changes and update the entire website at once … that means we’re all dedicated to updating our components & are delaying the update until we’re finished.
That’s not ideal — and has the potential to break a lot of things at once. I plan, instead, of putting a default version in the shared header file. And some mechanism to source in a newer version by setting a variable in the individual tool’s PHP code before the header is pulled in. So each tool within the site has a $strJQueryRev, $strBootstrapRev, etc variable. Then the shared header file looks for that variable — loads a newer version when requested or loads the currently used older version when no version is indicated.
if($strJQueryRev == "3.5.1"){
echo "<script src=\"https://code.jquery.com/jquery-3.5.1.min.js\">\n";
}
elseif($strJQueryRev == "3.1.1"){
echo "<script src=\"https://code.jquery.com/jquery-3.1.1.min.js\">\n";
}
else{
echo "<script src=\"https://code.jquery.com/jquery-2.2.4.min.js\">\n"; # Old, in use, version is default
}
Or even
if(!$strRevisionNumber){$strRevisionNumber="2.2.4";}
echo "<script src=\"https://code.jquery.com/jquery-$strRevisionNumber.min.js\">
Each developer can add a version number to a single tool, test it, push it up through production using the newest modules. Move on to the next tool. The site still isn’t done until we’re all done, but we can slowly roll out the update as people are able to test their tools.
Cyberark — Error Listing Accounts
I was getting an odd error from my attempt to list accounts in Cyberark — “Object reference not set to an instance of an object”. Searching the Internet yielded a lot of issues that weren’t my problem (ampersands in account names in an older version, issues with SSL {and, seriously, someone says disable SSL on the connection they use to retrieve passwords!?! And not just random someone, but RAND?!?}). My issue turned out to be that I was copy/pasting code and used requests.post instead of requests.get — attempting to POST to a GET URL generates this error too.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): cyberark.example.com:443
DEBUG:urllib3.connectionpool:https://cyberark.example.com:443 “POST /PasswordVault/API/auth/Cyberark/Logon HTTP/1.1” 200 182
Before request, header is {‘Content-Type’: ‘application/json’, ‘Authorization’: ‘5TQz5WVjYm5tMjBh5C00M5YyLT50MjYt5Tc2Y5I2ZDI5…AwMDA5MDA7’}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): cyberark.example.com:443
DEBUG:urllib3.connectionpool:https://cyberark.example.com:443 “POST /PasswordVault/api/Accounts?search=sample_account&searchType=contains HTTP/1.1” 500 97
{“ErrorCode”:”CAWS00001E”,”ErrorMessage”:”Object reference not set to an instance of an object.”} 500 Internal Server Error
Python Time-Expiring Cache
I needed to post information into a SharePoint Online list. There’s an auth header required to post data, but the authentication expires every couple of minutes. Obviously, I could just get a new auth string each time … but that’s terribly inefficient. I could also use what I had and refresh it when it fails … inelegant but effective. I wanted, instead, to have a value cached for a duration slightly less than the server-side expiry on the auth string. This decorator allows me to use the cached auth header string for some period of time and actually run the function that grabs the auth header string before the string is invalidated.
import functools
import time
from datetime import datetime
def timed_cache(iMaxAge, iMaxSize=128, boolTyped=False):
#######################################
# LRU cache decorator with expiry time
#
# Args:
# iMaxAge: Seconds to live for cached results.
# iMaxSize: Maximum cache size (see functools.lru_cache).
# boolTyped: Cache on distinct input types (see functools.lru_cache).
#######################################
def _decorator(fn):
@functools.lru_cache(maxsize=iMaxSize, typed=boolTyped)
def _new(*args, __time_salt, **kwargs):
return fn(*args, **kwargs)
@functools.wraps(fn)
def _wrapped(*args, **kwargs):
return _new(*args, **kwargs, __time_salt=int(time.time() / iMaxAge))
return _wrapped
return _decorator
# Usage example -- 23 second cache expiry
@timed_cache(23)
def slow_function(iSleepTime: int):
datetimeStart = datetime.now()
time.sleep(iSleepTime)
return f"test started at {datetimeStart} and ended at at {datetime.now()}"
print(f"Start at {datetime.now()}")
for i in range(1, 50):
print(slow_function(5))
if i % 5 is 0:
print(f"sleeping 5 at {datetime.now()}")
time.sleep(5)
print(f"done sleeping at {datetime.now()}\n\n")
print(f"Ended at at {datetime.now()}")
VSCode — Shortcut for Uppercase and Lowercase Conversion
While you can run a command to convert the selected text to upper (or lower) case, there doesn’t appear to be a quick way to do it. Luckily, you can define your own keyboard shortcuts and map those shortcuts to commands. From the File menu, select “Preferences” and “Keyboard Shortcuts” (or use the Ctrl-K Ctrl-S combo).
In the upper right-hand corner, click this icon to open the custom keyboard shortcut JSON file
Add JSON elements for the shortcuts you want to define — the key combination, the command to run, and on what to run the command
Sample key command bindings:
[
{
"key": "ctrl+shift+u",
"command": "editor.action.transformToUppercase",
"when": "editorTextFocus"
},
{
"key": "ctrl+shift+l",
"command": "editor.action.transformToLowercase",
"when": "editorTextFocus"
}
]
Save … voila, a keyboard shortcut to change to upper and lower case.