<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Rich and Strange Aeons</title>
  <link>https://mindstalk.dreamwidth.org/</link>
  <description>Rich and Strange Aeons - Dreamwidth Studios</description>
  <lastBuildDate>Thu, 26 Aug 2021 16:47:56 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>mindstalk</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/241388/374172</url>
    <title>Rich and Strange Aeons</title>
    <link>https://mindstalk.dreamwidth.org/</link>
    <width>100</width>
    <height>75</height>
  </image>

<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/582101.html</guid>
  <pubDate>Thu, 26 Aug 2021 16:47:56 GMT</pubDate>
  <title>python JSON datetime at last</title>
  <link>https://mindstalk.dreamwidth.org/582101.html</link>
  <description>content warning: geeky computer stuff&lt;br /&gt;&lt;br /&gt;At work I have a common flow of Python code querying MySQL and dumping results into JSON.  This works great except our tables tend to have columns for create and modify dates.  And Python&apos;s json library won&apos;t convert datetime types to string, so dumping the result of &quot;SELECT * FROM&quot; errors.  And I&apos;ve had bits of ad hoc code to remote datetime values, then a little function for it, but it was still a pain.  Especially today, when for stupid VPC reasons I&apos;m writing a simple generic SQL service.&lt;br /&gt;&lt;br /&gt;In annoyance I tried searching again and found, buried in the middle of a stackoverflow with answers about subclassing and shit:&lt;br /&gt;&lt;br /&gt;json.dumps(thing, default=str)&lt;br /&gt;&lt;br /&gt;Bam, done.  The function passed to &apos;default&apos; gets invoked on anything that errors at first.  And in Python &apos;str&apos; works on pretty much anything.&lt;br /&gt;&lt;br /&gt;If I cared about the exact format I could write a function that inspected type and converted dates (or just assume datetime is the only cause of errors so just invoke a method when triggered), but str is fine for now.&lt;br /&gt;&lt;br /&gt;Soooo simple.  Thanks, python, and stackoverflow person who gave the simplest answer.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=582101&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/582101.html</comments>
  <category>python</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/561516.html</guid>
  <pubDate>Sun, 14 Jun 2020 04:01:28 GMT</pubDate>
  <title>my first ever Python bug</title>
  <link>https://mindstalk.dreamwidth.org/561516.html</link>
  <description>Years and years ago, when Perl was still the dominant scripting language, with Python and Ruby nipping at its heels, and CPAN was where you would look for cool libraries, I wrote my first Python program.  I don&apos;t recall what it did, whether it was meant to do something useful or just do something like &quot;10 9 1 blastoff&quot; as a test, but I do know that it looped based on a command line parameter.  And that it didn&apos;t work, running nigh-forever when it had a parameter of &apos;20&apos; and should stop after 20 times.  It took me like 20 minutes to figure out what was wrong.&lt;br /&gt;&lt;br /&gt;I can replicate the basic problem:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
import sys
count = 0
while count &amp;lt; sys.argv[1]:
    print(count)
    count += 1
else:
    print(&quot;Blastoff!&quot;)
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the behavior still replicates -- if you run it in Python 2.  In Python 3, you&apos;ll get&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
TypeError: &apos;&amp;lt;&apos; not supported between instances of &apos;int&apos; and &apos;str&apos;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Because sys.argv is a list of strings.  Thing is, Perl is a very accommodating language; the equivalent code in Perl will just work, as I well knew.  Or rather, Perl has separate comparison operators for numeric and string values, so this code, using &apos;&amp;lt;&apos;, would quietly try to convert sys.argv[1] into a number for comparison with &apos;count&apos;.  (If you wanted lexicographic comparison, you would use &apos;count lt sys.argv[1]&apos;, except of course it would be more like &apos;$count lt $argv[1]&apos; or something; anyway, there the value of $count would be converted to a string for comparison.)&lt;br /&gt;&lt;br /&gt;I remember being very put out.  Though I did go write a &apos;real&apos; script in Python, and showed it to my boss, who was able to read and understand it with no Python knowledge.  Go go executable pseudocode.&lt;br /&gt;&lt;br /&gt;These days, on the rare occasions I poke at Perl, I&apos;m more likely to be annoyed by the lack of a REPL, or easy ways to print nested data structures, or the quirky way function arguments are handled.  Perl still does some things better (&apos;use strict;&apos;) but I don&apos;t miss it.&lt;br /&gt;&lt;br /&gt;But dang, that bug.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=561516&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/561516.html</comments>
  <category>programming</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/556771.html</guid>
  <pubDate>Mon, 13 Apr 2020 03:24:25 GMT</pubDate>
  <title>wtf Python</title>
  <link>https://mindstalk.dreamwidth.org/556771.html</link>
  <description>I was writing some code, in a file called &apos;code.py&apos;.  I tried adding doctests and running them; this would hang, or complain about circular imports.  It seems that &apos;import doctest&apos; will run a file in the directory called &apos;code.py&apos; -- e.g. make a &apos;code.py&apos; file like&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
