master 419d76f6562a cached
17 files
39.8 KB
12.2k tokens
54 symbols
1 requests
Download .txt
Repository: garybernhardt/destroy-all-software-extras
Branch: master
Commit: 419d76f6562a
Files: 17
Total size: 39.8 KB

Directory structure:
gitextract_ee0bj18n/

├── das-0010-fast-tests-with-and-without-rails/
│   └── test
├── das-0026-controller-refactoring-demo-part-2/
│   └── account_controller.rb
├── das-0030-some-vim-tips/
│   ├── grb256.vim
│   └── ir_black.vim
├── das-0070-time-to-first-request/
│   └── time_to_first_request.sh
├── das-0094-computing-by-constructing/
│   ├── everything.py
│   └── lambda.py
├── das-0095-power-of-lambda-calculus/
│   ├── everything.py
│   └── lambda.py
└── das-0102-data-compressor-from-scratch/
    ├── LICENSE
    ├── README
    ├── RUNME.sh
    ├── bin.rb
    ├── garyzip.rb
    ├── imgcat
    ├── rendertree.rb
    └── tree.dot

================================================
FILE CONTENTS
================================================

================================================
FILE: das-0010-fast-tests-with-and-without-rails/test
================================================
#!/bin/bash
#
# From Destroy All Software screencast #10, at:
# http://destroyallsoftware.com/screencasts/catalog/fast-tests-with-and-without-rails
#
# Released under the MIT license: http://opensource.org/licenses/MIT
#
# Put this in the script/ directory of your Rails app, then run it with a spec
# filename. If the spec uses spec_helper, it'll be run inside Bundler.
# Otherwise, it'll be run directly with whatever `rspec` executable is on the
# path.

set -e

need_rails=1

if [ $# -gt 0 ]; then # we have args
    filename=$1
    # Remove trailing line numbers from filename, e.g. spec/my_spec.rb:33
    grep_filename=`echo $1 | sed 's/:.*$//g'`

    # if we can't match "spec_helper" in our file we have a stand-alone spec
    grep -r '\bspec_helper\b' $grep_filename > /dev/null || need_rails=''
else # we have no args
    filename='spec'
fi

command='rspec'

if [ $need_rails ]; then
    command="ruby -S bundle exec $command"
fi

RAILS_ENV=test $command $filename



================================================
FILE: das-0026-controller-refactoring-demo-part-2/account_controller.rb
================================================
#-- copyright
# ChiliProject is a project management system.
#
# Copyright (C) 2010-2011 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# See doc/COPYRIGHT.rdoc for more details.
#++

class AccountController < ApplicationController
  include CustomFieldsHelper

  # prevents login action to be filtered by check_if_login_required application scope filter
  skip_before_filter :check_if_login_required

  # Login request and validation
  def login
    if request.get?
      logout_user
    else
      authenticate_user
    end
  end

  # Log out current user and redirect to welcome page
  def logout
    logout_user
    redirect_to home_url
  end

  # Enable user to choose a new password
  def lost_password
    redirect_to(home_url) && return unless Setting.lost_password?
    if params[:token]
      handle_existing_token
    else
      generate_token
    end
  end

  def handle_existing_token
    @token = Token.find_by_action_and_value("recovery", params[:token])
    redirect_to(home_url) && return unless have_valid_token?
    @user = @token.user
    if request.post?
      reset_password
    else
      render :template => "account/password_recovery"
    end
  end

  def have_valid_token?
    @token and !@token.expired?
  end

  def reset_password
    @user.password = params[:new_password]
    @user.password_confirmation = params[:new_password_confirmation]
    if @user.save
      @token.destroy
      flash[:notice] = l(:notice_account_password_updated)
      redirect_to :action => 'login'
    else
      render :template => "account/password_recovery"
    end
  end

  def generate_token
    return unless request.post?

    user = User.find_by_mail(params[:mail])

    if ensure_user_exists(user) && ensure_no_external_auth(user)
      create_new_token(user)
    end
  end

  def ensure_user_exists(user)
    if user
      true
    else
      flash.now[:error] = l(:notice_account_unknown_email)
      false
    end
  end

  def ensure_no_external_auth(user)
    if user.auth_source_id
      flash.now[:error] = l(:notice_can_t_change_password)
      false
    else
      true
    end
  end

  def create_new_token(user)
    token = Token.new(:user => user, :action => "recovery")
    if token.save
      Mailer.deliver_lost_password(token)
      flash[:notice] = l(:notice_account_lost_email_sent)
      redirect_to :action => 'login', :back_url => home_url
      return
    end
  end

  # User self-registration
  def register
    redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
    if request.get?
      session[:auth_source_registration] = nil
      @user = User.new(:language => Setting.default_language)
    else
      @user = User.new(params[:user])
      @user.admin = false
      @user.register
      if session[:auth_source_registration]
        @user.activate
        @user.login = session[:auth_source_registration][:login]
        @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
        if @user.save
          session[:auth_source_registration] = nil
          self.logged_user = @user
          flash[:notice] = l(:notice_account_activated)
          redirect_to :controller => 'my', :action => 'account'
        end
      else
        @user.login = params[:user][:login]
        @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]

        case Setting.self_registration
        when '1'
          register_by_email_activation(@user)
        when '3'
          register_automatically(@user)
        else
          register_manually_by_administrator(@user)
        end
      end
    end
  end

  # Token based account activation
  def activate
    redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
    token = Token.find_by_action_and_value('register', params[:token])
    redirect_to(home_url) && return unless token and !token.expired?
    user = token.user
    redirect_to(home_url) && return unless user.registered?
    user.activate
    if user.save
      token.destroy
      flash[:notice] = l(:notice_account_activated)
    end
    redirect_to :action => 'login'
  end

  private

  def logout_user
    if User.current.logged?
      cookies.delete Redmine::Configuration['autologin_cookie_name']
      Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
      self.logged_user = nil
    end
  end

  def authenticate_user
    if Setting.openid? && using_open_id?
      open_id_authenticate(params[:openid_url])
    else
      password_authentication
    end
  end

  def password_authentication
    user = User.try_to_login(params[:username], params[:password])

    if user.nil?
      invalid_credentials
    elsif user.new_record?
      onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
    else
      # Valid user
      successful_authentication(user)
    end
  end


  def open_id_authenticate(openid_url)
    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url) do |result, identity_url, registration|
      if result.successful?
        user = User.find_or_initialize_by_identity_url(identity_url)
        if user.new_record?
          # Self-registration off
          redirect_to(home_url) && return unless Setting.self_registration?

          # Create on the fly
          user.login = registration['nickname'] unless registration['nickname'].nil?
          user.mail = registration['email'] unless registration['email'].nil?
          user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
          user.random_password
          user.register

          case Setting.self_registration
          when '1'
            register_by_email_activation(user) do
              onthefly_creation_failed(user)
            end
          when '3'
            register_automatically(user) do
              onthefly_creation_failed(user)
            end
          else
            register_manually_by_administrator(user) do
              onthefly_creation_failed(user)
            end
          end
        else
          # Existing record
          if user.active?
            successful_authentication(user)
          else
            account_pending
          end
        end
      end
    end
  end

  def successful_authentication(user)
    # Valid user
    self.logged_user = user
    # generate a key and set cookie if autologin
    if params[:autologin] && Setting.autologin?
      set_autologin_cookie(user)
    end
    call_hook(:controller_account_success_authentication_after, {:user => user })
    redirect_back_or_default :controller => 'my', :action => 'page'
  end

  def set_autologin_cookie(user)
    token = Token.create(:user => user, :action => 'autologin')
    cookie_options = {
      :value => token.value,
      :expires => 1.year.from_now,
      :path => Redmine::Configuration['autologin_cookie_path'],
      :secure => Redmine::Configuration['autologin_cookie_secure'],
      :httponly => true
    }
    cookies[Redmine::Configuration['autologin_cookie_name']] = cookie_options
  end

  # Onthefly creation failed, display the registration form to fill/fix attributes
  def onthefly_creation_failed(user, auth_source_options = { })
    @user = user
    session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
    render :action => 'register'
  end

  def invalid_credentials
    logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
    flash.now[:error] = l(:notice_account_invalid_creditentials)
  end

  # Register a user for email activation.
  #
  # Pass a block for behavior when a user fails to save
  def register_by_email_activation(user, &block)
    token = Token.new(:user => user, :action => "register")
    if user.save and token.save
      Mailer.deliver_register(token)
      flash[:notice] = l(:notice_account_register_done)
      redirect_to :action => 'login'
    else
      yield if block_given?
    end
  end

  # Automatically register a user
  #
  # Pass a block for behavior when a user fails to save
  def register_automatically(user, &block)
    # Automatic activation
    user.activate
    user.last_login_on = Time.now
    if user.save
      self.logged_user = user
      flash[:notice] = l(:notice_account_activated)
      redirect_to :controller => 'my', :action => 'account'
    else
      yield if block_given?
    end
  end

  # Manual activation by the administrator
  #
  # Pass a block for behavior when a user fails to save
  def register_manually_by_administrator(user, &block)
    if user.save
      # Sends an email to the administrators
      Mailer.deliver_account_activation_request(user)
      account_pending
    else
      yield if block_given?
    end
  end

  def account_pending
    flash[:notice] = l(:notice_account_pending)
    redirect_to :action => 'login'
  end
