text:
# Building a terrible 'IoT' temperature logger

I had approximately the following exchange with a co-worker a few days ago:

Them: “Hey, do you have a spare Raspberry Pi lying around?”
Me: [thinks] “..yes, actually.”
T: “Do you want to build a temperature logger with Prometheus and a DS18B20+?
M: “Uh, okay?”

It later turned out that that co-worker had been enlisted by yet another individual to provide a temperature logger for their project of brewing cider, to monitor the temperature during fermentation. Since I had all the hardware at hand (to wit, a Raspberry Pi 2 that I wasn’t using for anything and temperature sensors provided by the above co-worker), I threw something together. It also turned out that the deadline was quite short (brewing began just two days after this initial exchange), but I made it work in time.

## Interfacing the thermometer

As noted above, the core of this temperature logger is a DS18B20 temperature sensor. Per the manufacturer:

The DS18B20 digital thermometer provides 9-bit to 12-bit Celsius temperature measurements … communicates over a 1-Wire bus that by definition requires only one data line (and ground) for communication with a central microprocessor. … Each DS18B20 has a unique 64-bit serial code, which allows multiple DS18B20s to function on the same 1-Wire bus. Thus, it is simple to use one microprocessor to control many DS18B20s distributed over a large area.

Indeed, this is a very easy device to interface with. But even given the svelte hardware needs (power, data and ground signals), writing some code that speaks 1-Wire is not necessarily something I’m interested in. Fortunately, these sensors are very commonly used with the Raspberry Pi, as illustrated by an Adafruit tutorial published in 2013.

The Linux kernel provided for the Pi in its default Raspbian (Debian-derived) distribution supports bit-banging 1-Wire over its GPIOs by default, requiring only a device tree overlay to activate it. This is as simple as adding a line to /boot/config.txt to make the machine’s boot loader instruct the kernel to apply a change to the hardware configuration at boot time:

dtoverlay=w1-gpio

With that configuration, one simply needs to wire the sensor up. The w1-gpio device tree configuration by default uses GPIO 4 on the Pi as the data line, then power and grounds need to be connected and a pull-up resistor added to the data line (since 1-Wire is an open-drain bus).

The w1-therm kernel module already understands how to interface with these sensors- meaning I don’t need to write any code to talk to the temperature sensor: Linux can do it all for me! For instance, reading the temperature out in an interactive shell to test, after booting with the 1-Wire overlay enabled:

$modprobe w1-gpio w1-therm$ cd /sys/bus/w1/devices
$ls 28-000004b926f1 w1_bus_master1$ cat 28-000004b926f1/w1_slave
9b 01 4b 46 7f ff 05 10 6e : crc=6e YES
9b 01 4b 46 7f ff 05 10 6e t=25687

The kernel periodically scans the 1-Wire bus for slaves and creates a directory for each device it detects. In this instance, there is one slave on the bus (my temperature sensor) and it has serial number 000004b926f1. Reading its w1_slave file (provided by the w1-therm driver) returns the bytes that were read on both lines, a summary of transmission integrity derived from the message checksum on the first line, and t=x on the second line, where x is the measured temperature in milli-degrees Celsius. Thus, the measured temperature above was 25.687 degrees.

While it’s fairly easy to locate and read these files in sysfs from a program, I found a Python library that further simplifies the process: w1thermsensor provides a simple API for detecting and reading 1-wire temperature sensors, which I used when implementing the bridge for capturing temperature readings (detailed more later).

### 1-Wire details

I wanted to verify for myself how the 1-wire interfacing worked so here are the details of what I’ve discovered, presented because they may be interesting or helpful to some readers. Most documentation of how to perform a given task with a Raspberry Pi is limited to comments like “just add this line to some file and do the other thing!” with no discussion of the mechanics involved, which I find very unsatisfying.

The line added to /boot/config.txt tells the Rapberry Pi’s boot loader (a version of Das U-Boot) to pass the w1-gpio.dtbo device tree overlay description to the kernel. The details of what’s in that overlay can be found in the kernel source tree at arch/arm/boot/dts/overlays/w1-gpio-overlay.dts.

This in turn pulls in the w1-gpio kernel module, which is part of the upstream kernel distribution- it’s very simple, setting or reading the value of a GPIO port as requested by the Linux 1-wire subsystem.

Confusingly, if we examine the dts file describing the device tree overlay, it can take a pullup option that controls a rpi,parasitic-power parameter. The documentation says this “enable(s) the parasitic power (2-wire, power-on-data) feature”, which is confusing. 1-Wire is inherently capable of supplying parasitic power to slaves with modest power requirements, with the slaves charging capacitors off the data line when it’s idle (and being held high, since it’s an open-collector bus). So, saying an option will enable parasitic power is confusing at best and probably flat wrong.

Further muddying the waters, there also exists a w1-gpio-pullup overlay that includes a second GPIO to drive an external pullup to provide more power, which I believe allows implementation of the strong pull-up described in Figure 6 of the DS18B20 datasheet (required because the device’s power draw while reading the temperature exceeds the capacity of a typical parasitic power setup):

By also connecting the pullup GPIO to the data line (or putting a FET in there like the datasheet suggests), the w1-gpio driver will set the pullup line to logic high for a requested time, then return it to Hi-Z where it will idle. But for my needs (cobbling something together quickly), it’s much easier to not even bother with parasite power.

In conclusion for this section: I don’t know what the pullup option for the 1-Wire GPIO overlay actually does, because enabling it and removing the external pull-up resistor from my setup causes the bus to stop working. The documentation is confusingly imprecise, so I gave up on further investigation since I already had a configuration that worked.

## Prometheus scraping

To capture store time-series data representing the temperature, per the co-worker’s original suggestion I opted to use Prometheus. While it’s designed for monitoring the state of computer systems, it’s plenty capable of storing temperature data as well. Given I’ve used Prometheus before, it seemed like a fine option for this application though on later consideration I think a more robust (and effortful) system could be build with different technology choices (explored later in this post).

The Raspberry Pi with temperature sensor in my application is expected to stay within range of a WiFi network with internet connectivity, but this network does not permit any incoming connections, nor does it permit connections between wireless clients. Given I wanted to make the temperature data available to anybody interested in the progress of brewing, there needs to be some bridge to the outside world- thus Prometheus should run on a different machine from the Pi.

The easy solution I chose was to bring up a minimum-size virtual machine on Google Cloud running Debian, then install Prometheus and InfluxDB from the Debian repositories:

