text:
# CW1200 ChipWhisperer-Pro¶

The CW1200 (ChipWhisperer Pro) is an upgraded version of the ChipWhisperer Lite capture hardware. The Pro includes an FPGA with much more space than the Lite, allowing many new features to be added, including a larger sample buffer, streaming-mode captures, additional trigger methods, and a touchscreen interface. These features make it a high-end device suitable for laboratory use.

Available in the ChipWhisperer-Pro Starter Kit

Datasheet

## Quick-Start Guide¶

To quickly setup the ChipWhisperer-Pro, connect it to a computer via a USB-A to USB-B cable and plug in its 5V power supply. Connect a 20-pin cable between it and a target board, as well as a coax cable between the measure SMA connector (if you're doing power analysis) or the glitch SMA connector (if you're doing voltage glitching) and the SMA connector on the target. Be sure to check the relevant hardware documentation for your target before proceeding as well.

Once that's done, follow our software/driver installation guide at chipwhisperer.readthedocs.io, which will take the rest of the way towards learning about side channel attacks!

## Product Highlights¶

• Synchronous (capture board and target board both use the same clock) capture and glitch architecture, offering vastly improved performance over a typical asynchronous oscilloscope setup
• 10-bit 105MS/s ADC for capturing power traces
• Can be clocked at both the same clock speed as the target and 4 times faster
• +55dB adjustable low noise gain, allowing the Pro to easily measure small signals
• Clock and voltage fault generation via FPGA-based pulse generation
• XMEGA (PDI), AVR (ISP), and STM32F (UART Serial) bootloader built in
• Advanced hardware trigger modules: IO (UART and SPI) and Analog Waveform (SAD)
• Large sample buffer (98k samples) and stream mode allow for long captures - perfect for SPA attacks
• LCD Screen
• Trigger In and Trigger Out SMA connectors
• Waterproof carrying case

## Specifications¶

### Analog Capture and Clock¶

Feature Notes/Range
ADC Clock Source Internally generated (x1 or x4 from output clock), external input (x1 or x4 from input clock)
Sample Buffer Size 98 119 samples
ADC Trigger Rising-edge, Falling-edge, High, Low
Presampling Yes
Capture Streaming Yes (10Ms/s max)
Clock Generation Range 5-200MHz
Clock Output Regular, with glitch inserted, glitch only

### Triggering¶

Feature Notes/Range
Modules Basic, Analog, SPI, UART
Analog Trigger Sum of Absolute Difference (128 samples)
Basic Trigger Inputs TIO 1-4, nRST, SMA
Basic Trigger Combination One of OR, AND, NAND

### IO¶

Feature Notes/Range
GPIO Voltage 3.3V
Logic Outputs TIO 1-4, nRST, PDIC, PDID
Logic Inputs TIO 1-4
UART Serial TIO 1-4 assignment
Clock Fixed, HS2 output, HS1 Input
Trigger Out Yes
Programmers STM32F UART, Atmel PDI (for XMEGA), Atmel ISP (for AVR)
Power rails 5V, 3.3V

### Glitch¶

Feature Notes/Range
Voltage Glitching Yes
Clock Glitching Yes
Glitch Outputs Clock-XOR, Clock-OR, Glitch-Only, Enable-Only
Glitch Width* 0-49.8% of a clock cycle, 100% (enable-only)
Glitch Width Increments 0.4% of a clock cycle
Glitch Offset 0-49.8% of a clock cycle, 100% (enable-only)
Glitch Offset Increments 0.4% of a clock cycle
Glitch Cycle Offset [0, 2^32)
Glitch Cycle Repeat [0, 8192]
Voltage Glitch Type High-power, low-power crowbar
Voltage Glitch Pulse Current 20A
Glitch Trigger Rising-Edge

* Actual glitch width will be affected by cabling used for glitch output

## Using the ChipWhisperer-Pro¶

All communication with the ChipWhisperer-Lite is done through ChipWhisperer's Python API, which is documented on our ReadTheDocs Page.

ChipWhisperer also has many Jupyter Notebook tutorials/labs, which serve as learning material for side-channel attacks, as well as examples on how to use the ChipWhisperer API. If you followed the install instructions on ReadTheDocs, this will be in the jupyter/ folder in the place you installed ChipWhisperer.

We also have full courses available at https://learn.chipwhisperer.io/ that supplement the Jupyter Notebook tutorials.

### Using from Other Languages¶

While the ChipWhisperer API is written in Python, any language that can talk to libusb should be compatable. This will require you to write your own backend and is officially unsupported by NewAE.

### Power Supply¶

The ChipWhisperer Pro can only be powered through its 5 V jack. It cannot be powered through the USB port - internally, there are no connections to the USB port's 5 V rail. This limitation is primarily due to the high current draw of the Pro: while powering the touchscreen running and an external target, it would be easy to exceed the USB current limit, causing all sorts of issues.

