Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • ThomasPowell 11:01 am on July 20, 2020 Permalink  

    Planet Fitness Cancellation Template 

    Update: I put this in the mail on Tuesday and got cancellation confirmation less than 48 hours later.

    Also, your mileage may vary, some locations are a little more of a stickler about certified mail, but you should get a confirmation from the location within a few days if they’ve accepted.

    I needed to cancel Planet Fitness in the middle of the COVID-19 pandemic and I really didn’t want to be showing up at a gym in person right now (time and unnecessary risk) just to cancel.

    I called up my local Planet Fitness and was told I could either come in in person *or* send a [yes, snail mail] letter to the Planet Fitness I signed up at.

    So, I’ve thrown together a cheap template to help you include everything you need to cancel (it’s just name, date of birth, and signature, according to the person on the phone.)

    You can download the doc I put together at: Planet Fitness Cancellation Word Doc template

     
  • ThomasPowell 9:25 am on July 5, 2022 Permalink | Reply
    Tags: billion laughs attack, owasp,   

    TIL https://en.wikipedia.org/wiki/Billion_laughs_attack

    Looks like Nokogiri is too simplistic (by default) to be affected, but the Psych parser in Ruby isn’t so lucky (if you expand to ruby objects, of course… it parses to a Psych object just fine.)

     
  • ThomasPowell 9:21 pm on June 21, 2022 Permalink | Reply
    Tags: design patterns, factory pattern   

    Factory Pattern in Ruby 

    A discussion came up today discussing how the factory pattern looks in certain languages, and I found myself thinking about how it might look in Ruby. A quick Google resulted in an example that seemed to violate part of the reason for the Factory Pattern in the first place (there was a distinct factory for every subclass?), so I decided to ponder my own contrived example to refresh my knowledge.

    Factory Pattern Contrived Example: Shapes

    One example that I quickly thought of (but quickly became useless beyond three sides) was a factory that got an instance of a Shape subclass when given a variable number of sides. Ultimately, a Triangle can have its perimeter and area determined if only the lengths of the sides are known, but any shape beyond that needs either diagonals or angles specified. So I settled on the factory producing either a Triangle that could report back an area or a perimeter or a generic Polygon (arbitrarily excluding Triangle from this) that would only report back perimeter and raise an InterdeterminateArea if the area was requested.

    No news is Good news

    A hallmark of the factory pattern is blocking instantiation directly on the target classes (in this case, making new protected so that only classes within the hierarchy can access it. If our .new method is properly protected, then we should receive a NoMethodError calling .new. (It is enough to assert that NoMethodError is raised because otherwise, all classes should respond to .new:

    The MiniTest cases

    require 'minitest/autorun'
    require_relative 'shape_factory'
    
    class TestShapeFactory < MiniTest::Unit::TestCase
      def test_triangle
        triangle=Shape.get_shape(3,3,3)
        assert_in_epsilon(3.89, triangle.area, 0.01)
        assert_equal(9, triangle.perimeter)
        assert_instance_of(Triangle, triangle)
      end
    
      def test_polygon
        polygon=Shape.get_shape(4,4,4,4)
        assert_equal(16, polygon.perimeter)
        assert_raises(IndeterminateArea) {polygon.area}
        assert_instance_of(Polygon, polygon)
      end
    
      def test_new_shape
        assert_raises(NoMethodError) {Triangle.new}
        assert_raises(NoMethodError) {Polygon.new}
        assert_raises(NoMethodError) {Shape.new}
      end
    end
    

    Above we have are testing that get_shape with 3 arguments returns a Triangle that can return an area (using assert_in_epsilon because the result is irrational) and a perimeter. test_polygon tests that a shape with 4 sides returns a Polygon that can correctly return a perimeter but raises an InterdeterminateArea when #area is called. Finally, test_new_shape validates that we have correctly blocked .new calls on Shape, Polygon, and Triangle.

    shape_factory.rb

    class Shape
      # be sure to protect {class}.new, not instance.new
      class << self
        protected :new
      end
    
      def self.get_shape(*sides)
        case sides.length
        when 3
          Triangle.new(*sides)
        else
          Polygon.new(*sides)
        end
      end
    
      def perimeter
        @perimeter ||= @sides.inject(:+)
      end
    
      def area
        raise 'not implemented'
      end
    
      def initialize(*sides)
        @sides = sides
      end
    end
    
    class Triangle < Shape
      def area
        # Heron's Formula
        Math.sqrt(perimeter/2.0*(@sides.map {|s| perimeter/2.0 - s}.inject(:*)))
      end
    end
    
    class IndeterminateArea < StandardError; end
    
    class Polygon < Shape
      def area
        raise IndeterminateArea
      end
    end
    

    Ultimately, Polygon could probably be collapsed into Shape and only return Triangle. Of course, implementations of shapes with more sides could be made to provide area, but they would require providing additional information to get_shape that might expose the need for the sender to have an awareness of implementation details. Another option might be to pass the successive vertices of the polygon which might allow deeper inferring of how to calculate meaningful information from the shape, but this example is a start with a factory pattern implementation that can be expanded as necessary.

     
  • ThomasPowell 6:58 am on June 21, 2022 Permalink | Reply
    Tags: 3dprint, aeropress, ender3pro   

    Finally got the Aeropress stand printed on the &#x1f308; silk PLA 

    Direct repackaging of the design here on Amazon
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
%d bloggers like this: