Skip to content

Create growingrecs.py #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions growingrecs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/lib/python2.7

# MIT License.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BSD license was what I chose for the github repo. It might be good for us to develop some suitable boilerplate to go at the top of each script, with links to the github, license, and other info. Not urgent, just a thought.

# Copyright 2014 Frances Hocutt

# growingrecs.py is a command-line tool to help you plan your garden.
# Given a crop, it uses the Growstuff API to finds the most common conditions
# that Growstuff users have used for that crop: how much sun, and whether they
# planted from seeds, seedlings, rootstock, etc.).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to have instructions for running this from the command line, eg. what args does it take, etc.


import requests
import string

def getcropinfo(crop):
"""Given a crop, gets the data available in Growstuff.

crop - a string with the crop to get data on. Whitespace and capitalization
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe mention that it needs to match the display name of a crop in Growstuff's database

are ok.
"""
cropslug = slugify(crop)
cropinfo = apirequest(cropslug)
return cropinfo

def slugify(crop):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to explain what a slug is.

"""Creates a slug. Lowercases, trims whitespace, replaces " " with "-"."""
crop = string.lower(crop)
crop = string.strip(crop)
crop = crop.replace(" ", "-")
return crop

def apirequest(cropslug):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interests of specificity I would suggest calling this something like fetch_crop_data

"""Given a slug, retrieves data from the Growstuff API. Returns a dict.

If the API returns an error, the user is prompted to try again.
"""
URI = "http://growstuff.org/crops/%s.json" % cropslug
r = requests.get(URI)
if r.status_code == 200:
cropinfo = r.json()
return cropinfo
elif r.status_code == 404:
#this gives NoneType not subscriptable errors, #FIXME
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a non-Python person, I don't understand this FIXME comment. Could you help me understand?

print ("We couldn't find that crop. "
"Please enter a crop that is in the Growstuff database.\n")
run()
else:
print "API error, please try again.\n"
run()

def parseplantings(cropinfo):
"""Counts how many plantings have the same (planted_from, sunniness) combo.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we necessarily need to combine these. We can just roughly replicate what's in the sidebar of the crop page, eg:

Plant from: seed (18), seedling (4)
Plant in: sun (22), semi-shade (10)

You could express this as a percentage if you liked. But I'm thinking that the combined version is a) quite a lot of complicated code, and b) not actually as useful as it might seem -- as a gardener, I don't actually need that combined information. If we want this to be the simplest possible API example, we don't need to do all that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incidentally, Growstuff's own code for how we generate that is in app/models/crop.rb in the methods crop.sunniness and crop.planted_from, which each return a hash. The actual display of this data is in app/views/crops/_planting_advice.html.haml


Returns a dict with frequency of conditions and an int with the total
number of plantings.

cropinfo - a dict from the API's json output
"""
planting_info = {}
plantings_count = cropinfo["plantings_count"]
for item in cropinfo["plantings"]:
conditions = (item["planted_from"], item["sunniness"])
if conditions in planting_info:
planting_info[conditions] += 1
else:
planting_info[conditions] = 1
return (planting_info, plantings_count)

def mostplantings(planting_info):
"""Returns a tuple with the most frequent conditions:
(planted_from, sunniness)."""
v = list(planting_info.values())
k = list(planting_info.keys())
return k[v.index(max(v))]

def run():
crop = raw_input("What would you like to plant?\n")
cropinfo = getcropinfo(crop)
planting_info, plantings_count = parseplantings(cropinfo)
if plantings_count > 0:
planted_from, sunniness = mostplantings(planting_info)
print "%s was planted %s times." % (crop, plantings_count)
print "It was most often planted from %s in %s." % (planted_from,
sunniness)
else:
print "%s has not been planted yet." % crop

if __name__ == "__main__":
run()

def test(crop, cropinfo):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be left in the code?

"""Same as run() but without the API call."""
planting_info, plantings_count = parseplantings(cropinfo)
if plantings_count > 0:
planted_from, sunniness = mostplantings(planting_info)
print "%s was planted %d times." % (crop, plantings_count)
print "It was most often planted from %s in %s." % (planted_from,
sunniness)
else:
print "%s has not been planted yet." % crop