To make this setup more flexible, the Pro ships with two power sources:

• A 5 V, 2.1 A power supply. This supply is suitable for a permanent bench setup.
• A USB-to-barrel jack cable. This solution is more portable: if you're travelling with a laptop, you can use a second USB port for power. A USB charger will also work here.

If you're using the USB power cable, it is recommended to use a separate power supply to power any external target boards.

### Connectors¶

#### Using Glitch Port¶

The "GLITCH" port is used for voltage glitching. It's connected to two MOSFET elements, as the following figure shows:

The 1200 glitch output can be commanded to turn on either of those MOSFETs via scope.io.glitch_hp and scope.io.glitch_lp fields:

  scope.io.glitch_hp = True #enable high power glitch
scope.io.glitch_hp = False #disable high power glitch

scope.io.glitch_lp = True #enable low power glitch
scope.io.glitch_lp = False #disable low power glitch

Be careful using this feature, as you don't want to short the MOSFETs for too long. It's also possible to damage the ChipWhisperer-Pro by burning these MOSFETs up if used incorrectly. See Fault101 Voltage Glitch Labs for more information.

#### Using Measure Port¶

The "MEASURE" port is the input to the low-noise amplifier and ADC.

#### 20-Pin Connector¶

The 20-pin connector carries power and IO pins between the ChipWhisperer-Lite and the target board. The pinout is as follows:

Number Name Dir Description
1 +VUSB (5V) O 5V from power supply.
2 GND O System GND.
3 +3.3V O +3.3V to Target Device, can be turned off, 200mA available.
4 FPGA-HS1 I/O High Speed Input (normally clock in).
5 PROG-RESET I/O Target RESET Pin (nRST).
6 FPGA-HS2 I/O High Speed Output (normally clock or glitch out).
7 PROG-MISO I/O SPI input: MISO (for SPI + AVR Programmer).
8 VTarget I Drive this pin with desired I/O voltage in range 1.5V-5V.
9 PROG-MOSI I/O SPI output: MOSI (for SPI + AVR Programmer).
10 FPGA-TARG1 I/O TargetIO Pin 1 - Usually UART TX or RX.
11 PROG-SCK I/O SPI output: SCK (for SPI + AVR Programmer).
12 FPGA-TARG2 I/O TargetIO Pin 2 - Usually UART RX or TX.
13 PROG-PDIC I/O PDI Programming Clock (XMEGA Programmer), or CS pin (SPI). Also used for STM32 bootloader
14 FPGA-TARG3 I/O TargetIO Pin 3 - Usually bidirectional IO for smartcard.
15 PROG-PDID I/O PDI Programming Data (XMEGA Programmer).
16 FPGA-TARG4 I/O TargetIO Pin 4 - Usually trigger input.
17 GND O
18 +3.3V O
19 GND O
20 +VUSB (5V) O

When talking about the ChipWhisperer's firmware, there is really two parts to this:

1. The FPGA Bitstream file.
2. The SAM3U USB interface chip firmware.

The FPGA bitstream alone is what is normally configured by the ChipWhisperer-Capture software. This bitstream is always the most up-to-date, since it's automatically reloaded by the computer every time you power cycle the ChipWhisperer-Capture. The SAM3U firmware is not updated automatically, but it tends to change less frequently.

##### Checking Firmware Version¶

The firmware version can be accessed as follows:

>>> import chipwhisperer as cw
>>> scope = cw.scope()
>>> print(scope.fw_version)
{'major': 0, 'minor': 11, 'debug': 0}

The version of the newest firmware can be printed as follows:

>>> import chipwhisperer as cw
>>> scope = cw.scope()
>>> print(scope.latest_fw)
{'major': 0, 'minor': 11}

If a firmware update is available, the user will be warned when connecting to the scope:

>>> scope = cw.scope()
WARNING:root:Your firmware is outdated - latest is 0.12. Suggested to update firmware, as you may experience errors

See https://chipwhisperer.readthedocs.io/en/latest/api.html#firmware-update for instructions on how to update the SAM3U firmware.

##### Linux usbserial module Workaround¶

There is an issue in some versions of Linux, where the SAM3U is not assigned a serial port when it enters bootloader mode. Here are some steps to resolve this issue (Note. this is not a permanent fix, you must go through these steps each time you put your ChipWhisperer into bootloader mode.). These steps assume you've already put ChipWhisperer into bootloader mode.

1. Unplug your ChipWhisperer (Leave unplugged until instructed otherwise)
3. Once logged in again, open a terminal session
4. Run this command: sudo modprobe usbserial vendor=0x3eb product=0x6124
5. Plug your ChipWhisperer back in
6. Check that a serial port is now open using: ls -l /dev/ttyUSB*

You should now be able to program the bootloader from ChipWhisperer Capture through the port you created