$influx Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring. Connected to http://localhost:8086 version 1.0.2 InfluxDB shell version: 1.0.2 > CREATE DATABASE prometheus; Examining the Prometheus logs again, now it was failing and complaining that the specified retention policy didn’t exist. Noting that the Influx documentation for the CREATE DATABASE command mentioned that the autogen retention policy will be used if no other is specified, setting the retention-policy flag to autogen and restarting Prometheus made data start appearing, which I verified by waiting a little while and making a query (guessing a little bit about how I would query a particular metric): > USE prometheus; > SELECT * FROM w1therm_temperature LIMIT 10; name: w1therm_temperature ------------------------- time id instance job value 1532423583303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423598303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423613303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423628303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423643303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423658303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423673303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423688303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423703303000000 000004b926f1 localhost:9000 w1therm 297.9 1532423718303000000 000004b926f1 localhost:9000 w1therm 297.9 ## Results A sample graph of the temperature over two days: The fermentation temperature is quite stable, with daily variation of less than one degree in either direction from the baseline. ## Refinements I later improved the temperature server to handle SIGHUP as a trigger to scan for sensors again, which is a slight improvement over restarting it, but not very important because the server is already so simple (and fast to restart). On reflection, using Prometheus and scraping temperatures is a very strange way to go about solving the problem of logging the temperature (though it has the advantage of using only tools I was already familiar with so it was easy to do quickly). Pushing temperature measurements from the Pi via MQTT would be a much more sensible solution, since that’s a protocol designed specifically for small sensors to report their states. Indeed, there is no shortage of published projects that do exactly that more efficiently than my Raspberry Pi, most of them using ESP8266 microcontrollers which are much lower-power and can still connect to Wi-Fi networks. ### Rambling about IoT security Getting sensor readings through an MQTT broker and storing them to be able to graph them is not quite as trivial as scraping them with Prometheus, but I suspect there does exist a software package that does most of the work already. If not, I expect a quick and dirty one could be implemented with relative ease. On the other hand, running a device like that which is internet-connected but is unlikely to ever receive anything remotely looking like a security update seems ill-advised if it’s meant to run for anything but a short amount of time. In that case having the sensor be part of a Zigbee network instead, which does not permit direct internet connectivity and thus avoids the fraught terrain of needing to protect both the device itself from attack and the data transmitted by the device from unauthorized use (eavesdropping) by taking ownership of that problem away from the sensor. It remains possible to forward messages out to an MQTT broker on the greater internet using some kind of bridge (indeed, this is the system used by many consumer “smart device” platforms, like Philips’ Hue though I don’t think they use MQTT), where individual devices connect only to the Zigbee network, and a more capable bridge is responsible for internet connectivity. The problem of keeping the bridge secure remains, but is appreciably simpler than needing to maintain the security of each individual device in what may be a heterogeneous network. It’s even possible to get inexpensive off-the-shelf temperature and humidity sensors that connect to Zigbee networks like some sold by Xiaomi, offering much better finish than a prototype-quality one I might be able to build myself, very good battery life, and still capable of operating in a heterogenous Zigbee network with arbitrary other devices (though you wouldn’t know it from the manufacturer’s documentation, since they want consumers to commit to their “platform” exclusively)! So while my solution is okay in that it works fine with hardware I already had on hand, a much more robust solution is readily available with off-the-shelf hardware and only a little bit of software to glue it together. If I needed to do this again and wanted a solution that doesn’t require my expertise to maintain it, I’d reach for those instead. 1. Hostname changed to an obviously fake one for anonymization purposes. [return] # Quick and dirty web image optimization Given a large pile of images that nominally live on a web server, I want to make them smaller and more friendly to serve to clients. This is hardly novel: for example, Google offer detailed advice on reducing the size of images for the web. I have mostly JPEG and PNG images, so, jpegtran and optipng are the tools of choice for bulk lossless compression. To locate and compress images, I’ll use GNU find and parallel to invoke those tools. For JPEGs I take a simple approach, preserving comment tags and creating a progressive JPEG (which can be displayed at a reduced resolution before the entire image has been downloaded). find -iname '*.jpg' -printf '%P,%s\n' \ -exec jpegtran -o -progressive -copy comments -outfile {} {} \; \ > delta.csv  Where things get a little more interesting is when I output the name and size of each located file (-printf ...) and store those in a file (> delta.csv).1 This is so I can collect more information about the changes that were made. ## Check the JPEGs Loading up a Jupyter notebook for quick computations driven with Python, I load the file names and original sizes, adding the current size of each listed file to my dataset. import os deltas = [] with open('delta.csv', 'r') as f: for line in f: name, _, size = line.partition(',') size = int(size) newsize = os.stat(name).st_size deltas.append((name, size, newsize)) From there, it’s quick work to do some list comprehensions and generate some overall statistics: original_sizes = [orig for (_, orig, _) in deltas] final_sizes = [new for (_, _, new) in deltas] shrinkage = [orig - new for (_, orig, new) in deltas] pct_total_change = 100 * (sum(original_sizes) - sum(final_sizes)) / sum(original_sizes) pct_change = [shrinkage / orig for (shrinkage, orig) in zip(shrinkage, original_sizes)] avg_pct_change = 100 * sum(pct_change) / len(pct_change) print('Total size reduction:', sum(shrinkage), 'bytes ({}%)'.format(round(pct_total_change, 2))) avg = sum(shrinkage) / len(shrinkage) print('Average reduction per file:', avg, 'bytes ({}%)'.format(round(avg_pct_change, 2))) This is by no means good code, but that’s why this short write-up is “quick and dirty”. Over the JPEGs alone, I rewrote 2162 files, saving 8820474 bytes overall; about 8.4 MiB, 8.02% of the original size of all of the files- a respectable savings for exactly zero loss in quality. ## PNGs I processed the PNGs in a similar fashion, having optipng emit interlaced PNGs which can be displayed at reduced resolution without complete data and try more combinations of compression parameters than it usually would, trading CPU time for possible gains. There was no similar tradeoff with the JPEGs, since apparently jpegtran’s optimization of encoding is entirely deterministic whereas optipng relies on experimental compression of image data with varying parameters to find a minimum size. Since I observed that many of the PNGs were already optimally-sized and interlacing made them significantly larger (by more than 10% in many cases), I also considered only files that were more than 256 KiB in size. To speed up processing overall, I used parallel to run multiple instances of optipng at once (since it’s a single-threaded program) to better utilize the multicore processors at my disposal. find -iname '*.png' -size +256k -printf '%P,%s\n' \ -exec parallel optipng -i 1 -o 9 ::: {} + \ > delta.csv  Running the same analysis over this output, I found that interlacing had a significant negative effect on image size. There were 68 inputs larger than 256 KiB, and the size of all of the files increased by 2316732 bytes; 2.2 MiB, nearly 10% of the original size. A few files had significant size reductions (about 300 KiB in the best case), but the largest increase in size had similar magnitude. Given the overall size increase, the distribution of changes must be skewed towards net increases. ### Try again Assuming most of the original images were not interlaced (most programs that write PNG don’t interlace unless specifically told to) and recognizing that interlaced PNGs tend to compress worse, I ran this again but without interlacing (-i 0) and selecting all files regardless of size. The results of this second run were much better: over 3102 files, save 12719421 bytes (12.1 MiB), 15.9% of the original combined size. One file saw a whopping 98% reduction in size, from 234 KB to only 2914 bytes- inspecting that one myself, the original was inefficiently coded 32 bits per pixel (8-bit RGBA), and it was reduced to two bits per pixel. I expect a number of other files had similar but less dramatic transformations. Some were not shrunk at all, but optipng is smart enough to skip rewriting those so it will never make a file larger- the first run was an exception because I asked it to make interlaced images. ## That’s all I saved about 20 MiB for around 5000 files- not bad. A copy of the notebook I used to do measurements is available (check out nbviewer for an online viewer), useful if you want to do something similar with your own images. I would not recommend doing it to ones that are not meant purely for web viewing, since the optimization process may strip metadata that is useful to preserve. 1. Assumption: none of the file names contain commas, since I’m calling this a CSV (comma-separated values) file. It’s true in this instance, but may not be in others. [return] # sax-ng Over on Cemetech, we’ve long had an embedded chat widget called “SAX” (“Simultaneous Asynchronous eXchange”). It behaves kind of like a traditional shoutbox, in that registered users can use the SAX widget to chat in near-real-time. There is also a bot that relays messages between the on-site widget and an IRC channel, which we call “saxjax”. The implementation of this, however, was somewhat lacking in efficiency. It was first implemented around mid-2006, and saw essentially no updates until just recently. The following is a good example of how dated the implementation was: // code for Mozilla, etc if (window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest() xmlhttp.onreadystatechange=state_Change xmlhttp.open("GET",url,true) xmlhttp.send(null) } else if (window.ActiveXObject) { // code for IE xmlhttp=new ActiveXObject("Microsoft.XMLHTTP") if (xmlhttp) { xmlhttp.onreadystatechange=state_Change xmlhttp.open("GET",url,true) xmlhttp.send() } }  The presence of ActiveXObject here implies it was written at a time when a large fraction of users would have been using Internet Explorer 5 or 6 (the first version of Internet Explorer released which supported the standard form of XMLHttpRequest was version 7). Around a year ago (that’s how long this post has been a draft for!), I took it upon myself to design and implement a more modern replacement for SAX. This post discusses that process and describes the design of the replacement, which I have called “sax-ng.” ## Legacy SAX The original SAX implementation, as alluded to above, is based on AJAX polling. On the server, a set of approximately the 30 most recent messages were stored in a MySQL database and a few PHP scripts managed retrieving and modifying messages in the database. This design was a logical choice when initially built, since the web site was running on a shared web host (supporting little more than PHP and MySQL) at the time. Eventually this design became a problem, as essentially every page containing SAX that is open at any given time regularly polls for new messages. Each poll calls into PHP on the server, which opens a database connection to perform one query. Practically, this means a very large number of database connections being opened at a fairly regular pace. In mid-2012 the connection count reached levels where the shared hosting provider were displeased with it, and requested that we either pay for a more expensive hosting plan or reduce resource usage. In response, we temporarily disabled SAX, then migrated the web site to a dedicated server provided by OVH, who had opened a new North American datacenter in July. We moved to the dedicated server in August of 2012. This infrastructure change kept the system running, and opened the door to a more sophisticated solution since we gained the ability to run proper server applications. Meanwhile, the limitations of saxjax (the IRC relay bot) slowly became more evident over time. The implementation was rather ad-hoc, in Python. It used two threads to implement relay, with a dismaying amount of shared state used to relay messages between the two threads. It tended to stop working correctly in case of an error in either thread, be it due to a transient error response from polling the web server for new messages, or an encoding-related exception thrown from the IRC client (since Python 2.x uses bytestrings for most tasks unless specifically told not to, and many string operations (particularly outputting the string to somewhere) can break without warning when used with data that is not 8-bit clean (that is, basically anything that isn’t ASCII). Practically, this meant that the bot would frequently end up in a state where it would only relay messages one way, or relay none at all. I put some time into making it more robust to these kinds of failures early in 2015, such that some of the time it would manage to catch these errors and outright restart (rather than try to recover from an inconsistent state). Doing so involved some pretty ugly hacks though, which prompted a return to some longtime thoughts on how SAX could be redesigned for greater efficiently and robustness. ## sax-ng For a long time prior to beginning this work, I frequently (semi-jokingly) suggested XMPP (Jabber) as a solution to the problems with SAX. At a high level this seems reasonable: XMPP is a chat protocol with a number of different implementations available, and is relatively easy to set up as a private chat service. On the other hand, the feature set of SAX imposes a few requirements which are not inherently available for any given chat service: 1. An HTTP gateway, so clients can run inside a web browser. 2. Group chat, not just one-to-one conversation capability. 3. External authentication (logging in to the web site should permit connection to chat as well). 4. Retrieval of chat history (so a freshly-loaded page can have some amount of chat history shown). As it turns out, ejabberd enables all of these, with relatively little customization. mod_http_bind provides an HTTP gateway as specified in XEP-0206, mod_muc implements multi-user chat as specified in XEP-0045 which also includes capabilities to send chat history to clients when they connect, and authentication can be handled by an external program which speaks a simple binary protocol and is invoked by ejabberd. Main implementation of the new XMPP-based system was done in about a week, perhaps 50 hours of concerted work total (though I may be underestimating). I had about a month of “downtime” at the beginning of this past summer, the last week of which was devoted to building sax-ng. ### ejabberd The first phase involved setting up an instance of ejabberd to support the rest of the system. I opted to run it inside Docker, ideally to make the XMPP server more self-contained and avoid much custom configuration on the server. Conveniently, somebody had already built a Docker configuration for ejabberd with a wealth of configuration switches, so it was relatively easy to set up. Implementing authentication against the web site was also easy, referring to the protocol description in the ejabberd developers guide. Since this hooks into the website’s authentication system (a highly modified version of phpBB), this script simply connects to the mysql server and runs queries against the database. Actual authentication is performed with phpBB SIDs (Session ID), rather than a user’s password. It was built this way because the SID and username are stored in a cookie, which is available to a client running in a web browser. This is probably also somewhat more secure than storing a password in the web browser, since the SID is changed regularly so data exposure via some vector cannot compromise a user’s web site password. Error handling in the authentication script is mostly nonexistent. The Erlang approach to such problems is mostly “restart the component if it fails”, so in case of a problem (of which the only real possibility is a database connection error) ejabberd will restart the authentication script and attempt to carry on. In practice this has proven to be perfectly reliable. In XMPP MUC (Multi-User Chat), users are free to choose any nickname they wish. For our application, there is really only one room and we wish to enforce that the nickname used in XMPP is the same as a user’s username on the web site. There ends up being no good way in ejabberd to require that a user take a given nickname, but we can ensure that it is impossible to impersonate other users by registering all site usernames as nicknames in XMPP. Registered nicknames may only be used by the user to which they are registered, so the only implementation question is in how to automatically register nicknames. I ended up writing a small patch to mod_muc_admin, providing an ejabberdctl subcommand to register a nickname. This patch is included in its entirety below. diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 9c69628..3666ba0 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -15,6 +15,7 @@ start/2, stop/1, % gen_mod API muc_online_rooms/1, muc_unregister_nick/1, + muc_register_nick/3, create_room/3, destroy_room/3, create_rooms_file/1, destroy_rooms_file/1, rooms_unused_list/2, rooms_unused_destroy/2, @@ -38,6 +39,9 @@ %% Copied from mod_muc/mod_muc.erl -record(muc_online_room, {name_host, pid}). +-record(muc_registered, + {us_host = {\{<<"">>, <<"">>}, <<"">>} :: {\{binary(), binary()}, binary()} | '$1',
+         nick = <<"">> :: binary()}).

