<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The focus of this notebook is refactoring a loop that\n",
    "- gets user input\n",
    "- quits if that input matches some sentinel value\n",
    "- processes the user input\n",
    "\n",
    "The interesting part starts around cell #4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from functools import partial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def convert(s):\n",
    "    converters = (int, float)\n",
    "    \n",
    "    for converter in converters:\n",
    "        try:\n",
    "            value = converter(s)\n",
    "        except ValueError:\n",
    "            pass\n",
    "        else:\n",
    "            return value\n",
    "        \n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def process_input(s):\n",
    "    value = convert(s)\n",
    "    print('%r becomes %r' % (s, value))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below is a typical loop for\n",
    "- getting user input\n",
    "- quitting the loop if the user enters a special value\n",
    "- processing the input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    while True:\n",
    "        s = input(prompt)\n",
    "        if s == 'quit':\n",
    "            break\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It works as shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below is a different way of writing that loop.\n",
    "\n",
    "How would you apply it to loop at the bottom of\n",
    "[2016-04/2016-Apr-Gutenberg.py](https://github.com/joefriedrich/COhPy_Challenges/blob/master/2016-04/2016-Apr-Gutenberg.py)?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    for s in iter(partial(input, prompt), 'quit'):\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It can be reduced to a generator expression."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "123.34\n",
      "gimme: 1243\n",
      "1243\n",
      "gimme: hello\n",
      "hello\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "prompt = 'gimme: '\n",
    "get_values = (convert(s) for s in iter(partial(input, prompt), 'quit'))\n",
    "for value in get_values:\n",
    "    print(value)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.4.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}<commit_msg>20160708-dojo-user-input-loop-with-iter-partial-input-prompt-sentinel.ipynb: Add alternatives to partial(input, prompt).<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "The focus of this notebook is refactoring a loop that\n",
    "- gets user input\n",
    "- quits if that input matches some sentinel value\n",
    "- processes the user input\n",
    "\n",
    "The interesting part starts around cell #4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "from functools import partial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def convert(s):\n",
    "    converters = (int, float)\n",
    "    \n",
    "    for converter in converters:\n",
    "        try:\n",
    "            value = converter(s)\n",
    "        except ValueError:\n",
    "            pass\n",
    "        else:\n",
    "            return value\n",
    "        \n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def process_input(s):\n",
    "    value = convert(s)\n",
    "    print('%r becomes %r' % (s, value))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Below is a typical loop for\n",
    "- getting user input\n",
    "- quitting the loop if the user enters a special value\n",
    "- processing the input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    while True:\n",
    "        s = input(prompt)\n",
    "        if s == 'quit':\n",
    "            break\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "It works as shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Below is a different way of writing that loop.\n",
    "\n",
    "How would you apply it to loop at the bottom of\n",
    "[2016-04/2016-Apr-Gutenberg.py](https://github.com/joefriedrich/COhPy_Challenges/blob/master/2016-04/2016-Apr-Gutenberg.py)?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    for s in iter(partial(input, prompt), 'quit'):\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "It can be reduced to a generator expression."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "123.34\n",
      "gimme: 1243\n",
      "1243\n",
      "gimme: hello\n",
      "hello\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "prompt = 'gimme: '\n",
    "get_values = (convert(s) for s in iter(partial(input, prompt), 'quit'))\n",
    "for value in get_values:\n",
    "    print(value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2017-10-06 More thoughts about partial(input, prompt) and alternatives to it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "prompt = 'gimme: '\n",
    "\n",
    "def get_input():\n",
    "    return input(prompt)\n",
    "\n",
    "def main():\n",
    "    for s in iter(get_input, 'quit'):\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    for s in iter(lambda : input(prompt), 'quit'):\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def my_partial(function, *args, **kwargs):\n",
    "    def helper():\n",
    "        return function(*args, **kwargs)\n",
    "    return helper\n",
    "\n",
    "def main():\n",
    "    prompt = 'gimme: '\n",
    "    for s in iter(my_partial(input, prompt), 'quit'):\n",
    "        process_input(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gimme: 123.34\n",
      "'123.34' becomes 123.34\n",
      "gimme: 1243\n",
      "'1243' becomes 1243\n",
      "gimme: hello\n",
      "'hello' becomes 'hello'\n",
      "gimme: quit\n"
     ]
    }
   ],
   "source": [
    "main()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
{'fraction_non_alphanumeric': 0.20708864847408365, 'fraction_numerical': 0.026481511383820443, 'mean_word_length': 2.0226939970717424, 'pattern_counts': {'":': 254, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5713405', 'n_tokens_mistral': 5071, 'n_tokens_neox': 4711, 'n_words': 1000}