#### Streaming Mode¶

The ChipWhisperer Pro has a streaming mode that allows extremely long captures as long as relatively low sampling rates are used. For example, this plot shows an exerpt from two traces with nearly 1 million samples:

This capture mode is useful for many types of attacks, including:

• Full captures of slow software AES libraries
• Power analysis on ECC
• Context switches on embedded operating systems

While streaming, the ChipWhisperer hardware sends ADC data back to the capture software while recording more samples (instead of waiting until the end of the capture). During this process, the ADC samples are sent back to the computer in packets of approximately 3000 samples at a time. As a block diagram, this looks like:

The main danger in streaming mode is that the FPGA's sample buffer can overflow if the PC doesn't request these packets quickly enough. In practice, the maximum transfer rate is around 10 Msamples/s, so the maximum ADC frequency is approximately 10 MHz in streaming mode. Trying to stream above this rate will usually cause data to be lost: the FPGA overwrites samples after the buffer is full, so it's impossible to recover these samples after overrunning the buffer.

On the software end, there are two things to watch for:

• Long captures from streaming mode (millions of points) may take several seconds to record. When working with these long captures, make sure the software's timeouts are long enough.

• Extremely long captures take a lot of memory. 64-bit Python is recommended if you plan on capturing many traces with millions of samples - you can hit the memory limit on 32-bit Python pretty quickly.

#### Trigger Module¶

Unlike the ChipWhisperer-Lite, the Pro has three different trigger modes to help capture traces when it's difficult to get a concrete trigger signal. A block diagram of the trigger module is:

The first two trigger modes use a combination of the trigger inputs - the four GPIO inputs and the auxiliary SMA input. In the Capture software, these five inputs can be enabled independently and combined in three methods (AND, OR, and NAND). This combined trigger signal is the input for the edge/level and I/O decode detectors. The last trigger mode looks directly at the power trace and does not use these trigger inputs.

##### Edge/Level¶

The edge/level detector can trigger on four different events:

• Trigger input is low (0)

• Trigger input is high (1)

• Trigger input had a rising edge (0 -> 1)
• Trigger input had a falling edge (1 -> 0)

This mode is suitable when the target is using one of the GPIO pins as a trigger signal - if you have control over the target's source code, let it output a rising edge when the encryption or other operation begins.

##### I/O Decoder¶

The I/O decoder examines the trigger signal, assumes that it is either UART or SPI traffic, and outputs a trigger signal when it detects a certain pattern on the line. In the capture software, the settings for this decoder are:

• Decode Type: Which type of traffic is being captured in the trigger signal? Might be USART or SPI data.

• Trigger Data: Which data are we searching for? This setting should be a list of bytes to be detected in order. For example, ['r', '0'] would detect the string "r0", and [0x07] would detect a bell character.

• Baud: What baud rate does this line use? This needs to be set manually.

When using this trigger mode, target IO1/IO2 are probably the best inputs to use: these are normally the serial TX and RX lines. It's possible to enable either one of these to trigger on sending or receiving data, respectively.

##### Sum of Absolute Differences (SAD)¶

Some targets don't have nice trigger signals to detect. Sad!

The Sum of Absolute Differences module has two 128 sample buffers. The FPGA stores the ADC's 128 most recent samples in one buffer and a fixed pattern in the other. Then, after every sample, it calculates

If this sum is below a fixed threshold, the output trigger signal will be set. This trigger module allows the ChipWhisperer to detect a specific pattern (for instance, an encryption operation) in a power trace without any other data.

The settings for the SAD module are:

• Point Range: The samples in the current trace to be used for the SAD module's fixed values. This range is forced to have a width of 128.
• Set SAD Reference from Current Trace: Sets the fixed 128 samples to the current selection.

• SAD Reference vs. Cursor: Shows the current output of the SAD calculation. Useful for setting the threshold - it's easy to capture a number of traces and check what typical values are for this SAD output.

• SAD Threshold: The trigger point for the SAD module. A value of 0 indicates a perfect match. If this threshold is too low, noise will stop the trigger from appearing; if it's too high, the scope will trigger at random offsets.

Note that this SAD module does not play well with downsampling: the inputs to the SAD buffer are not downsampled. This means that downsampled traces cannot be used as a reference. If you want to use this trigger type, set up your SAD trigger with downsampling turned off first.

#### SMA I/O¶

The Pro has an extra SMA connector intended to be used for additional trigger logic. It can be used either as a trigger input or output.

Input: The Aux SMA trigger input can be used in the exact same manner as the other trigger inputs: the digital level is combined with the other active triggers (through an AND or OR gate) and this is used as the trigger signal. This is helpful for using other creative trigger signals. For example, if you have a custom target board, you could connect an FPGA output as an additional trigger signal. Alternatively, you could use a high-end oscilloscope's pattern detection as a trigger input.