%%----------------------------
%% gen_mod
@@ -73,6 +77,11 @@ commands() ->
module = ?MODULE, function = muc_unregister_nick,
args = [{nick, binary}],
result = {res, rescode}},
+     #ejabberd_commands{name = muc_register_nick, tags = [muc],
+              desc = "Register the nick in the MUC service to the JID",
+              module = ?MODULE, function = muc_register_nick,
+              args = [{nick, binary}, {jid, binary}, {domain, binary}],
+              result = {res, rescode}},

#ejabberd_commands{name = create_room, tags = [muc_room],
desc = "Create a MUC room name@service in host",
@@ -193,6 +202,16 @@ muc_unregister_nick(Nick) ->
error
end.

+muc_register_nick(Nick, JID, Domain) ->
+    {jid, UID, Host, _,_,_,_} = jlib:string_to_jid(JID),
+    F = fun (MHost, MNick) ->
+                mnesia:write(#muc_registered{us_host=MHost,
+                                             nick=MNick})
+        end,
+    case mnesia:transaction(F, [{\{UID, Host}, Domain}, Nick]) of
+        {atomic, ok} -> ok;
+        {aborted, _Error} -> error
+    end.

%%----------------------------

It took me a while to work out how exactly to best implement this feature, but considering I had never worked in Erlang before it was reasonably easy. I do suspect some familiarity with Haskell and Rust provided background to more easily understand certain aspects of the language, though. The requirement that I duplicate the muc_registered record (since apparently Erlang provides no way to import records from another file) rubs me the wrong way, though.

In practice, then, a custom script traverses the web site database, invoking ejabberdctl to register the nickname for every existing user at server startup and then periodically or on demand when the server is running.

### Web interface

The web interface into XMPP was implemented with Strophe.js, communicating with ejabberd via HTTP-bind with the standard support in both the client library and server.

The old SAX design served a small amount of chat history with every page load so it was immediately visible without performing any additional requests after page load, but since the web server never receives chat data (it all goes into XMPP directly), this is no longer possible. The MUC specification allows a server to send chat history to clients when they join a room, but that still requires several HTTP round-trips (taking up to several seconds) to even begin receiving old lines.

I ended up storing a cache of messages in the browser, which is used to populate the set of displayed messages on initial page load. Whenever a message is received and displayed, its text, sender and a timestamp are added to the local cache. On page load, messages from this cache which are less than one hour old are displayed. The tricky part with this approach is avoiding duplication of lines when messages sent as part of room history already exist, but checking the triple of sender, text and timestamp seems to handle these cases quite reliably.

### webridge

The second major feature of SAX is to announce activity on the web site’s bulletin board, such as when people create or reply to threads. Since the entire system was previously managed by code tightly integrated with the bulletin board, a complete replacement of the relevant code was required.

In the backend, SAX functionality was implemented entirely in one PHP function, so replacing the implementation was relatively easy. The function’s signature was something like saxSay($type,$who, $what,$where), where type is a magic number indicating what kind of message it is, such as the creation of a new thread, a post in a thread or a message from a user. The interpretation of the other parameters depends on the message type, and tends to be somewhat inconsistent.

The majority of that function was a maze of comparisons against the message type, emitting a string which was eventually pushed into the chat system. Rather than attempt to make sense of that code, I decided to replace it with a switch statement over symbolic values (whereas the old code just used numbers with no indication of purpose), feeding simple invocations of sprintf. Finding the purpose of each of the message types was most challenging among that, but it wasn’t terribly difficult as I ended up searching the entire web site source code for references to saxSay and determined the meaning of the types from the caller’s context.

To actually feed messages from PHP into XMPP, I wrote a simple relay bot which reads messages from a UNIX datagram socket and repeats them into a MUC room. A UNIX datagram socket was selected because there need not be any framing information in messages coming in (just read a datagram and copy its payload), and this relay should not be accessible to anything running outside the same machine (hence a UNIX socket).

The bot is implemented in Python with Twisted, utilizing Twisted’s provided protocol support for XMPP. It is run as a service under twistd, with configuration provided via environment variables because I didn’t want to write anything to handle reading a more “proper” configuration file. When the PHP code calls saxSay, that function connects to a socket with path determined from web site configuration and writes the message into that socket. The relay bot (“webridge”) receives these messages and writes them into MUC.

### saxjax-ng

Since keeping a web page open for chatting is not particularly convenient, we also operate a bridge between the SAX chat and an IRC channel called saxjax. The original version of this relay bot was of questionable quality at best: the Python implementation ran two threads, each providing one-way communication though a list. No concurrency primitives, little sanity.

Prior to creation of sax-ng I had put some amount of effort in improving the reliability of that system, since an error in either thread would halt all processing of messages in the direction corresponding to the thread in which the error occurred. Given there was essentially no error handling anywhere in the program, this sort of thing happened with dismaying frequency.

saxjax-ng is very similar in design to webridge, in that it’s Twisted-based and uses the Twisted XMPP library. On the IRC side, it uses Twisted’s IRC library (shocking!). Both ends of this end up being very robust when combined with the components that provide automatic reconnection and a little bit of custom logic for rotating through a list of IRC servers. Twisted guarantees singlethreaded operation (that’s the whole point; it’s an async event loop), so relaying a message between the two connections is simply a matter of repeating it on the other connection.

## Contact with users

This system has been perfectly reliable since deployment, after a few changes. Most notably, the http-bind interface for ejabberd was initially exposed on port 5280 (the default for http-bind). Users behind certain restrictive firewalls can’t connect to that port, so we quickly reconfigured our web server to reverse-proxy to http-bind and solve that problem. Doing so also means the XMPP server doesn’t need its own copy of the server’s SSL certificate.

There are still some pieces of the web site that emit messages containing HTML entities in accordance with the old system. The new system.. doesn’t emit HTML entities because that should be the responsibility of something doing HTML presentation (Strong Opinion) and I haven’t bothered trying to find the things that are still emitting HTML-like strings.

The reconnect logic on the web client tends to act like it’s received multiples of every message that arrives after it’s tried to reconnect to XMPP, such as when a user puts their computer to sleep and later resumes; the web client tries to detect the lost connection and reopen it, and I think some event handlers are getting duplicated at that point. Haven’t bothered working on a fix for that either.

# Conclusion

ejabberd is a solid piece of software and not hard to customize. Twisted is a good library for building reliable network programs in Python, but has enough depth that some of its features lack useful documentation so finding what you need and figuring out how to use it can be difficult. This writeup has been languishing for too long so I’m done writing now.

# Reverse-engineering Ren'py packages

Some time ago (September 3, 2013, apparently), I had just finished reading Analogue: A Hate Story (which I highly recommend, by the way) and was particularly taken with the art. At that point it seems my engineer’s instincts kicked in and it seemed reasonable to reverse-engineer the resource archives to extract the art for my own nefarious purposes.

A little examination of the game files revealed a convenient truth: it was built with Ren’Py, a (open-source) visual novel engine written in Python. Python is a language I’m quite familiar with, so the actual task promised to be well within my expertise.

## Code

Long story short, I’ve build some rudimentary tools for working with compiled Ren’py data. You can get it from my repository on BitBucket. Technically-inclined readers might also want to follow along in the code while reading.

## Background

There are a large number of games designed with Ren’py. It’s an easy tool to get started with and hack on, since the script language is fairly simple and because it’s open-source, more sophisticated users are free to bend it to their will. A few examples of (in my opinion) high-quality things built with the engine:

Since visual novels tend to live or die on the combination of art and writing, the ability to examine the assets outside the game environment offers interesting possibilities.

Since it was handy, I started my experimentation with Analogue.

## RPA resource archives

The largest files distributed with the game were .rpa files, so I investigated those first for finding art. As it turned out, this was exactly the place I needed to look. Start by examining the raw data:

