Added docker and first exercise
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# IPython Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# docker
|
||||||
|
.docker_cid
|
||||||
|
Dockerfile
|
||||||
36
Dockerfile.sample
Normal file
36
Dockerfile.sample
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y zsh \
|
||||||
|
vim \
|
||||||
|
tmux \
|
||||||
|
python3-numpy \
|
||||||
|
python3-scipy \
|
||||||
|
python3-matplotlib \
|
||||||
|
ipython3 \
|
||||||
|
python3-pillow \
|
||||||
|
python3-pip
|
||||||
|
|
||||||
|
RUN pip3 install jupyter scikit-image ipykernel
|
||||||
|
|
||||||
|
# Use the same gid and uid as your user on the host system. You can find them
|
||||||
|
# out with the id programm. This way the file ownership in mapped directories is
|
||||||
|
# consistent with the host system.
|
||||||
|
RUN echo "%sudo ALL=(ALL) ALL" >> /etc/sudoers
|
||||||
|
RUN groupadd --gid 1000 user
|
||||||
|
RUN useradd --uid 1000 --gid user \
|
||||||
|
--home-dir /home/user --shell /usr/bin/bash \
|
||||||
|
--groups sudo,user \
|
||||||
|
--password password \
|
||||||
|
user
|
||||||
|
|
||||||
|
|
||||||
|
# set default passwords
|
||||||
|
RUN echo user:password | chpasswd && \
|
||||||
|
echo root:password | chpasswd
|
||||||
|
|
||||||
|
RUN mkdir -p /home/user && chown -R user:user /home/user
|
||||||
|
|
||||||
|
USER user
|
||||||
|
WORKDIR /home/user'
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "jupyter notebook --ip 0.0.0.0"]
|
||||||
83
README.md
83
README.md
@@ -1,2 +1,81 @@
|
|||||||
# Hausaufgaben
|
# FU Berlin - Image Processing SS 18
|
||||||
Hausaufgaben und Musterlösungen für den Kurs Bildverarbeitung im SS 2018
|
|
||||||
|
The assignments will be published to this repository.
|
||||||
|
All assignments will be IPython Notebooks. That you have to complete.
|
||||||
|
|
||||||
|
## Work flow
|
||||||
|
|
||||||
|
The rough workflow is:
|
||||||
|
1. You clone this repository.
|
||||||
|
2. Edit the exercises.
|
||||||
|
3. Push it to your private repository.
|
||||||
|
4. I fetch your code when the assignment is due. (Every Wednesday at 8:00 a.m.)
|
||||||
|
5. You fetch the latest assignments from this repository.
|
||||||
|
|
||||||
|
It is required to use private git repositories.
|
||||||
|
The university offers free private repositories [here](https://git.imp.fu-berlin.de/)
|
||||||
|
or you can get [5 GitHub repositories for free](https://education.github.com/) as a student.
|
||||||
|
|
||||||
|
First clone this repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone --origin upstream https://github.com/BildverarbeitungSS18/Hausaufgaben
|
||||||
|
```
|
||||||
|
|
||||||
|
Get into the new folder
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd Hausaufgaben
|
||||||
|
```
|
||||||
|
|
||||||
|
Add your remote
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git remote add origin <your git repo url>
|
||||||
|
```
|
||||||
|
|
||||||
|
Please clear the notebook's output before committing. Otherwise the repository
|
||||||
|
size can get pretty big.
|
||||||
|
The best thing is to setup a `pre-commit` hook that removes the outputs before
|
||||||
|
the files are committed:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ln -s ../../nb_strip_output.py .git/hooks/pre-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise you manually clean the output with `Cell -> All Output -> Clear` or
|
||||||
|
use the `nb_strip_output.py <filename>` script.
|
||||||
|
|
||||||
|
To get the latest assignments into your repository see [how to sync a fork](https://help.github.com/articles/syncing-a-fork/).
|
||||||
|
|
||||||
|
Paste a link to your repository into the kvv assignment box.
|
||||||
|
Make sure that I have read and write rights on your repository.
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
There exists a script for a [docker](https://www.docker.com/) image.
|
||||||
|
All the libraries we will use are included in this image.
|
||||||
|
It is recommended to use the image, but you are free to setup the environment
|
||||||
|
for yourself.
|
||||||
|
|
||||||
|
First [install docker](https://docs.docker.com/engine/installation/) on your computer.
|
||||||
|
|
||||||
|
Build the image:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./docker_build.sh
|
||||||
|
```
|
||||||
|
The build script will create a user with your username and uid inside the image.
|
||||||
|
It may take some minutes until the image is built.
|
||||||
|
|
||||||
|
If you don't have a bash you can manually edit the `Dockerfile.sample`.
|
||||||
|
See the docker documentation for [details](https://docs.docker.com/)
|
||||||
|
|
||||||
|
To run the image:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./docker_start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Now visit [localhost:8888](http://localhost:8888). Jupyter Notebook
|
||||||
|
should be ready to use.
|
||||||
|
|||||||
273
assignments/01_assignment.ipynb
Normal file
273
assignments/01_assignment.ipynb
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Image Processing SS 18 - Assignment - 01\n",
|
||||||
|
"\n",
|
||||||
|
"### Deadline is 25.4.2018 at 8:00\n",
|
||||||
|
"\n",
|
||||||
|
"Please solve the assignments together with a partner.\n",
|
||||||
|
"I will run every notebook. Make sure the code runs through, when clicked on `Kernel` -> `Restart & Run All`.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Introduction to Python / Numpy\n",
|
||||||
|
"\n",
|
||||||
|
"* [Learn Python in 15 minutes](https://learnxinyminutes.com/docs/python3/): We will use Python 3.\n",
|
||||||
|
"* [Numpy for Matlab Users](https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html#general-purpose-equivalents)\n",
|
||||||
|
"* [Numpy Quickstart](https://docs.scipy.org/doc/numpy-dev/user/quickstart.html)\n",
|
||||||
|
"\n",
|
||||||
|
"## Libraries\n",
|
||||||
|
"\n",
|
||||||
|
"We will use the following libraries:\n",
|
||||||
|
"\n",
|
||||||
|
"* matplotlib\n",
|
||||||
|
"* numpy\n",
|
||||||
|
"* scipy\n",
|
||||||
|
"* skimage\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Exercise 0 - Setup Development Enviroment - [1 Point]\n",
|
||||||
|
"\n",
|
||||||
|
"Find a partner, follow the steps in the [README](https://github.com/BildverarbeitungSS18/Hausaufgaben/blob/master/README.md) and paste a link to your repository, names and matriculation numbers into the KVV assignment box.\n",
|
||||||
|
"You do not need to upload any files to the KVV. I will clone your repository. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# display the plots inside the notebook\n",
|
||||||
|
"%matplotlib inline"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"import pylab\n",
|
||||||
|
"pylab.rcParams['figure.figsize'] = (12, 12) # This makes the plot bigger"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"The [skimage](http://scikit-image.org/) library comes with multiple useful test images. Let's start with an image of an astronaut. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from skimage.data import astronaut"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"img = astronaut() # Get the image\n",
|
||||||
|
"print(img.shape) # the dimension of the image\n",
|
||||||
|
"print(img.dtype) # the image type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We have a `(512, 512, 3)` array of unsigned bytes. At `img[x, y]` there are three values for R,G and B."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We will always work with floating point arrays between 0 and 1. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"img = img / 255."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Lets display the image."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"plt.imshow(img)\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"This is [Eileen Collins](https://en.wikipedia.org/wiki/Eileen_Collins). She was the first astronaut \n",
|
||||||
|
" to fly the Space Shuttle through a complete 360-degree pitch maneuver. What an inspiring woman."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercise 1 - Plot - [1 Point]\n",
|
||||||
|
"\n",
|
||||||
|
"Plot the R, G and B channels separately."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Your code here"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercise 2 - RGB to HSV [6 Points]\n",
|
||||||
|
"\n",
|
||||||
|
"Implement the `rgb_to_hsv` and `hsv_to_rgb` functions. Don't use any color conversion functions from a library.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def rgb_to_hsv(x):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Converts the numpy array `x` from RGB to the HSV. \n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" # Your code here\n",
|
||||||
|
" return x"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def hsv_to_rgb(x):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Converts the numpy array `x` from HSV to the RGB. \n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" # Your code here\n",
|
||||||
|
" return x"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Plot the saturation of the astronaut image"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"img_as_hsv = rgb_to_hsv(img)\n",
|
||||||
|
"# your code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Increase the saturation by a factor of 2, convert it back to RGB and plot the result."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# your code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercise 3 - Callculation [2 Points]\n",
|
||||||
|
"\n",
|
||||||
|
"In the figure below you can see the [CIE-XYZ](https://de.wikipedia.org/wiki/CIE-Normvalenzsystem) color space.\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"What are the approximate x,y,z values for the following Adobe RGB colors:\n",
|
||||||
|
"* `(0, 0.5, 0.5)`\n",
|
||||||
|
"* `(0.33, 0.33, 0.33)`\n",
|
||||||
|
"\n",
|
||||||
|
"A sodium-vapor lamp shines with double the intensity of a mercury-vapor lamp\n",
|
||||||
|
". The light from the sodium lamp only contains \n",
|
||||||
|
"the spectral line at `589,00nm` and the light from the mercury lamp only the\n",
|
||||||
|
"spectral line at `435,83 nm`.\n",
|
||||||
|
"\n",
|
||||||
|
"What color does a human experience? What are the approximate x,y,z values? \n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 1
|
||||||
|
}
|
||||||
83
docker_build.sh
Normal file
83
docker_build.sh
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
|
||||||
|
echo "Usage: docker_build.sh"
|
||||||
|
echo "Builds a docker image with a user that matches the username and uid of the host user."
|
||||||
|
fi
|
||||||
|
|
||||||
|
uid=$(id -u)
|
||||||
|
username=$(whoami)
|
||||||
|
password='password' # dummy password
|
||||||
|
out="Dockerfile"
|
||||||
|
|
||||||
|
if [ "$1" == "sample" ]; then
|
||||||
|
out="Dockerfile.sample"
|
||||||
|
uid="1000"
|
||||||
|
username="user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using username: $username with uid: $uid"
|
||||||
|
echo "The default password is: $password"
|
||||||
|
|
||||||
|
cat << EOF > $out
|
||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y zsh \\
|
||||||
|
vim \\
|
||||||
|
tmux \\
|
||||||
|
git \\
|
||||||
|
python3-numpy \\
|
||||||
|
python3-scipy \\
|
||||||
|
python3-matplotlib \\
|
||||||
|
ipython3 \\
|
||||||
|
python3-pip \\
|
||||||
|
python-pillow \\
|
||||||
|
python-pip \\
|
||||||
|
python-numpy \\
|
||||||
|
python-scipy \\
|
||||||
|
python-matplotlib \\
|
||||||
|
ipython \\
|
||||||
|
python-pil \\
|
||||||
|
python-pillow \\
|
||||||
|
python-pip
|
||||||
|
|
||||||
|
|
||||||
|
ENV LC_ALL en_US.UTF-8
|
||||||
|
RUN locale-gen en_US.UTF-8
|
||||||
|
|
||||||
|
RUN pip3 install jupyter scikit-image ipykernel
|
||||||
|
RUN pip install jupyter scikit-image ipykernel
|
||||||
|
|
||||||
|
RUN ipython3 kernel install
|
||||||
|
RUN ipython kernel install
|
||||||
|
|
||||||
|
# Use the same gid and uid as your user on the host system. You can find them
|
||||||
|
# out with the id programm. This way the file ownership in mapped directories is
|
||||||
|
# consistent with the host system.
|
||||||
|
RUN echo "%sudo ALL=(ALL) ALL" >> /etc/sudoers
|
||||||
|
RUN groupadd --gid $uid $username
|
||||||
|
RUN useradd --uid $uid --gid $username \\
|
||||||
|
--home-dir /home/$username --shell /usr/bin/bash \\
|
||||||
|
--groups sudo,$username \\
|
||||||
|
--password $password \\
|
||||||
|
$username
|
||||||
|
|
||||||
|
|
||||||
|
# set default passwords
|
||||||
|
RUN echo $username:$password | chpasswd && \\
|
||||||
|
echo root:$password | chpasswd
|
||||||
|
|
||||||
|
RUN mkdir -p /home/$username && chown -R $username:$username /home/$username
|
||||||
|
|
||||||
|
USER $username
|
||||||
|
WORKDIR /home/$username'
|
||||||
|
|
||||||
|
RUN echo "PATH=$PATH:/usr/local/bin:~/.local/bin/" > /home/$username/.bashrc
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "jupyter notebook --ip 0.0.0.0"]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ "$1" != "sample" ]; then
|
||||||
|
docker build -t 'image_processing_ss16' .
|
||||||
|
fi
|
||||||
21
docker_start.sh
Normal file
21
docker_start.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
PORT="8888"
|
||||||
|
CIDFILE=".docker_cid"
|
||||||
|
username=$(whoami)
|
||||||
|
|
||||||
|
if [ -e $CIDFILE ]; then
|
||||||
|
CID=$(cat $CIDFILE)
|
||||||
|
CMD="docker start $CID"
|
||||||
|
$CMD
|
||||||
|
else
|
||||||
|
CMD="docker run \
|
||||||
|
--cidfile=$CIDFILE \
|
||||||
|
-p $PORT:$PORT \
|
||||||
|
-v `pwd`:/home/$username/image_processing \
|
||||||
|
-d \
|
||||||
|
--name image_processing_ss16_container \
|
||||||
|
image_processing_ss16"
|
||||||
|
echo "$CMD"
|
||||||
|
$CMD
|
||||||
|
fi
|
||||||
110
nb_strip_output.py
Normal file
110
nb_strip_output.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
"""
|
||||||
|
strip output of IPython Notebooks
|
||||||
|
add this as `.git/hooks/pre-commit`
|
||||||
|
to run every time you commit a notebook
|
||||||
|
|
||||||
|
strip outputs from an IPython Notebook Opens a notebook, strips its output, and
|
||||||
|
writes the outputless version to the original file. Useful mainly as a git
|
||||||
|
filter or pre-commit hook for users who don't want to track output in VCS.
|
||||||
|
This does mostly the same thing as the `Clear All Output` command in the
|
||||||
|
notebook UI.
|
||||||
|
LICENSE: Public Domain
|
||||||
|
Adapted from: https://gist.github.com/minrk/6176788
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
from subprocess import PIPE, Popen
|
||||||
|
import io
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Jupyter >= 4
|
||||||
|
from nbformat import read, write, NO_CONVERT
|
||||||
|
except ImportError:
|
||||||
|
# IPython 3
|
||||||
|
try:
|
||||||
|
from IPython.nbformat import read, write, NO_CONVERT
|
||||||
|
except ImportError:
|
||||||
|
# IPython < 3
|
||||||
|
from IPython.nbformat import current
|
||||||
|
|
||||||
|
def read(f, as_version):
|
||||||
|
return current.read(f, 'json')
|
||||||
|
|
||||||
|
def write(nb, f):
|
||||||
|
return current.write(nb, f, 'json')
|
||||||
|
|
||||||
|
|
||||||
|
def get_rev():
|
||||||
|
command = "git rev-parse --verify HEAD".split(" ")
|
||||||
|
if subprocess.call(command, stdin=PIPE, stdout=PIPE, stderr=PIPE) == 0:
|
||||||
|
return 'HEAD'
|
||||||
|
else:
|
||||||
|
return '4b825dc642cb6eb9a060e54bf8d69288fbee4904'
|
||||||
|
|
||||||
|
|
||||||
|
def get_notebooks(against):
|
||||||
|
command = "git diff-index -z --cached {} --name-only".format(against)
|
||||||
|
p = Popen(command.split(" "), stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
output, err = p.communicate()
|
||||||
|
assert p.returncode == 0, \
|
||||||
|
"Command failed: {}\nstdout:\n{}\nstderr:\n{}"\
|
||||||
|
.format(command, output, err)
|
||||||
|
files = [binary_fname.decode('utf8')
|
||||||
|
for binary_fname in output.split(b'\x00')]
|
||||||
|
return set([f for f in files if f.endswith(".ipynb")])
|
||||||
|
|
||||||
|
|
||||||
|
def run_as_git_hook():
|
||||||
|
against = get_rev()
|
||||||
|
for notebook_fname in get_notebooks(against):
|
||||||
|
print("Stripping output from: {}".format(notebook_fname))
|
||||||
|
strip_output(notebook_fname)
|
||||||
|
|
||||||
|
command = "git diff-index --check --cached {} --".format(against)
|
||||||
|
subprocess.call(command.split(" "))
|
||||||
|
|
||||||
|
|
||||||
|
def _cells(nb):
|
||||||
|
"""Yield all cells in an nbformat-insensitive manner"""
|
||||||
|
if nb.nbformat < 4:
|
||||||
|
for ws in nb.worksheets:
|
||||||
|
for cell in ws.cells:
|
||||||
|
yield cell
|
||||||
|
else:
|
||||||
|
for cell in nb.cells:
|
||||||
|
yield cell
|
||||||
|
|
||||||
|
|
||||||
|
def strip_output(filename):
|
||||||
|
"""strip the outputs from a notebook"""
|
||||||
|
|
||||||
|
with io.open(filename, 'r', encoding='utf8') as f:
|
||||||
|
nb = read(f, as_version=NO_CONVERT)
|
||||||
|
|
||||||
|
nb.metadata.pop('signature', None)
|
||||||
|
for cell in _cells(nb):
|
||||||
|
if 'outputs' in cell:
|
||||||
|
cell['outputs'] = []
|
||||||
|
if 'prompt_number' in cell:
|
||||||
|
cell['prompt_number'] = None
|
||||||
|
with io.open(filename, 'w', encoding='utf8') as f:
|
||||||
|
write(nb, f)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Strips the output from a notebook')
|
||||||
|
parser.add_argument('file', type=str, default='', nargs='?',
|
||||||
|
help='remove the output from this notebook')
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.file == '':
|
||||||
|
run_as_git_hook()
|
||||||
|
|
||||||
|
else:
|
||||||
|
fname = args.file
|
||||||
|
if not os.path.exists(fname):
|
||||||
|
print("File {} does not exists.".format(fname))
|
||||||
|
strip_output(fname)
|
||||||
Reference in New Issue
Block a user