Output: When the trigger module produces a trigger signal, the ChipWhisperer can reproduce this signal on the Aux SMA. This allows an external oscilloscope to be used to capture traces alongside the ChipWhisperer.

#### Touchscreen¶

The touchscreen on the ChipWhisperer Pro shows various details about its status and current settings.

##### Screen 1: Clock¶

The clock screen shows the status of the CLKGEN and ADC clocks along with the frequency counter.

TODO: picture

• CLKGEN: Current frequency of CLKGEN clock in kHz

• Source: Input to CLKGEN DCM. Could be system clock or EXTCLK

• DCM: Lock status of CLKGEN DCM

• Reset DCM: Reset the CLKGEN output. Useful if clock has locked at the wrong frequency
• Source: Input to ADC DCM. Could be related to CLKGEN or EXTCLK

• DCM: Lock status of ADC DCM

• Reset DCM: Reset the ADC clock output
• Frequency Counter: Current frequency measured by the frequency counter
• Source: Input to frequency counter. Could be either EXTCLK or CLKGEN

##### Screen 2: Routing¶

The routing screen shows the status of the various I/O pins.

TODO: picture

• Aux Output: Status of the aux SMA connections. Could be used as trigger input/output, glitch output, and/or clock output

• IO Pins: Status of each of the IO pins on the 20 pin connector. Possible values depend on pin

• Target Power State: Status of the 3.3 V output. Can be toggled here to reset target
• Target HS IO-Out: Signal connected to high-speed output (HS2). Could be CLKGEN, glitch module, or disabled

##### Screen 3: Trigger¶

The trigger screen shows the current settings for the trigger module and the ADC capture settings.

TODO: picture

• Trigger Pins: Whether each trigger input is enabled. Active inputs are highlighted

• Mode: Trigger combination method. Could be AND, OR, or NAND
• Trigger Source: The trigger type in use. Active trigger module is highlighted

• State: The current output level of the trigger module
• Trigger Mode: The ADC trigger type. Active mode is highlighted

• Samples:

• Delay: Current ADC offset. This is the number of samples to wait after trigger before recording begins

• Pre: Number of pre-trigger samples to be saved

• Time: Delay, but converted into a time
• Total: Number of samples to be recorded in total
• Mode: Amplification type. Either low or high

• Setting: Low noise amplifier gain level

##### Screen 4: Glitch¶

The glitch screen shows the current settings for the glitch module.

TODO: picture

• Clock Src: Input to the glitch module's clock. Active clock is highlighted

• DCM: Lock status of the glitch module's DCM
• Glitch Setup:

• Width: Duty cycle of glitch pulse, as a fraction of one period

• Offset: Distance between clock rising edge and glitch pulse rising edge, as a fraction of one period


text:
# How to implement conditional probability distribution on set-valued Random Variables

I'm trying to implement conditional probability distribution when the events of two RVs are sets. If I try to extrapolate concepts from real or categorical variables to sets things become confusing for me. In the usual scenario, for some pair of discrete RVs, $$X,Y$$, we can compute the conditional probability of two "punctual" events by using the Bayes theorem: $$P(Y=y|X=x)=\frac{P(X=x|Y=y)P(Y=y)}{\sum_{y'\in\mathcal{Y}}P(X=x|Y=y')P(Y=y')}=\frac{f(x,y)}{\sum_{y'\in\mathcal{Y}}f(x,y')},$$ where $$f(x,y)=\sum_{(x',y')\in (\mathcal{X},\mathcal{Y})}\chi(x'=x,y'=y)$$ is an accumulator function giving the total number of times the specific joint event $$x,y$$ is observed in the sample space (i.e. the indicator function $$\chi(x'=x,y'=y)$$ equals one when $$x'=x,y'=y$$ holds). I'd like to compute such probability when events drawn by $$X,Y$$ are sets $$\boldsymbol{x},\boldsymbol{y}$$, respectively. So, how to define the corresponding $$f(\boldsymbol{x},\boldsymbol{y})$$?

I've tried with two main options: $$(1)\hspace{10mm}f(\boldsymbol{x},\boldsymbol{y})=\sum_{(\boldsymbol{x}',\boldsymbol{y}')\in(\mathcal{X},\mathcal{Y})}|(\boldsymbol{x}\cap\boldsymbol{y})\cap(\boldsymbol{x}'\cap\boldsymbol{y}')|,$$ and $$(2)\hspace{10mm}f(\boldsymbol{x},\boldsymbol{y})=\sum_{(\boldsymbol{x}',\boldsymbol{y}')\in(\mathcal{X},\mathcal{Y})}|(\boldsymbol{x}\cap\boldsymbol{y})\cap \boldsymbol{x}'\cup(\boldsymbol{x}\cap\boldsymbol{y})\cap \boldsymbol{y}'|,$$

