Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Sunday, March 12, 2023

This is a Python test...

 I'd actually prefer to drop this into a browser add in, and maybe I will, but for the most part I'm testing whether I can hack some Python to grab an image [of mine] from Flickr and do what I usually do manually.

Well....that looks correct.  But it's one image at a time - it'd be nice to throw in an array of images and have it pick them all up and generate the HTML in an output file instead of one the command line....but, one thing at a time.  That DEFINITELY works better than what I was doing where I went to my photo, opened it in generic view, looked at all sizes, went to the appropriate size [usually 640x462], grabbed the url, grabbed the image src, and then cut and paste into a TEXT doc I keep on my desktop.

This has promise.  If I get a better version to work, I'll detail what I did.  Note that I STOLE this code from a public github user with the same need.  Props to her/him for doing all the heavy lifting that involves using the API/Key to grab all the sizes and craft the HTML.  I just wish it could pick the right orientation and size more easily.  But....that's what reading code is for.

Sarah at the Aster Lineup by:

Monday, November 08, 2021

Secret Santa

There is a LOT of garbage in this code. Notes to myself, print statements to debug, etc.  But this is the current incarnation of the secret santa code I'm using.  The old XML/Outlook version in C sharp was better, but I ran into email issues with Office moving online and switching employers and ending up on a Mac. Now I just generate .txt files.

2022 updates should include getting rid of the separate checks for exclusions and telling it to check for anyone in the full exclusion list so I can make it ragged.

Here....target == who[1] or target == who[2] or target == who[0]

And there's a lot of unnecessary iterative garbage to make sure it can brute force it's way to a list when it gets toward the end where it might dead end itself.  But to be honest, that doesn't take 100 iterations, it's over in like four. Anyway...I think I can boil this down to a dozen lines of code, so maybe I'll do that next year. Personally, I'm just glad I was able to find it again after moving machines twice in 2.5 years.

#0 fix the code >>

#0a put the guts of the retry in a function that can error out with an error message

#0b and let the error message run a global retry

#  load >> run >> each person >> one person fails >> clear and run

#1 import from a settings file (don't need a UI although the last one had one)

#2 which means we need to write to a settings file

#   name, spouse, last year (use the format year(last)file.txt as the default

#   use JSON instead of XML this time), ah....need an email address!

#3 put it in a bucket (file) in S3, put the code in a python lambda

#4 autoemail - lambda send email with ses: https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/

 

 

#2020 list...this needs to generate from input/output

#e.g. that last value should be a read from last year's file

listWho = [("Scott","Jen","Jackie")]

listWho = listWho + [("Eryn","Scott","Jen")]

listWho = listWho + [("Oliver","Jackie","Andrew")]

listWho = listWho + [("Jen","Scott","Ceri")]

listWho = listWho + [("Andrew","Jackie","Jen")]

listWho = listWho + [("Jackie","Andrew","John")]

listWho = listWho + [("Allison","Ceri","Andrew")]

listWho = listWho + [("Ceri","Allison","Ellen")]

listWho = listWho + [("John","Ellen","Scott")]

listWho = listWho + [("Ellen","John","Allison")]

 

 

 

def LoopLoop(listWho):

    targetExclusion = []

   

    for who in listWho:

        #print (len(listWho))

        #print(who)

        print(" ")

        print(" ")

        print("Owner: " + who[0])

        myRand = random.randint(0,len(listWho)-1)

        #print("random: " + str(myRand))

        target = listWho[myRand][1]

        #print("target: " + target)

        myIter = 0

        #could put all this in a function and call for success or failure

        #eg while false...

        #target can't be used already

 

        while target == who[1] or target == who[2] or target == who[0] or target in targetExclusion:

            target = listWho[random.randint(0,len(listWho)-1)][0] #I think it was my [1] here that was the mess, never returned somne folks

            print("temp target: " + target)

           

            myIter = myIter + 1

            #print(myIter)

            if myIter >=100:

                print("I FAILED")

                return False;

                #break #kill it and we will start over

 

        targetExclusion = targetExclusion + [target]

        print(targetExclusion)

        print("target: " + target)

        f= open(str(datetime.now().year) + "_" + who[0] + ".txt","w+")

        f.write("YOUR SECRET SANTA RECIPIENT IS: " + target)

        f.close()

        #do it again

        #actually, turn this into the loop

    return True; #ah, this is where I"m failing, I have to get to len to return true

 

 