end


================================================
FILE: das-0030-some-vim-tips/grb256.vim
================================================
" Based on
runtime colors/ir_black.vim

let g:colors_name = "grb256"

hi pythonSpaceError ctermbg=red guibg=red

hi Comment ctermfg=darkgray

hi StatusLine ctermbg=darkgrey ctermfg=white
hi StatusLineNC ctermbg=black ctermfg=lightgrey
hi VertSplit ctermbg=black ctermfg=lightgrey
hi LineNr ctermfg=darkgray
hi CursorLine     guifg=NONE        guibg=#121212     gui=NONE      ctermfg=NONE        ctermbg=234
hi Function         guifg=#FFD2A7     guibg=NONE        gui=NONE      ctermfg=yellow       ctermbg=NONE        cterm=NONE
hi Visual           guifg=NONE        guibg=#262D51     gui=NONE      ctermfg=NONE        ctermbg=236    cterm=NONE

hi Error            guifg=NONE        guibg=NONE        gui=undercurl ctermfg=16       ctermbg=red         cterm=NONE     guisp=#FF6C60 " undercurl color
hi ErrorMsg         guifg=white       guibg=#FF6C60     gui=BOLD      ctermfg=16       ctermbg=red         cterm=NONE
hi WarningMsg       guifg=white       guibg=#FF6C60     gui=BOLD      ctermfg=16       ctermbg=red         cterm=NONE
hi SpellBad       guifg=white       guibg=#FF6C60     gui=BOLD      ctermfg=16       ctermbg=160         cterm=NONE

" ir_black doesn't highlight operators for some reason
hi Operator        guifg=#6699CC     guibg=NONE        gui=NONE      ctermfg=lightblue   ctermbg=NONE        cterm=NONE

highlight DiffAdd term=reverse cterm=bold ctermbg=lightgreen ctermfg=16
highlight DiffChange term=reverse cterm=bold ctermbg=lightblue ctermfg=16
highlight DiffText term=reverse cterm=bold ctermbg=lightgray ctermfg=16
highlight DiffDelete term=reverse cterm=bold ctermbg=lightred ctermfg=16

highlight PmenuSel ctermfg=16 ctermbg=156



================================================
FILE: das-0030-some-vim-tips/ir_black.vim
================================================
" ir_black color scheme
" More at: http://blog.infinitered.com/entries/show/8


" ********************************************************************************
" Standard colors used in all ir_black themes:
" Note, x:x:x are RGB values
"
"  normal: #f6f3e8
" 
"  string: #A8FF60  168:255:96                   
"    string inner (punc, code, etc): #00A0A0  0:160:160
"  number: #FF73FD  255:115:253                 
"  comments: #7C7C7C  124:124:124
"  keywords: #96CBFE  150:203:254             
"  operators: white
"  class: #FFFFB6  255:255:182
"  method declaration name: #FFD2A7  255:210:167
"  regular expression: #E9C062  233:192:98
"    regexp alternate: #FF8000  255:128:0
"    regexp alternate 2: #B18A3D  177:138:61
"  variable: #C6C5FE  198:197:254
"  
" Misc colors:
"  red color (used for whatever): #FF6C60   255:108:96 
"     light red: #FFB6B0   255:182:176
"
"  brown: #E18964  good for special
"
"  lightpurpleish: #FFCCFF
" 
" Interface colors:
"  background color: black
"  cursor (where underscore is used): #FFA560  255:165:96
"  cursor (where block is used): white
"  visual selection: #1D1E2C  
"  current line: #151515  21:21:21
"  search selection: #07281C  7:40:28
"  line number: #3D3D3D  61:61:61