On the one hand, the motivation behind $$(1)$$ is that $$\boldsymbol{x}\cap\boldsymbol{y}$$ provides a measure of how the attributes of both sets should be observed jointly (such as any intersection event). In turn intersecting this intersection event against other intersection events $$\boldsymbol{x}'\cap\boldsymbol{y}'$$ should provide the measure of how much the joint attributes are observed through the sample space. On the other hand, the motivation behind $$(2)$$ is that in order to compute $$f(\boldsymbol{x},\boldsymbol{y})$$ we need to look for $$\boldsymbol{x}\cap\boldsymbol{y}$$'s attributes in each event of the sample space, without building new events.

However, I'm not sure which one of these analogies is correct (or none at all) with respect to the usual notion of observing the joint event in a sample space. Please, some one can help me to clarify/fix/prove this?

Thank you in advance

## 1 Answer

Your understanding of the basic situation (without sets) has some caveats. It seems that you are defining

$$f(x,y) = \Pr[X=x \land Y=y] \times |\mathcal{X}| \times |\mathcal{Y}|.$$

You seems to be assuming that $$X,Y$$ are independently and uniformly distributed over the sample space $$\mathcal{X} \times \mathcal{Y}$$. Note that this is a big assumption -- it typically won't hold, and if it doesn't hold, your formula is not correct.

You don't need a fancy accumulator function. There is a simpler expression for $$f$$, namely, $$f(x,y) = 1$$ if $$x \in \mathcal{X},y \in \mathcal{Y}$$ (and $$f(x,y) = 0$$ otherwise, if you allow that to happen). Again, this is only valid if $$X,Y$$ are uniformly distributed on $$\mathcal{X} \times \mathcal{Y}$$.

When $$X,Y$$ are sets, the exact same formula holds... under the same assumptions. No changes needed at all.

Your proposed formulas (1), (2) are not correct.

In practice, usually $$X,Y$$ are typically not independently and uniformly distributed. Therefore, these formulas are usually not useful in practice. Instead, you need to work directly with the probabilities; counts and $$f$$ probably won't be useful in that case.

format: plain


text:
This function is no longer required by current versions of the eBird Basic Dataset (EBD).

auk_clean(f_in, f_out, sep = "\t", remove_text = FALSE, overwrite = FALSE)

## Arguments

f_in character; input file. If file is not found as specified, it will be looked for in the directory specified by the EBD_PATH environment variable. character; output file. character; the input field separator, the basic dataset is tab separated by default. Must only be a single character and space delimited is not allowed since spaces appear in many of the fields. logical; whether all free text entry columns should be removed. These columns include comments, location names, and observer names. These columns cause import errors due to special characters and increase the file size, yet are rarely valuable for analytical applications, so may be removed. Setting this argument to TRUE can lead to a significant reduction in file size. logical; overwrite output file if it already exists.

## Value

If AWK ran without errors, the output filename is returned, however, if an error was encountered the exit code is returned.

Other text: auk_select(), auk_split()

## Examples

if (FALSE) {
# get the path to the example data included in the package
f <- system.file("extdata/ebd-sample.txt", package = "auk")
# output to a temp file for example
# in practice, provide path to output file
# e.g. f_out <- "output/ebd_clean.txt"
f_out <- tempfile()

# clean file to remove problem rows
# note: this function is deprecated and no longer does anything
auk_clean(f, f_out)
}


text:
Pratice Number System Questions and answers.

Home » Quantitative Aptitude » Number System » Questions
1 / 20

Which of the following is the smallest fraction?

$\frac{7}{6},\frac{7}{9},\frac{4}{5},\frac{5}{7}$
$\frac{7}{6}$
$\frac{7}{9}$
$\frac{4}{5}$
$\frac{5}{7}$


text:
This page is not ready to go live; just roughly copying over some material from last year.

# Rosetta Stone

Here's how it looks to say the same thing in various of these languages.

1. Function application and parentheses

In Scheme and the lambda calculus, the functions you're applying always go to the left. So you write (foo 2) and also (+ 2 3).

Mostly that's how OCaml is written too:

foo 2

But a few familiar binary operators can be written infix, so:

2 + 3

You can also write them operator-leftmost, if you put them inside parentheses to help the parser understand you:

( + ) 2 3

I'll mostly do this, for uniformity with Scheme and the lambda calculus.

In OCaml and the lambda calculus, this:

foo 2 3

means the same as:

((foo 2) 3)

These functions are "curried". foo 2 returns a 2-fooer, which waits for an argument like 3 and then foos 2 to it. ( + ) 2 returns a 2-adder, which waits for an argument like 3 and then adds 2 to it. For further reading:

2. Currying