$cd "Analogue A Hate Story/game"$ ls
bytecode.rpyb
data.rpa
dlc1.rpa
nd.rpa
$less data.rpa RPA-3.0 00000000035f5c75 414154bb <F0><AA><D6>^MީZ<A0><90><FB>^M6<B9><B7>^X<A3><82><F3>F<B0><DF>k8(<BF>ߦx<9C><D5>T [snip] There’s an obvious file identifier (RPA-3.0), followed by a couple numbers and a lot of compressed-looking data. The first number turns out to be very close to the total file size, so it’s probably some size or offset field, while the other one looks like some kind of signature. $ python -c 'print(0x35f5c75)'
56581237
$stat -c %s data.rpa 56592058 At this point I simply referred to the Ren’Py source code, rather than waste time experimenting on the data itself. Turns out the first number is the file offset of the index, and the second one is a key used for simple obfuscation of elements of the index (numbers are bitwise exclusive-or’d with the key). The archive index itself is a DEFLATE-compressed block of pickled Python objects. The index maps file names to tuples of offset and block length specifying where within the archive file the data can be found. With that knowledge in hand, it’s short work to build a decoder for the index data and dump it all to files. This is rpa.py in my tools. Extracting the archives pulls out plenty of images and other media, as well as a number of interesting-looking .rpyb files, which we’ll discuss shortly. ### Cosplay For a bit of amusement, I exercised my web-programming chops a little and built a standalone web page for playing with the extracted costumes and expressions of *Hyun-ae and *Mute, which I’ve included below. Here’s a link to the bare page for standalone amusement as well. ## Script guts The basic format of compiled scripts (.rpyb files) is similar to that of resource packages. The entire thing is a tuple of (data, statements), where data is a dictionary of basic metadata and statements is a list of objects representing the script’s code. The statements in this are just the Ren’py abstract syntax tree, so all the objects come from the renpy.ast module. Unfortunately and as I’ll discuss later, the pickle format makes this representation hard to work with. The structure of AST members is designed such that each object can have attached bytecode. In practice this appears to never happen in archives. In my investigations of the source, it appears that Ren’py only writes Python bytecode as a performance enhancement, and most of it ends up in bytecode.rpyb. That file appears to provide some sort of bytecode cache that overrides script files in certain situations. For the purposes of reverse-engineering this is fortunate– Python bytecode is documented, but rather more difficult to translate into something human-readable than the source code that is actually present in RPYB archives. Here’s some of the Act 1 script from Analogue run through the current version of my script decompiler: ## BEGIN Label 'dont_understand', params=None, hide=False dont_understand: ## <class 'renpy.ast.Show'> -- don't know how to dump this! ## <class 'renpy.ast.Say'> -- don't know how to dump this! ## <class 'renpy.ast.Jump'> -- don't know how to dump this! ## BEGIN Label 'nothing', params=None, hide=False nothing: python: shown_message = None for block in store.blocks: for message in block.contents: if message == _message: shown_message = str(store.blocks.index(block)+1) + "-" + str(block.contents.index(message)+1) if shown_message: gray_out(shown_message) ## <class 'renpy.ast.With'> -- don't know how to dump this! ## <class 'renpy.ast.Show'> -- don't know how to dump this! ## <class 'renpy.ast.With'> -- don't know how to dump this! ## <class 'renpy.ast.Say'> -- don't know how to dump this!  Clearly there are a few things my decompiler needs to learn about. It does, however, handle the more common block elements such as If statements. In any case, the Python code embedded in these scripts tends to be more interesting than the rest (which are mostly just dialogue and display manipulation) for the purposes of reverse-engineering. If you’re more interested in spoiling the game for yourself, it’s not as useful. A few telling bits of logic from options.rpy: init -3: ## BEGIN Python python hide: ## BEGIN PyCode, exec mode, from game/options.rpy renpy.demo_mode = True init -1: ## BEGIN Python python hide: ## BEGIN PyCode, exec mode, from game/options.rpy config.developer = True config.screen_width = 1024 if persistent.resolution == None: persistent.resolution = 2 if persistent.old_resolution == None: persistent.old_resolution = persistent.resolution if not persistent.resolution: config.screen_height = 600 else: config.screen_height = 640 if renpy.demo_mode: config.window_title = u"Analogue trial" else: config.window_title = u"Analogue: A Hate Story" config.name = "Analogue" config.version = "0.0"  The spacing here is interesting; I suspect (but haven’t attempted to verify) that the Ren’py script compiler strips comments since there haven’t been any in all of the scripts I’ve examined, so it’s likely that the unusual empty blocks in the code were comment blocks in a former life. I’ve yet to dig much into what determines when demo_mode is set, but I doubt it would be difficult to forcibly set (or clear) if one were so inclined. Not that I condone such an action.. A little bit of interesting game-critical logic, also from Analogue (caution: minor spoilers) store.radiation = 0 store.reactor_enabled = True def interact_cb(): if store.radiation and store.reactor_enabled: store.radiation_levels += 0.01 if (any_read("7-*") or (store.current_character == "mute" and get_m("6-9").enabled)) and store.radiation_levels < 0.65: store.radiation_levels = 0.65 store.radiation_levels = min (store.radiation_levels, 0.8) config.interact_callbacks.append(interact_cb) You can get some idea of how specialized Ren’py’s execution environment is from this code. Particularly, store is a magic value injected into the locals of Python script blocks which maps to the RPY persistent variable store, which stores most of the game state. config is a similar magic value providing a handle to the engine configuration. In this instance, radiation refers to a sort of hidden timer which forces the player to solve a puzzle on expiration (assuming the preconditions have been met), then make a decision which causes the plot to fork depending on that decision. Elsewhere in the code, I found a few developer switches which allow one to display the value of this countdown and reset or force it. ## Conclusions As the official documentation notes, the process of resource compilation is not very secure but is enough to deter casual copying. I’ve shown here that such a claim is entirely correct, though script decompilation may be somewhat harder than the developers envisioned due to the choice of pickle as a serialization format. It’s nothing particularly new to me, but a reminder to designers of software: if it runs on your attacker’s system, it can be hacked. It’s not a question of “if”, but instead “how fast”. I was mostly interested in extracting resources with this project, which was quite easy. In that matter, I think the designers of Ren’Py made a good design decision. The compiled archives and scripts are much more robust against accidental modification in the face of curious users than not compiling anything, but the developers do not expend undue effort building something harder to break which would eventually be broken anyway by a sufficiently determined attacker. ### Portability As I alluded to earlier, the pickle representation makes the Ren’Py AST hard to work with. This is because many of the objects contain references to the engine state, which in turn implies most of the engine needs to be initialized when unpickling the AST. To say the least, this is not easy- engine initialization is not easily separated from game startup. To illustrate the problem, observe that the Ren’Py developer kit is simply the engine itself packaged with a game of sorts that provides help in getting a new project set up by modifying the included scripts. There simply seems to be no part of the engine that is designed to run without the rest of it running as well. In experimenting with different products built with Ren’Py, I’ve had to make changes to some combination of the engine itself and my code in order to bootstrap the engine state to a point where the AST can be successfully unpickled. Suffice to say, this has hampered my progress somewhat, and led me to consider slightly different avenues of attack. The most promising of these would involve a semi-custom unpickler which avoids instantiating actual Ren’Py objects; the only data that need be preserved is the structural information, rather than the many hooks into engine state that are also included in the pickle serialization. Further continuation of this project is likely to take this approach to deserialization. # GStreamer's playbin, threads and queueing I’ve been working on a project that uses GStreamer to play back audio files in an automatically-determined order. My implementation uses a playbin, which is nice and easy to use. I had some issues getting it to continue playback on reaching the end of a file, though. According to the documentation for the about-to-finish signal, This signal is emitted when the current uri is about to finish. You can set the uri and suburi to make sure that playback continues. This signal is emitted from the context of a GStreamer streaming thread. Because I wanted to avoid blocking a streaming thread under the theory that doing so might interrupt playback (the logic in determining what to play next hits external resources so may take some time), my program simply forwarded that message out to be handled in the application’s main thread by posting a message to the pipeline’s bus. Now, this approach appeared to work, except it didn’t start playing the next URI, and the pipeline never changed state- it was simply wedged. Turns out that you must assign to the uri property from the same thread, otherwise it doesn’t do anything. Fortunately, it turns out that blocking that streaming thread while waiting for data isn’t an issue (determined by experiment by simply blocking the thread for a while before setting the uri). # "Four"ier transform I liked the joke and am familiar enough with the math of working in unusual bases that I felt a need to implement a quick version of this in Python. Code follows. #!/usr/bin/env python def fourier(x, b): """Attempts to find a fourier version of x, working down from base b. Returns the fouriest base.""" mostFours = 0 bestBase = -1 for base in range(b, 1, -1): fours = 0 t = x while t != 0: if (t % base) == 4: fours += 1 t //= base # Prefer lower bases if fours >= mostFours: print(baseconvert(x, base) + "_{0}".format(base)) mostFours = fours bestBase = base return bestBase BASE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" def baseconvert(x, base): s = "" while x != 0: s += BASE_CHARS[x % base] x //= base return ''.join(reversed(s)) if __name__ == '__main__': from sys import argv, exit if len(argv) < 2: print("""Usage: {0} <number> Computes the "four"ier transform of <number>, printing the optimizations to reach the "fouriest" form.""".format(argv[0])) exit(1) x = int(argv[1]) # Base 36 is the largest sensible base to use base = fourier(x, 36) if base == -1: print("{0} is four-prime!".format(x)) This is Python 3.x code, using explicit integer division. It should work under the 2.x series if you change line 34 to use “/=” rather than “//=”. It can only go up to base 36, because I didn’t want to deal with bases that are hard to represent in reasonable ways. Up to base 64 is an option, but in that case I would have wanted to use MIME base 64, which puts digits at positions 52 through 61, which would be confusing to read. Thus it only supports up to base 36, but could be adjusted with relative east to do larger bases. Running a few examples: $ python fourier.py 624
HC_36
HT_35
IC_34
IU_33
JG_32
K4_31
143_23
1B4_20
440_12
4444_5

$python fourier.py 65535 1EKF_36 1IHF_35 1MNH_34 1R5U_33 1VVV_32 2661_31 2COF_30 2JQO_29 2RGF_28 38O6_27 3IOF_26 44LA_25 B44F_18 14640_15 4044120_5$ python fourier.py 3
3 is four-prime!

A few quirks: it prefers lower bases, so bases that match earlier attempts in fouriness will be printed, despite having equal fouriness. I’ve decided to call values that have no representations containing a ‘4’ character “four-prime”, which is probably going to be a rare occurrence, but the program handles it okay.

Generalization of the algorithm is certainly possible, and basically requires changing the condition on line 14 to match different digit values. For example, a hypothetical “Three”ier transform would replace the ‘4’ on line 14 with a ‘3’.

There’s a rather interesting discussion of the topic over on Reddit, as well as a few other implementations. (Thanks to Merth for pointing those out to me.)

# Rationale

I was reading up on web frameworks available when programming in Haskell earlier today, and I liked the use of domain-specific languages (DSLs) within frameworks such as the routing syntax in Yesod. Compared to how routes are specified in Django (as a similar example that I’m already familiar with), the DSL is both easier to read (because it doesn’t need to be valid code in the hosting language) and faster (since it ends up getting compiled into the application as properly executable code).

A pattern I find myself using rather often in Python projects is to have a small module (usually called config) that encapsulates an INI-style configuration file. It feels like an ugly solution though, since it generally just exports a ConfigParser instance. Combined with consideration of DSLs in Haskell, that got me thinking: what if there were an easier way that made INI configuration files act like Python source such that they could just be imported and have the contents of the file exposed as simple Python types (thus hiding some unnecessary complexity)?

# Implementation

I was aware of Python’s import hook mechanisms, so I figured that it should be a good way to approach this problem, and it ended up being a good excuse to learn more about the import hook mechanism. Thus, the following code provides a way to expose INI-style configuration as Python modules. It should be compatible with Python 3 after changing the import of ConfigParser on line 1 to configparser, but I only tested it on Python 2.7.

import ConfigParser, imp, os, sys

def __init__(self, prefix):
self.prefix = prefix

if name in sys.modules:
return sys.modules[name]

module = imp.new_module(name)
if name == self.prefix:
# 'from config import foo' gets config then config.foo,
# so we need a dummy package.
module.__package__ = name
module.__path__ = []
module.__file__ = __file__
else:
# Try to find a .ini file
module.__package__, _, fname = name.rpartition('.')
fname += '.ini'
module.__file__ = fname
if not os.path.isfile(fname):
raise ImportError("Could not find a .ini file matching " + name)
else:

sys.modules[name] = module
return module

def find_module(self, name, path=None):
if name.startswith(self.prefix):
return self
else:
return None

"""Load ini-style file f into module m."""
cp = ConfigParser.SafeConfigParser()
for section in cp.sections():
setattr(m, section, dict(cp.items(section)))

def init(package='config'):
"""Install the ini import hook for the given virtual package name."""
sys.meta_path.append(INILoader(package))

Most of this code should be fairly easy to follow. The magic of the import hook itself is all in the INILoader class, and exactly how that works is specified in PEP 302.

# Usage

So how do you use this? Basically, you must simply run init(), then any imports from the specified package (config by default) will be resolved from an .ini file rather than an actual Python module. Sections in a file are exposed as dictionaries under the module.

An example is much more informative than the preceding short description, so here’s one. I put the code on my Python path as INIImport.py and created foo.ini with the following contents:

[cat]
sound=meow
[dog]
sound=woof
[cow]
sound=moo

It has three sections, each describing an animal. Now I load up a Python console and use it:

>>> import INIImport
>>> INIImport.init()
>>> from config import foo
>>> foo.cat
{'sound': 'meow'}
>>> foo.dog['sound']
'woof'

This has the same semantics as a normal Python module, so it can be reloaded or aliased just like any other module:

>>> import config.foo
>>> foo == config.foo
True
<module 'config.foo' from 'foo.ini'>

The ability to reload this module is particularly handy, because my normal configuration module approach doesn’t provide an easy way to reload the file.

## Improvements, Limitations

Some addition improvements come to mind if I were to release this experiment as production-quality code. Notably, additional path manipulations for finding .ini files would be useful, such as taking a path argument to init(), supplying a set of directories to search within. Having a way to remove the import hook that it installs would also be good, and straightforward to implement. There’s no way to get all the sections in the module, so it would also be useful to export the sections somehow– perhaps by having the module support the mapping protocol (so all the sections could be retrieved with module.items(), for example).

The main limitation of this scheme is that it has no way to determine the desired type of loaded configuration values, so everything is a string. This is a typical limitation when using the ConfigParser module, but compared to a more robust configuration scheme such as defining objects in a Python file (such as Django does), this might be an annoying loss of expressiveness. The values can always be coerced to the required type when retrieving them, but that’s a bit of unnecessary extra code in whatever uses the configuration.

It may also be useful to provide a way to write configuration back to a file when modifying a config module, but my simplistic implementation makes no attempt at such. Doing so would not be terribly difficult, just involving some wrapper objects to handle member assignment for sections and items, then providing a mechanism for saving the current values back to the original file.

## Postlude

This made for an interesting experiment, and it should be a handy example for how to implement import hooks in Python. You may use this code freely within your own work, but I’d appreciate if you leave a note here that it was useful, and link back to this post.


text:
# 7: Qualitative Analysis of Group III Ions (Experiment)

##### Objectives
• To follow a classic qualitative analysis scheme to separate and identify the ions in a known mixture of Group III cations
• To apply this scheme to identify the Group III cations present in an unknown sample.

Cations are typically divided into Groups, where each group shares a common reagent that can be used for selective precipitation. In an earlier lab you performed a qualitative analysis of the Group I cations, all of which formed insoluble chlorides upon the addition of HCl (aq). In today’s lab you will analyze solutions of the Group III cations, which include $$\ce{Cr^{3+}}$$, $$\ce{Al^{3+}}$$, $$\ce{Fe^{3+}}$$, and $$\ce{Ni^{2+}}$$. All the Group III cations form insoluble sulfides or hydroxides in a basic solution saturated with $$\ce{H2S}$$. The procedure will be similar to the previous Group I analysis experiment in that you will first prepare and analyze a known mixture of all four cations as a positive control. You will then analyze an unknown sample containing one, two, three or all four of the Group III cations. Your objective will be to identify which Group III cation(s) are present in your unknown sample.

Remember that in qualitative analysis the ions in a given group are first separated from each other, and then a characteristic test is performed for each ion in order to confirm the presence of that ion.

### Separation and Confirmation of Group III Cations

An aqueous mixture of $$\ce{Cr^{3+}}$$, $$\ce{Al^{3+}}$$, $$\ce{Fe^{3+}}$$, and $$\ce{Ni^{2+}}$$ is first treated with a mixture of $$\ce{NaOH}$$ and $$\ce{NaOCl}$$ solutions. This causes the iron and nickel cations to precipitate out as hydroxide salts, while the chromium and aluminum cations remain in solution:

$\ce{Fe^{3+} (aq) + 3 OH^{-} (aq) -> Fe(OH)3 (s) } \label{1}$

$\ce{Ni^{2+} (aq) + 2 OH^{-} (aq) -> Ni(OH)2 (s) } \label{2}$

$\ce{2 Cr^{3+} (aq) + 3 OCl^{-} (aq) + 10 OH^{-} (aq) -> 2 CrO4^{2-} (aq) + 3 Cl^{-} (aq) + 5 H2O (l) } \label{3}$

$\ce{Al^{3+} (aq) + 4 OH^{-} (aq) -> Al(OH)4^{-} (aq) }\label{4}$

Note in the last two equations above that $$\ce{Cr^{3+}}$$ is oxidized to the soluble $$\ce{CrO4^{2-}}$$ ion while $$\ce{Al^{3+}}$$ forms a soluble complex ion with $$\ce{OH^{-}}$$. Neither iron nor nickel form hydroxo-complex ions and therefore precipitate out as solids. The resulting mixture is centrifuged and then decanted, separating the solids ($$\ce{Fe(OH)3}$$ and $$\ce{Ni(OH)2}$$) from the supernatant solution (containing $$\ce{CrO4^{2-}}$$ and $$\ce{Al(OH)4^{-}}$$).

In order to separate the chromium ions from the aluminum ions in the aqueous supernatant solution, the solution is first acidified in order to destroy the aluminum hydroxo-complex ion:

$\ce{Al(OH)4^{-} (aq) + 4 H^{+} (aq) -> Al^{3+} (aq) + 4 H2O (l) }\label{5}$

Next the solution is made just basic enough to precipitate out the aluminum as its hydroxide salt, but not so basic that it would remain in solution as the hydroxo-complex ion. This is accomplished by slowly adding aqueous ammonia:

$\ce{Al^{3+} (aq) + 3 NH3 (aq) + 3 H2O (l) -> Al(OH)3 (s) + 3 NH4^{+} (aq) } \label{6}$

The supernatant solution containing $$\ce{CrO4^{2-}}$$ can then be decanted from the white gelatinous precipitate which is the solid $$\ce{Al(OH)3}$$. A positive confirmation for $$\ce{Al^{3+}}$$ is accomplished by dissolving the solid precipitate in acetic acid and adding the reagent catechol violet, which reacts with $$\ce{Al^{3+}}$$ to produce a blue solution.

In order to confirm the presence of chromium in the supernatant solution, aqueous BaCl2 is added to it. This results in the formation of a finely divided, pale yellow precipitate of barium chromate:

$\ce{Ba^{2+} (aq) + CrO4^{2-} (aq) -> BaCrO4 (s) } \label{7}$

Recall that a mixture of solid precipitates of $$\ce{Fe(OH)3}$$ and $$\ce{Ni(OH)2}$$ is collected at the beginning of this analysis scheme. The next step is to separate them. First the hydroxide precipitates are dissolved in nitric acid:

$\ce{Ni(OH)2 (s) + 2 H^{+} (aq) -> Ni^{2+} (aq) + 2 H2O (l) } \label{8}$

$\ce{Fe(OH)3 (s) + 3 H^{+} (aq) -> Fe^{3+} (aq) + 3 H2O (l) } \label{9}$

The acidified solution is then made basic by adding aqueous ammonia. Once the solution has become basic, the excess ammonia will react with $$\ce{Ni^{2+}}$$ to form an aqueous complex ion while the $$\ce{Fe^{3+}}$$ will precipitate out once more as red $$\ce{Fe(OH)3}$$ since $$\ce{Fe^{3+}}$$ does not typically form complex ions with $$\ce{NH3}$$:

$\ce{Ni^{2+} (aq) + 6 NH3 (aq) -> Ni(NH3)6^{2+} (aq) } \label{10}$

$\ce{Fe^{3+} (aq) + 3 NH3 (aq) + 3 H2O (l) -> Fe(OH)3 (s) + 3 NH4^{+} (aq) } \label{11}$

The presence of $$\ce{Ni^{2+}}$$ in the aqueous solution is confirmed by adding dimethylglyoxime ($$\ce{C4H8N2O2}$$) resulting in the formation of a rose red precipitate:

$\ce{Ni^{2+} (aq) + 2 C4H8N2O2 (aq) -> Ni(C4H7N2O2)2 (s) + 2 H^{+} (aq) } \label{12}$

In order to confirm the presence of $$\ce{Fe^{3+}}$$, the red $$\ce{Fe(OH)3}$$ precipitate is dissolved in $$\ce{HCl}$$ (aq), and then $$\ce{KSCN}$$ (aq) is added to the solution. A positive result is the formation of a dark red solution indicating the presence of $$\ce{FeSCN^{2+}}$$ (aq):

$\ce{Fe^{3+} (aq) + SCN^{-} (aq) -> FeSCN^{2+} (aq) } \label{13}$

The entire analysis scheme is represented in abbreviated form using the follwing flow chart:

Figure 1: GROUP III CATIONS ANALYSIS SCHEME

## Procedure

Chemicals

0.1 M $$\ce{Cr(NO3)3}$$ (aq), 0.1 M $$\ce{Al(NO3)3}$$ (aq), 0.1 M $$\ce{Ni(NO3)2}$$ (aq), 0.1 M $$\ce{Fe(NO3)3}$$ (aq), 6 M $$\ce{HCl}$$ (aq), 6 M $$\ce{HNO3}$$ (aq), 6 M acetic acid, 6 M $$\ce{NaOH}$$ (aq), 6 M $$\ce{NH3}$$ (aq), 1 M $$\ce{NaOCl}$$ (aq), 1 M $$\ce{BaCl2}$$ (aq), 0.5 M $$\ce{KSCN}$$ (aq), catechol violet, dimethylglyoxime.

Equipment

12 small test tubes, 30-mL beaker, beaker tongs, Bunsen burner, 10-mL graduated cylinder, glass stirring rod, small watch glass, dropper pipets, red and blue litmus paper, centrifuge, wash bottle filled with deionized water, 150-mL beaker (for waste solutions).

For the hot water bath: 250-mL beaker, stand, ring clamp, wire gauze

##### Safety
• The PPE for this lab includes safety goggles, lab coat and nitrile gloves.
• Exercise appropriate caution when using all concentrated acids and bases in this lab as they can cause serious chemical burns to your skin. If any acid comes into contact with your skin or eyes, immediately rinse the affected areas with copious amounts of water for 15 minutes, and inform your instructor.

Waste Disposal

All the waste chemicals generated by this lab are toxic and must be disposed of in the hazardous-waste container in the fume hood. Rinse all glassware directly into the waste container using a wash bottle.

Any unused portion of the unknown sample should be discarded in the hazardous-waste container. Rinse the test tube and return it to the instructor’s bench at the end of lab.

General Instructions

Similar to last week’s procedure, you will analyze a known mixture of all four Group III cations as a positive control experiment. You will then analyze an unknown sample in order to determine which Group III cations are contained within the sample.

• Be sure to label all tubes and solutions because they will accumulate rapidly, and it is very easy to get tubes and/or solutions mixed up.
• Make sure all glassware is thoroughly cleaned and rinsed with deionized water between uses to avoid cross-contamination.
• The centrifuge must be balanced before each use. Balancing is done by placing a test tube containing water opposite to the test tube containing the precipitate in the centrifuge. The two test tubes should have approximately equal weights.
• The pH of a solution is tested by dipping a stirring rod into the solution and then touching it to a piece of litmus paper resting on a clean, dry watch glass. If a solution is acidic it will turn blue litmus paper red. If a solution is basic it will turn red litmus paper blue.

### Part A: Analysis of Known Mixture of Group III Cations – A Positive Control Experiment

Preparation of Known Solution and Separation of $$\ce{Cr^{3+}}$$ and $$\ce{Al^{3+}}$$ from $$\ce{Fe^{3+}}$$ and $$\ce{Ni^{2+}}$$

1. Prepare a mixture of Group III cations by adding 1.0 mL of each of the following 0.1 M aqueous solutions to a small test tube: $$\ce{Cr(NO3)3}$$, $$\ce{Al(NO3)3}$$, $$\ce{Fe(NO3)3}$$, and $$\ce{Ni(NO3)2}$$. Transfer 2.0 mL of this mixture to a 30-mL beaker and use it for your positive control experiment.
2. Add 2 mL of 6 M $$\ce{NaOH}$$ to the 30-mL beaker containing your positive control solution. Boil the solution very gently (use a pair of beaker tongs to hold the beaker) over an open Bunsen burner flame for about one minute. Note that the time to boil is variable and depends on the volume of solution you have. Do not boil the solution to dryness. If you boil the solution to dryness, then you must repeat this step again.
3. Remove the beaker from the flame and slowly add 2 mL of 1 M $$\ce{NaClO}$$. Swirl the beaker for 30 seconds using your beaker tongs, then gently boil the mixture for about one minute.
4. Again, remove the beaker from the flame and add sixteen drops of 6M $$\ce{NH3}$$. Swirl the mixture, then gently boil for another minute.
5. Transfer the mixture from the beaker into a small test tube and centrifuge in order to separate the solid from the solution. Decant the supernatant solution (containing the chromium and the aluminum) into another test tube and save the solid (containing the nickel and the iron). Save this supernatant solution for further analysis. It contains the aluminum and chromium cations.
6. Wash the solid by adding 4 mL of water and twenty drops of 6 M $$\ce{NaOH}$$. Stir vigorously then centrifuge the mixture. Decant the supernatant solution into your “waste” beaker and discard this solution.
7. Add 2 mL of 6 M $$\ce{HNO3}$$ to the washed solid. Save the contents of this test tube for further analysis. It contains the iron and nickel cations.

Separation of $$\ce{Al^{3+}}$$ from $$\ce{Cr^{3+}}$$

1. Slowly add 6 M acetic acid to the supernatant solution saved from Step 5 until it is acidic (test with blue litmus paper).
2. Add 6 M $$\ce{NH3}$$ one drop at a time until the solution just becomes basic again (test with red litmus paper). Now add twenty additional drops of excess $$\ce{NH3}$$. At this point a translucent, gelatinous precipitate of $$\ce{Al(OH)3}$$ should appear in the clear (or pale yellow) solution.
3. Stir the mixture for about a minute to allow the system to reach equilibrium. Centrifuge the mixture, then decant the supernatant solution into another small test tube. This solution must be saved for further tests.
4. To wash the collected solid, first add 6 mL of deionized water to it. Then place the test tube with the solid (and water) in a hot water bath for about two minutes while occasionally stirring the mixture. Check with your instructor if you are unsure about how to set up a hot water bath. Finally, centrifuge this mixture and decant the supernatant solution into your “waste” beaker. Discard the solution and save the solid.

Confirmation of $$\ce{Al^{3+}}$$

1. To the solid from Step 11 add four drops of 6 M acetic acid and 6 mL of water. Stir in order to dissolve the solid. Finally, add four drops of catechol violet to the resulting solution. The appearance of a blue solution confirms the presence of $$\ce{Al^{3+}}$$ in the original solution.

Confirmation of $$\ce{Cr^{3+}}$$

1. To the decanted solution from Step 10, add twelve drops of 1 M $$\ce{BaCl2}$$. The formation of a very fine, pale yellow precipitate ($$\ce{BaCrO4}$$) confirms the presence of $$\ce{Cr^{3+}}$$ in the original solution.

Separation of $$\ce{Fe^{3+}}$$ from $$\ce{Ni^{2+}}$$

1. If the precipitate from Step 7 is not completely dissolved, stir it until it is completely dissolved. If necessary, place the test tube in a hot water bath in order to completely dissolve the precipitate.
2. Slowly add 6 M $$\ce{NH3}$$ to the solution until it is basic (test with red litmus paper). You should see a red-brown precipitate of $$\ce{Fe(OH)3}$$ appear when the solution turns basic.
3. Add an additional 20 drops of 6 M $$\ce{NH3}$$ and stir to mix well. At this point the nickel should be dissolved in the solution as $$\ce{Ni(NH3)6}$$.
4. Centrifuge the mixture and decant the supernatant solution into another test tube. Save both the solid and solution.

Confirmation of $$\ce{Ni^{2+}}$$

1. Add eight drops of dimethylglyoxime to the solution saved in Step 17. The appearance of a rose-red precipitate confirms the presence of $$\ce{Ni^{2+}}$$ in the original solution.

Confirmation of $$\ce{Fe^{3+}}$$

1. To the precipitate saved in Step 17 add twelve drops of 6 M $$\ce{HCl}$$. Next, add 4 mL of deionized water and stir well until the precipitate is completely dissolved. Finally, add four drops of 0.5 M $$\ce{KSCN}$$. The formation of a dark red solution confirms the presence of $$\ce{Fe^{3+}}$$ in the original solution.

### Part B: Analysis and Identification of Group III Cations in an Unknown Sample

1. Obtain a test tube which contains a mixture of Group III cations. Record the ID Code of the sample on your Report Form.
2. Transfer 2.0 mL of the above mixture into a 30-mL beaker and repeat the procedure used in Part A.
3. On your Report Form, construct a flow chart similar to the one shown in the Background. Indicate on the flow chart whether the test for each ion is positive or negative. Then, in space provided, indicate which ions are present in your unknown sample.

## Lab Report: Qualitative Analysis of Group III Cations

Name: ____________________________ Date: ________________________

Lab Partner: ________________________ Lab Section: __________________

In the space provided below construct a flow cart for the analysis of your unknown. Indicate on the flow chart whether the test for each ion is positive or negative:

Unknown ID number: __________________

Ions present in your unknown: ____________________________________

## Pre-laboratory Assignment: Qualitative Analysis of Group III Cations

1. Given the very low value of $$K_{sp}$$ for $$\ce{Cr(OH)3}$$, a precipitate of $$\ce{Cr(OH)3}$$ would be expected if only 6 M $$\ce{NaOH}$$ were added to the mixture of Group III cations in the first step of the procedure. Explain how and why the chromium remains in solution.
1. A solution may contain one or more of the Group III cations. When this solution is combined with $$\ce{NaOH}$$ (aq), $$\ce{NaOCl}$$ (aq) and $$\ce{NH3}$$ (aq) only a colorless solution is obtained with no precipitate evident. Indicate whether each of the following cations is present, absent or undetermined.
• $$\ce{Cr^{3+}}$$ _____________________
• $$\ce{Al^{3+}}$$ _____________________
• $$\ce{Fe^{3+}}$$ _____________________
• $$\ce{Ni^{2+}}$$ _____________________

Explain.

7: Qualitative Analysis of Group III Ions (Experiment) is shared under a CC BY-NC license and was authored, remixed, and/or curated by Santa Monica College.

format: plain


text:
# Angles of elevation

From points A and B on level ground, the angles of elevation of the top of a building are 25° and 37° respectively. If |AB| = 57m, calculate, to the nearest meter, the distances of the top of the building from A and B if they are both on the same side of the building.

Result

h =  69.73 m
d1 =  165 m
d2 =  116 m

#### Solution:

$a = 57 \ m \ \\ A = (25^\circ \rightarrow rad) = (25 \cdot \ \dfrac{ \pi }{ 180 } \ ) = 0.436332312999 \ \\ B = (37^\circ \rightarrow rad) = (37 \cdot \ \dfrac{ \pi }{ 180 } \ ) = 0.645771823238 \ \\ \ \\ \tan A = \dfrac{ h }{ a+b } \ \\ \tan B = \dfrac{ h }{ b } \ \\ b = \dfrac{ h }{ \tan B } \ \\ \ \\ a \tan A + b \tan A = h \ \\ a \tan A + \dfrac{ h }{ \tan B } \tan A = h \ \\ \ \\ h = \dfrac{ a \cdot \ \tan(A) }{ 1 - \tan(A)/\tan(B) } = \dfrac{ 57 \cdot \ \tan(0.4363) }{ 1 - \tan(0.4363)/\tan(0.6458) } \doteq 69.728 = 69.73 \ \text { m }$
$b = \dfrac{ h }{ \tan(B) } = \dfrac{ 69.728 }{ \tan(0.6458) } \doteq 92.5348 \ m \ \\ \ \\ d_{ 1 } = \sqrt{ h^2 + (a+b)^2 } = \sqrt{ 69.728^2 + (57+92.5348)^2 } \doteq 164.9938 = 165 \ \text { m }$
$d_{ 2 } = \sqrt{ h^2 + b^2 } = \sqrt{ 69.728^2 + 92.5348^2 } \doteq 115.8662 = 116 \ \text { m }$

Leave us a comment of this math problem and its solution (i.e. if it is still somewhat unclear...):

Be the first to comment!

## Next similar math problems:

1. Movement
From the crossing of two perpendicular roads started two cyclists (each at different road). One runs at average speed 28 km/h, the second at average speed 24 km/h. Determine the distance between them after 45 minutes cycling.
2. Theater
The theater has in each row with 19 seats. Ticket to the first 10 rows is for 30 USD. In next rows is for 15 USD. The theater was completely sold out. Revenue was 12255 USD. How many rows are in the theater?
3. Prism X
The prism with the edges of the lengths x cm, 2x cm and 3x cm has volume 20250 cm3. What is the area of surface of the prism?
4. Hens
11 hens will eat spilled grain from 6AM to 16 PM. At 11 hour grandmother brought 4 hens from the neighbors. At what time was grain out?
5. Precious metals
In 2006-2009, the value of precious metals changed rapidly. The data in the following table represent the total rate of return (in percentage) for platinum, gold, an silver from 2006 through 2009: Year Platinum Gold Silver 2009 62.7 25.0 56.8 2008 -41.3 4
6. Grower
Grower harvested 190 kg of apples. Pears harvested 10 times less. a) How many kg pears harvested? b) How many apples and pears harvested? c) How many kg harvested pears less than apples?
7. Root
The root of the equation ? is: ?
8. Evaluate - order of ops
Evaluate the expression: 32+2[5×(24-6)]-48÷24 Pay attention to the order of operation including integers
9. Short cut
Imagine that you are going to the friend. That path has a length 330 meters. Then turn left and go another 2000 meters and you are at a friend's. The question is how much the journey will be shorter if you go direct across the field?
10. Time
Write time in minutes rounded to one decimal place: 5 h 28 m 26 s.
11. Balls
Three metal balls with volumes V1=71 cm3 V2=78 cm3 and V3=64 cm3 melted into one ball. Determine it's surface area.
12. Cube 6
Volume of the cube is 216 cm3, calculate its surface area.