print(listWho)

mybool = False

print(mybool)

while mybool == False:

    print(mybool)

    mybool = LoopLoop(listWho)

 

print ("Mybool = ")

print (mybool)

print ("end of script")

Wednesday, February 13, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Mad Lib (4) - Vue.js style

I thought a madlib lended itself more appropriately to Python, but perhaps that's because I grew up in the age of Zork and Leather Goddess of Phobos.  It works just fine with Vue, although the branching it's asking for next might be a challenge.  I haven't really tried control statements with Vue.  Wait, that's not true - I used the for/next in the random quote example.

I might actually have to put a little thought into the structure for that one.  I'm not sure what "branching" means in that context.  Select one of two verbs at random, and then use the other one later?  Allow them to only select from a few options and branch depending on the one they select?  That second one makes more sense if I'm not going to implement some NLP weirdness.  I haven't used a dropdown in Vue, so that will be a good challenge.


The code....I wonder how long until these start exceeding my textarea and I'll have to actually change the tag attributes.

Tuesday, February 12, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Mad Lib (4)

Simple one - do a madlib in this style and try it with string interpolation/substitution. Part II will be harder - it branches...I wonder if I'll have to use a picker to limit choices....I'll have to ponder that one. This one needs some sort of NLP to clean up the verb.

noun = input("Please provide a noun: ")
verb = input("Please provide a verb: ")
adverb = input("Please provide an adverb: ")
adjective = input("Please provide an adjective: ")

print("Do you " + verb + " your " + adjective + " " + noun + " " +  adverb + " That's funny!")

print(f'With literal string interpolation: Do you {verb} your {adjective} {noun} {adverb}.  That\'s funny!')
print('With interpolation: Do you %s your %s %s %s}.  That\'s funny!'%(verb,adjective,noun,adverb))


================ RESTART: C:/Users/u0024159/Desktop/MadLib.py ================
Please provide a noun: banana
Please provide a verb: ate
Please provide an adverb: quickly
Please provide an adjective: yellow
Do you ate your yellow banana quickly That's funny!
With literal string interpolation: Do you ate your yellow banana quickly.  That's funny!
With interpolation: Do you ate your yellow banana quickly}.  That's funny!
>>> 

Monday, February 11, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Saying Hello

https://jsfiddle.net/NodToNothing/arbhqcs6/3/

Interesting exercise - keep the input, concat, and output separate.  Write it without variables and do different greetings for different people.  In the end, I'm the arbitrator of what constitutes the acceptance criteria, so I used Vue again and bound the mustache output to a function tied to an input box.  Admittedly, I could have skipped the function altogether and just printed Hello in HTML and then the value of the input box.  No concatenation at all, at least not actively.

I did learn that Vue ignores the value on the input and you need to set it in the initial data values.  There's a lot of magic under the covers tying the message variable and val model together in a function mapped to the HTML.  That's slick.  I shouldn't be too impressed given I played with React back in 2013 for a team demo and have been through Angular training, but I find it refreshing anew, particularly given how fast you can set up a UI.  VB COM speed to demo days indeed.


Cheater textarea again for anyone who wants to grab some "code", although it's easier to go to the JSFiddle.  I got to thinking I'd usually do this in Python (and IDLE) and it looks like I can go Py fiddle as well: https://pyfiddle.io/  Although that's not really any faster than running IDLE on my desktop.

Friday, February 08, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part f

Version f...I think that's also 6. Break it out into functions. Some of that was already done, but I finished the job. I guess, if I was being a good programmer, I might have it ask whether the tip should be rounded up or not. And yeah, there's some weird code in a few spots, but fast and functional was my goal, not elegant.
 