" ********************************************************************************
" The following are the preferred 16 colors for your terminal
"           Colors      Bright Colors
" Black     #4E4E4E     #7C7C7C
" Red       #FF6C60     #FFB6B0
" Green     #A8FF60     #CEFFAB
" Yellow    #FFFFB6     #FFFFCB
" Blue      #96CBFE     #FFFFCB
" Magenta   #FF73FD     #FF9CFE
" Cyan      #C6C5FE     #DFDFFE
" White     #EEEEEE     #FFFFFF


" ********************************************************************************
set background=dark
hi clear

if exists("syntax_on")
  syntax reset
endif

let colors_name = "ir_black"


"hi Example         guifg=NONE        guibg=NONE        gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE

" General colors
hi Normal           guifg=#f6f3e8     guibg=black       gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE
hi NonText          guifg=#070707     guibg=black       gui=NONE      ctermfg=black       ctermbg=NONE        cterm=NONE

hi Cursor           guifg=black       guibg=white       gui=NONE      ctermfg=black       ctermbg=white       cterm=reverse
hi LineNr           guifg=#3D3D3D     guibg=black       gui=NONE      ctermfg=darkgray    ctermbg=NONE        cterm=NONE

hi VertSplit        guifg=#202020     guibg=#202020     gui=NONE      ctermfg=darkgray    ctermbg=darkgray    cterm=NONE
hi StatusLine       guifg=#CCCCCC     guibg=#202020     gui=italic    ctermfg=white       ctermbg=darkgray    cterm=NONE
hi StatusLineNC     guifg=black       guibg=#202020     gui=NONE      ctermfg=blue        ctermbg=darkgray    cterm=NONE  

hi Folded           guifg=#a0a8b0     guibg=#384048     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE
hi Title            guifg=#f6f3e8     guibg=NONE        gui=bold      ctermfg=NONE        ctermbg=NONE        cterm=NONE
hi Visual           guifg=NONE        guibg=#262D51     gui=NONE      ctermfg=NONE        ctermbg=darkgray    cterm=NONE

hi SpecialKey       guifg=#808080     guibg=#343434     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE

hi WildMenu         guifg=green       guibg=yellow      gui=NONE      ctermfg=black       ctermbg=yellow      cterm=NONE
hi PmenuSbar        guifg=black       guibg=white       gui=NONE      ctermfg=black       ctermbg=white       cterm=NONE
"hi Ignore           guifg=gray        guibg=black       gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE

hi Error            guifg=NONE        guibg=NONE        gui=undercurl ctermfg=white       ctermbg=red         cterm=NONE     guisp=#FF6C60 " undercurl color
hi ErrorMsg         guifg=white       guibg=#FF6C60     gui=BOLD      ctermfg=white       ctermbg=red         cterm=NONE
hi WarningMsg       guifg=white       guibg=#FF6C60     gui=BOLD      ctermfg=white       ctermbg=red         cterm=NONE

" Message displayed in lower left, such as --INSERT--
hi ModeMsg          guifg=black       guibg=#C6C5FE     gui=BOLD      ctermfg=black       ctermbg=cyan        cterm=BOLD

if version >= 700 " Vim 7.x specific colors
  hi CursorLine     guifg=NONE        guibg=#121212     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=BOLD
  hi CursorColumn   guifg=NONE        guibg=#121212     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=BOLD
  hi MatchParen     guifg=#f6f3e8     guibg=#857b6f     gui=BOLD      ctermfg=white       ctermbg=darkgray    cterm=NONE
  hi Pmenu          guifg=#f6f3e8     guibg=#444444     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE
  hi PmenuSel       guifg=#000000     guibg=#cae682     gui=NONE      ctermfg=NONE        ctermbg=NONE        cterm=NONE
  hi Search         guifg=NONE        guibg=NONE        gui=underline ctermfg=NONE        ctermbg=NONE        cterm=underline
endif

" Syntax highlighting
hi Comment          guifg=#7C7C7C     guibg=NONE        gui=NONE      ctermfg=darkgray    ctermbg=NONE        cterm=NONE
hi String           guifg=#A8FF60     guibg=NONE        gui=NONE      ctermfg=green       ctermbg=NONE        cterm=NONE
hi Number           guifg=#FF73FD     guibg=NONE        gui=NONE      ctermfg=magenta     ctermbg=NONE        cterm=NONE

hi Keyword          guifg=#96CBFE     guibg=NONE        gui=NONE      ctermfg=blue        ctermbg=NONE        cterm=NONE
hi PreProc          guifg=#96CBFE     guibg=NONE        gui=NONE      ctermfg=blue        ctermbg=NONE        cterm=NONE
hi Conditional      guifg=#6699CC     guibg=NONE        gui=NONE      ctermfg=blue        ctermbg=NONE        cterm=NONE  " if else end

hi Todo             guifg=#8f8f8f     guibg=NONE        gui=NONE      ctermfg=red         ctermbg=NONE        cterm=NONE
hi Constant         guifg=#99CC99     guibg=NONE        gui=NONE      ctermfg=cyan        ctermbg=NONE        cterm=NONE

hi Identifier       guifg=#C6C5FE     guibg=NONE        gui=NONE      ctermfg=cyan        ctermbg=NONE        cterm=NONE
hi Function         guifg=#FFD2A7     guibg=NONE        gui=NONE      ctermfg=brown       ctermbg=NONE        cterm=NONE
hi Type             guifg=#FFFFB6     guibg=NONE        gui=NONE      ctermfg=yellow      ctermbg=NONE        cterm=NONE
hi Statement        guifg=#6699CC     guibg=NONE        gui=NONE      ctermfg=lightblue   ctermbg=NONE        cterm=NONE

hi Special          guifg=#E18964     guibg=NONE        gui=NONE      ctermfg=white       ctermbg=NONE        cterm=NONE
hi Delimiter        guifg=#00A0A0     guibg=NONE        gui=NONE      ctermfg=cyan        ctermbg=NONE        cterm=NONE
hi Operator         guifg=white       guibg=NONE        gui=NONE      ctermfg=white       ctermbg=NONE        cterm=NONE

hi link Character       Constant
hi link Boolean         Constant
hi link Float           Number
hi link Repeat          Statement
hi link Label           Statement
hi link Exception       Statement
hi link Include         PreProc
hi link Define          PreProc
hi link Macro           PreProc
hi link PreCondit       PreProc
hi link StorageClass    Type
hi link Structure       Type
hi link Typedef         Type
hi link Tag             Special
hi link SpecialChar     Special
hi link SpecialComment  Special
hi link Debug           Special


