<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>George&#039;s weblog &#187; python</title>
	<atom:link href="http://www.helyar.net/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.helyar.net</link>
	<description>From the desktop of George Helyar</description>
	<lastBuildDate>Thu, 26 Aug 2010 14:27:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Get external IP address with Python</title>
		<link>http://www.helyar.net/2010/get-external-ip-address-with-python/</link>
		<comments>http://www.helyar.net/2010/get-external-ip-address-with-python/#comments</comments>
		<pubDate>Wed, 26 May 2010 18:04:43 +0000</pubDate>
		<dc:creator>George Helyar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.helyar.net/?p=493</guid>
		<description><![CDATA[Here&#8217;s a quick snippet of Python code (tested in 3.0) to quickly look up your external IP address over HTTP and display it: import urllib.request print&#40;str&#40;urllib.request.urlopen&#40;&#34;http://www.whatismyip.com/automation/n09230945.asp&#34;&#41;.read&#40;&#41;, &#34;utf8&#34;&#41;&#41;]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a quick snippet of Python code (tested in 3.0) to quickly look up your external IP address over HTTP and display it:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #ff7700;font-weight:bold;color: blue;">import</span> <span style="color: #dc143c;color: blue;">urllib</span>.<span style="color: black;color: black;">request</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">print</span><span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">str</span><span style="color: black;color: black;">&#40;</span><span style="color: #dc143c;color: blue;">urllib</span>.<span style="color: black;color: black;">request</span>.<span style="color: black;color: black;">urlopen</span><span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;http://www.whatismyip.com/automation/n09230945.asp&quot;</span><span style="color: black;color: black;">&#41;</span>.<span style="color: black;color: black;">read</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span>, <span style="color: #483d8b;color: maroon;">&quot;utf8&quot;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.helyar.net/2010/get-external-ip-address-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ffmpeg target file sizes (again)</title>
		<link>http://www.helyar.net/2009/ffmpeg-target-file-sizes-again/</link>
		<comments>http://www.helyar.net/2009/ffmpeg-target-file-sizes-again/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 17:41:05 +0000</pubDate>
		<dc:creator>George Helyar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.helyar.net/?p=330</guid>
		<description><![CDATA[This script is now available as an ongoing project that can be downloaded. Please see the Video Encoding Project. As a bit of a revision to a previous entry, I have converted the combination bash/python scripts I gave earlier into a single large python script. This can now be used without editing any files to [...]]]></description>
			<content:encoded><![CDATA[<p>This script is now available as an ongoing project that can be downloaded. Please see the <a href="http://www.helyar.net/enc">Video Encoding Project</a>.<br />
<hr />
<p>As a bit of a revision to a <a href="http://www.helyar.net/2009/how-to-set-target-file-sizes-in-ffmpeg/">previous entry</a>, I have converted the combination bash/python scripts I gave earlier into a single large python script.</p>
<p>This can now be used without editing any files to set sizes. An example of use is:<br />
<code>$ ./enc.py -s 700 -a 192 -o '-deinterlace' da_*.VOB</code><br />
All of these flags are optional except the file list, where at least 1 file must be specified.</p>
<p><a href='http://www.helyar.net/wp-content/uploads/2009/07/enc.tar.gz'>enc.tar.gz</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #808080; font-style: italic;color: green;">#!/usr/bin/python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">getopt</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> <span style="color: #dc143c;color: blue;">getopt</span>, GetoptError
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">sys</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> argv, exit
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">subprocess</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> Popen, PIPE
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">re</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> search
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> secs<span style="color: black;color: black;">&#40;</span>h, m, s<span style="color: black;color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> <span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#40;</span>h<span style="color: #66cc66;color: black;">*</span><span style="color: #ff4500;color: maroon;">60</span><span style="color: black;color: black;">&#41;</span>+m<span style="color: black;color: black;">&#41;</span><span style="color: #66cc66;color: black;">*</span><span style="color: #ff4500;color: maroon;">60</span><span style="color: black;color: black;">&#41;</span>+s
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> calc_video_bitrate<span style="color: black;color: black;">&#40;</span>target_bytes, ab, <span style="color: #dc143c;color: blue;">time</span><span style="color: black;color: black;">&#41;</span>:
  audio_bytes = <span style="color: black;color: black;">&#40;</span>ab <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1000</span> / <span style="color: #ff4500;color: maroon;">8</span><span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #dc143c;color: blue;">time</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> <span style="color: black;color: black;">&#40;</span>target_bytes - audio_bytes<span style="color: black;color: black;">&#41;</span> / <span style="color: #dc143c;color: blue;">time</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">8</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> get_duration<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">file</span><span style="color: black;color: black;">&#41;</span>:
  ffmpeg = Popen<span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;ffmpeg&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;-i&quot;</span>, <span style="color: #008000;color: blue;">file</span><span style="color: black;color: black;">&#41;</span>, stderr=PIPE<span style="color: black;color: black;">&#41;</span>
  match = search<span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;(<span style="color: #000099; font-weight: bold;">\\</span>d+):(<span style="color: #000099; font-weight: bold;">\\</span>d+):(<span style="color: #000099; font-weight: bold;">\\</span>d+)<span style="color: #000099; font-weight: bold;">\\</span>.<span style="color: #000099; font-weight: bold;">\\</span>d+&quot;</span>, ffmpeg.<span style="color: black;color: black;">communicate</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">1</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>
  ffmpeg.<span style="color: black;color: black;">stderr</span>.<span style="color: black;color: black;">close</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;color: blue;">if</span> match == <span style="color: #008000;color: blue;">None</span>: <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> <span style="color: #ff4500;color: maroon;">0</span>
  dur = match.<span style="color: black;color: black;">groups</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> secs<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>dur<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>, <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>dur<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">1</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>, <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>dur<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> encode<span style="color: black;color: black;">&#40;</span>source, dest, opts, vbr, abr=<span style="color: #ff4500;color: maroon;">128</span><span style="color: black;color: black;">&#41;</span>:
  command1 = <span style="color: #483d8b;color: maroon;">&quot;ffmpeg -i %s -pass 1 -an -vcodec libx264 -vpre fastfirstpass -b %d -bt %d -threads 0 %s -y pass1.mp4&quot;</span> <span style="color: #66cc66;color: black;">%</span> <span style="color: black;color: black;">&#40;</span>source, vbr, vbr, opts<span style="color: black;color: black;">&#41;</span>
  command2 = <span style="color: #483d8b;color: maroon;">&quot;ffmpeg -i %s -pass 2 -acodec libfaac -ac 2 -ab %dk -vcodec libx264 -vpre hq -b %d -bt %d -threads 0 %s -y %s&quot;</span> <span style="color: #66cc66;color: black;">%</span> <span style="color: black;color: black;">&#40;</span>source, abr, vbr, vbr, opts, dest<span style="color: black;color: black;">&#41;</span>
&nbsp;
  pass1 = Popen<span style="color: black;color: black;">&#40;</span>command1.<span style="color: black;color: black;">split</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#41;</span>
  pass1.<span style="color: black;color: black;">wait</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
  pass2 = Popen<span style="color: black;color: black;">&#40;</span>command2.<span style="color: black;color: black;">split</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#41;</span>
  pass2.<span style="color: black;color: black;">wait</span><span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
&nbsp;
target_size = <span style="color: #ff4500;color: maroon;">350</span> <span style="color: #808080; font-style: italic;color: green;">#MiB</span>
ab = <span style="color: #ff4500;color: maroon;">128</span> <span style="color: #808080; font-style: italic;color: green;">#kbps</span>
extra_options = <span style="color: #483d8b;color: maroon;">&quot;&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;color: green;"># Parse args</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">try</span>:
  opts, args = <span style="color: #dc143c;color: blue;">getopt</span><span style="color: black;color: black;">&#40;</span>argv<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">1</span>:<span style="color: black;color: black;">&#93;</span>, <span style="color: #483d8b;color: maroon;">&quot;s:a:o:&quot;</span>, <span style="color: black;color: black;">&#91;</span><span style="color: #483d8b;color: maroon;">&quot;size=&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;ab=&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;opts=&quot;</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">except</span> GetoptError, err:
  <span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #008000;color: blue;">str</span><span style="color: black;color: black;">&#40;</span>err<span style="color: black;color: black;">&#41;</span>
  exit<span style="color: black;color: black;">&#40;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">for</span> o, a <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> opts:
  <span style="color: #ff7700;font-weight:bold;color: blue;">if</span> o <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> <span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;-s&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;--size&quot;</span><span style="color: black;color: black;">&#41;</span>:
    target_size = <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>a<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1024</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1024</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">elif</span> o <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> <span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;-a&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;--ab&quot;</span><span style="color: black;color: black;">&#41;</span>:
    ab = <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>a<span style="color: black;color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">elif</span> o <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> <span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;-o&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;--opts&quot;</span><span style="color: black;color: black;">&#41;</span>:
    extra_options = a
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">if</span> <span style="color: #008000;color: blue;">len</span><span style="color: black;color: black;">&#40;</span>args<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">&lt;</span> <span style="color: #ff4500;color: maroon;">1</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #483d8b;color: maroon;">&quot;Usage: &quot;</span> + argv<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span> + \
    <span style="color: #483d8b;color: maroon;">&quot; [-s &lt;size (MiB)&gt;] [-a &lt;audio bit rate (kbps)&gt;] [-o &lt;additional options&gt;] &lt;file list&gt;&quot;</span>
  exit<span style="color: black;color: black;">&#40;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;color: green;"># Loop through files</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">for</span> <span style="color: #008000;color: blue;">file</span> <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> args:
  duration = get_duration<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">file</span><span style="color: black;color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">if</span> duration <span style="color: #66cc66;color: black;">&lt;</span>= <span style="color: #ff4500;color: maroon;">0</span>:
    <span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #483d8b;color: maroon;">&quot;Unable to get length of&quot;</span>, <span style="color: #008000;color: blue;">file</span>
    <span style="color: #ff7700;font-weight:bold;color: blue;">continue</span>
&nbsp;
  bitrate = calc_video_bitrate<span style="color: black;color: black;">&#40;</span>target_size, ab, duration<span style="color: black;color: black;">&#41;</span>
&nbsp;
  encode<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">file</span>, <span style="color: #008000;color: blue;">file</span> + <span style="color: #483d8b;color: maroon;">&quot;.mp4&quot;</span>, extra_options, bitrate, ab<span style="color: black;color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.helyar.net/2009/ffmpeg-target-file-sizes-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to set target file sizes in ffmpeg</title>
		<link>http://www.helyar.net/2009/how-to-set-target-file-sizes-in-ffmpeg/</link>
		<comments>http://www.helyar.net/2009/how-to-set-target-file-sizes-in-ffmpeg/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 21:29:39 +0000</pubDate>
		<dc:creator>George Helyar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[aac]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[x264]]></category>

		<guid isPermaLink="false">http://www.helyar.net/?p=240</guid>
		<description><![CDATA[This script is now available as an ongoing project that can be downloaded. Please see the Video Encoding Project. This post describes the methods and mathematics behind the script. After much searching, I found almost nothing regarding how to target a specific file size with ffmpeg, such as 700MiB to fit on a CD. Almost [...]]]></description>
			<content:encoded><![CDATA[<p>This script is now available as an ongoing project that can be downloaded. Please see the <a href="http://www.helyar.net/enc">Video Encoding Project</a>. This post describes the methods and mathematics behind the script.<br />
<hr />
<p>After much searching, I found almost nothing regarding how to target a specific file size with ffmpeg, such as 700MiB to fit on a CD. Almost everything I found suggested to use a negative bitrate for mencoder, such as -700000. However, this did not work for me at all (even by copying and pasting verbatim). Because of this, I set about doing it manually with some mathematics.</p>
<p>What I am going to do here assumes a single audio stream, a single video stream and nothing else in the output file at all (i.e. no subtitles, no alternate languages, no director&#8217;s commentaries, etc).</p>
<p>When encoding media, audio uses a constant bit rate. This means that you can calculate how much space it will take if you know which bit rate you are using and how long the stream is in seconds. This also means that to know how big the video stream should be, we can calculate how big the audio stream will be and subtract it from the target file size. For example, if the target file size is 350MiB and the audio will take up 30MiB, we know the video should aim to be 320MiB (ignoring overheads in the multiplexing, container headers, etc). We can use the same calculations in reverse to work out an average or constant bit rate from a file size and a length in seconds.</p>
<p>In this example, I will be using <a href="http://www.amazon.co.uk/Dads-Army-Complete-Collection-DVD/dp/B000VA3J7K">Dad&#8217;s Army</a> Series 6 Episode 1 &#8211; The Deadly Attachment. I have already ripped this from the DVD with <a href="http://www.slysoft.com/en/anydvd.html">SlySoft AnyDVD</a> and PgcDemux on Windows. Automating PgcDemux rips is worth a whole entry in itself. Note that I have bought this legally and I do not intend to sell or share it. I just want a copy that I can store on my network and play from any computer. Storing 14 DVD images on hard drives takes quite a lot of space, which is where encoding comes in handy. In fact, some of my box sets contain over 60 DVDs (roughly 270GiB).</p>
<p>&#8212;&#8212;&#8212;-<br />
To install ffmpeg on Debian, it is best to get it from the Debian Multimedia repository. Add</p>
<pre>deb http://www.debian-multimedia.org lenny main
deb-src http://www.debian-multimedia.org lenny main</pre>
<p>to your /etc/apt/sources.list and then run</p>
<pre># apt-get update
# apt-get install debian-multimedia-keyring
# apt-get update
# apt-get install ffmpeg</pre>
<p>&#8212;&#8212;&#8212;-</p>
<p>The first thing we need to do to put this into practice is to get the length of the stream. If you supply the file to ffmpeg without telling it to do anything, it will give you an error. However, this error already contains all of the information we need:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: black;">$ <span style="color: #c20cb9; font-weight: bold;color: blue;">ffmpeg</span> <span style="color: #660033;">-i</span> da_6_01.VOB
FFmpeg version SVN-r13582, Copyright <span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>c<span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span> <span style="color: #000000;color: maroon;">2000</span>-<span style="color: #000000;color: maroon;">2008</span> Fabrice Bellard, et al.
  configuration: <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;color: black;">/</span>usr ...
  built on May  <span style="color: #000000;color: maroon;">3</span> <span style="color: #000000;color: maroon;">2009</span> <span style="color: #000000;color: maroon;">12</span>:07:<span style="color: #000000;color: maroon;">18</span>, <span style="color: #c20cb9; font-weight: bold;color: blue;">gcc</span>: 4.3.2
Input <span style="color: #666666; font-style: italic;">#0, mpeg, from 'da_6_01.VOB':</span>
  Duration: 00:<span style="color: #000000;color: maroon;">29</span>:<span style="color: #000000;color: maroon;">23.90</span>, start: <span style="color: #000000;color: maroon;">0.287267</span>, bitrate: <span style="color: #000000;color: maroon;">5987</span> kb<span style="color: #000000; font-weight: bold;color: black;">/</span>s
    Stream <span style="color: #666666; font-style: italic;">#0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x576 [PAR 16:15 DAR 4:3], 9800 kb/s, 25.00 tb(r)</span>
    Stream <span style="color: #666666; font-style: italic;">#0.1[0x80]: Audio: ac3, 48000 Hz, stereo, 192 kb/s</span>
Must supply at least one output <span style="color: #c20cb9; font-weight: bold;color: blue;">file</span></pre></div></div>

<p>We can see that the duration is 00:29:23.90.</p>
<p>As this is an error, we need to redirect stderr to stdout. This can be done with 2>&#038;1. We then need the line that contains the &#8220;Duration&#8221;, which we can get with grep. We can cut this line up to take the time out.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: black;">$ <span style="color: #c20cb9; font-weight: bold;color: blue;">ffmpeg</span> <span style="color: #660033;">-i</span> da_6_01.VOB <span style="color: #000000;color: maroon;">2</span><span style="color: #000000; font-weight: bold;color: black;">&gt;&amp;</span><span style="color: #000000;color: maroon;">1</span> <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">grep</span> Duration <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">cut</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">' '</span> <span style="color: #660033;">-f</span> <span style="color: #000000;color: maroon;">4</span> <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">cut</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">'.'</span> <span style="color: #660033;">-f</span> <span style="color: #000000;color: maroon;">1</span>
00:<span style="color: #000000;color: maroon;">29</span>:<span style="color: #000000;color: maroon;">23</span></pre></div></div>

<p>This can be converted into seconds with the formula <code>s' = (h * 60 + m) * 60 + s</code>.</p>
<p>I used a python script to do this and to perform the necessary calculations mentioned earlier. Note that most of this python script is just for the convenience of getopts and that, if needed, it can be cut down significantly at the cost of flexibility. If you always want the same output size and audio bitrate, this script can be simplified to just a couple of lines.</p>
<p>calc_bitrate.py:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #808080; font-style: italic;color: green;">#!/usr/bin/python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">getopt</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> <span style="color: #dc143c;color: blue;">getopt</span>, GetoptError
<span style="color: #ff7700;font-weight:bold;color: blue;">from</span> <span style="color: #dc143c;color: blue;">sys</span> <span style="color: #ff7700;font-weight:bold;color: blue;">import</span> argv, exit
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> secs<span style="color: black;color: black;">&#40;</span>h, m, s<span style="color: black;color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> <span style="color: black;color: black;">&#40;</span>h <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">60</span> + m<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">60</span> + s
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">def</span> calc_video_bitrate<span style="color: black;color: black;">&#40;</span>target_size, abr, <span style="color: #dc143c;color: blue;">time</span><span style="color: black;color: black;">&#41;</span>:
  target_bytes = target_size <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1024</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1024</span>
  audio_bytes = <span style="color: black;color: black;">&#40;</span><span style="color: black;color: black;">&#40;</span>abr <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">1000</span><span style="color: black;color: black;">&#41;</span> / <span style="color: #ff4500;color: maroon;">8</span><span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #dc143c;color: blue;">time</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> <span style="color: black;color: black;">&#40;</span>target_bytes - audio_bytes<span style="color: black;color: black;">&#41;</span> / <span style="color: #dc143c;color: blue;">time</span> <span style="color: #66cc66;color: black;">*</span> <span style="color: #ff4500;color: maroon;">8</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">try</span>:
  opts, args = <span style="color: #dc143c;color: blue;">getopt</span><span style="color: black;color: black;">&#40;</span>argv<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">1</span>:<span style="color: black;color: black;">&#93;</span>, <span style="color: #483d8b;color: maroon;">&quot;s:a:t:&quot;</span>, <span style="color: black;color: black;">&#91;</span><span style="color: #483d8b;color: maroon;">&quot;size=&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;abr=&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;time=&quot;</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">except</span> GetoptError, err:
  <span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #008000;color: blue;">str</span><span style="color: black;color: black;">&#40;</span>err<span style="color: black;color: black;">&#41;</span>
  exit<span style="color: black;color: black;">&#40;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
target_size = <span style="color: #ff4500;color: maroon;">350</span> <span style="color: #808080; font-style: italic;color: green;">#MiB</span>
abr = <span style="color: #ff4500;color: maroon;">128</span> <span style="color: #808080; font-style: italic;color: green;">#kbps</span>
<span style="color: #dc143c;color: blue;">time</span> = <span style="color: #ff4500;color: maroon;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">for</span> o, a <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> opts:
  <span style="color: #ff7700;font-weight:bold;color: blue;">if</span> o <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> <span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;-s&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;--size&quot;</span><span style="color: black;color: black;">&#41;</span>:
    target_size = <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>a<span style="color: black;color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;color: blue;">elif</span> o <span style="color: #ff7700;font-weight:bold;color: blue;">in</span> <span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;-a&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;--abr&quot;</span><span style="color: black;color: black;">&#41;</span>:
    abr = <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>a<span style="color: black;color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">if</span> <span style="color: #008000;color: blue;">len</span><span style="color: black;color: black;">&#40;</span>args<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">&lt;</span> <span style="color: #ff4500;color: maroon;">1</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #483d8b;color: maroon;">&quot;Usage: &quot;</span> + argv<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span> + <span style="color: #483d8b;color: maroon;">&quot; [-s &lt;size (M)&gt;] [-a &lt;audio bit rate (k)&gt;] [[hh:]mm:]ss&quot;</span>
  exit<span style="color: black;color: black;">&#40;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
time_part = args<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span>.<span style="color: black;color: black;">split</span><span style="color: black;color: black;">&#40;</span><span style="color: #483d8b;color: maroon;">&quot;:&quot;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;color: blue;">if</span> <span style="color: #008000;color: blue;">len</span><span style="color: black;color: black;">&#40;</span>time_part<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">&lt;</span> <span style="color: #ff4500;color: maroon;">2</span>: time_part = <span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span> + time_part
<span style="color: #ff7700;font-weight:bold;color: blue;">if</span> <span style="color: #008000;color: blue;">len</span><span style="color: black;color: black;">&#40;</span>time_part<span style="color: black;color: black;">&#41;</span> <span style="color: #66cc66;color: black;">&lt;</span> <span style="color: #ff4500;color: maroon;">3</span>: time_part = <span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span> + time_part
<span style="color: #dc143c;color: blue;">time</span> = secs<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>time_part<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">0</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>, <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>time_part<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">1</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span>, <span style="color: #008000;color: blue;">int</span><span style="color: black;color: black;">&#40;</span>time_part<span style="color: black;color: black;">&#91;</span><span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#93;</span><span style="color: black;color: black;">&#41;</span><span style="color: black;color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: blue;">print</span> <span style="color: #483d8b;color: maroon;">&quot;%d&quot;</span> <span style="color: #66cc66;color: black;">%</span> calc_video_bitrate<span style="color: black;color: black;">&#40;</span>target_size, abr, <span style="color: #dc143c;color: blue;">time</span><span style="color: black;color: black;">&#41;</span></pre></div></div>

<p>A typical usage for this would be <code>./calc_python.py -s 350 -a 128 29:23</code>.</p>
<p>We can then use a combination of these inside a shell script easily. I&#8217;m using bash syntax just to nest the commands into a single line but for compatibility with other shells, backticks (`) can be used and this is what I normally prefer. This script loops through all of the .VOB files in the directory and gives their target video bitrate for a 350MiB output and 128kbps audio.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: black;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #000000; font-weight: bold;color: blue;">for</span> vob <span style="color: #000000; font-weight: bold;color: blue;">in</span> <span style="color: #000000; font-weight: bold;color: black;">*</span>.VOB
<span style="color: #000000; font-weight: bold;color: blue;">do</span>
  <span style="color: #007800;">BR</span>=$<span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>.<span style="color: #000000; font-weight: bold;color: black;">/</span>calc_bitrate.py <span style="color: #660033;">-s</span> <span style="color: #000000;color: maroon;">350</span> <span style="color: #660033;">-a</span> <span style="color: #000000;color: maroon;">128</span> $<span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span><span style="color: #c20cb9; font-weight: bold;color: blue;">ffmpeg</span> <span style="color: #660033;">-i</span> <span style="color: #007800;color: black;">$vob</span> <span style="color: #000000;color: maroon;">2</span><span style="color: #000000; font-weight: bold;color: black;">&gt;&amp;</span><span style="color: #000000;color: maroon;">1</span> <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">grep</span> Duration <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">cut</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">' '</span> <span style="color: #660033;">-f</span> <span style="color: #000000;color: maroon;">4</span> <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">cut</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">'.'</span> <span style="color: #660033;">-f</span> <span style="color: #000000;color: maroon;">1</span><span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span><span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span>
  <span style="color: #7a0874; font-weight: bold;color: blue;">echo</span> <span style="color: #007800;color: black;">$vob</span> <span style="color: #007800;color: black;">$BR</span>
<span style="color: #000000; font-weight: bold;color: blue;">done</span></pre></div></div>

<p>I use this in 2-pass VBR mode with the libx264 video encoder and libfaac audio encoder in an mp4 container just by replacing the &#8220;echo&#8221; line of the above script with the following 2 lines:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: black;"><span style="color: #c20cb9; font-weight: bold;color: blue;">ffmpeg</span> <span style="color: #660033;">-i</span> <span style="color: #007800;color: black;">$vob</span> <span style="color: #660033;">-an</span> <span style="color: #660033;">-pass</span> <span style="color: #000000;color: maroon;">1</span> <span style="color: #660033;">-vcodec</span> libx264 <span style="color: #660033;">-vpre</span> fastfirstpass <span style="color: #660033;">-b</span> <span style="color: #007800;color: black;">$BR</span> <span style="color: #660033;">-bt</span> <span style="color: #007800;color: black;">$BR</span> <span style="color: #660033;">-deinterlace</span> <span style="color: #660033;">-threads</span> <span style="color: #000000;color: maroon;">0</span> <span style="color: #660033;">-y</span> pass1.mp4
<span style="color: #c20cb9; font-weight: bold;color: blue;">ffmpeg</span> <span style="color: #660033;">-i</span> <span style="color: #007800;color: black;">$vob</span> <span style="color: #660033;">-acodec</span> libfaac <span style="color: #660033;">-ab</span> 128k <span style="color: #660033;">-ac</span> <span style="color: #000000;color: maroon;">2</span> <span style="color: #660033;">-pass</span> <span style="color: #000000;color: maroon;">2</span> <span style="color: #660033;">-vcodec</span> libx264 <span style="color: #660033;">-vpre</span> hq <span style="color: #660033;">-b</span> <span style="color: #007800;color: black;">$BR</span> <span style="color: #660033;">-bt</span> <span style="color: #007800;color: black;">$BR</span> <span style="color: #660033;">-deinterlace</span> <span style="color: #660033;">-threads</span> <span style="color: #000000;color: maroon;">0</span> <span style="color: #660033;">-y</span> <span style="color: #000000; font-weight: bold;color: black;">`</span><span style="color: #7a0874; font-weight: bold;color: blue;">echo</span> <span style="color: #007800;color: black;">$vob</span> <span style="color: #000000; font-weight: bold;color: black;">|</span> <span style="color: #c20cb9; font-weight: bold;color: blue;">sed</span> <span style="color: #ff0000;">'s/VOB/mp4/'</span><span style="color: #000000; font-weight: bold;color: black;">`</span></pre></div></div>

<p>I have 2 versions of this script, one with &#8220;-deinterlace&#8221; and one without. PAL video (576i &#8211; used in Europe), such as Dad&#8217;s Army needs deinterlacing. NTSC video (480 &#8211; used in North America) usually does not.</p>
<p>For ripping DVDs to H.264 and maintaining the quality, I wouldn&#8217;t use a bitrate lower than 1000k or an audio bitrate lower than 128k stereo. This means that for getting media onto a CD, you probably want no smaller than 350MiB for 30 to 40 minutes or 700MiB for 1 hour or more, depending on your resolution. Also note that I only intend to play these in computers and fitting them onto CDs is just a convenience &#8211; standalone DVD players will not be able to play H.264 or AAC (Blu-ray and HDDVD players may be able to &#8211; mp4 containers and reading CDs would be more of an issue).</p>
<h3>Update:</h3>
<p>I have successfully tested this in a LG BD370 Blu-ray player.</p>
<p>I have not tried actually burning these onto CDs yet so if 2 won&#8217;t fit on a 700MiB CD, even with overburn (because of overheads that were ignored, as stated earlier) then the simplest solution is to just target a smaller file size with something like &#8220;-s 348&#8243;.</p>
<h2>The result</h2>
<p>Dad&#8217;s Army episodes are not all of the same length. Some are several minutes longer than others. The following shows how no matter the size of the input file, they all produce the same size output file:
<pre>$ ll da_5_*.VOB
-r--r--r-- 1 mythtv mythtv 1364660224 2009-06-04 00:01 da_5_01.VOB
-r--r--r-- 1 mythtv mythtv 1360699392 2009-06-04 00:01 da_5_02.VOB
-r--r--r-- 1 mythtv mythtv  956084224 2009-06-04 00:02 da_5_03.VOB
-r--r--r-- 1 mythtv mythtv 1355888640 2009-06-04 00:02 da_5_04.VOB
-r--r--r-- 1 mythtv mythtv 1114351616 2009-06-03 23:59 da_5_05.VOB
-r--r--r-- 1 mythtv mythtv 1034289152 2009-06-04 00:00 da_5_06.VOB
-r--r--r-- 1 mythtv mythtv 1045202944 2009-06-04 00:00 da_5_07.VOB
-r--r--r-- 1 mythtv mythtv 1345318912 2009-06-04 00:00 da_5_08.VOB
-r--r--r-- 1 mythtv mythtv 1391529984 2009-06-04 00:02 da_5_09.VOB
-r--r--r-- 1 mythtv mythtv 1342748672 2009-06-04 00:03 da_5_10.VOB
-r--r--r-- 1 mythtv mythtv 1158017024 2009-06-04 00:03 da_5_11.VOB
-r--r--r-- 1 mythtv mythtv 1157097472 2009-06-04 00:03 da_5_12.VOB
-r--r--r-- 1 mythtv mythtv 1180098560 2009-06-04 00:04 da_5_13.VOB
$ ll -h da_5_*.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 06:18 da_5_01.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 06:55 da_5_02.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 07:30 da_5_03.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 08:08 da_5_04.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 08:44 da_5_05.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 09:21 da_5_06.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 09:58 da_5_07.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 10:36 da_5_08.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 11:15 da_5_09.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 11:54 da_5_10.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 12:29 da_5_11.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 13:05 da_5_12.mp4
-rw-r--r-- 1 mythtv mythtv 352M 2009-06-17 13:41 da_5_13.mp4</pre>
<h2>Update:</h2>
<p>A pure python replacement script is available <a href="http://www.helyar.net/2009/ffmpeg-target-file-sizes-again/">here</a> that simplifies use.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.helyar.net/2009/how-to-set-target-file-sizes-in-ffmpeg/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>There is no logical equivalent to conditional statements!</title>
		<link>http://www.helyar.net/2009/there-is-no-logical-equivalent-to-conditional-statements/</link>
		<comments>http://www.helyar.net/2009/there-is-no-logical-equivalent-to-conditional-statements/#comments</comments>
		<pubDate>Mon, 18 May 2009 13:45:59 +0000</pubDate>
		<dc:creator>George Helyar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[conditional]]></category>
		<category><![CDATA[logic]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.helyar.net/?p=182</guid>
		<description><![CDATA[For a long time, I have seen chunks of code in languages such as Lua and Python that claim that they can reproduce the C conditional operator just by using two logical operators, &#8220;and&#8221; and &#8220;or&#8221;. The conditional statement in C uses the following format: v = c ? t : f; This is equivalent [...]]]></description>
			<content:encoded><![CDATA[<p>For a long time, I have seen chunks of code in languages such as Lua and Python that claim that they can reproduce the C conditional operator just by using two logical operators, &#8220;and&#8221; and &#8220;or&#8221;.</p>
<p>The conditional statement in C uses the following format:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;color: black;">v <span style="color: #339933;color: black;">=</span> c <span style="color: #339933;color: black;">?</span> t <span style="color: #339933;color: black;">:</span> f<span style="color: #339933;color: black;">;</span></pre></div></div>

<p>This is equivalent to saying &#8220;if the condition c (a boolean expression) is met assign t to v, otherwise assign f to v&#8221;. It&#8217;s a shorthand way of writing</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;color: black;"><span style="color: #b1b100;color: blue;">if</span> <span style="color: #009900;color: black;">&#40;</span>c<span style="color: #009900;color: black;">&#41;</span>
  v <span style="color: #339933;color: black;">=</span> t<span style="color: #339933;color: black;">;</span>
<span style="color: #b1b100;color: blue;">else</span>
  v <span style="color: #339933;color: black;">=</span> f<span style="color: #339933;color: black;">;</span></pre></div></div>

<p>Some example outputs:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;color: black;">v <span style="color: #339933;color: black;">=</span> <span style="color: #0000dd;color: maroon;">1</span> <span style="color: #339933;color: black;">?</span> <span style="color: #ff0000;color: maroon;">&quot;foo&quot;</span> <span style="color: #339933;color: black;">:</span> <span style="color: #ff0000;color: maroon;">&quot;bar&quot;</span><span style="color: #339933;color: black;">;</span> <span style="color: #808080; font-style: italic;color: green;">/* v = &quot;foo&quot; */</span>
v <span style="color: #339933;color: black;">=</span> <span style="color: #0000dd;color: maroon;">0</span> <span style="color: #339933;color: black;">?</span> <span style="color: #ff0000;color: maroon;">&quot;foo&quot;</span> <span style="color: #339933;color: black;">:</span> <span style="color: #ff0000;color: maroon;">&quot;bar&quot;</span><span style="color: #339933;color: black;">;</span> <span style="color: #808080; font-style: italic;color: green;">/* v = &quot;bar&quot; */</span>
v <span style="color: #339933;color: black;">=</span> <span style="color: #0000dd;color: maroon;">1</span> <span style="color: #339933;color: black;">?</span> <span style="color: #0000dd;color: maroon;">0</span> <span style="color: #339933;color: black;">:</span> <span style="color: #0000dd;color: maroon;">2</span><span style="color: #339933;color: black;">;</span>         <span style="color: #808080; font-style: italic;color: green;">/* v = 0 */</span></pre></div></div>

<p>In the first example, the condition is true (C has no boolean type, anything that isn&#8217;t zero equates to true) so &#8220;t&#8221; is assigned. In the second example, the condition is false (zero) so &#8220;f&#8221; is assigned. The important thing to note here is that in the third example, the condition is true so &#8220;t&#8221; is still assigned.</p>
<p>As proof of this final value, the following was taken from a cgwin shell using the gcc compiler</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;color: black;">~$ <span style="color: #c20cb9; font-weight: bold;color: blue;">gcc</span> <span style="color: #660033;">--version</span>
<span style="color: #c20cb9; font-weight: bold;color: blue;">gcc</span> <span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>GCC<span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span> 3.4.4 <span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>cygming special, gdc <span style="color: #000000;color: maroon;">0.12</span>, using dmd <span style="color: #000000;color: maroon;">0.125</span><span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span>
Copyright <span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>C<span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span> <span style="color: #000000;color: maroon;">2004</span> Free Software Foundation, Inc.
This is <span style="color: #c20cb9; font-weight: bold;color: blue;">free</span> software; see the <span style="color: #7a0874; font-weight: bold;color: blue;">source</span> <span style="color: #000000; font-weight: bold;color: blue;">for</span> copying conditions.  There is NO
warranty; not even <span style="color: #000000; font-weight: bold;color: blue;">for</span> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
&nbsp;
~$ <span style="color: #c20cb9; font-weight: bold;color: blue;">cat</span> cond.c
<span style="color: #666666; font-style: italic;">#include &lt;stdio.h&gt;</span>
&nbsp;
int main<span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span>void<span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;color: black;">&#123;</span>
  <span style="color: #7a0874; font-weight: bold;color: blue;">printf</span><span style="color: #7a0874; font-weight: bold;color: black;">&#40;</span><span style="color: #ff0000;color: maroon;">&quot;The result is %d!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, <span style="color: #000000;color: maroon;">1</span> ? <span style="color: #000000;color: maroon;">0</span> : <span style="color: #000000;color: maroon;">2</span><span style="color: #7a0874; font-weight: bold;color: black;">&#41;</span>;
&nbsp;
  <span style="color: #7a0874; font-weight: bold;color: blue;">return</span> <span style="color: #000000;color: maroon;">0</span>;
<span style="color: #7a0874; font-weight: bold;color: black;">&#125;</span>
~$ <span style="color: #c20cb9; font-weight: bold;color: blue;">gcc</span> <span style="color: #660033;">-Wall</span> <span style="color: #660033;">-o</span> cond cond.c
~$ .<span style="color: #000000; font-weight: bold;color: black;">/</span>cond
The result is <span style="color: #000000;color: maroon;">0</span><span style="color: #000000; font-weight: bold;color: black;">!</span>
~$</pre></div></div>

<p>The following is an implementation in Python that always gives the same behaviour as the conditional operator in C.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #ff7700;font-weight:bold;color: blue;">def</span> cond_if<span style="color: black;color: black;">&#40;</span>c, t, f<span style="color: black;color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">if</span> c: <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> t
  <span style="color: #ff7700;font-weight:bold;color: blue;">else</span>: <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> f</pre></div></div>

<p>We can show the same examples again:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_if<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">True</span>, <span style="color: #483d8b;color: maroon;">&quot;foo&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;bar&quot;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #483d8b;color: maroon;">'foo'</span>
<span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_if<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">False</span>, <span style="color: #483d8b;color: maroon;">&quot;foo&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;bar&quot;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #483d8b;color: maroon;">'bar'</span>
<span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_if<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">True</span>, <span style="color: #ff4500;color: maroon;">0</span>, <span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #ff4500;color: maroon;">0</span></pre></div></div>

<p>However, many people claim that the same code can be written more concisely and, more importantly, inline by using logical operators to mimic the behaviour. The following is such a function:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #ff7700;font-weight:bold;color: blue;">def</span> cond_logic<span style="color: black;color: black;">&#40;</span>c, t, f<span style="color: black;color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;color: blue;">return</span> c <span style="color: #ff7700;font-weight:bold;color: blue;">and</span> t <span style="color: #ff7700;font-weight:bold;color: blue;">or</span> f</pre></div></div>

<p>When we try to actually run this, with the same examples again, we see where it all falls down.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: black;"><span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_logic<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">True</span>, <span style="color: #483d8b;color: maroon;">&quot;foo&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;bar&quot;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #483d8b;color: maroon;">'foo'</span>
<span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_logic<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">False</span>, <span style="color: #483d8b;color: maroon;">&quot;foo&quot;</span>, <span style="color: #483d8b;color: maroon;">&quot;bar&quot;</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #483d8b;color: maroon;">'bar'</span>
<span style="color: #66cc66;color: black;">&gt;&gt;&gt;</span> cond_logic<span style="color: black;color: black;">&#40;</span><span style="color: #008000;color: blue;">True</span>, <span style="color: #ff4500;color: maroon;">0</span>, <span style="color: #ff4500;color: maroon;">2</span><span style="color: black;color: black;">&#41;</span>
<span style="color: #ff4500;color: maroon;">2</span></pre></div></div>

<p>While it works for the first two examples as it should, any pair of values which can be equated to a boolean expression will corrupt the logic used. In this example, simply passing zero as the &#8220;t&#8221; makes the result of &#8220;c and t&#8221; false (because false and _ = false), which reduces it to &#8220;false or f&#8221;, which returns &#8220;f&#8221; (because false or _ = _). No combination of parenthesis or variables will correct this problem.</p>
<p>Here&#8217;s the final example again but this time in Lua:</p>

<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;color: black;"><span style="color: #66cc66;color: black;">&gt;</span> <span style="color: #b1b100;color: blue;">function</span> cond_logic<span style="color: #66cc66;color: black;">&#40;</span>c, t, f<span style="color: #66cc66;color: black;">&#41;</span>
<span style="color: #66cc66;color: black;">&gt;&gt;</span>   <span style="color: #b1b100;color: blue;">return</span> c <span style="color: #b1b100;color: blue;">and</span> t <span style="color: #b1b100;color: blue;">or</span> f<span style="color: #66cc66;color: black;">;</span>
<span style="color: #66cc66;color: black;">&gt;&gt;</span> <span style="color: #b1b100;color: blue;">end</span>
&nbsp;
<span style="color: #66cc66;color: black;">&gt;</span> <span style="color: #66cc66;color: black;">=</span> cond_logic<span style="color: #66cc66;color: black;">&#40;</span><span style="color: #cc66cc;color: maroon;">1</span>, <span style="color: #b1b100;color: blue;">false</span>, <span style="color: #cc66cc;color: maroon;">2</span><span style="color: #66cc66;color: black;">&#41;</span><span style="color: #66cc66;color: black;">;</span>
<span style="color: #cc66cc;color: maroon;">2</span></pre></div></div>

<p>So, the next time someone tells you that your code can be improved in this way or that logical operators can be used to mimic the conditional operator, tell them that they are wrong and give them an example to prove it, then stick to using if statements if the language does not provide a conditional operator.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.helyar.net/2009/there-is-no-logical-equivalent-to-conditional-statements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