import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers
#Version 4: ask again for a number - already done!
#Version 5: no negative numbers
#Version 6: use some functions

def inputNumber(message):
  while True:
    try:
       returnValue = float(raw_input(message))
       if returnValue < 0:
           raise ValueError
       else:
           return returnValue
    except ValueError:
       return inputNumber("Not a non-negative value! Try again.")

def grandTotal(tip, bill):
    return str(y + (y * x/100))

def grandTotalRounded(tip, bill):
    return str(y + math.ceil((y * x/100)*100)/100)
    
def tipPrint(tip):
    return str((y * x/100)*100)

def tipRoundedPrint(tip):
    return str(math.ceil((y * x/100)*100))


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + tipPrint(x) + " cents") #cents
print("Tip rounded up is: " + tipRoundedPrint(x) + " cents")  #what do I expect?
print("Total is: " + grandTotal(x,y))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + grandTotalRounded(y,x))

Sigh...mismatched function name.  If I had a dime for every time...

Enter a tip:3
Tip is: 3.0
Enter a bill/total: 82.55
Bill is: 82.55
Tip is: 247.65 cents
Tip rounded up is: 248.0 cents

Traceback (most recent call last):
  File "C:/Python27/TipCalculator.py", line 45, in 
    print("Total is: " + grandTotal(x,y))
NameError: name 'grandTotal' is not defined
>>> ================================ RESTART ================================
>>> 
Enter a tip:3
Tip is: 3.0
Enter a bill/total: 82.55
Bill is: 82.55
Tip is: 247.65 cents
Tip rounded up is: 248.0 cents
Total is: 85.0265
Total rounded up is: 85.03
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not a non-negative value! Try again.1.8
Tip is: 1.8
Enter a bill/total: 77.25
Bill is: 77.25
Tip is: 139.05 cents
Tip rounded up is: 140.0 cents
Total is: 78.6405
Total rounded up is: 78.65

Thursday, February 07, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part d/e

It was exciting to find out I'd already done part d/4, so I jumped right into no negative numbers. That would be a really mean tipping system. I found some other bugs as I went - I spelled negative wrong, the tip info didn't say "cents" so you couldn't be sure what was going on there, and my error handling message wasn't generic enough to cover all cases (versus specific messages, which is annoying for me, although good for the user).
import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers
#Version 4: ask again for a number - already done!
#Version 5: no negative numbers

def inputNumber(message):
  while True:
    try:
       returnValue = float(raw_input(message))
       if returnValue < 0:
           raise ValueError
       else:
           return returnValue
    except ValueError:
       return inputNumber("Not a non-negative value! Try again.")


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100) + " cents") #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)) + " cents")  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))

I notice that I don't always have the right precision...my money isn't necessarily two decimal spots. I think I know how to fix that with a decimal or I could bite the bullet and use one of the money packages/imports that exists. That might be part 8. I notice I have to flip it to a GUI coming up here soon...I'll have to port this code over to javascript (although I'd be much, much faster with C#).

Enter a tip:-1
Tip is: -1.0
Enter a bill/total: 1.50
Bill is: 1.5
Tip is: -1.5
Tip rounded up is: -1.0
Total is: 1.485
Total rounded up is: 1.49
>>> ================================ RESTART ================================
>>> 
Enter a tip:-1
Not an integer! Try again.-2
Not an integer! Try again.3
Not an integer! Try again.4
Not an integer! Try again.
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not an integer! Try again.3
Tip is: 3.0
Enter a bill/total: 150
Bill is: 150.0
Tip is: 450.0
Tip rounded up is: 450.0
Total is: 154.5
Total rounded up is: 154.5
>>> ================================ RESTART ================================
>>> 
Enter a tip:-3
Not a non-negiative value! Try again.0
Tip is: 0.0
Enter a bill/total: 150
Bill is: 150.0
Tip is: 0.0 cents
Tip rounded up is: 0.0
Total is: 150.0
Total rounded up is: 150.0
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not a non-negative value! Try again.-3
Not a non-negative value! Try again.-4
Not a non-negative value! Try again.3
Tip is: 3.0
Enter a bill/total: 17.25
Bill is: 17.25
Tip is: 51.75 cents
Tip rounded up is: 52.0
Total is: 17.7675
Total rounded up is: 17.77
>>> 