while True:
    pass
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;start python, import doctest, and watch it hang.&lt;br /&gt;&lt;br /&gt;This seems poor, and undocumented.  Probably I should file a bug later.&lt;br /&gt;&lt;br /&gt;I guess I have a new candidate for interview questions about problem solving.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=556771&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/556771.html</comments>
  <category>python</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/513680.html</guid>
  <pubDate>Thu, 07 Feb 2019 14:53:14 GMT</pubDate>
  <title>Python is annoying</title>
  <link>https://mindstalk.dreamwidth.org/513680.html</link>
  <description>Our code works with binary data (hashes/digest) and hexstring representations of such data, a lot. It was written in Python 2, when everything was a string, but some strings were &amp;quot;beef&amp;quot; and some were &amp;quot;&apos;\xbe\xef&apos;&amp;quot;&lt;br /&gt;&lt;br /&gt;Then we converted to Python 3, which introduced the &apos;bytes&apos; type for binary data, and Unicode strings everywhere, which led to some type problems I had figured out, but a recent debugging session revealed I had to think about it some more.  Basically we can now have a hexstring &quot;beef&quot;, the bytes object b&apos;\xbe\xef&apos; described by that hexstring... and the bytes b&quot;beef&quot; which is the UTF-8 encoding of the string.&lt;br /&gt;&lt;br /&gt;In particular, the function binascii.hexlify (aka binascii.b2a_hex) which we used a lot, changed what it returned.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
Python 2:
&amp;gt;&amp;gt;&amp;gt; binascii.a2b_hex(&quot;beef&quot;)
&apos;\xbe\xef&apos;
&amp;gt;&amp;gt;&amp;gt; binascii.hexlify(_)
&apos;beef&apos;

Python 3:
&amp;gt;&amp;gt;&amp;gt; binascii.a2b_hex(&quot;beef&quot;)
b&apos;\xbe\xef&apos;
&amp;gt;&amp;gt;&amp;gt; binascii.hexlify(_)
b&apos;beef&apos;