text:
# Spandanam | സ്പന്ദനം | spandanamnews.blogspot.com | Spandanam News| Spandanamblog.com

## Tuesday, September 21, 2021

Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF Download: Students of Standard 12 can now download Plus Two Economics Chapter 3 Production and Costs question and answers pdf from the links provided below in this article. Plus Two Economics Chapter 3 Production and Costs Question and Answer pdf will help the students prepare thoroughly for the upcoming Plus Two Economics Chapter 3 Production and Costs exams.

## Plus Two Economics Chapter 3 Production and Costs Question and Answers

Plus Two Economics Chapter 3 Production and Costs question and answers consists of questions asked in the previous exams along with the solutions for each question. To help them get a grasp of chapters, frequent practice is vital. Practising these questions and answers regularly will help the reading and writing skills of students. Moreover, they will get an idea on how to answer the questions during examinations. So, let them solve Plus Two Economics Chapter 3 Production and Costs questions and answers to help them secure good marks in class tests and exams.

 Board Kerala Board Study Materials Question and Answers For Year 2021 Class 12 Subject Economics Chapters Economics Chapter 3 Production and Costs Format PDF Provider Spandanam Blog

## How to check Plus Two Economics Chapter 3 Production and Costs Question and Answers?

2. Click on the 'Plus Two Question and Answers'.
3. Look for your 'Plus Two Economics Chapter 3 Production and Costs Question and Answers'.