In Scheme, on the other hand, there's a difference between ((foo 2) 3) and (foo 2 3). Scheme distinguishes between unary functions that return unary functions and binary functions. For our seminar purposes, it will be easiest if you confine yourself to unary functions in Scheme as much as possible.

Scheme is very sensitive to parentheses and whenever you want a function applied to any number of arguments, you need to wrap the function and its arguments in a parentheses. So you have to write (foo 2); if you only say foo 2, Scheme won't understand you.

Scheme uses a lot of parentheses, and they are always significant, never optional. Often the parentheses mean "apply this function to these arguments," as just described. But in a moment we'll see other constructions in Scheme where the parentheses have different roles. They do lots of different work in Scheme.

3. Binding suitable values to the variables three and two, and adding them.

In Scheme:

(let* ((three 3))
(let* ((two 2))
(+ three two)))

Most of the parentheses in this construction aren't playing the role of applying a function to some arguments---only the ones in (+ three two) are doing that.

In OCaml:

let three = 3 in
let two = 2 in
( + ) three two

In the lambda calculus:

Here we're on our own, we don't have predefined constants like + and 3 and 2 to work with. We've got to build up everything from scratch. We'll be seeing how to do that over the next weeks.

But supposing you had constructed appropriate values for + and 3 and 2, you'd place them in the ellided positions in:

(((\three (\two ((... three) two))) ...) ...)

In an ordinary imperatival language like C:

int three = 3;
int two = 2;
three + two;

4. Mutation

In C this looks almost the same as what we had before:

int x = 3;
x = 2;

Here we first initialize x to hold the value 3; then we mutate x to hold a new value.

In (the imperatival part of) Scheme, this could be done as:

(let ((x (box 3)))
(set-box! x 2))

In general, mutating operations in Scheme are named with a trailing !. There are other imperatival constructions, though, like (print ...), that don't follow that convention.

In (the imperatival part of) OCaml, this could be done as:

let x = ref 3 in
x := 2

Of course you don't need to remember any of this syntax. We're just illustrating it so that you see that in Scheme and OCaml it looks somewhat different than we had above. The difference is much more obvious than it is in C.

In the lambda calculus:

Sorry, you can't do mutation. At least, not natively. Later in the term we'll be learning how in fact, really, you can embed mutation inside the lambda calculus even though the lambda calculus has no primitive facilities for mutation.

5. Anonymous functions

Functions are "first-class values" in the lambda calculus, in Scheme, and in OCaml. What that means is that they can be arguments to, and results of, other functions. They can be stored in data structures. And so on. To read further:

We'll begin by looking at what "anonymous" functions look like. These are functions that have not been bound as values to any variables. That is, there are no variables whose value they are.

In the lambda calculus:

(\x M)

---where M is any simple or complex expression---is anonymous. It's only when you do:

((\y N) (\x M))