vs.
&amp;gt;&amp;gt;&amp;gt; binascii.a2b_hex(&quot;beef&quot;)
b&apos;\xbe\xef&apos;
&amp;gt;&amp;gt;&amp;gt; _.hex()
&apos;beef&apos;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I found it easy to assume that if one of our functions was returning b&quot;beef&quot; and the other &quot;beef&quot; that they were on the same page, when really, not.&lt;br /&gt;&lt;br /&gt;Bunch of examples in the cut.&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://mindstalk.dreamwidth.org/513680.html#cutid1&quot;&gt;Grah Python&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=513680&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/513680.html</comments>
  <category>python</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/490829.html</guid>
  <pubDate>Fri, 23 Mar 2018 02:04:09 GMT</pubDate>
  <title>refactoring $*#&amp;*# Python</title>
  <link>https://mindstalk.dreamwidth.org/490829.html</link>
  <description>Once again, into the Pyth circle of hell.  This time trying to convert our code from Python 2 to 3.  2to3 does much fo the grunt work of print() and &apos;from . import&apos;, though it didn&apos;t always get the latter right.  But instead of string and unicode, we now have string and bytes value types, and a strong barrier between them.  And of course no static compiler to find up front when types might be mixed up.  And yes, we&apos;re weak on unit tests, especially tests that exercise all possible code paths.  Things seem to mostly work now, but will they under all conditions?  Who knows?&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=490829&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/490829.html</comments>
  <category>programming</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/470323.html</guid>
  <pubDate>Wed, 12 Apr 2017 01:41:31 GMT</pubDate>
  <title>vigorous vim; frigging Python</title>
  <link>https://mindstalk.dreamwidth.org/470323.html</link>
  <description>Speaking of aggravating values of fun... I foresaw a &lt;a href=&quot;https://mindstalk.dreamwidth.org/469356.html&quot;&gt;day of boring editing in my future&lt;/a&gt;?  Well, I managed to make that half a day.  I&apos;d looked for programmatic solutions but they all seemed half-assed in bad ways, especially in breaking the logging information (filename, function name) we want.  So I went through by hand... and a good mastery of vim commands and maps.  It&apos;s funny, I haven&apos;t had to make a new vim map in forever, but the skills are there.&lt;br /&gt;&lt;br /&gt;Samples:  (Edit: all the [] should be angle brackets; I forgot how Dreamwidth swallows them.)&lt;br /&gt;&lt;br /&gt;map CP            :s/,/+/g&lt;cr&gt;  #turns commma to plus, down a line&lt;br /&gt;map KE            cwkinnlog.error([Esc]A)[ESC]CP&lt;br /&gt; #changes word under cursor to &apos;kinnlog.error(&apos;, appends &apos;)&apos; to line, invokes CP&lt;br /&gt;map KX            cwkinnlog.exception([Esc]A)[ESC]CP&lt;br /&gt;map fp /print^M   # fast search for &apos;print&apos;, since CP changes the current search to &apos;,&apos;&lt;br /&gt;map St istr(^[   #inserts &apos;str(&apos; and goes back to command more.&lt;br /&gt;map stt a)^[   #inserts &apos;)&apos; and goes back to command more&lt;br /&gt;map kld cf(kinnlog.debug(^[   #changes everything from cursor to a &apos;(&apos;&lt;br /&gt;&lt;br /&gt;I got to show off more simply last week, too; I was setting up the product for Co-worker, and had to edit the IP address in a bunch of files.&lt;br /&gt;$ vi *.json&lt;br /&gt;/[IP 1]&lt;br /&gt;C[IP2]&quot;,&lt;br /&gt;n #search next&lt;br /&gt;. #ditto&lt;br /&gt;:wn  #write, move to next file -- which preserves all the state, so I can keep going &apos;n&apos; and &apos;.&apos;&lt;br /&gt;&lt;br /&gt;She was impressed by my speed.  (If you&apos;re wondering why not regexes, there were only 1 or 2 addresses per file, this seemed as fast or faster as recalling a &apos;:%s/...&apos;)&lt;br /&gt;&lt;br /&gt;*******&lt;br /&gt;&lt;br /&gt;All that said and done... Python makes it easy to write code.  Python has an awesomely nice standard library, including a logger module with many handlers like RotatingFileHandler.  Python makes it easy to rip out the guts of a stub logging module and replace it with something sophisticated.&lt;br /&gt;&lt;br /&gt;Python 2 has a print statement which can take an indefinite list of things, and print them all, without any type information.&lt;br /&gt;&lt;br /&gt;Python 2 does not provide any function that does something similar, so converting from those print statements to calls to actual logging functions was terribly painful and/or un-typesafe. I mean, a lot of the time I can&apos;t tell easily what the type of the value of a variable is where it&apos;s being used.  Granted you can wrap almost anything in &apos;str()&apos;, and maybe I should have been more thorough about doing just that.  Python doesn&apos;t have a compiler, and as long as it&apos;s basically syntactically correct, will be happy until it tries to actually execute the code. I really hate this.&lt;/cr&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=470323&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/470323.html</comments>
  <category>python</category>
  <category>vim</category>
  <category>work</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/465980.html</guid>
  <pubDate>Sun, 05 Feb 2017 16:49:15 GMT</pubDate>
  <title>Hoisting Shadows</title>
  <link>https://mindstalk.dreamwidth.org/465980.html</link>
  <description>A bit after writing &lt;a href=&quot;https://mindstalk.dreamwidth.org/465845.html&quot;&gt;the previous post on shadowing variables in JavaScript&lt;/a&gt;, I came across &lt;a href=&quot;http://www.w3schools.com/js/js_hoisting.asp&quot;&gt;this page on hoisting&lt;/a&gt;.  JavaScript re-writes your code so that declarations but not initializations to the top of current scope, meaning the script or function[1].  So&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