" Special for Ruby
hi rubyRegexp                  guifg=#B18A3D      guibg=NONE      gui=NONE      ctermfg=brown          ctermbg=NONE      cterm=NONE
hi rubyRegexpDelimiter         guifg=#FF8000      guibg=NONE      gui=NONE      ctermfg=brown          ctermbg=NONE      cterm=NONE
hi rubyEscape                  guifg=white        guibg=NONE      gui=NONE      ctermfg=cyan           ctermbg=NONE      cterm=NONE
hi rubyInterpolationDelimiter  guifg=#00A0A0      guibg=NONE      gui=NONE      ctermfg=blue           ctermbg=NONE      cterm=NONE
hi rubyControl                 guifg=#6699CC      guibg=NONE      gui=NONE      ctermfg=blue           ctermbg=NONE      cterm=NONE  "and break, etc
"hi rubyGlobalVariable          guifg=#FFCCFF      guibg=NONE      gui=NONE      ctermfg=lightblue      ctermbg=NONE      cterm=NONE  "yield
hi rubyStringDelimiter         guifg=#336633      guibg=NONE      gui=NONE      ctermfg=lightgreen     ctermbg=NONE      cterm=NONE
"rubyInclude
"rubySharpBang
"rubyAccess
"rubyPredefinedVariable
"rubyBoolean
"rubyClassVariable
"rubyBeginEnd
"rubyRepeatModifier
"hi link rubyArrayDelimiter    Special  " [ , , ]
"rubyCurlyBlock  { , , }

hi link rubyClass             Keyword 
hi link rubyModule            Keyword 
hi link rubyKeyword           Keyword 
hi link rubyOperator          Operator
hi link rubyIdentifier        Identifier
hi link rubyInstanceVariable  Identifier
hi link rubyGlobalVariable    Identifier
hi link rubyClassVariable     Identifier
hi link rubyConstant          Type  


" Special for Java
" hi link javaClassDecl    Type
hi link javaScopeDecl         Identifier 
hi link javaCommentTitle      javaDocSeeTag 
hi link javaDocTags           javaDocSeeTag 
hi link javaDocParam          javaDocSeeTag 
hi link javaDocSeeTagParam    javaDocSeeTag 

hi javaDocSeeTag              guifg=#CCCCCC     guibg=NONE        gui=NONE      ctermfg=darkgray    ctermbg=NONE        cterm=NONE
hi javaDocSeeTag              guifg=#CCCCCC     guibg=NONE        gui=NONE      ctermfg=darkgray    ctermbg=NONE        cterm=NONE
"hi javaClassDecl              guifg=#CCFFCC     guibg=NONE        gui=NONE      ctermfg=white       ctermbg=NONE        cterm=NONE


" Special for XML
hi link xmlTag          Keyword 
hi link xmlTagName      Conditional 
hi link xmlEndTag       Identifier 


" Special for HTML
hi link htmlTag         Keyword 
hi link htmlTagName     Conditional 
hi link htmlEndTag      Identifier 


" Special for Javascript
hi link javaScriptNumber      Number 


" Special for Python
"hi  link pythonEscape         Keyword      


" Special for CSharp
hi  link csXmlTag             Keyword      


" Special for PHP


================================================
FILE: das-0070-time-to-first-request/time_to_first_request.sh
================================================
#!/bin/bash

main() {
    print_runtime > /dev/null
    print_runtime
}

print_runtime() {
    pid=$(start_server)
    runtime=$(time_command wait_for_server)
    baseline=$(time_command wait_for_server)
    echo $runtime - $baseline | bc
    kill -9 $pid
}

start_server() {
    cd example
    rackup >/dev/null 2>&1 &
    echo $!
}

time_command() {
    local cmd=$*
    TIMEFORMAT="%3R"
    (time $cmd) 2>&1
}

wait_for_server() {
    while true; do
        lsof -i :9292 > /dev/null
        if [[ $? == 0 ]]; then
            break
        fi
    done
}

main



================================================
FILE: das-0094-computing-by-constructing/everything.py
================================================
#!/usr/bin/env python3

NULL = (
    lambda x: x
)

TRUE = (
    lambda t: lambda f: t(NULL)
)
FALSE = (
    lambda t: lambda f: f(NULL)
)
IF = (
    lambda cond: lambda t: lambda f: cond(t)(f)
)

ZERO = (
    lambda f: lambda x: x
)

ADD1 = (
    lambda n: lambda f: lambda x: f( n(f)(x) )
)
ADD = (
    lambda n: lambda m: n(ADD1)(m)
)

# Is this number equal to zero?
IS_ZERO = (
    lambda n: n(lambda x: FALSE)(TRUE)
)

# Subtract 1: opposite of S, so SUB1(ONE) == ZERO.
# Like Y, this is more complex and subtle than most
# of our functions have been. It's OK to skip over it
# during this introduction.
SUB1 = (
    (lambda n:
     lambda f:
     lambda x: n (lambda g: lambda h: h(g(f)))
                 (lambda u: x)
                 (lambda u: u))
)

# Multiplication: "add m to zero n times".
MULT = (
    lambda n: lambda m: n(lambda x:
                          ADD(x)(m))(ZERO)
)

ONE = (
    ADD1(ZERO)
)
SIX = (
    ADD1(ADD1(ADD1(ADD1(ADD1(ADD1(ZERO))))))
)


================================================
FILE: das-0094-computing-by-constructing/lambda.py
================================================
#!/usr/bin/env python3

ONE = 1
IS_ZERO = lambda x: x == 0
SUB1 = lambda x: x - 1
MULT = lambda x: lambda y: x * y
IF = lambda cond: lambda t_func: lambda f_func: t_func(None) if cond else f_func(None)

print(
    (
        lambda myself: (
            lambda n: (
                IF(
                    IS_ZERO(n)
                )(
                    lambda _: ONE
                )(
                    lambda _: MULT(n)( myself(myself)(SUB1(n)) )
                )
            )
        )
    )(
        lambda myself: (
            lambda n: (
                IF(
                    IS_ZERO(n)
                )(
                    lambda _: ONE
                )(
                    lambda _: MULT(n)( myself(myself)(SUB1(n)) )
                )
            )
        )
    )
    (6)
)


================================================
FILE: das-0095-power-of-lambda-calculus/everything.py
================================================
#!/usr/bin/env python3

NULL = (
    lambda x: x
)

