Skip to content

Instantly share code, notes, and snippets.

@lancejohnson
lancejohnson / shopify_graphql_requests.py
Created August 23, 2023 16:52
Shopify GraphQL query using Requests
# Instantiate the client with an endpoint.
endpoint="https://renovationreserve.myshopify.com/admin/api/2023-07/graphql.json"
# Provide a GraphQL query
query = """
query ProductsBySku($skuFilter: String!){
products(first: 1, query: $skuFilter) {
edges {
node {
id
@lancejohnson
lancejohnson / strikes.r
Last active April 24, 2022 18:42
Model a "Strikes" system for deciding on sample sizes for binary tests with a threshold probability
# We're using a baseball analogy. E.g. A mailer gets 3 strikes per out and 3 outs in the first 9 pitches. All the limits are defined below
# inputs
ThresholdProb <- 0.03 # this is the minimum probability we need to be profitable for the business
num_simulations <- 1000
strikes_per_out = 3
outs_limit = 1
# The game starts here!
mailers_per_pitch = round(1 / ThresholdProb, 0)
mailers_per_simulation <- 1 / ThresholdProb * strikes_per_out * outs_limit
@lancejohnson
lancejohnson / close_crm_count_monthly_queries.py
Created August 26, 2020 17:55
Generate the counts for a given query over a period of months. Not beautiful, but pretty quick.
from os import environ
import requests
from requests.auth import HTTPBasicAuth
def create_close_params(starting_year, ending_year):
def generate_first_day_of_the_month(starting_year, ending_year):
first_day_of_the_month = []
for year in range(starting_year, ending_year + 1):
for month in range(1, 13):
@lancejohnson
lancejohnson / close_crm_count_leads.py
Created August 26, 2020 17:02
I frequently need an easy way to count the number of leads that match a given query in Close CRM. This is a quick way to do that. See Close CRM docs for more help https://developer.close.com/#leads
from os import environ
import requests
from requests.auth import HTTPBasicAuth
CLOSE_API_KEY = environ.get("CLOSE_API_KEY", "")
BASE_URL = "https://api.close.com/api/v1/lead/"
PARAMS = {"query": """(original_lead_status:"stat_pdBqiRfX6DrpDrE8v320qT2tCSSNURza5cv8aSWxdcp" and created >= "2020-06-01 00:00:00" and created <= "2020-06-30 23:59:59") or lead_status_change(new_status:"stat_pdBqiRfX6DrpDrE8v320qT2tCSSNURza5cv8aSWxdcp" and date >= "2020-06-01 00:00:00" and date <= "2020-06-30 23:59:59")"""}
resp = requests.get(BASE_URL, params=PARAMS, auth=HTTPBasicAuth(CLOSE_API_KEY, ""))
num_of_results = resp.json()["total_results"]
import calendar
def get_first_and_last_day_for_a_year(year_num):
first_and_last_dates = []
first_and_last_dates_formatted = []
for i in range(1, 13):
_, num_days = calendar.monthrange(year_num, i)
first_day = datetime.date(year_num, i, 1)
last_day = datetime.date(year_num, i, num_days)
first_and_last_dates.append([first_day, last_day])
## Input
{
"starting_url": "https://www.landwatch.com/Oklahoma_land_for_sale/Osage_County/Land",
"bucket": "landtoolsai"
}
## Output
Request: /scrape_landwatch
Status: 502
Latency: 1111 ms
@lancejohnson
lancejohnson / s3_to_buffer_test.py
Created April 18, 2020 16:58
A simple file to be sure I can load a file, keep it in memory and use it.
import boto3
import csv
import io
import os
from PIL import Image, ImageDraw, ImageFont
import pdb
def image_test():
def load_file_from_s3(*, bucket, key):
@lancejohnson
lancejohnson / census_surnames.py
Last active July 3, 2020 17:58
Download a range of surnames by rank from Census.gov. It calls the Census.gov Surname API (you must have an API key from the government). Here is a link to the API https://www.census.gov/data/developers/data-sets/surnames.2010.html. I chose to call the top 100,000 surnames due to frequency. Page 4 of this explanatory PDF has an excellent frequen…
import csv
import os
import requests
CENSUS_API_KEY = os.environ.get("CENSUS_API_KEY", "")
CENSUS_SURNAME_URL = "https://api.census.gov/data/2010/surname"
params = {
"key": CENSUS_API_KEY,
"get": "NAME,COUNT",
@lancejohnson
lancejohnson / word_split.py
Last active March 26, 2020 13:42
A simple python function to split a string into a list of strings based on a character limit. It preserves the words entire. For instance if you have a limit of four characters "A dog" would be generated as ["A", "dog"] so as not to split up the word into ["A do", "g"]
def add_string_breaks(string):
list_words_in_str = string.split()
str_standard_whitespace = " ".join(list_words_in_str)
count_words_in_str = len(list_words_in_str)
slogan_lines = []
i = 0
possible_words_in_line = count_words_in_str
while i < possible_words_in_line:
text_already_newline = " ".join(slogan_lines)
�E�H�@#t����o���ُ���l%�|`��t�q�d =&#�Q"K^I����߯�U�TV��M�LhDo��ƿ����w�͟����L�
<�1�7��-^�?���ψ=��6�L�.n2fF��NDr$��-��f�uWqt �0-�S h0�
��`NPC��8���w-'�߰�@ԊP�HRhU�hR�2�W��}6�)!���_�³}y0�h�Q!��ȵ! ����a������yڏ��~�*' ��# \���~2�����l6Ȑ29
�\$ݧC�=:S#�ca�b9����.�� ��NL�Z�-H��g ��&���㘘�K� �a�ﮞ.�5?�|��W��yqr��9������
�b�b8G��}�Y"�2(���-�q�W^��O�)�]���(���<M(|���8���sY&�C�˼�\Qu\+����/���`Myb���Q�
<�t��ę:{Q�'^\?}��`]�9vr��4��( ������ ��P��e����cL���l�o�����1�q��:��>
�G_�="�wd8�:����6�Ћjp1@�����5���e�>�&�pk��r�*v�CZ����a�Nͽ��3�}�˟ ߽�O|��͕�=2�Q'
< áo�SǬa��,���pb�$XQb���<�O������-��q�4Vt�䣀��6��.���P�îV�����Q2��S���I��P�i&A�Gd�.����`x�M[�����>
%����Y�u� k�'��p�kFs�9G���A0N��I���(�|U�ÕFD��E���六\���
�v�D��Y������ewI�^�H PE�|��,�#k��I?qiK�;�zoCr+#���0����%A��1�V1LnU�I���x��yq������.�i��2�H�sX�r��5��q����"3T���n��L�\�O