Wednesday, February 06, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part c

Version 3, or c, depending on your preference. Goal is to only enter numbers. This wasn't working for me very well until I swapped input for raw_input. Apparently I could have eval-ed the input, or been a normal boy and just used Python 3. It's on here somewhere.

import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers

def inputNumber(message):
  while True:
    try:
       return float(raw_input(message))
    except ValueError:
       return inputNumber("Not an integer! Try again.")


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100)) #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)))  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))

This was actually way more interesting on output then I'd have expected. First, I was using a function from 101 computing, and they converted input to int...that was no good. It rounded my whole bill. So I used a float. Which works. Even with a more complicated set of inputs. And then my non-numeric inputs crashed, which is where I had to switch to raw_input for 2.7 and a tighter loop.
Enter a tip:7
Tip is: 7
Enter a bill/total: 2.50
Bill is: 2
Tip is: 0
Tip rounded up is: 0.0
Total is: 2
Total rounded up is: 2.0
>>> ================================ RESTART ================================
>>> 
Enter a tip:7
Tip is: 7.0
Enter a bill/total: 2.50
Bill is: 2.5
Tip is: 17.5
Tip rounded up is: 18.0
Total is: 2.675
Total rounded up is: 2.68
>>> ================================ RESTART ================================
>>> 
Enter a tip:8.5
Tip is: 8.5
Enter a bill/total: 2.57
Bill is: 2.57
Tip is: 21.845
Tip rounded up is: 22.0
Total is: 2.78845
Total rounded up is: 2.79
>>> 

Tuesday, February 05, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part b

I don't know why this was so difficult.  I'm pretty sure that /100, *100, /100 is probably wrong anyway, it just works because the math works.  Anyway, rounding UP the pennies in the % because I'm a greedy corporate f*cker.


import math

print("Enter a tip:")
x =input()
print("Tip is: " + str(x))
print("Enter a bill/total: ")
y = input()
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100)) #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)))  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))


Output for a good use case:
Enter a tip:
3
Tip is: 3
Enter a bill/total: 
1.85
Bill is: 1.85
Tip is: 5.55
Tip rounded up is: 6.0
Total is: 1.9055
Total rounded up is: 1.91

Sunday, February 03, 2019

I'm tired of typing month/day/year once a month...

Quick code for listing month/day/year in Python.  I believe [0] is the first weekday of the month.  Weird little function/library.  There are a lot of variations to play with: https://docs.python.org/2/library/calendar.html

import datetime, calendar
year = 2019
month = 1
num_days = calendar.monthrange(year, month)[1]
for i in range(1,num_days+1):
    print(str(month) + "/" + str(i) + "/" + str(year) + ": ")

Acceptance criteria failure! My numbers are first to last, I want last to first.  So the range gets modified.

import datetime, calendar
year = 2019
month = 2
num_days = calendar.monthrange(year, month)[1]
for i in range(num_days, 0, -1):
    print(str(month) + "/" + str(i) + "/" + str(year) + ": ")

Tuesday, May 01, 2018

Things I Read May 2018