TRUE = (
    lambda t: lambda f: t(NULL)
)
FALSE = (
    lambda t: lambda f: f(NULL)
)
IF = (
    lambda cond: lambda t: lambda f: cond(t)(f)
)

ZERO = (
    lambda f: lambda x: x
)

ADD1 = (
    lambda n: lambda f: lambda x: f( n(f)(x) )
)
ADD = (
    lambda n: lambda m: n(ADD1)(m)
)

# Is this number equal to zero?
IS_ZERO = (
    lambda n: n(lambda x: FALSE)(TRUE)
)

# Subtract 1: opposite of S, so SUB1(ONE) == ZERO.
# Like Y, this is more complex and subtle than most
# of our functions have been. It's OK to skip over it
# during this introduction.
SUB1 = (
    (lambda n:
     lambda f:
     lambda x: n (lambda g: lambda h: h(g(f)))
                 (lambda u: x)
                 (lambda u: u))
)

# Multiplication: "add m to zero n times".
MULT = (
    lambda n: lambda m: n(lambda x:
                          ADD(x)(m))(ZERO)
)

ONE = (
    ADD1(ZERO)
)
SIX = (
    ADD1(ADD1(ADD1(ADD1(ADD1(ADD1(ZERO))))))
)


================================================
FILE: das-0095-power-of-lambda-calculus/lambda.py
================================================
#!/usr/bin/env python3

print(
    ( lambda myself: ( lambda n: ( ( lambda cond: lambda t: lambda f: cond(t)(f))( ( lambda n: n(lambda x: ( lambda t: lambda f: f(( lambda x: x))))(( lambda t: lambda f: t(( lambda x: x)))))(n))( lambda _:( ( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda f: lambda x: x))) )( lambda _: ( lambda n: lambda m: n(lambda x: ( lambda n: lambda m: n(( lambda n: lambda f: lambda x: f( n(f)(x) )))(m))(x)(m))(( lambda f: lambda x: x)))(n)( myself(myself)(( (lambda n: lambda f: lambda x: n (lambda g: lambda h: h(g(f))) (lambda u: x) (lambda u: u)))(n)) )))))( lambda myself: ( lambda n: ( ( lambda cond: lambda t: lambda f: cond(t)(f))( ( lambda n: n(lambda x: ( lambda t: lambda f: f(( lambda x: x))))(( lambda t: lambda f: t(( lambda x: x)))))(n))( lambda _:( ( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda f: lambda x: x))) )( lambda _: ( lambda n: lambda m: n(lambda x: ( lambda n: lambda m: n(( lambda n: lambda f: lambda x: f( n(f)(x) )))(m))(x)(m))(( lambda f: lambda x: x)))(n)( myself(myself)(( (lambda n: lambda f: lambda x: n (lambda g: lambda h: h(g(f))) (lambda u: x) (lambda u: u)))(n)) )))))

    (( ( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda n: lambda f: lambda x: f( n(f)(x) ))(( lambda f: lambda x: x)))))))))

    (lambda x: x + 1)(0)
)


================================================
FILE: das-0102-data-compressor-from-scratch/LICENSE
================================================
Copyright 2017 Gary Bernhardt

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: das-0102-data-compressor-from-scratch/README
================================================
These are the files used in Destroy All Software production 0102, "Data
Compressor From Scratch", available at:

    https://www.destroyallsoftware.com/screencasts/catalog/data-compressor-from-scratch

The files are:

- RUNME.sh, which wasn't used in the screencast, but exists to give you an
  easy way to run this code and see it work. You can execute it via
  `./RUNME.sh` (without the backquotes).

- garyzip.rb, which is the file written in the screencast.

- bin.rb, which defines BinPacker and BinUnpacker, responsible for packing
  sequences of int8s, int16s (unused in the screencast), int32s, and arbitrary
  bits into bytes.

- rendertree.rb, which provides the `render_tree` function used to show the
  Huffman coding trees visually.

