Cooking: Getting organized

I prefer staying at home and eating a homemade meal than going out and spending money for a meal I might not even enjoy that much. This attitude might have to do that I’m an introvert, but I also prefer knowing what’s in the food I’m eating (therefore, I’m not the biggest fan of ordering in either). Especially since I have my little sweetheart, I’m way more concerned about healthy nutrition than I was before.

Currently, I fall back to quick and boring suppers way too often due to a few reasons:

  1. There are days, were I just simply don’t feel like cooking.
  2. My little one tends to be very clingy later in the afternoon and as soon as I step into the kitchen, he wants me to pick him up (also because he wants to watch me cooking).
  3. Although cooking is generally cheaper than going out, it can get quite expensive if you choose organic ingredients. Therefore, it’s best to look weekly at the local flyers, buy groceries that are on a good sale and then plan recipes that use those ingredients. Also, stocking up on items while they are on sale is a good idea (as long as they have a due date far in the future of course).

I’ve struggled with the above-mentioned hurdles for quite a while now. It’s time I tackle them finally.

Overcome ‘I’m too tired/lazy’

  • Plan meals ahead (at least a week in advance).
  • Write down recipes (it’s ingredients and maybe just a link to a site) that I like and some that I would like to try in the future.
  • Plan for 5 to 6 quick meals and only one or two more labor intense suppers.
  • Create the list of recipes via org-mode in emacs. Save the files in my gdrive so that I can access it on my phone.
  • Write an elisp script that copies ingredient lists into the ‘grocery shopping’ list via a key-press.
  • Write a script that organizes the weekly grocery shopping list by combining groceries and sorting them by store aisles.
  • Have a few quick meals (such as fish and chips) in the freezer for days where I’m truly lacking time for cooking or just really badly lazy.
  • Manage cooking with my little one

  • Find recipes that don’t require a lot of cutting.
  • Ask my hubby more often for help.
  • Prepare food already on the weekend while my husband and the little one are busy playing.
  • Keep the pantry full and organized

  • Create a list with all pantry items (name and amount) and it’s due date.
  • Create an emacs extension which will automatically search for recipes that use soon to be due pantry items.
  • Keep it cheap

  • Start searching every week for groceries that are on sale and create the meal plan accordingly.
  • Write an elisp script that takes as input groceries (that are on sale that week) and as output all kind of recipes that use those groceries.
  • Elisp code

    So far I have only one little function implemented which helps me copy an ingredients list in org-mode into my grocery.org file.
    An example ingredient list looks like:

    |   2 | small | shallots                 | minced      |
    |   1 |       | garlic clove             | minced      |
    |   2 | tsp   | Dijon mustard            |             |
    | 1/4 | cup   | balsamic vinegar         |             |
    |     |       | salt and pepper to taste |             |
    | 1/2 | cup   | olive oil                |             |
    

    If I have the pointer at the start of the table and call my elisp function, then it automatically puts the first three columns of my table in the kill ring. Afterwards, I just need to yank it into my grocery file and create a macro so that moving ingredient lists into my grocery list goes even faster. Below is my short unspectacular code.

    (defun custom/save-till-end-of-table()
      (interactive)
      (setq cont t)
      (setq startpoint (point))
      (while cont
        (next-line)
        (if (not(char-equal ?| (char-after)))
    	(progn
    	  (backward-char)
    	  (setq cont nil))))
      (org-shifttab)
      (backward-char 2)
      (kill-ring-save startpoint (point))
      (message (string (char-after))))

    My goal is to improve this code still so that it automatically yanks the table into a user-specified file.

    Aurebesh typing test for emacs

    This entry is part 3 of 3 in the series Aurebesh

    A few weeks ago, I posted the Aurebesh typing test. Since I’ve recently started learning elisp, I figured that I should implement the typing test as a feature for emacs.

    The code below is terrible with bugs and problems, but heck, it’s my first elisp program after all. My goal is to improve the version over time and to add features such as logging results in a separate file and displaying a progress statistic. To use it, you’ll need to first install the Aurebesh font.

    (setq correct 0)
    (setq wrong 0)
    (setq seconds-left 60)
    (setq test-start t)
    
    (require 'widget)
    
    (defun aurebesh-typing-test ()
      "Aurebesh typing test"
      (interactive)
      (get-buffer-create "*Aurebesh typing test*")
      (custom/reset-aurebesh-typing-test-vars)
      (custom/aurebesh-typing-test))
    
    (defun custom/reset-aurebesh-typing-test-vars()
      (setq test-start t)
      (setq correct 0)
      (setq wrong 0)
      (setq seconds-left 60))
    
    (defun custom/aurebesh-typing-test()
      (with-current-buffer "*Aurebesh typing test*"
        (custom/setup-buffer)
        (custom/refresh-seconds)
        (custom/create-line-with-widget)
        (insert "Correct / wrong answers: " (number-to-string correct) " / " (number-to-string wrong) " \n")
        (custom/setup-widget)
        (custom/set-aurebesh)))
    
    (defun custom/setup-buffer()
      (kill-all-local-variables)
      (let ((inhibit-read-only t))
        (erase-buffer))
      (remove-overlays))
    
    (defun custom/refresh-seconds()
      (with-no-warnings
        (goto-line 1)
        (custom/delete-line)
        (insert "Seconds: " (number-to-string seconds-left) "\n")))
    
    (defun custom/delete-line()
      (let ((beg (point)))
        (forward-line 1)
        (delete-region beg (point))))
    
    (defun custom/create-line-with-widget()
      (if (> seconds-left 0)
          (setq randomChar (custom/get-random-char))
        (setq randomChar ""))
      (widget-insert randomChar)
      (widget-insert "\t")
      (widget-create 'editable-field
    		 :size 15
    		 :correct (string randomChar)
    		 :notify 'custom/check-input-value)
      (widget-insert "\n"))
    
    (defun custom/setup-widget()
      (use-local-map widget-keymap)
      (widget-setup)
      (widget-forward 1))
    
    (defun custom/set-aurebesh()
      "Sets the aurebesh font in current buffer"
      (interactive)
      (setq buffer-face-mode-face '(:family "Aurebesh"))
      (buffer-face-mode))
    
    (defun custom/check-input-value(widget &rest ignore)
      "Compare aurebesh input character with requested one."
      (cond
       ((string-match 
         (widget-get widget :correct)
         (widget-value widget))
        (custom/correct-input widget))
       ((not(= (length (widget-value widget)) 0))
        (custom/wrong-input))))
    
    (defun custom/correct-input(widget)
      (if test-start
          (progn
    	(custom/start-timer)
    	(setq test-start nil)))
      (if (> seconds-left 0)
          (progn
    	(setq correct (+ correct 1))
    	(custom/next-character widget))))
    
    (defun custom/start-timer()
      "Start Aurebesh test"
      (setq seconds-left 60)
      (setq timer (run-with-timer 0 1 'custom/decrement-seconds)))
    
    (defun custom/decrement-seconds()
      (with-current-buffer "*Aurebesh typing test*"
        (if (> seconds-left 0)
    ;	(progn
    	  (setq seconds-left (- seconds-left 1))
    ;	  (custom/refresh-seconds)
    ;	  (widget-forward 1))
          (custom/stop-aurebesh-typing-test))))
    
    (defun custom/stop-aurebesh-typing-test()
      (with-current-buffer "*Aurebesh typing test*"
      (custom/refresh-seconds)
      (cancel-timer timer)
      (custom/set-arial)))
    
    (defun custom/set-arial()
       "Sets the arial font in current buffer"
       (interactive)
       (setq buffer-face-mode-face '(:family "Arial"))
       (buffer-face-mode))
    
    (defun custom/next-character(widget)
      (with-current-buffer "*Aurebesh typing test*"
        (custom/fill-random-character widget)
        (custom/fill-correct-wrong-answers)
        (custom/refresh-seconds)
        (widget-forward 1)
        ))
    
    (defun custom/fill-random-character(widget)
      (with-no-warnings
        (goto-line 2))
      (delete-char 1)
      (if (> seconds-left 0)
          (setq randomChar (custom/get-random-char))
        (setq randomChar ""))
      (widget-insert randomChar)
      (widget-put widget :correct (string randomChar))
      (widget-value-set widget ""))
    
    (defun custom/get-random-char ()
      "Insert a random alphanumeric character.."
      (let ((mycharset "abcdefghijklmnopqrstyvwxyz"))
        (elt mycharset (random (length mycharset)))))
    
    (defun custom/fill-correct-wrong-answers()
      (with-no-warnings
        (goto-line 3))
      (kill-line)
      (insert "Correct / wrong answers: " (number-to-string correct) " / " (number-to-string wrong) " \n"))
      
    (defun custom/wrong-input()
      (message "%s" (widget-get widget :correct))
      (widget-value-set widget "")
      (setq wrong (+ wrong 1)))