console.log(a);
var a=5;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;turns into&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
var a;
console.log(a);
a=5;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Put that way, it&apos;s clear why the problem happens, if not why the language was designed this way.&lt;br /&gt;&lt;br /&gt;Does the same thing happen in Python?  Searching did not get clear results.  I saw pages contrasting JavaScript with Python, which doesn&apos;t even *have* declarations.  OTOH, the same behavior occurs.  So... I dunno.&lt;br /&gt;&lt;br /&gt;[1] JavaScipt does not have block scoping the way C and Perl[2] do; scopes are delimited by curly braces, but random curly braces do nothing to isolate variables.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
{ a=5; }
console.log(a);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;will work just fine. :(&lt;br /&gt;&lt;br /&gt;[2] As I was verifying this in Perl, I ran into behavior I&apos;d forgotten.  I&apos;d thrown in &quot;use strict;&quot; but wasn&apos;t getting the errors I expected.  Eventually I recalled that $a and $b have special meaning in Perl (I think for comparison functions), and I guess are pre-declared, and I was using $a a la the above code, so strict didn&apos;t complain about trying to access $a before assigning to it.  Sigh.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=465980&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/465980.html</comments>
  <category>perl</category>
  <category>python</category>
  <category>javascript</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mindstalk.dreamwidth.org/450941.html</guid>
  <pubDate>Mon, 08 Aug 2016 21:01:55 GMT</pubDate>
  <title>Simplified Shadows of Python</title>
  <link>https://mindstalk.dreamwidth.org/450941.html</link>
  <description>I spent longer than I expected figuring out the problem described in Robbie&apos;s &lt;a href=&quot;https://mivehind.net/2016/08/07/shadows-of-python/&quot;&gt;Shadows of Python&lt;/a&gt; post.  I kept revising my e-mail to him: &quot;You&apos;re wrong because of X.  No, I mean Y.  Um, Z?&quot;  Eventually I got it, I think, and distilled it to a simpler piece of contrasting code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
x=1

def f():
    print(x)

def g():
    print(x)
    x=2

&amp;gt;&amp;gt;&amp;gt; f()
1
&amp;gt;&amp;gt;&amp;gt; g()
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
  File &quot;r.py&quot;, line 8, in g
    print(x)
UnboundLocalError: local variable &apos;x&apos; referenced before assignment
&lt;/module&gt;&lt;/stdin&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simply because we will (or even &lt;i&gt;might&lt;/i&gt;, it works if the assignment is in an if clause) assign to x in the future, it becomes a local variable for the scope of the whole function, blocking access to the outer scope definition.  This compile-time annoyance from the same language that has no equivalent to Perl&apos;s &apos;use strict;&apos; to stop you from using misspelled variables.  Thanks, Python.&lt;br /&gt;&lt;br /&gt;Checking against the other big scripting language, Perl:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
$x=1;

sub f {
    print $x, &quot;\n&quot;;
}
sub g {
    print $x, &quot;\n&quot;;
    $x=2;
}

f();
g();
f();

[Zefiris:0] perl r.pl
1
1
2
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy access to a global variable.  If you use &apos;my $x=2;&apos; in g(), then the change to the global-level variable is avoided, of course.&lt;br /&gt;&lt;br /&gt;Python would let you use &apos;global x&apos; in g(), or &apos;nonlocal x&apos; for intermediate scopes, but that gives you full access to x.  There&apos;s no &quot;I&apos;m going to create a new local variable from this point on, while having used an outer variable earlier in the function.&quot;  And this doesn&apos;t work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
x=1
def h():
    x=x
    print(x)
h()
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can do that in Perl, with or without &apos;my&apos;, getting expected behavior in each case.&lt;br /&gt;&lt;br /&gt;This is part of the reason I&apos;m willing to work in C++ again; yes, it&apos;s annoying, but I&apos;ve seen no language that doesn&apos;t have mindbendingly stupid shit in it somewhere.&lt;br /&gt;&lt;br /&gt;Edit: someday I&apos;ll remember I want the pre tag, not the code tag, for preserving indentation.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mindstalk&amp;ditemid=450941&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mindstalk.dreamwidth.org/450941.html</comments>
  <category>python</category>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