- tree.dot, a manually-created tree diagram shown at the beginning of the
  screencast. You can render it via `dot -Tpng tree.dot | ./imgcat` (requires
  iTerm 2 or a terminal implementing iTerm 2's PNG rendering escape codes).

- imgcat, which is distributed by the authors of iTerm 2 but included here for
  convenience. It allows us to print PNGs to the terminal. It will only work
  with iTerm 2 or other terminals that implement iTerm 2's PNG rendering
  escape codes.

DEPENDENCIES

- Ruby 2.4.1 (or probably older or newer versions, but try 2.4.1 if anything
  goes wrong).
- For the tree rendering, iTerm 2 version 3.0.15.

SUPPORT

This code is entirely unsupported and is for educational purposes only.

LICENSE

All files here is released under the MIT license, with the exception of
`imgcat`, whose copyright is held by the authors of iTerm 2. See the file
`LICENSE`.


================================================
FILE: das-0102-data-compressor-from-scratch/RUNME.sh
================================================
#!/usr/bin/env bash

set -e -o pipefail

echo -n "abbcccc" | ./garyzip.rb compress | hexdump



================================================
FILE: das-0102-data-compressor-from-scratch/bin.rb
================================================
# This file was used in Destroy All Software production 0102, "Data Compressor
# From Scratch". It wasn't shown in the screencast, so it's not designed to be
# as readable as the main code. All of this code is exactly as used in the
# screencast except for the addition of comments.
#
# To see how this file was used to build a data compressor, visit:
#
#   https://www.destroyallsoftware.com/screencasts/catalog/data-compressor-from-scratch

class BinPacker
  def initialize
    @bits = []
  end

  def int32(int)
    @bits << [int_to_bits(int, 32), int]
    self
  end

  def int16(int)
    @bits << [int_to_bits(int, 16), int]
    self
  end

  def int8(int)
    @bits << [int_to_bits(int, 8), int]
    self
  end

  def int(int, bit_count)
    @bits << [int_to_bits(int, bit_count), int]
    self
  end

  def bits(bits)
    @bits << [bits, bits]
    self
  end

  def pack
    [flattened_bits.map(&:to_s).join].pack("b*")
  end

  def flattened_bits
    @bits.map { |bits, original| bits }.flatten(1)
  end

  # This function was banged out to be used once during recording, without
  # regard for whether anyone would ever read it. Oh well!
  def debug
    # Some ANSI escape codes that we'll use
    red = "\e[31;49m"
    reset = "\e[0m"

    # Pack up the original packed values into DebugValues containing DebugBits.
    # The DebugValues carry the original data plus the serialized bits; the
    # DebugBits carry the original bits plus the colorized bits.
    debug_values = @bits.each_with_index.map do |(bits, original), index|
      mark_this_group = index % 2 == 0
      debug_bits = bits.map do |bit|
        bit_string = mark_this_group ? red + bit.to_s + reset : bit.to_s
        DebugBit.new(bit_string, bit)
      end
      DebugValue.new(debug_bits, original)
    end

    # Print the original bit groups with their added alternating colors.
    $stderr.puts "Original values (#{debug_values.length}):"
    bit_strings = debug_values.map(&:debug_bits).map do |group|
      # Reverse so the bits are printed in decreasing significance order, as
      # expected by humans.
      group.map(&:colorized_bit).reverse.join
    end
    original_values = debug_values.map(&:original).map(&:to_s)
    max_original_length = original_values.map(&:length).max
    bit_strings.zip(original_values).each do |bit_string, original|
      $stderr.puts "  " + original.rjust(max_original_length) + " | " + bit_string
    end
    $stderr.puts

    # Print the actual bytes in three forms (bits, base-10 number, and ASCII
    # character), maintaining the alternate coloring so we can see how the
    # original bit groups map to the output bytes.
    $stderr.puts "Bytes (#{pack.length}):"
    debug_values.map(&:debug_bits).flatten(1).each_slice(8) do |group|
      padding = "0" * (8 - group.length)
      colorized_bits = padding + group.map(&:colorized_bit).reverse.join
      just_the_bits = group.map(&:bit)

      # Convert this group of bits into a character
      char = [just_the_bits.map(&:to_s).join].pack("b*")

      $stderr.puts "  " + colorized_bits + " | " + char.ord.to_s.ljust(3) + " | " + char.inspect
    end
    $stderr.puts

    # Print the final packed string, which will be the same as the ASCII
    # characters rendered for the packed bits.
    $stderr.puts "Packed string (#{pack.length}): #{pack.inspect}"
    $stderr.puts
  end

  DebugValue = Struct.new(:debug_bits, :original)
  DebugBit = Struct.new(:colorized_bit, :bit)

  private

  def int_to_bits(int, bit_count)
    bits = []
    bit_count.times do
      bits << (int & 0x1)
      int >>= 1
    end
    bits
  end
end

class BinUnpacker
  def initialize(packed)
    @bits = packed.unpack("b*").fetch(0).chars.map(&:to_i)
  end

  def int32
    int(32)
  end

  def int16
    int(16)
  end

  def int8
    int(8)
  end

  def bits(count)
    bits = @bits[0...count]
    @bits = @bits[count..-1]
    bits
  end

  def peek(n)
    @bits[0...n]
  end

  def int(bit_count)
    bits, @bits = @bits[0...bit_count], @bits[bit_count..-1]
    int = 0
    bits.reverse.each do |bit|
      int <<= 1
      int |= bit
    end
    int
  end
end


================================================
FILE: das-0102-data-compressor-from-scratch/garyzip.rb
================================================
#!/usr/bin/env ruby

# This file was used in Destroy All Software production 0102, "Data Compressor
# From Scratch". It wasn't shown in the screencast, so it's not designed to be
# as readable as the main code. All of this code is exactly as used in the
# screencast except for:
#
# - This comment.
# - Calls to `render_tree` and `packer.debug` in the `compress` function, so
#   you can easily run this file and see the debug output from the screencast.
#
# To see this work, try the command below. Note that the tree printed by
# `render_tree` will only work in iTerm 2, or other terminals that support its
# PNG rendering escape codes. If you're not using iTerm 2, you can comment out
# the call to `render_tree`.
#
#   echo -n "abbcccc" | ./garyzip.rb compress | hexdump
#
# To see how this file was written, visit:
#
#   https://www.destroyallsoftware.com/screencasts/catalog/data-compressor-from-scratch

require "./rendertree"
require "./bin"

def compress(original)
  tree = build_tree(original)
  table = build_table(tree)
  packer = BinPacker.new

  packer.int32(original.length)
  pack_table(table, packer)

  original.bytes.each do |byte|
    bits = look_up_byte(table, byte)
    packer.bits(bits)
  end

  render_tree(tree)
  packer.debug

  packer.pack
end

def decompress(compressed)
  unpacker = BinUnpacker.new(compressed)

  data_length = unpacker.int32
  table = unpack_table(unpacker)

  data_length.times.map do
    look_up_bits(table, unpacker)
  end.map(&:chr).join
end

def build_tree(original)
  bytes = original.bytes
  unique_bytes = bytes.uniq

  nodes = unique_bytes.map do |byte|
    Leaf.new(byte, bytes.count(byte))
  end

  until nodes.length == 1
    node1 = nodes.delete(nodes.min_by(&:count))
    node2 = nodes.delete(nodes.min_by(&:count))
    nodes << Node.new(node1, node2, node1.count + node2.count)
  end

  nodes.fetch(0)
end

def build_table(node, path=[])
  if node.is_a? Node
    build_table(node.left, path + [0]) +
      build_table(node.right, path + [1])
  else
    [TableRow.new(node.byte, path)]
  end
end

def look_up_byte(table, byte)
  table.each do |row|
    if row.byte == byte
      return row.bits
    end
  end

  awoijf
end

# a = 00
# b = 01
# c = 1

def look_up_bits(table, unpacker)
  table.each do |row|
    if row.bits == unpacker.peek(row.bits.length)
      unpacker.bits(row.bits.length)
      return row.byte
    end
  end

  awoijf
end

def pack_table(table, packer)
  packer.int8(table.length - 1)
  table.each do |row|
    packer.int8(row.byte)
    packer.int8(row.bits.length)
    packer.bits(row.bits)
  end
end

def unpack_table(unpacker)
  table_length = unpacker.int8 + 1
  table_length.times.map do
    byte = unpacker.int8
    bit_count = unpacker.int8
    bits = unpacker.bits(bit_count)
    TableRow.new(byte, bits)
  end
end

Node = Struct.new(:left, :right, :count)
Leaf = Struct.new(:byte, :count)

TableRow = Struct.new(:byte, :bits)

if ARGV.fetch(0) == "compress"
  $stdout.write(compress($stdin.read))
else
  $stdout.write(decompress($stdin.read))
end


================================================
FILE: das-0102-data-compressor-from-scratch/imgcat
================================================
#!/bin/bash

# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
    if [[ $TERM == screen* ]] ; then
        printf "\033Ptmux;\033\033]"
    else
        printf "\033]"
    fi
}

# More of the tmux workaround described above.
function print_st() {
    if [[ $TERM == screen* ]] ; then
        printf "\a\033\\"
    else
        printf "\a"
    fi
}