On month four.  That's a good run...
  • (BOOK/STORY) 5/31/2018: The Good Guys by Stephen Brust
    • I liked it, quite a bit, but it didn't blow me away.  I've met Stephen at Gameholecon and he's friends with Emma Bull and the Scribbly folks from the Twin Cities.  I've read two of his books and I think he and I have a slightly different writing style, which is probably more accurately a slightly different story telling style, which is probably more accurately a slightly different way of thinking.  I'd actually recommend it, although I'm not sure I'd read a sequel.
  • (BOOK/STORY) 5/30/2018: Inspired: How to Create Tech Products Customers Love
    • Excellent...I think I need to do a different post I have so many notes.
  • 5/29/2018: Immersive Learning in the Target Dojo - because we're looking at Dojos at work.
    • T shaped developer vs. I shaped.
    • No managers.
    • Come in different flavors
    • Target  has a lot more dojo material including tours.
  • 5/28/2018: Dungeons & Dragons, Volume 3 - Shadowplague (graphic novel, reading on Hoopla)
  • 5/27/2018: Dungeons & Dragons, Volume 2 - Shadowplague (graphic novel, reading on Hoopla)
  • 5/26/2018: Dungeons & Dragons, Volume 1 - Shadowplague (graphic novel, reading on Hoopla)
  • 5/25/2018: Queens of Infamy: Anne Boleyn on Long Reads by Anne Thériault 
    • I never had the opportunity to use "noted Tudor fuckboy" during my undergraduate degree.  I'm not sure Retha Warnicke would have appreciated it, but then again, she seemed pretty fun.
    • An entirely amusing paragraph on Anne bringing the blow job to England.
    • "Sadly, this A++ dick joke did not persuade the papal legate" is the best response I've ever seen to the "been to Spain" consummation tales about Arthur and Catherine.
    • "Henry, of course, could never resist the chance to be a tacky asshole." - probably spot on and, even more spot on in reference to Henry 8's wives, "they were all Henry's victims."
    • This made me wonder if people of the time ever said "Not my Harry" and "Not my King" and referred to him only as 8, implying a 9, or at least post-8, couldn't come soon enough.
  • 5/24/2018: The Theory of the Case: Competitive Intelligence Tips for Attorneys - University of Georgia Law, Suzanne R. Graham
    • I love the term "anecdata" based solely on a single incident.
    • More of a list - a comprehensive list - than a dig.  But the idea of "triangulation" as a way of validating the data is interesting.  And I respect her end-of-essay points about the unpredictable and that tools that "claim that past performance is the best predictor of future results" are not the only answer.
  • 5/23/2018: Analyzing the Analytics: A Review of Legal Analytics Platforms - The CRIV Sheet 39.2 (February 2017). - Diana J. Koppang, Neal, Gerber & Eisenberg, LLP
    • I liked her contention that she wants transparency in the search/results methodology and that's what she gets by crafting her own search.  
    • "know how we can trust the data and to what extent"
    • She also says you should always ask to have a dev in the demo for precisely those reasons.  
    • Go find her PDF!
  • 5/22/2018: Why Is New Orleans' Black Female Mayor Secretly Working With White Nationalists? - Splinter
    • Robert E Lee Beads, reinstalling racist statues, all sorts of crazy that surprised even me (who likes to read about crazies)
  • 5/21/2018: azn2azn (November 2017) - An Asian-American Twin Cities Zine.
    • I liked the poems, but the word "trigger" is used a little loosely.  From truly triggering events like police brutality, rape, and abuse, to questionable uses like Bollywood music during yoga (because it's traditionally a space for the elite pre-immigration and your ancestors might not have been elite? reminded me of the Singh story about the guy practicing yoga/healing who wanted to kill his faux-brother the king only to find out the king wanted to leave him material concerns so he could focus on spirituality), and being angry with friends only to say in the next statement the author got sober.  Triggering wasn't the issue there (presumably), alcohol was.  If it was, own it.
    • It was enlightening to read something so clearly different from my experience due to race, sexuality, identity.  A reminder that the world is very different through different lenses.
  • 5/20/2018: What's Next in Computing? - Chris Dixon (2016!)
    • Interesting to see the predictions from 2 years ago.  His focus on VR was pre-Pokemon Go (but not Ingress) and I saw an article for the first VR "kit" for online maps the other day, so it's coming of age.  IoT...yes, but still pretty quiet/centralized in some ways.  Machine learning/AI...spot on.
  • 5/19/2018: A NEW LOOK INSIDE THERANOS’ DYSFUNCTIONAL CORPORATE CULTURE - Wired
    • Great article about a truly dysfunctional culture.  Interesting to read this in light of Sprint and Inspired where the customer should be the focus, not the product.  Clearly, the product (and money and dates) were the focus for Theranos.
  • 5/18/2018: The Victorian Belief That a Train Ride Could Cause Instant Insanity
    • Kyle recommended this one from Atlas Obscura.  I don't think it delves enough into whether the train (and now, planes) causes the issue, exacerbates an existing issue, or for some people is an excuse because they have a foreign environment where they don't feel they have to behave.
  • 5/17/2018: Leaving Omelas: Science Fiction, Climate Change, and the Future by Vandana Singh.
    • Online essay.
    • "those who walk away do so because the Omelas paradigm allows them no agency in striving for a just and equitable social system."
    • I think she conflates dystopias and apocalyptic literature in some respect.  Per my thesis in college, I don't think a real dystopia has an escape, so the "great person" aspect is moot.  There might be an individual, but in the end they don't matter, only society can change society.
    • She's big on neartopias - finding the positive/ecological and societal change in society.
    • I very much enjoyed her Newtonian paradigm view of scifi.  That cause-effect isn't the end all of scifi, that everything is connected, and everything is interrelated.  Came through strongly in her story collection.
    • "Nature is objectified, transformed into a machine that is predictable and controllable, and we are outside it - masters of the machine..."
    • "Not all complex systems are sensitive to initial conditions..."
    • Posits place shapes the people....solid idea and one that makes scifi where there are so many places and inbetweens and emptiness-es, very interesting.
  • (BOOK/STORY) 5/16/2018: Ambiguity Machines and Other Stories by Vandana Singh: Requiem
    • A novella about global warming and Eskimos/Inuit and whaling.  Interesting story - very well written.  The scifi aspect had to do with the main character's aunt trying to create ways to live with other animals such that they could really start to understand them, and how animals were starting to communicate to eliminate human impacts to their environment (drilling machine/etc).
  • 5/15/2018 - Scalzi reread
  • (CODE) 5/14/2018: Data Science Essentials in Python: Collect - Organize - Explore - Predict - Value (The Pragmatic Programmers)
    • Chapter 2: Core Python for Data Science
    • Wrote a Top x words in a URL file program.
    • Wrote a file that indexes words and maps them to files in a directory using a dictionary.
    • Wrote a file that looks for phone numbers in a file.  That last one was only partially successful.  The 1- numbers not at the front or back of a file don't work as well.
    • Used PYTHONPATH to get to BeautifulSoup4 in my Anaconda3 directory (using IDLE usually, but I also have PyCharm and Sublime) as I'm in dev.
    • Used import sys and print(sys.path) to validate PYTHONPATH was returning the values I needed (BeautifulSoup wouldn't let me do a dual install and had dependencies of its own.  Could have mapped a path file in the project, but I'm playing, not pushing out production code).
  • (CODE) 5/14/2018: Data Science Essentials in Python: Collect - Organize - Explore - Predict - Value (The Pragmatic Programmers)
    • Chapter 1: What is Data Science - wrote a "Hello Scott" program.
  • (BOOK/STORY) 5/13/2018: Ambiguity Machines and Other Stories by Vandana Singh: Ambiguity Machines: An Examination
    • Three separate subtales about "machines" that transcend time and space and individuality.  They are generally structures/patterns.
  • (BOOK/STORY) 5/12/2018: Ambiguity Machines and Other Stories by Vandana Singh: Wake-Rider
    • This one felt incomplete.  Han Solo type (female) goes after a body that can stop a corporate-induced plague.  Ended with her floating and waiting.
  • (BOOK/STORY) 5/12/2018: Ambiguity Machines and Other Stories by Vandana Singh: Cry of the Karchal
    • I liked this even though it isn't strictly scifi.  More Arabian ghost story tying past to present via a woman who's a little like the mummy (in the modern movies), but...nice?  And a bird.
  • (BOOK/STORY) 5/12/2018: Ambiguity Machines and Other Stories by Vandana Singh: Sailing the Antarsa
    • Good story! About finding a different form of matter that flows between the stars and that it's comprised of life that can ride that matter.  Being immersed in it transforms the traveler.  Very "we're all in the same ecosystem" sort of story, but a great take.
  • (GN) 5/11/2018: KINO Volume 1: Escape From the Abyss
    • I assume this has to get better as it's primarily about a body in the clutches of a scientist who puts him in the equivalent of The Matrix to get his powers up to speed before he awakes.  There are competing companies/governments trying to get him back, but this whole book is just little in-his-head fights.  I wasn't enjoying it.
  • (GN) 5/10/2018: The Gravediggers Unions: Volume 1 - sort of a Cthulhu slant.  So so.  I discovered the Graphic Novel section on Hoopla, the online public library system.
  • (BOOK/STORY) 5/9/2018: Ambiguity Machines and Other Stories by Vandana Singh: Ruminations in an Alien Tongue
    • I liked this one!  There's a bit of the Star Trek episode (All Our Yesterdays) where a race abandons their planet by traveling to their own past.  In this story, they find alien artifacts that let them travel to other dimensions via the nexuses at the center of stars.  Because you can find a universe that best suits you, everyone just vacates.  One woman is left, and she tends to a traveler that comes from multiple dimensions (same traveler) and is always confused when he makes his way back to the lab/machines and the scientist who learned to use them.
  • (BOOK) 5/8/2018:  Sprint: How to Solve Big Problems and Test New Ideas in Just Five Days
    • Work-related book I was assigned.  We've done something similar on my teams, but there's a new push to determine faster ways to solve problems.
  • 5/7/2018: Product Conference (hosted by Dev Jam) at the Minnesota History Museum
    • Focus was on products and how to iterate and fail faster. 
    • Sara Cowles: Data Driven and Human Centered: Learning to Connect the Data for Maximum Impact  Talked about Ethnio software, the HEART Framework (Google Ventures), how we speed prototyping, and included some info about five (5) being the optimal number of testers per the Sprint book (above).
    • Mike Gillespie - Amazon's Culture of Innovation. Didn't get into enough detail.  Kind of boring.  The whole bit about no code until a press release, an 8 page product paper, and then a full user manual first really smells like old school waterfall in a way.
    • Vivienne Whifield - May you fail....over and over again.  Ok presentation.  Tied it to her kids and personal experiences with failure in the workplace.  I was wearing out a bit by end of day.
    • Keynote David Hussman - You're Definitely Wrong....  David looks in pretty rough shape physically, but he still gives a good presentation.    Pushing a variation of post-agile, beyond agile, deconstructed agile.
    • Jeff Sussna - Continuous Learning: Harnessing Change for Competitive Advantage.  I really enjoyed his keynote.  All about conversations and user-centered design and cross-functional design.  Good speaker - he's obviously been deep in this space for a while as a consultant.
  • (BOOK/STORY) 5/6/2018: Pretty Maggie Moneyeyes - Harlan Ellison, I Have No Mouth & I Must Scream
    • I think this one is also in Deathbird Stories and I have read it a dozen times.  There's quite a bit to unpack in this story, particularly about the characters and whether they got what they wanted or even deserved.  It makes sense it's in Deathbird Stories because it's about the worship of money, the worship of beauty, loneliness, and more.
  • (BOOK/STORY) 5/5/2018: Delusion for a Dragon Slayer - Harlan Ellison, I Have No Mouth & I Must Scream
    • One of my favorites.  I think it's also in Deathbird Stories.  There are some things it has in common with Lonelyache. But I like how it's handled better here in a magical Heavy Metal-esque world of legend with a harsh ending.
  • (BOOK/STORY) 5/4/2018: Lonelyache - Harlan Ellison, I Have No Mouth & I Must Scream
    • One of my least favorite of his stories.  The personification of dread and the heaviness of life as a thing in the corner.
  • 5/3/2018: Overview - Chrome Extensions
  • 5/3/2018: Getting Started Tutorial - Chrome Extensions
    • Yes, I did read both of those Chrome Extensions articles in full and modified - but not created - an in house Chrome extension for managing session tracking between our error system, session tracking system, enterprise tracking system, and Kibana (AWS logging).  Works like a charm, but I only had to do the configuration management to add the Kibana section.  Theoretically you could say it was coding because I had to use string concatenation, replacement, and character escape sequences, but that's just silly stuff.  It's more impressive that as a manager I checked my code into TFS and overrode the review and other policies (because it was POC, not mainline build).  That should scare everyone.
  • 5/2/2018: America’s Greatest Horticulturist Left Behind a Plum Mystery
    • Kyle posted it. Good article on Luther Burbank.
  • 5/1/2018: Kriegsspiel – The 19th Century War Game That Changed History - Military History Now.com
    • "all the cats living in the house hosting the game were banished"
    • This holds true for pretty much everything, including software teams, over one hundred years later.  "By giving his officer corps more responsibility, accountability and better understanding of tactics, the Prussians had a far more effective command structure."


Friday, February 02, 2018

Twitter Bot Analysis

I was playing around with this on my free time: https://rinzewind.org/blog-en/2018/replicating-the-new-york-times-bot-twitter-analysis-with-r-and-python.html

It was a good opportunity to mess around with Twitter's API, mess around with python (including pickling and caching), and mess around with R, which I've never touched before.  I made minor changes to the code so I could include user names and poked at the other properties on the Twitter user object.

Despite it being all spelled out for me, there were some tricky bits.  pip-ing the right Twitter api instance.  I had to use twitter-python, not just twitter, so there was some installing and uninstalling to get it right.  I could have used the OAuth/REST interfaces, but I wanted to mimic the article.  In the Python, trying to add the username was a little tricky for me mapping what he dumped to the cache (dd) back against the file.  The cache made it tricky because I had to remember to go kill it if I made model changes.  R...I thought I had it all wrong because I couldn't see the ggplot graph AT ALL at first.  But it was a sample size issue.  I was using small accounts, not million-user accounts, so the alpha wasn't layering up enough to show any depth of color.  A few minor changes to shape, alpha, size, and fill and it was easily visible, although it's less useful for real bot analysis.  R was fun to play with, but does most of the heavy lifting with the tidyverse module.  It was more about knowing the general syntax of the chart than doing any coding.

plt1 <- dd="" font="" ggplot="">
geom_point(aes(x = order, y = created_at),
color = "blue", fill="green", shape=21, alpha = 1, size = 2) +
xlab(sprintf("@%s's followers", username)) + 
ylab("Join date") + 
scale_y_datetime(date_breaks = "1 year", date_labels = "%Y")

To top it off, I think I maxed out my api rate limit, although I haven't checked.  I hope I wasn't blacklisted.  The number of calls is minimal, so if you're doing even as few as 1000 users, it can get maxed out quickly.
But, it worked for a while.  Here's Klund with a pretty typical chart.  A stable line since he started with a variety of users under the line and a little bit of clumping likely related to popular tweets.



And me.  One of the devs I work with told me it looks like a dinosaur.  The clumping in the circle, though minimal, is interesting because they're new people all at once. In my case, it's not bots, but some gaming and horror movie related companies that like some of my tweets.


Friday, February 03, 2017

Big O

A post I left elsewhere tonight.  I'm playing around with the first bits of The Python Companion to Data Science.

Hmm...my notes tell me a Python set should be approximately 15-30 times faster than a list, and Big O notation tells me I should see a more significant difference at the scale I'm using, but on lookup, it's about only twice as fast. I can't find anywhere that blames my copy of Windows for the problem, although I suspect it has something to do with that. Wait...no no. PEBKAC. I was doing the list to set conversion inside my elapsed timer. Took it outside the elapsed timer code and I'm 60x faster on the actual lookup, which is the magnitude of difference I expected to see based on O(n) and O(1). I think I just invented my next question for an intern candidate. Go back to what you're doing. I'm O(1)k now.

The code in question...