that (\x M) has a "name" (it's named y during the evaluation of N).

In Scheme, the same thing is written:

(lambda (x) M)

Not very different, right? For example, if M stands for (+ 3 x), then here is an anonymous function that adds 3 to whatever argument it's given:

(lambda (x) (+ 3 x))

In OCaml, we write our anonymous function like this:

fun x -> ( + ) 3 x

6. Supplying an argument to an anonymous function

Just because the functions we built aren't named doesn't mean we can't do anything with them. We can give them arguments. For example, in Scheme we can say:

((lambda (x) (+ 3 x)) 2)

The outermost parentheses here mean "apply the function (lambda (x) (+ 3 x)) to the argument 2, or equivalently, "give the value 2 as an argument to the function (lambda (x) (+ 3 x)).

In OCaml:

(fun x -> ( + ) 3 x) 2

7. Binding variables to values with "let"

Let's go back and re-consider this Scheme expression:

(let* ((three 3))
(let* ((two 2))
(+ three two)))

Scheme also has a simple let (without the *), and it permits you to group several variable bindings together in a single let- or let*-statement, like this:

(let* ((three 3) (two 2))
(+ three two))

Often you'll get the same results whether you use let* or let. However, there are cases where it makes a difference, and in those cases, let* behaves more like you'd expect. So you should just get into the habit of consistently using that. It's also good discipline for this seminar, especially while you're learning, to write things out the longer way, like this:

(let* ((three 3))
(let* ((two 2))
(+ three two)))

However, here you've got the double parentheses in (let* ((three 3)) ...). They're doubled because the syntax permits more assignments than just the assignment of the value 3 to the variable three. Myself I tend to use [ and ] for the outer of these parentheses: (let* [(three 3)] ...). Scheme can be configured to parse [...] as if they're just more (...).

It was asked in seminar if the 3 could be replaced by a more complex expression. The answer is "yes". You could also write:

(let* [(three (+ 1 2))]
(let* [(two 2)]
(+ three two)))

It was also asked whether the (+ 1 2) computation would be performed before or after it was bound to the variable three. That's a terrific question. Let's say this: both strategies could be reasonable designs for a language. We are going to discuss this carefully in coming weeks. In fact Scheme and OCaml make the same design choice. But you should think of the underlying form of the let-statement as not settling this by itself.

Repeating our starting point for reference:

(let* [(three 3)]
(let* [(two 2)]
(+ three two)))

Recall in OCaml this same computation was written:

let three = 3 in
let two = 2 in
( + ) three two

8. Binding with "let" is the same as supplying an argument to a lambda

The preceding expression in Scheme is exactly equivalent to:

(((lambda (three) (lambda (two) (+ three two))) 3) 2)

The preceding expression in OCaml is exactly equivalent to:

(fun three -> (fun two -> ( + ) three two)) 3 2

Read this several times until you understand it.

9. Functions can also be bound to variables (and hence, cease being "anonymous").

In Scheme:

(let* [(bar (lambda (x) B))] M)

then wherever bar occurs in M (and isn't rebound by a more local let or lambda), it will be interpreted as the function (lambda (x) B).

Similarly, in OCaml:

let bar = fun x -> B in
M

This in Scheme:

(let* [(bar (lambda (x) B))] (bar A))

as we've said, means the same as:

((lambda (bar) (bar A)) (lambda (x) B))

which beta-reduces to:

((lambda (x) B) A)

and that means the same as:

(let* [(x A)] B)

in other words: evaluate B with x assigned to the value A.

Similarly, this in OCaml:

let bar = fun x -> B in
bar A

is equivalent to:

(fun x -> B) A

and that means the same as:

let x = A in
B

10. Pushing a "let"-binding from now until the end

What if you want to do something like this, in Scheme?

(let* [(x A)] ... for the rest of the file or interactive session ...)

or this, in OCaml:

let x = A in
... for the rest of the file or interactive session ...

Scheme and OCaml have syntactic shorthands for doing this. In Scheme it's written like this:

(define x A)
... rest of the file or interactive session ...

In OCaml it's written like this:

let x = A;;
... rest of the file or interactive session ...

It's easy to be lulled into thinking this is a kind of imperative construction. But it's not! It's really just a shorthand for the compound let-expressions we've already been looking at, taking the maximum syntactically permissible scope. (Compare the "dot" convention in the lambda calculus, discussed above. I'm fudging a bit here, since in Scheme (define ...) is really shorthand for a letrec epression, which we'll come to in later classes.)

11. Some shorthand

OCaml permits you to abbreviate:

let bar = fun x -> B in
M

as:

let bar x = B in
M

It also permits you to abbreviate:

let bar = fun x -> B;;

as:

let bar x = B;;

Similarly, Scheme permits you to abbreviate:

(define bar (lambda (x) B))

as:

(define (bar x) B)

and this is the form you'll most often see Scheme definitions written in.

However, conceptually you should think backwards through the abbreviations and equivalences we've just presented.

(define (bar x) B)

just means:

(define bar (lambda (x) B))

which just means:

(let* [(bar (lambda (x) B))] ... rest of the file or interactive session ...)

which just means:

(lambda (bar) ... rest of the file or interactive session ...) (lambda (x) B)

or in other words, interpret the rest of the file or interactive session with bar assigned the function (lambda (x) B).

You can override a binding with a more inner binding to the same variable. For instance the following expression in OCaml:

let x = 3 in
let x = 2 in
x

will evaluate to 2, not to 3. It's easy to be lulled into thinking this is the same as what happens when we say in C:

int x = 3;
x = 2;

but it's not the same! In the latter case we have mutation, in the former case we don't. You will learn to recognize the difference as we proceed.

The OCaml expression just means:

(fun x -> ((fun x -> x) 2) 3)

and there's no more mutation going on there than there is in:

∀x. (F x or ∀x (not (F x)))

When a previously-bound variable is rebound in the way we see here, that's called shadowing: the outer binding is shadowed during the scope of the inner binding.

## Some more comparisons between Scheme and OCaml

• Simple predefined values

Numbers in Scheme: 2, 3
In OCaml: 2, 3

Booleans in Scheme: #t, #f
In OCaml: true, false

The eighth letter in the Latin alphabet, in Scheme: #\h
In OCaml: 'h'

• Compound values

These are values which are built up out of (zero or more) simple values.

Ordered pairs in Scheme: '(2 . 3) or (cons 2 3)
In OCaml: (2, 3)

Lists in Scheme: '(2 3) or (list 2 3)
In OCaml: [2; 3]
We'll be explaining the difference between pairs and lists next week.

The empty list, in Scheme: '() or (list)
In OCaml: []

The string consisting just of the eighth letter of the Latin alphabet, in Scheme: "h"
In OCaml: "h"

A longer string, in Scheme: "horse"
In OCaml: "horse"

A shorter string, in Scheme: ""
In OCaml: ""


text:
# Connecting 5V device to 3.3V input through a single resistor

Hi I've got a Raspberry Pi, that's 3.3V device, and a Nextion display, which is a 5V device. They are talking over UART. Obviously RPi's UART RXD link can be damaged if connected directly to the Nextion display output.

Long time ago I read somewhere an explanation that it's not the voltage that damages the lower voltage devices but the current that can flow through. And therefore for input pins like this it's enough to put a big enough resistor between the 5V output pin and 3.3V input pin to limit the current and be done with it. No resistor dividers, no level shifters, just a single resistor. Makes sense to me, but I can't find the original article for reference.

How can I tell what value should such a resistor have?

• ohm's law, considering the impedance of each side without adjustment. often times loads are dynamic, so a single resistor can't produce the same result in all modes of operation; ex: too much while in sleep mode, not enough during boot... a lot of noob-targeted 3.3v hobby electronics are 5v tolerant anyway, and your RX likely already has a high impedance that would curtail damage; the only issue is threading the schitt-trigger voltage window. – dandavis Jul 24 '17 at 4:46
• @dan a lot of noob-targeted 3.3v hobby electronics are 5v tolerant anywayblatantly untrue. The four biggest, 3.3V arduinos, esp8xxx, msp430 launchpads, and raspberry pis all lack 5v tolerant inputs. – Passerby Jul 24 '17 at 5:34
• I'm sorry but I personally disagree with this. If a 3.3V chip says it can accept on its pins a maximum voltage of let's say 4V, then if you apply 5V signals you violate this requirement. Current has nothing to do with it. And also ask yourself this: if it is that simple, why everyone is using a level-shifter instead of a single resistor? – nickagian Jul 24 '17 at 6:24
• The single resistor trick can be used, when done right, for applying higher voltages to some series/generations of Atmel/AVR chips, as they themselves indicate, and as such define the behaviour. This then applied to a bunch of Arduinos, and through limited understanding of what is universal and what is not, that has now become the rule, dangerous as it may be. – Asmyldof Jul 24 '17 at 7:10
• @Asmyldof Oh, I didn't know this but I find it really sad. This is one of the negative aspects of Arduinos being so widespread used. – nickagian Jul 24 '17 at 7:21

For high-impedance inputs, you can use a voltage divider to level shift downwards. The requirements are that the resistor values need to be large enough to not strain the source too much, and small enough so the impedance of the input does not affect the resulting voltage.

That usually gives you a wide range, at least if there is no internal pull-up or pull-down on that input.

The single resistor approach can work with some components, but in general it means that some transistor will have current flowing from base to collector, which is generally a bad idea, even if it is only a little. The circuit simply is not designed for this case, and what happens is therefore undefined.

• Thanks for the explanation, I'll use a voltage divider then :) – MLu Jul 24 '17 at 22:49

Originally I gave an answer which calculated a minimum safe resistance to ensure that the current into the pin did not exceed 10mA. However, as Simon says above, allowing a GPIO pin to go above its rated voltage, regardless of how much you limit the current is a bad idea. See this article for an explanation. In short, the internal over voltage protection is for transients and will fail if a sustained over or under voltage is applied even at very small currents. Its also silly, as a voltage divider is only one extra resistor.

Finally the Nextion may not be 3.3V tolerant, and may need a step up converter to take the Rpi Tx from 3.3V to 5V. see here for how to do this.

• I wouldn't call it a "step up converter"! :-) This refers to something else normally. – nickagian Jul 24 '17 at 7:16


text:
Identify the level of measurement (nominal, ordinal, or interval-ratio) of each of the following variables: (1) How satisfied a person is wi

Question

Identify the level of measurement (nominal, ordinal, or interval-ratio) of each of the following variables: (1) How satisfied a person is with his or her employment benefits, measured as very satisfied, somewhat satisfied, neither satisfied nor dissatisfied, somewhat dissatisfied, or very dissatisfied. (2) The number of times someone has shoplifted in her or his life. (3) The number of times someone has voted in a public election measured as 0-1 times, 2-3 times, or 4 or more times. (4) The type of attomey a criminal defendant has attrial, measured as privately retained or publicly funded.

in progress 0
1 year 2021-08-06T15:36:14+00:00 1 Answers 0 views 0

1. Solution :

Nominal variable

A nominal variable is defined as a variable which is used to $$\text{nam}e \text{ or label or categorize some particular attributes }$$  which are being measured.

An ordinal variable is the one in which the order matters, but the difference between any two orders does not matter.

In interval ratio variable is defined as the variable where the difference between any two values is meaningful.

The level of measurement  for each of the following are :

1) Variables that are categorized in categories so that it is ordinal data.

2) Data scaled with the two categories her or his,  so it is a nominal data.

3) Number of votes categorized in the intervals so it is Interval type data.

4) nominal data.