Question 1.
Which among the following cost curves is not ‘U’ shaped?
AFC curve is rectangular hyperbola.

Question 2.
Identify the shape of the following AFC curve?

The shape of AFC curve is rectangular hyperbola.

Question 3.
When a firm increased the number of labour from 10 to 11, keeping the capital fixed the total product increased from 120 to 130. Which of the following statement is correct in this regard?
(a) The total product fell
(b) This is a long run production
(c) The average product is rising
(d) 10 is the marginal product of an increased unit of labour.
(d) 10 is the marginal product of an increased unit of labour.

Question 4.
Slope of an isoquant is:
(a) marginal cost
(b) DMRS
(c) DMRTS
(d) None of the above
(c) DMRTS

Question 5.
When MP becomes zero, TP:
(a) increases
(b) decreases
(c) becomes maximum
(d) becomes negative
(c) becomes maximum

Question 6.
Which among the following is not ‘u’ shape
(a) MC
(b) AC
(c) AVC
(d) AFC
(d) AFC

Question 7.
When AC is minimum
(a) MC > AC
(b) MC = AC
(c) MC < AC
(d) None of these
(b) MC = AC

Question 8.
All the following curves are U shaped except
(a) the AVC curve
(b) the AFC curve
(c) the AC curve
(d) the MC curve
(b) the AFC curve