# print_image filename inline base64contents
#   filename: Filename to convey to client
#   inline: 0 or 1
#   base64contents: Base64-encoded contents
function print_image() {
    print_osc
    printf '1337;File='
    if [[ -n "$1" ]]; then
      printf 'name='`echo -n "$1" | base64`";"
    fi
    if $(base64 --version 2>&1 | grep GNU > /dev/null)
    then
      BASE64ARG=-d
    else
      BASE64ARG=-D
    fi
    echo -n "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}'
    printf ";inline=$2"
    printf ":"
    echo -n "$3"
    print_st
    printf '\n'
}

function error() {
    echo "ERROR: $*" 1>&2
}

function show_help() {
    echo "Usage: imgcat filename ..." 1>& 2
    echo "   or: cat filename | imgcat" 1>& 2
}

## Main

if [ -t 0 ]; then
    has_stdin=f
else
    has_stdin=t
fi

# Show help if no arguments and no stdin.
if [ $has_stdin = f -a $# -eq 0 ]; then
    show_help
    exit
fi

# Look for command line flags.
while [ $# -gt 0 ]; do
    case "$1" in
    -h|--h|--help)
        show_help
        exit
        ;;
    -*)
        error "Unknown option flag: $1"
        show_help
        exit 1
      ;;
    *)
        if [ -r "$1" ] ; then
            print_image "$1" 1 "$(base64 < "$1")"
        else
            error "imgcat: $1: No such file or directory"
            exit 2
        fi
        ;;
    esac
    shift
done

# Read and print stdin
if [ $has_stdin = t ]; then
    print_image "" 1 "$(cat | base64)"
fi

exit 0


================================================
FILE: das-0102-data-compressor-from-scratch/rendertree.rb
================================================
# This file was used in Destroy All Software production 0102, "Data Compressor
# From Scratch". It wasn't shown in the screencast, so it's not designed to be
# as readable as the main code. All of this code is exactly as used in the
# screencast except for:
#
# - New comments (including this one)
# - The call to `imgcat` was changed to refer to the `imgcat` script in this
#   directory Previously, it relied on the `imgcat` in my ~/bin directory,
#   which is in $PATH.
#
# To see how this file was used to build a data compressor, visit:
#
#   https://www.destroyallsoftware.com/screencasts/catalog/data-compressor-from-scratch

require "open3"

# Render a Huffman tree by converting it into Graphviz dot code, then piping
# the dot into the `dot` command line tool, and finally into the `imgcat`
# script. This will only work in recent versions of iTerm 2, or any other
# terminal that supports iTerm 2's PNG rendering escape codes.
def render_tree(nodes)
  nodes = [nodes] unless nodes.is_a? Array
  dot = [
    "digraph {",
    "ordering=out",
    "dpi=120",
    nodes.map do |node|
      tree_to_dot(node)
    end,
    "}"
  ].flatten.join("\n")
  rendered = Open3.popen3("dot -Tpng | ./imgcat") do |stdin, stdout, stderr, wait_thr|
    stdin.write(dot)
    stdin.close
    stdout.read
  end
  $stderr.puts(rendered)
end