### Plus Two Economics Production and Costs Two Mark Questions and Answers

Question 1.
Let the production function of a firm be Q = 5 L1/2 K1/2
Find the maximum output that the firm can produce with 100 units of L and 100 units of K.
The production function is
Q = 5 L1/2 K1/2
Since the firm uses 100 units of L and 100 units of
K, we get the production function as
Q = 5 × 1001/2 1001/2
Q = 5 × 10x 10
Q = 5 × 100 = 500

Question 2.
Derive marginal product and average product from the total product schedule.

Question 3.
Find the maximum possible output for a firm with zero units of labour and 10 units of capital when its production function is
Q = 5L + 2K
The production function is Giving the values of L and K, we get
Q = 5 × 0 + 2 × 10
Q = 0 + 20 = 20

Question 4.
“In the long run, all costs are variable”. Do you agree? Justify your answer.
Yes. In the long run, all costs are variable. This is because there is sufficient time available in the long run for any factor of production to get increased. As there are only variable factors, in the long run, all costs are variable.

Question 5.
“The AVC is U shaped” explain the reasons for the ‘U’ shape of AVC curve. Also, draw a diagram to clarify your points.
The SMC and AVC curves start rising when production starts. As output increases, SMC falls. AVC being the average of marginal costs also falls but falls less than SMC. Then after a point, SMC start rising. AVC, however, continues to fall as long as value of SMC remains less than the prevailing value of AVC.

Once the SMC has risen sufficiently its value becomes greater than the value of AVC. The AVC starts rising. Therefore, the AVC curve is “U” shaped. It is given in the following diagram.

Question 6.
TFC of a firm is ₹2,000 and TVC is ₹3,000. It produces 20 units. Calculate the AVC and AC of the firm.
TC = TFC + TVC
AC = 5000/20 = 250
AVC = 3000/20 = 150

Question 7.
Can there be some fixed cost in the long run?
No, there cannot be some fixed cost in the long run. This is because, in the long run all factors of production can be adjusted and variable.

Question 8.
Let the production function of a firm be Q = 10 L1/2 K1/2 Find out the maximum possible output that the firm can produce with 100 units of L and 100 units of K.
The production function is,
Q = 10 L1/2 K1/2
L =100 units
K =100 units
∴ Q = 10 × 1001/2 × 1001/2
= 10 × (10²)1/2 × (10²)1/2
= 10 × 10 × 10
= 1,000 units

Question 9.
The table given below shows the total product schedule of labour. Determine the AP and MP of labour?

Question 10.
Prove that AC is the sum of AFC and AVC.

Question 11.
A bus company started its operation with two buses, four labourers. It has paid a one-time road tax. As the passengers increased the company arranged more tripes, with the help of additional labour and for using more fuels. Classify the costs incurred by the bus company into fixed and variable.

Question 12.
Both short run and long run average and marginal cost curves are U-shaped. But reasons for the U-shape are not the same. Bring out the differences.
Behaviour of output in the short run as explained by the law of variable proportions Behaviour of output in the long run as explained by the laws of returns to scale.

### Plus Two Economics Production and Costs Three Mark Questions and Answers

Question 1.
Match the following.

Question 2.
Categorize the following into fixed cost
(a) wages of temporary workers
(b) cost of raw materials
(c) salary of permanent staff
(d) cost of transportation
(e) cost of plant

 Fixed Cost Variable Cost Salary of permanent staff Cost of raw materials Cost.of acquiring land Cost of transportation Cost of plant Wages of temporary workers

Question 3.
Identify the following curves.

1. TC
2. TVC
3. TFC

Question 4.
Identify the shapes of the following cost curves.

1. AFC
2. AC
3. TFC
4. TVC
5. TC

1. AFC – Rectangular hyperbola
2. AC – ‘U’shape
3. TFC – Straight line parallel to X axis
4. TVC – Inverse‘S’ shape
5. TC – Inverse‘S’ shape

Question 5.
There exists vertical distance between 1. TVC and TC and (b) TC and TFC. What does this distance indicate?

1. TVC and TC
2. TC and TFC

1. The vertical distance between TVC and TC represents the Total Fixed Costs (TFC).
2. The vertical distance between TC and TFC represents the Total Variable Costs (TVC)

Question 6.
Complete the following table

Question 7.
Name the following curves. ,

Question 8.
What do you mean by an ‘isoquant’?
An isoquant is the set of all possible combinations of the two inputs that yield the same maximum possible level of output. Each isoquant represents a particular level of output and is labelled with that amount of output. The shape of isoquant is drawn below.

Question 9.
With the help of a diagram show the relation between average exists and average variable cost.

Both AC and AVC are U shaped. As the output increases the gap between AC and AVC narrows.

Question 10.
In the short run, Total Variable Cost is zero when output is zero. When output rises, Total Cost also rises. Draw a suitable diagram and explain the relationship between Total Fixed Cost, Total Variable Cost and Total Cost.

Question 11.
“Average Fixed Cost (AFC) curve is a continuously falling curve.”

1. Substantiate this statement by giving the reasons.
2. Graphically represent the AFC curve

1. TFC is constant & hence AFC falls
2.

### Plus Two Economics Production and Costs Five Mark Questions and Answers

Question 1.
The marginal product and total product of input are related’. Prove this statement.’
The marginal product (MP) and total product (TP) of input are related. The points of the relationship are given below.

1. When MP increases, TP also increases
2. When MP is zero, TP becomes maximum
3. When MP becomes negative, TP turns negative

Question 2.
Differentiate between returns to a factor and returns to scale.
Returns to a factor refers to the effects on output of changes in one input with all other inputs are hold constant. On the other hand, returns to scale refers to the effect on total output of charges in some constant rate in all the inputs simultaneously.

Question 3.
The marginal cost and average cost are related to each other. Prove this using diagram and a numerical example?

Marginal cost are addition made to the total costs by the production of an additional unit of the commodity.
MC = TCn – TCn-1

Average lost is per unit cost of production which is obtained by dividing the total cost by number of units of output produced.
$$A C=\frac{T C}{Q}$$

Since AC is obtained by dividing TC by all units, MC is the addition to TC by producing an additional unit so MC brings a change in AC.

From above:

1. When MC is less than AC, then MC will fall
2. When MC is equal to AC, AC remains costant.
3. When MC is more than AC, AC rises

Question 4.
Which of the following represent the long run production function?
1. MC is less than AC, then MC will fall

• Law of variable proportion
• Returns to scale

2. Explain what may happen when all inputs vary simultaneously?
Returns to scale.
When all inputs are varied simultaneously the output may change in three ways.
1. Constant returns to scale:
It is when a proportional increase in inputs result in an increase in output by the same proportion.

2. Increasing returns to scale:
It is when a proportional increase in all inputs result in an increase in output by more than proportion.

3. Decreasing returns to scale:
It is when a proportional increase in all inputs result in an increase in output by less than proportion

Question 5.
State whether the statement are true or false.

1. TC never becomes zero.
2. AC is sum total of AFC and AVC.
3. When AC rises, AC and MC are equal
4. Real cost is the cost in money terms
5. TFC curve is U shaped

1. True
2. True
3. False
4. False
5. False

Question 6.
The following table shows the total cost schedule of a firm. What is the total fixed cost schedule of the firm? Calculate the JVC, AFC, AVC, SAC and SMC of the firm

Question 7.
The diagram shows the total product curve of a factor in the law of variable proportion.

1. Explain the law
2. With the help of a diagram illustrate the average and marginal product curve and their relation.

1. Law of variable proportion says that if one variable input is added with other fixed inputs the marginal product of a factor input initially rises but after reaching a certain level of output it starts falling.

2. The relation between the average and marginal product is given below. BothAPand MPare ‘n ’shaped. MPwill always pass through the maximum of AP.

Question 8.
Theory of production deals with producer’s behaviour, and according to this theory output produced by a firm passes through three stages in the short run.

1. Which are the three stages of production?
2. Analyse and bring out the salient features of each stage.
3. Which stage of production is very important as far as a firm is concerned? Why?
4. Give suitable diagram by drawing the Total Prod-uct, Average Product & Marginal Product curves.

1. Increasing, diminishing and negative
2. First output increases at increasing rate, then at diminishing rate & finally starts falling.
3. Second stage, profit maximisation occurs in this Stage.
4.

Question 9.
If other things remaining same, graphically explain what happens to the supply curve for readymade shirts if there is

1. An increase in the wages paid to the tailors.

### Plus Two Economics Production and Costs Eight Mark Questions and Answers

Question 1.
Prepare a seminar report on the topic “Production Function.”
Respected teachers and dear friends:
The topic of my seminar paper is “Production Function”. The production function of a firm shows relationship between inputs and output. In this seminar paper, I would like to present the different production functions such as short run production function and the long run production function.

Introduction:
As we know the production function shows the transformation of inputs into output. The production function can be of two types – short run production function known as Law of Variable proportion and the long run production function known as returns to scale. Q =F(F1 F2… Fn)

Contents:
A. Law of Variable proportion

1. Increasing returns
2. Diminishing returns
3. Negative returns

A. The Law of Variable Proportions
When more and more units of a variable input are added with the fixed input, the marginal product would increase only upto a certain point. Therefore, the marginal product declines. This phenomenon is known as the Law of Variable Proportions. It is also known as returns to a factor.

The shape of TP, AP and MP suggests that they are specifically passing through three phases.
They are:
1. First phase:
In the first stage, both AP and MP increase. As a result TP also increases at an increasing rate. This stage is known as the stage of increasing return to a factor. AP reaches the maximum level in this stage.

2. Second phase:
Both AP and MP decrease at this stage. The TP increases at a decreasing rate. More importantly, TP reaches maximum and MP touches zero. This stage is also known as the stage of diminishing returns to a factor.

3. Third phase:
At this stage, the MP becomes negative. As a result, TP also starts declining. The decline of AP is continuous. In the graph, when TP reaches maximum and MP touches zero. When MP becomes negative, TP starts declining. This stage is known as the stage of negative returns to a factor.

B. Returns to scale

1. Increasing returns
2. Constant returns
3. Decreasing returns
(for details, refer summary part)

B. Returns to scale
As stated earlier, all the factor inputs become variable in the long run and thereby no distinction can be made between fixed inputs and variable inputs. Return to scale is associated with long run production function.

Returns to scale refers to the change in output when all inputs are variable and the proportion between inputs remains constant. When all the inputs vary in the same proportion, the output (TP) behaves in different manner, which can be clubbed into three categories.

1. Increasing Returns to Scale (IRS):
When a proportionate change in all the inputs leads to more than proportionate change in output, it is known as the stage of increasing returns to scale. For instance, a 10% change in inputs results in more than 10% change in output.

2. Constant Returns to Scale (CRS):
When a proportionate change in all the inputs leads to change in output in the same proportion is known as the stage of constant returns to scale. It indicates that a 10% change in inputs leads to exactly 10% change in output.

3. Decreasing Returns to Scale (DRS):
When a proportionate change in all the inputs leads to less than proportionate change in output is known as the stage of decreasing returns to scale. It indicates that a 10% change in inputs leads to less than 10% change in output.

Conclusion:
Thus it can be concluded that there are two types of production function depending upon the use of inputs and the time period.

Question 2.
Prepare a seminar paper on Law of Returns to Scale.
Returns to scale:
As stated earlier, all the factor inputs become variable in the long run and thereby no distinction can be made between fixed inputs and variable inputs. Return to scale is associated with long run production function.

Returns to scale refers to the change in output when all inputs are variable and the proportion between inputs remains constant. When all the inputs vary in the same proportion, the output (TP) behaves in different manner, which can be clubbed into three categories.

1. Increasing Returns to Scale (IRS):
When a proportionate change in all the inputs leads to more than proportionate change in output, it is known as the stage of increasing returns to scale. For instance, a 10 percentage change in inputs results in more than 10 percentage change in output.

2. Constant Returns to Scale (CRS):
When a proportionate change in all the inputs leads to change in output in the same proportion is known as the stage of constant returns to scale. It indicates that a 10 percentage change in inputs leads to exactly 10 percentage change in output.

3. Decreasing Returns to Scale (DRS):
When a proportionate change in all the inputs leads to less than proportionate change in output is known as the stage of decreasing returns to scale. It indicates that a 10 percentage change in inputs leads to less than 10 percentage change in output.

Question 3.
From the table given below

1. Fill the blank columns
2. Using the information in the table draw TC, TVC, TFC in one and AC, AVC, AFC, MC in other and prepare a short note on them.

1.

2. Use the data to draw the diagram.
TC, TVC and TFC represent total costs. TC = TFC + TVC. TFC is the cost incurred on fixed factors. TVC is the cost incurred on variable costs. Even though the level of output is zero there will be some costs. This is known as fixed cost. When the level of output is zero total variable costs also will be zero.

It will increase as the level of output increases. AFC is the cost that always falls. It is a rectangular hyperbola. AVC, AC, MC are ‘U’ shaped. The MC will always pass through the minimum oftheAVCand AC.

## Benefits of the Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF

The Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF that has been provided above is extremely helpful for all students because of the way it has been drafted. It is designed by teachers who have over 10 years of experience in the field of education. These teachers use the help of all the past years’ question papers to create the perfect Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF.

## FAQ’s Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF

#### Where can I download Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF?

You can download Plus Two Economics Chapter 3 Production and Costs Question and Answers PDF for the latest 2021 session.


text:
# Is this a Norm?

How is the following formula calculated, assuming $a$ and $b$ are $n$-dimensional vectors?

$\parallel \overrightarrow{a} – \overrightarrow{b}\parallel^2$

as $(\vec{a}-\vec{b}).(\vec{a}-\vec{b})$


text:
SEARCH HOME
 Math Central Quandaries & Queries
 Question from Walter, a student: To whom it may concern, Given x^3 - 3xy + y^3 = 1 , determine y'' by implicitly differentiating twice. I cannot solve this. Would you be kind enough to perform the mathematics and show the steps involved in obtaining the solution? Thank you.

Hi Walter,

I differentiated both sides with respect to x, multiplied both sides by 1/3 and was left with

.                (1)

Solving for dy/dx gives

.                                 (2)

At this point I see two choices, you can differentiate equation 1 or equation 2 to find an expression for the second derivative of y with respect to x. I would differentiate equation 1 as I try to avoid the quotient rule if possible. In either case the expression you obtain will involve the second derivative as well as dy/dx. Substitute for dy/dx using equation 2 and simplify. If you are comparing your answer with one given in the textbook you may need to do some algebra to show they are equivalently as there are different ways to express the result.

Harley

Math Central is supported by the University of Regina and The Pacific Institute for the Mathematical Sciences.


text:
## SCF Calculation of tubular joint SCF

Many offshore structures are fabricated with tubular members. The connections between the different tubular members are denoted tubular joints. A tubular joint is made up of a chord (element of largest diameter) and one or more braces.

The classification of a joint is not solely determined by the geometry, but also by the axial loads in the members. For example, if the axial force in one brace in an X-joint is much less than the other, the joint would be classified as a T-joint.

Although real structures are composed of multiplanar joints, the treatment of simple planar joints can be used if the members are within $\pm 15^\circ$. The nominal axial and bending stresses are multiplied by the appropriate Stress Concentration Factor (SCF) to obtain the stress at the crown and saddle of the chord and brace1. The resulting stresses can be combined to find the resulting stresses along the perimeter of the chord-brace intersection as described in DNV RP-C203 2. Once the Hot Spot Stresses (HSS) are calculated, a fatigue calculation can be performed.

The equations used for the determination of the tubular joint SCF 3 4 are based on the equations developed by Efthymiou 5. A comprehensive comparison of tubular joint SCF parameteric equations can be found in "Stress Concentration Factors for Simple Tubular Joints, Assessment of Existing and Development of New Parametric Formulae"6.

CRM Engineering has developed an online calculator of the equations.

## SCF Calculation of tubular joint SCF via FEA

If the joint parameters are outside the formula validity or if no SCF correlation exists for a joint geometry, a finite element analysis can be performed to calculate the SCF. Examples of such a joint would be a chord comprised of a jacket and pile with a grouted annulus or a non-tubular section. A methodology for calculating the SCF from a finite element analysis is given in DNV RP-C203 1.

The SCF calculation around the circumference of the brace-chord intersection is tedious and time consuming. CRM Engineering has developed an automated method that reduces the time and cost of extracting the SCF. At each node along the intersection between the brace and the chord, a path is created on the brace and the chord normal to the intersection. For each node on the intersection, a local coordinate system is created such that the local x-axis is normal to the intersection and the local z-axis is normal to the brace or the chord. The local $\sigma_{xx}$ and $\tau_{xy}$ is extracted along the paths and the SCF calculated, using the larger of Method A and Method B.