def tree_to_dot(node)
  name = "node_#{node.object_id}"
  if node.is_a? Node
    [
      %{#{name}[label="(n=#{node.count})"]},
      %{#{name} -> node_#{node.left.object_id}[label="0"]},
      %{#{name} -> node_#{node.right.object_id}[label="1"]},
      tree_to_dot(node.left),
      tree_to_dot(node.right),
    ].join("\n")
  else
    [
      %{node_#{node.object_id}[label="#{node.byte.chr.gsub(/"/,'\"')}\n(n=#{node.count})"]},
    ].join("\n")
  end
end


================================================
FILE: das-0102-data-compressor-from-scratch/tree.dot
================================================
digraph {
  dpi=120
  ordering=out;

  # abbcccc
  # 1 a
  # 2 b
  # 4 c

  a[label="a\n(n=1)"]
  b[label="b\n(n=2)"]
  c[label="c\n(n=4)"]

  n1 [label="(n=3)"]
  n1 -> a [label=0]
  n1 -> b [label=1]

  n2 [label="(n=7)"]
  n2 -> n1 [label=0]
  n2 -> c [label=1]
}
Download .txt
gitextract_ee0bj18n/

├── das-0010-fast-tests-with-and-without-rails/
│   └── test
├── das-0026-controller-refactoring-demo-part-2/
│   └── account_controller.rb
├── das-0030-some-vim-tips/
│   ├── grb256.vim
│   └── ir_black.vim
├── das-0070-time-to-first-request/
│   └── time_to_first_request.sh
├── das-0094-computing-by-constructing/
│   ├── everything.py
│   └── lambda.py
├── das-0095-power-of-lambda-calculus/
│   ├── everything.py
│   └── lambda.py
└── das-0102-data-compressor-from-scratch/
    ├── LICENSE
    ├── README
    ├── RUNME.sh
    ├── bin.rb
    ├── garyzip.rb
    ├── imgcat
    ├── rendertree.rb
    └── tree.dot
Download .txt
SYMBOL INDEX (54 symbols across 4 files)

FILE: das-0026-controller-refactoring-demo-part-2/account_controller.rb
  class AccountController (line 14) | class AccountController < ApplicationController
    method login (line 21) | def login
    method logout (line 30) | def logout
    method lost_password (line 36) | def lost_password
    method handle_existing_token (line 45) | def handle_existing_token
    method have_valid_token? (line 56) | def have_valid_token?
    method reset_password (line 60) | def reset_password
    method generate_token (line 72) | def generate_token
    method ensure_user_exists (line 82) | def ensure_user_exists(user)
    method ensure_no_external_auth (line 91) | def ensure_no_external_auth(user)
    method create_new_token (line 100) | def create_new_token(user)
    method register (line 111) | def register
    method activate (line 147) | def activate
    method logout_user (line 163) | def logout_user
    method authenticate_user (line 171) | def authenticate_user
    method password_authentication (line 179) | def password_authentication
    method open_id_authenticate (line 193) | def open_id_authenticate(openid_url)
    method successful_authentication (line 234) | def successful_authentication(user)
    method set_autologin_cookie (line 245) | def set_autologin_cookie(user)
    method onthefly_creation_failed (line 258) | def onthefly_creation_failed(user, auth_source_options = { })
    method invalid_credentials (line 264) | def invalid_credentials
    method register_by_email_activation (line 272) | def register_by_email_activation(user, &block)
    method register_automatically (line 286) | def register_automatically(user, &block)
    method register_manually_by_administrator (line 302) | def register_manually_by_administrator(user, &block)
    method account_pending (line 312) | def account_pending

FILE: das-0102-data-compressor-from-scratch/bin.rb
  class BinPacker (line 10) | class BinPacker
    method initialize (line 11) | def initialize
    method int32 (line 15) | def int32(int)
    method int16 (line 20) | def int16(int)
    method int8 (line 25) | def int8(int)
    method int (line 30) | def int(int, bit_count)
    method bits (line 35) | def bits(bits)
    method pack (line 40) | def pack
    method flattened_bits (line 44) | def flattened_bits
    method debug (line 50) | def debug
    method int_to_bits (line 108) | def int_to_bits(int, bit_count)
  class BinUnpacker (line 118) | class BinUnpacker
    method initialize (line 119) | def initialize(packed)
    method int32 (line 123) | def int32
    method int16 (line 127) | def int16
    method int8 (line 131) | def int8
    method bits (line 135) | def bits(count)
    method peek (line 141) | def peek(n)
    method int (line 145) | def int(bit_count)

FILE: das-0102-data-compressor-from-scratch/garyzip.rb
  function compress (line 26) | def compress(original)
  function decompress (line 45) | def decompress(compressed)
  function build_tree (line 56) | def build_tree(original)
  function build_table (line 73) | def build_table(node, path=[])
  function look_up_byte (line 82) | def look_up_byte(table, byte)
  function look_up_bits (line 96) | def look_up_bits(table, unpacker)
  function pack_table (line 107) | def pack_table(table, packer)
  function unpack_table (line 116) | def unpack_table(unpacker)

FILE: das-0102-data-compressor-from-scratch/rendertree.rb
  function render_tree (line 21) | def render_tree(nodes)
  function tree_to_dot (line 40) | def tree_to_dot(node)
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (44K chars).
[
  {
    "path": "das-0010-fast-tests-with-and-without-rails/test",
    "chars": 976,
    "preview": "#!/bin/bash\n#\n# From Destroy All Software screencast #10, at:\n# http://destroyallsoftware.com/screencasts/catalog/fast-t"
  },
  {
    "path": "das-0026-controller-refactoring-demo-part-2/account_controller.rb",
    "chars": 9234,
    "preview": "#-- copyright\n# ChiliProject is a project management system.\n#\n# Copyright (C) 2010-2011 the ChiliProject Team\n#\n# This "
  },
  {
    "path": "das-0030-some-vim-tips/grb256.vim",
    "chars": 1664,
    "preview": "\" Based on\nruntime colors/ir_black.vim\n\nlet g:colors_name = \"grb256\"\n\nhi pythonSpaceError ctermbg=red guibg=red\n\nhi Comm"
  },
  {
    "path": "das-0030-some-vim-tips/ir_black.vim",
    "chars": 10140,
    "preview": "\" ir_black color scheme\n\" More at: http://blog.infinitered.com/entries/show/8\n\n\n\" **************************************"
  },
  {
    "path": "das-0070-time-to-first-request/time_to_first_request.sh",
    "chars": 565,
    "preview": "#!/bin/bash\n\nmain() {\n    print_runtime > /dev/null\n    print_runtime\n}\n\nprint_runtime() {\n    pid=$(start_server)\n    r"
  },
  {
    "path": "das-0094-computing-by-constructing/everything.py",
    "chars": 976,
    "preview": "#!/usr/bin/env python3\n\nNULL = (\n    lambda x: x\n)\n\nTRUE = (\n    lambda t: lambda f: t(NULL)\n)\nFALSE = (\n    lambda t: l"
  },
  {
    "path": "das-0094-computing-by-constructing/lambda.py",
    "chars": 797,
    "preview": "#!/usr/bin/env python3\n\nONE = 1\nIS_ZERO = lambda x: x == 0\nSUB1 = lambda x: x - 1\nMULT = lambda x: lambda y: x * y\nIF = "
  },
  {
    "path": "das-0095-power-of-lambda-calculus/everything.py",
    "chars": 976,
    "preview": "#!/usr/bin/env python3\n\nNULL = (\n    lambda x: x\n)\n\nTRUE = (\n    lambda t: lambda f: t(NULL)\n)\nFALSE = (\n    lambda t: l"
  },
  {
    "path": "das-0095-power-of-lambda-calculus/lambda.py",
    "chars": 1493,
    "preview": "#!/usr/bin/env python3\n\nprint(\n    ( lambda myself: ( lambda n: ( ( lambda cond: lambda t: lambda f: cond(t)(f))( ( lamb"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/LICENSE",
    "chars": 1054,
    "preview": "Copyright 2017 Gary Bernhardt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this soft"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/README",
    "chars": 1627,
    "preview": "These are the files used in Destroy All Software production 0102, \"Data\nCompressor From Scratch\", available at:\n\n    htt"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/RUNME.sh",
    "chars": 94,
    "preview": "#!/usr/bin/env bash\n\nset -e -o pipefail\n\necho -n \"abbcccc\" | ./garyzip.rb compress | hexdump\n\n"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/bin.rb",
    "chars": 4124,
    "preview": "# This file was used in Destroy All Software production 0102, \"Data Compressor\n# From Scratch\". It wasn't shown in the s"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/garyzip.rb",
    "chars": 3039,
    "preview": "#!/usr/bin/env ruby\n\n# This file was used in Destroy All Software production 0102, \"Data Compressor\n# From Scratch\". It "
  },
  {
    "path": "das-0102-data-compressor-from-scratch/imgcat",
    "chars": 1976,
    "preview": "#!/bin/bash\n\n# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;\n# <sequence> ST, and for all ESCs i"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/rendertree.rb",
    "chars": 1790,
    "preview": "# This file was used in Destroy All Software production 0102, \"Data Compressor\n# From Scratch\". It wasn't shown in the s"
  },
  {
    "path": "das-0102-data-compressor-from-scratch/tree.dot",
    "chars": 267,
    "preview": "digraph {\n  dpi=120\n  ordering=out;\n\n  # abbcccc\n  # 1 a\n  # 2 b\n  # 4 c\n\n  a[label=\"a\\n(n=1)\"]\n  b[label=\"b\\n(n=2)\"]\n  "
  }
]

About this extraction

This page contains the full source code of the garybernhardt/destroy-all-software-extras GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (39.8 KB), approximately 12.2k tokens, and a symbol index with 54 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!